parent
c325d4466f
commit
3e88e2cab4
|
@ -227,6 +227,9 @@ export default defineComponent({
|
||||||
routeIsFolders(): boolean {
|
routeIsFolders(): boolean {
|
||||||
return this.$route.name === 'folders';
|
return this.$route.name === 'folders';
|
||||||
},
|
},
|
||||||
|
routeHasNative(): boolean {
|
||||||
|
return this.routeIsBase && nativex.has();
|
||||||
|
},
|
||||||
isMonthView(): boolean {
|
isMonthView(): boolean {
|
||||||
if (this.$route.query.sort === 'timeline') return false;
|
if (this.$route.query.sort === 'timeline') return false;
|
||||||
|
|
||||||
|
@ -705,6 +708,10 @@ export default defineComponent({
|
||||||
if (!noCache) {
|
if (!noCache) {
|
||||||
try {
|
try {
|
||||||
if ((cache = await utils.getCachedData(cacheUrl))) {
|
if ((cache = await utils.getCachedData(cacheUrl))) {
|
||||||
|
if (this.routeHasNative) {
|
||||||
|
await nativex.extendDaysWithLocal(cache);
|
||||||
|
}
|
||||||
|
|
||||||
await this.processDays(cache);
|
await this.processDays(cache);
|
||||||
this.loading--;
|
this.loading--;
|
||||||
}
|
}
|
||||||
|
@ -723,6 +730,11 @@ export default defineComponent({
|
||||||
// Put back into cache
|
// Put back into cache
|
||||||
utils.cacheData(cacheUrl, data);
|
utils.cacheData(cacheUrl, data);
|
||||||
|
|
||||||
|
// Extend with native days
|
||||||
|
if (this.routeHasNative) {
|
||||||
|
await nativex.extendDaysWithLocal(data);
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure we're still on the same page
|
// Make sure we're still on the same page
|
||||||
if (this.state !== startState) return;
|
if (this.state !== startState) return;
|
||||||
await this.processDays(data);
|
await this.processDays(data);
|
||||||
|
@ -862,7 +874,15 @@ export default defineComponent({
|
||||||
const cacheUrl = this.getDayUrl(dayId);
|
const cacheUrl = this.getDayUrl(dayId);
|
||||||
try {
|
try {
|
||||||
const cache = await utils.getCachedData<IPhoto[]>(cacheUrl);
|
const cache = await utils.getCachedData<IPhoto[]>(cacheUrl);
|
||||||
if (cache) this.processDay(dayId, cache);
|
if (cache) {
|
||||||
|
// Cache only contains remote images; update from local too
|
||||||
|
if (this.routeHasNative) {
|
||||||
|
await nativex.extendDayWithLocal(dayId, cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the cache
|
||||||
|
this.processDay(dayId, cache);
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
console.warn(`Failed to process day cache: ${cacheUrl}`);
|
console.warn(`Failed to process day cache: ${cacheUrl}`);
|
||||||
}
|
}
|
||||||
|
@ -887,8 +907,13 @@ export default defineComponent({
|
||||||
async fetchDayExpire() {
|
async fetchDayExpire() {
|
||||||
if (this.fetchDayQueue.length === 0) return;
|
if (this.fetchDayQueue.length === 0) return;
|
||||||
|
|
||||||
|
// Map of dayId to photos
|
||||||
|
const dayIds = this.fetchDayQueue;
|
||||||
|
const dayMap = new Map<number, IPhoto[]>();
|
||||||
|
for (const dayId of dayIds) dayMap.set(dayId, []);
|
||||||
|
|
||||||
// Construct URL
|
// Construct URL
|
||||||
const dayStr = this.fetchDayQueue.join(',');
|
const dayStr = dayIds.join(',');
|
||||||
const url = this.getDayUrl(dayStr);
|
const url = this.getDayUrl(dayStr);
|
||||||
this.fetchDayQueue = [];
|
this.fetchDayQueue = [];
|
||||||
|
|
||||||
|
@ -905,20 +930,8 @@ export default defineComponent({
|
||||||
|
|
||||||
// Bin the data into separate days
|
// Bin the data into separate days
|
||||||
// It is already sorted in dayid DESC
|
// It is already sorted in dayid DESC
|
||||||
const dayMap = new Map<number, IPhoto[]>();
|
|
||||||
for (const photo of data) {
|
for (const photo of data) {
|
||||||
if (!dayMap.has(photo.dayid)) dayMap.set(photo.dayid, []);
|
dayMap.get(photo.dayid)?.push(photo);
|
||||||
dayMap.get(photo.dayid)!.push(photo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get local images if we are running in native environment.
|
|
||||||
// Get them all together for each day here.
|
|
||||||
if (nativex.has()) {
|
|
||||||
const promises: Promise<void>[] = [];
|
|
||||||
for (const [dayId, photos] of dayMap) {
|
|
||||||
promises.push(nativex.extendDayWithLocal(dayId, photos));
|
|
||||||
}
|
|
||||||
await Promise.all(promises);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store cache asynchronously
|
// Store cache asynchronously
|
||||||
|
@ -928,9 +941,20 @@ export default defineComponent({
|
||||||
// These loops cannot be combined because processDay
|
// These loops cannot be combined because processDay
|
||||||
// creates circular references which cannot be stringified
|
// creates circular references which cannot be stringified
|
||||||
for (const [dayId, photos] of dayMap) {
|
for (const [dayId, photos] of dayMap) {
|
||||||
|
if (photos.length === 0) continue;
|
||||||
utils.cacheData(this.getDayUrl(dayId), photos);
|
utils.cacheData(this.getDayUrl(dayId), photos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get local images if we are running in native environment.
|
||||||
|
// Get them all together for each day here.
|
||||||
|
if (this.routeHasNative) {
|
||||||
|
await Promise.all(
|
||||||
|
Array.from(dayMap.entries()).map(([dayId, photos]) => {
|
||||||
|
return nativex.extendDayWithLocal(dayId, photos);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Process each day as needed
|
// Process each day as needed
|
||||||
for (const [dayId, photos] of dayMap) {
|
for (const [dayId, photos] of dayMap) {
|
||||||
// Check if the response has any delta
|
// Check if the response has any delta
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { IPhoto } from './types';
|
import type { IDay, IPhoto } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type of a native promise (this will be the exact type in Java).
|
* Type of a native promise (this will be the exact type in Java).
|
||||||
|
@ -10,6 +10,7 @@ type NativePromise<T> = (call: string, arg: T) => void;
|
||||||
*/
|
*/
|
||||||
export type NativeX = {
|
export type NativeX = {
|
||||||
isNative: () => boolean;
|
isNative: () => boolean;
|
||||||
|
getLocalDays: NativePromise<string>;
|
||||||
getLocalByDayId: NativePromise<string>;
|
getLocalByDayId: NativePromise<string>;
|
||||||
getJpeg: NativePromise<string>;
|
getJpeg: NativePromise<string>;
|
||||||
};
|
};
|
||||||
|
@ -79,6 +80,13 @@ globalThis.nativexr = (call: string, resolve?: string, reject?: string) => {
|
||||||
*/
|
*/
|
||||||
export const has = () => !!nativex;
|
export const has = () => !!nativex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the local days array.
|
||||||
|
*
|
||||||
|
* @returns List of local days (JSON string)
|
||||||
|
*/
|
||||||
|
const getLocalDays = nativePromisify<number, string>(nativex?.getLocalDays.bind(nativex));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the local photos for a day with a dayId.
|
* Gets the local photos for a day with a dayId.
|
||||||
*
|
*
|
||||||
|
@ -95,6 +103,32 @@ const getLocalByDayId = nativePromisify<number, string>(nativex?.getLocalByDayId
|
||||||
*/
|
*/
|
||||||
const getJpeg = nativePromisify<string, string>(nativex?.getJpeg.bind(nativex), true);
|
const getJpeg = nativePromisify<string, string>(nativex?.getJpeg.bind(nativex), true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend a list of days with local days.
|
||||||
|
* Fetches the local days from the native interface.
|
||||||
|
*/
|
||||||
|
export async function extendDaysWithLocal(days: IDay[]) {
|
||||||
|
if (!has()) return;
|
||||||
|
|
||||||
|
// Query native part
|
||||||
|
const local: IDay[] = JSON.parse(await getLocalDays(0));
|
||||||
|
const remoteMap = new Map(days.map((d) => [d.dayid, d]));
|
||||||
|
|
||||||
|
// Merge local days into remote days
|
||||||
|
for (const day of local) {
|
||||||
|
const remote = remoteMap.get(day.dayid);
|
||||||
|
if (remote) {
|
||||||
|
remote.count = Math.max(remote.count, day.count);
|
||||||
|
} else {
|
||||||
|
days.push(day);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: sort depends on view
|
||||||
|
// (but we show it for only timeline anyway for now)
|
||||||
|
days.sort((a, b) => b.dayid - a.dayid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend a list of photos with local photos.
|
* Extend a list of photos with local photos.
|
||||||
* Fetches the local photos from the native interface and filters out duplicates.
|
* Fetches the local photos from the native interface and filters out duplicates.
|
||||||
|
|
Loading…
Reference in New Issue