@mentra/engine 3.2.0-dev.266 → 3.2.1-dev.276
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/generated/releaseMetadata.js +6 -6
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.js +17 -17
- package/build/react/MentraLiveOtaFlow.js.map +1 -1
- package/build/services/OtaErrorMapping.js +3 -3
- package/build/services/OtaErrorMapping.js.map +1 -1
- package/build/services/asg/gallerySyncService.d.ts +1 -1
- package/build/services/asg/gallerySyncService.d.ts.map +1 -1
- package/build/services/asg/gallerySyncService.js +8 -7
- package/build/services/asg/gallerySyncService.js.map +1 -1
- package/build/stores/gallerySync.d.ts +1 -1
- package/build/stores/gallerySync.d.ts.map +1 -1
- package/build/stores/gallerySync.js +4 -1
- package/build/stores/gallerySync.js.map +1 -1
- package/package.json +8 -8
- package/src/generated/releaseMetadata.ts +6 -6
- package/src/react/MentraLiveOtaFlow.tsx +17 -17
- package/src/services/OtaErrorMapping.ts +3 -3
- package/src/services/asg/gallerySyncService.ts +9 -11
- package/src/stores/gallerySync.ts +5 -1
|
@@ -17,7 +17,7 @@ export interface PhotoInfo {
|
|
|
17
17
|
thumbnailPath?: string;
|
|
18
18
|
glassesModel?: string;
|
|
19
19
|
}
|
|
20
|
-
export type SyncState = "idle" | "requesting_hotspot" | "connecting_wifi" | "syncing" | "complete" | "error" | "cancelled";
|
|
20
|
+
export type SyncState = "idle" | "requesting_hotspot" | "connecting_wifi" | "preparing" | "syncing" | "complete" | "error" | "cancelled";
|
|
21
21
|
export interface HotspotInfo {
|
|
22
22
|
ssid: string;
|
|
23
23
|
password: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gallerySync.d.ts","sourceRoot":"","sources":["../../src/stores/gallerySync.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAGD,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,oBAAoB,GACpB,iBAAiB,GACjB,SAAS,GACT,UAAU,GACV,OAAO,GACP,WAAW,CAAA;AAEf,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,WAAW,CAAA;CACzB;AAED,MAAM,WAAW,eAAe;IAE9B,SAAS,EAAE,SAAS,CAAA;IACpB,YAAY,EAAE,OAAO,CAAA;IAGrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,EAAE,CAAA;IAGrB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAGlB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,wBAAwB,EAAE,OAAO,CAAA;IAGjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,OAAO,CAAA;IAG1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IAEvD,YAAY,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAA;IACxC,eAAe,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5C,oBAAoB,EAAE,MAAM,IAAI,CAAA;IAChC,iBAAiB,EAAE,MAAM,IAAI,CAAA;IAC7B,UAAU,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,CAAA;IACxC,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,gBAAgB,EAAE,MAAM,IAAI,CAAA;IAG5B,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACnE,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5D,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACxD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5C,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,KAAK,IAAI,CAAA;IACrE,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IAGnD,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC5B,cAAc,EAAE,MAAM,CAAA;IAGtB,cAAc,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAClD,2BAA2B,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;IAGtD,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,KAAK,IAAI,CAAA;IACrG,yBAAyB,EAAE,MAAM,IAAI,CAAA;IAGrC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3D,YAAY,EAAE,MAAM,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,IAAI,CAAA;IAGtB,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAuBD,eAAO,MAAM,mBAAmB;;;;;;;;EAyN/B,CAAA;AAGD,eAAO,MAAM,kBAAkB,GAAI,OAAO,gBAAgB;;;;;;;;CAQxD,CAAA;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,gBAAgB,
|
|
1
|
+
{"version":3,"file":"gallerySync.d.ts","sourceRoot":"","sources":["../../src/stores/gallerySync.ts"],"names":[],"mappings":"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"}
|
|
@@ -209,7 +209,10 @@ export const selectSyncProgress = (state) => ({
|
|
|
209
209
|
failedFiles: state.failedFiles,
|
|
210
210
|
processingFiles: state.processingFiles,
|
|
211
211
|
});
|
|
212
|
-
export const selectIssyncing = (state) => state.syncState === "syncing" ||
|
|
212
|
+
export const selectIssyncing = (state) => state.syncState === "syncing" ||
|
|
213
|
+
state.syncState === "preparing" ||
|
|
214
|
+
state.syncState === "requesting_hotspot" ||
|
|
215
|
+
state.syncState === "connecting_wifi";
|
|
213
216
|
export const selectGlassesGalleryStatus = (state) => ({
|
|
214
217
|
photos: state.glassesPhotoCount,
|
|
215
218
|
videos: state.glassesVideoCount,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gallerySync.js","sourceRoot":"","sources":["../../src/stores/gallerySync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Gallery Sync Store\n * Manages gallery sync state independently of UI lifecycle\n */\n\nimport {create} from \"zustand\"\nimport {subscribeWithSelector} from \"zustand/middleware\"\n\n// Relocated from the host @/types/asg so this store is self-contained inside\n// engine. The host barrel re-exports this (a shim), so its importers are unchanged.\nexport interface PhotoInfo {\n name: string\n url: string\n download: string\n size: number\n modified: string | number // Unix timestamp (milliseconds) - can be string or number from API\n mime_type?: string\n is_video?: boolean\n thumbnail_data?: string\n downloaded_at?: number\n // Video duration in milliseconds (from glasses sync response)\n duration?: number\n // New fields for filesystem storage\n filePath?: string\n thumbnailPath?: string\n // Glasses model that captured this media\n glassesModel?: string\n}\n\n// Sync state machine states\nexport type SyncState =\n | \"idle\"\n | \"requesting_hotspot\"\n | \"connecting_wifi\"\n | \"syncing\"\n | \"complete\"\n | \"error\"\n | \"cancelled\"\n\nexport interface HotspotInfo {\n ssid: string\n password: string\n ip: string\n}\n\nexport interface SyncQueue {\n files: PhotoInfo[]\n currentIndex: number\n startedAt: number\n hotspotInfo: HotspotInfo\n}\n\nexport interface GallerySyncInfo {\n // State machine\n syncState: SyncState\n syncStarting: boolean\n\n // Progress tracking\n currentFile: string | null\n currentFileProgress: number // 0-100\n completedFiles: number\n totalFiles: number\n failedFiles: string[]\n\n // Queue (persisted separately via localStorageService)\n queue: PhotoInfo[]\n queueIndex: number\n\n // Hotspot info\n hotspotInfo: HotspotInfo | null\n syncServiceOpenedHotspot: boolean\n\n // Gallery status from glasses\n glassesPhotoCount: number\n glassesVideoCount: number\n glassesTotalCount: number\n glassesHasContent: boolean\n\n // Error tracking\n lastError: string | null\n}\n\nexport interface GallerySyncState extends GallerySyncInfo {\n // State transitions\n setSyncState: (state: SyncState) => void\n setSyncStarting: (starting: boolean) => void\n setRequestingHotspot: () => void\n setConnectingWifi: () => void\n setSyncing: (files: PhotoInfo[]) => void\n setSyncComplete: () => void\n setSyncError: (error: string) => void\n setSyncCancelled: () => void\n\n // Progress updates\n setCurrentFile: (fileName: string | null, progress: number) => void\n onFileProgress: (fileName: string, progress: number) => void\n onFileComplete: (fileName: string) => void\n onFileFailed: (fileName: string, error?: string) => void\n onFileProcessing: (fileName: string) => void\n onFileProcessed: (fileName: string) => void\n updateFileInQueue: (fileName: string, updatedFile: PhotoInfo) => void\n removeFilesFromQueue: (fileNames: string[]) => void\n\n // Processing queue tracking\n processingFiles: Set<string>\n processedFiles: number\n\n // Hotspot management\n setHotspotInfo: (info: HotspotInfo | null) => void\n setSyncServiceOpenedHotspot: (opened: boolean) => void\n\n // Gallery status from glasses\n setGlassesGalleryStatus: (photos: number, videos: number, total: number, hasContent: boolean) => void\n clearGlassesGalleryStatus: () => void\n\n // Queue management (for resume)\n setQueue: (files: PhotoInfo[], startIndex?: number) => void\n advanceQueue: () => void\n clearQueue: () => void\n\n // Full reset\n reset: () => void\n}\n\nconst initialState: GallerySyncInfo & {processingFiles: Set<string>; processedFiles: number} = {\n syncState: \"idle\",\n syncStarting: false,\n currentFile: null,\n currentFileProgress: 0,\n completedFiles: 0,\n totalFiles: 0,\n failedFiles: [],\n queue: [],\n queueIndex: 0,\n hotspotInfo: null,\n syncServiceOpenedHotspot: false,\n glassesPhotoCount: 0,\n glassesVideoCount: 0,\n glassesTotalCount: 0,\n glassesHasContent: false,\n lastError: null,\n processingFiles: new Set<string>(),\n processedFiles: 0,\n}\n\nexport const useGallerySyncStore = create<GallerySyncState>()(\n subscribeWithSelector((set, get) => ({\n ...initialState,\n\n // State transitions\n setSyncState: (syncState: SyncState) => set({syncState}),\n setSyncStarting: (syncStarting: boolean) => set({syncStarting}),\n\n setRequestingHotspot: () =>\n set({\n syncState: \"requesting_hotspot\",\n lastError: null,\n failedFiles: [],\n }),\n\n setConnectingWifi: () =>\n set({\n syncState: \"connecting_wifi\",\n }),\n\n setSyncing: (files: PhotoInfo[]) =>\n set({\n syncState: \"syncing\",\n // C4: Strip thumbnail_data (base64) from store to prevent OOM\n queue: files.map(({thumbnail_data: _thumbnailData, ...rest}) => rest),\n queueIndex: 0,\n totalFiles: files.length,\n completedFiles: 0,\n currentFile: files.length > 0 ? files[0].name : null,\n currentFileProgress: 0,\n failedFiles: [],\n lastError: null,\n processedFiles: 0,\n processingFiles: new Set<string>(),\n }),\n\n setSyncComplete: () =>\n set({\n syncState: \"complete\",\n currentFile: null,\n currentFileProgress: 0,\n // Keep queue intact so photos remain visible after sync\n // Don't clear: queue: [], queueIndex: 0\n }),\n\n setSyncError: (error: string) =>\n set({\n syncState: \"error\",\n lastError: error,\n currentFile: null,\n currentFileProgress: 0,\n }),\n\n setSyncCancelled: () =>\n set({\n syncState: \"cancelled\",\n currentFile: null,\n currentFileProgress: 0,\n queue: [],\n queueIndex: 0,\n }),\n\n // Progress updates\n setCurrentFile: (fileName: string | null, progress: number) =>\n set({\n currentFile: fileName,\n currentFileProgress: Math.max(0, Math.min(100, progress)),\n }),\n\n onFileProgress: (fileName: string, progress: number) => {\n const state = get()\n const clampedProgress = Math.max(0, Math.min(100, progress))\n // Throttle: skip update if same file and same percentage (prevents Zustand flood)\n if (clampedProgress === state.currentFileProgress && fileName === state.currentFile) {\n return\n }\n set({\n currentFile: fileName,\n currentFileProgress: clampedProgress,\n })\n },\n\n onFileComplete: (_fileName: string) => {\n const state = get()\n const newCompletedFiles = state.completedFiles + 1\n const newQueueIndex = state.queueIndex + 1\n const nextFile = state.queue[newQueueIndex]\n\n set({\n completedFiles: newCompletedFiles,\n queueIndex: newQueueIndex,\n currentFile: nextFile?.name || null,\n currentFileProgress: 0,\n })\n },\n\n onFileFailed: (fileName: string, _error?: string) => {\n const state = get()\n const newQueueIndex = state.queueIndex + 1\n const nextFile = state.queue[newQueueIndex]\n\n set({\n failedFiles: [...state.failedFiles, fileName],\n queueIndex: newQueueIndex,\n currentFile: nextFile?.name || null,\n currentFileProgress: 0,\n })\n },\n\n onFileProcessing: (fileName: string) => {\n const state = get()\n const newSet = new Set(state.processingFiles)\n newSet.add(fileName)\n set({processingFiles: newSet})\n },\n\n onFileProcessed: (fileName: string) => {\n const state = get()\n const newSet = new Set(state.processingFiles)\n newSet.delete(fileName)\n set({processingFiles: newSet, processedFiles: state.processedFiles + 1})\n },\n\n updateFileInQueue: (fileName: string, updatedFile: PhotoInfo) => {\n const state = get()\n const updatedQueue = state.queue.map((file) => (file.name === fileName ? updatedFile : file))\n set({queue: updatedQueue})\n },\n\n removeFilesFromQueue: (fileNames: string[]) => {\n if (fileNames.length === 0) return\n\n const filesToRemove = new Set(fileNames)\n const state = get()\n const failedFilesSet = new Set(state.failedFiles)\n const filesBeforeQueueIndex = state.queue\n .slice(0, state.queueIndex)\n .filter((file) => filesToRemove.has(file.name))\n const removedBeforeQueueIndex = filesBeforeQueueIndex.length\n const removedCompletedBeforeQueueIndex = filesBeforeQueueIndex.filter(\n (file) => !failedFilesSet.has(file.name),\n ).length\n const filteredQueue = state.queue.filter((file) => !filesToRemove.has(file.name))\n const removedCount = state.queue.length - filteredQueue.length\n\n if (removedCount === 0) return\n\n const nextQueueIndex = state.queueIndex - removedBeforeQueueIndex\n const currentFileRemoved = state.currentFile !== null && filesToRemove.has(state.currentFile)\n\n set({\n queue: filteredQueue,\n totalFiles: state.totalFiles - removedCount,\n completedFiles: Math.max(0, state.completedFiles - removedCompletedBeforeQueueIndex),\n queueIndex: nextQueueIndex,\n failedFiles: state.failedFiles.filter((fileName) => !filesToRemove.has(fileName)),\n processingFiles: new Set(Array.from(state.processingFiles).filter((fileName) => !filesToRemove.has(fileName))),\n currentFile: currentFileRemoved ? filteredQueue[nextQueueIndex]?.name || null : state.currentFile,\n })\n },\n\n // Hotspot management\n setHotspotInfo: (info: HotspotInfo | null) => set({hotspotInfo: info}),\n\n setSyncServiceOpenedHotspot: (opened: boolean) => set({syncServiceOpenedHotspot: opened}),\n\n // Gallery status from glasses\n setGlassesGalleryStatus: (photos: number, videos: number, total: number, hasContent: boolean) => {\n const state = get()\n // Reset to idle if sync is in a terminal state and new content is available\n // This allows syncing again after taking new photos\n const shouldResetToIdle =\n hasContent && (state.syncState === \"complete\" || state.syncState === \"error\" || state.syncState === \"cancelled\")\n\n set({\n glassesPhotoCount: photos,\n glassesVideoCount: videos,\n glassesTotalCount: total,\n glassesHasContent: hasContent,\n ...(shouldResetToIdle ? {syncState: \"idle\" as SyncState} : {}),\n })\n },\n\n clearGlassesGalleryStatus: () =>\n set({\n glassesPhotoCount: 0,\n glassesVideoCount: 0,\n glassesTotalCount: 0,\n glassesHasContent: false,\n }),\n\n // Queue management\n setQueue: (files: PhotoInfo[], startIndex: number = 0) =>\n set({\n // C4: Strip thumbnail_data (base64) from store to prevent OOM\n queue: files.map(({thumbnail_data: _thumbnailData, ...rest}) => rest),\n queueIndex: startIndex,\n totalFiles: files.length,\n completedFiles: startIndex,\n }),\n\n advanceQueue: () => {\n const state = get()\n set({queueIndex: state.queueIndex + 1})\n },\n\n clearQueue: () =>\n set({\n queue: [],\n queueIndex: 0,\n totalFiles: 0,\n completedFiles: 0,\n }),\n\n // Full reset\n reset: () => set({...initialState, processingFiles: new Set<string>()}),\n })),\n)\n\n// Selector helpers for common subscriptions\nexport const selectSyncProgress = (state: GallerySyncState) => ({\n syncState: state.syncState,\n currentFile: state.currentFile,\n currentFileProgress: state.currentFileProgress,\n completedFiles: state.completedFiles,\n totalFiles: state.totalFiles,\n failedFiles: state.failedFiles,\n processingFiles: state.processingFiles,\n})\n\nexport const selectIssyncing = (state: GallerySyncState) =>\n state.syncState === \"syncing\" || state.syncState === \"requesting_hotspot\" || state.syncState === \"connecting_wifi\"\n\nexport const selectGlassesGalleryStatus = (state: GallerySyncState) => ({\n photos: state.glassesPhotoCount,\n videos: state.glassesVideoCount,\n total: state.glassesTotalCount,\n hasContent: state.glassesHasContent,\n})\n"]}
|
|
1
|
+
{"version":3,"file":"gallerySync.js","sourceRoot":"","sources":["../../src/stores/gallerySync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Gallery Sync Store\n * Manages gallery sync state independently of UI lifecycle\n */\n\nimport {create} from \"zustand\"\nimport {subscribeWithSelector} from \"zustand/middleware\"\n\n// Relocated from the host @/types/asg so this store is self-contained inside\n// engine. The host barrel re-exports this (a shim), so its importers are unchanged.\nexport interface PhotoInfo {\n name: string\n url: string\n download: string\n size: number\n modified: string | number // Unix timestamp (milliseconds) - can be string or number from API\n mime_type?: string\n is_video?: boolean\n thumbnail_data?: string\n downloaded_at?: number\n // Video duration in milliseconds (from glasses sync response)\n duration?: number\n // New fields for filesystem storage\n filePath?: string\n thumbnailPath?: string\n // Glasses model that captured this media\n glassesModel?: string\n}\n\n// Sync state machine states\nexport type SyncState =\n | \"idle\"\n | \"requesting_hotspot\"\n | \"connecting_wifi\"\n | \"preparing\"\n | \"syncing\"\n | \"complete\"\n | \"error\"\n | \"cancelled\"\n\nexport interface HotspotInfo {\n ssid: string\n password: string\n ip: string\n}\n\nexport interface SyncQueue {\n files: PhotoInfo[]\n currentIndex: number\n startedAt: number\n hotspotInfo: HotspotInfo\n}\n\nexport interface GallerySyncInfo {\n // State machine\n syncState: SyncState\n syncStarting: boolean\n\n // Progress tracking\n currentFile: string | null\n currentFileProgress: number // 0-100\n completedFiles: number\n totalFiles: number\n failedFiles: string[]\n\n // Queue (persisted separately via localStorageService)\n queue: PhotoInfo[]\n queueIndex: number\n\n // Hotspot info\n hotspotInfo: HotspotInfo | null\n syncServiceOpenedHotspot: boolean\n\n // Gallery status from glasses\n glassesPhotoCount: number\n glassesVideoCount: number\n glassesTotalCount: number\n glassesHasContent: boolean\n\n // Error tracking\n lastError: string | null\n}\n\nexport interface GallerySyncState extends GallerySyncInfo {\n // State transitions\n setSyncState: (state: SyncState) => void\n setSyncStarting: (starting: boolean) => void\n setRequestingHotspot: () => void\n setConnectingWifi: () => void\n setSyncing: (files: PhotoInfo[]) => void\n setSyncComplete: () => void\n setSyncError: (error: string) => void\n setSyncCancelled: () => void\n\n // Progress updates\n setCurrentFile: (fileName: string | null, progress: number) => void\n onFileProgress: (fileName: string, progress: number) => void\n onFileComplete: (fileName: string) => void\n onFileFailed: (fileName: string, error?: string) => void\n onFileProcessing: (fileName: string) => void\n onFileProcessed: (fileName: string) => void\n updateFileInQueue: (fileName: string, updatedFile: PhotoInfo) => void\n removeFilesFromQueue: (fileNames: string[]) => void\n\n // Processing queue tracking\n processingFiles: Set<string>\n processedFiles: number\n\n // Hotspot management\n setHotspotInfo: (info: HotspotInfo | null) => void\n setSyncServiceOpenedHotspot: (opened: boolean) => void\n\n // Gallery status from glasses\n setGlassesGalleryStatus: (photos: number, videos: number, total: number, hasContent: boolean) => void\n clearGlassesGalleryStatus: () => void\n\n // Queue management (for resume)\n setQueue: (files: PhotoInfo[], startIndex?: number) => void\n advanceQueue: () => void\n clearQueue: () => void\n\n // Full reset\n reset: () => void\n}\n\nconst initialState: GallerySyncInfo & {processingFiles: Set<string>; processedFiles: number} = {\n syncState: \"idle\",\n syncStarting: false,\n currentFile: null,\n currentFileProgress: 0,\n completedFiles: 0,\n totalFiles: 0,\n failedFiles: [],\n queue: [],\n queueIndex: 0,\n hotspotInfo: null,\n syncServiceOpenedHotspot: false,\n glassesPhotoCount: 0,\n glassesVideoCount: 0,\n glassesTotalCount: 0,\n glassesHasContent: false,\n lastError: null,\n processingFiles: new Set<string>(),\n processedFiles: 0,\n}\n\nexport const useGallerySyncStore = create<GallerySyncState>()(\n subscribeWithSelector((set, get) => ({\n ...initialState,\n\n // State transitions\n setSyncState: (syncState: SyncState) => set({syncState}),\n setSyncStarting: (syncStarting: boolean) => set({syncStarting}),\n\n setRequestingHotspot: () =>\n set({\n syncState: \"requesting_hotspot\",\n lastError: null,\n failedFiles: [],\n }),\n\n setConnectingWifi: () =>\n set({\n syncState: \"connecting_wifi\",\n }),\n\n setSyncing: (files: PhotoInfo[]) =>\n set({\n syncState: \"syncing\",\n // C4: Strip thumbnail_data (base64) from store to prevent OOM\n queue: files.map(({thumbnail_data: _thumbnailData, ...rest}) => rest),\n queueIndex: 0,\n totalFiles: files.length,\n completedFiles: 0,\n currentFile: files.length > 0 ? files[0].name : null,\n currentFileProgress: 0,\n failedFiles: [],\n lastError: null,\n processedFiles: 0,\n processingFiles: new Set<string>(),\n }),\n\n setSyncComplete: () =>\n set({\n syncState: \"complete\",\n currentFile: null,\n currentFileProgress: 0,\n // Keep queue intact so photos remain visible after sync\n // Don't clear: queue: [], queueIndex: 0\n }),\n\n setSyncError: (error: string) =>\n set({\n syncState: \"error\",\n lastError: error,\n currentFile: null,\n currentFileProgress: 0,\n }),\n\n setSyncCancelled: () =>\n set({\n syncState: \"cancelled\",\n currentFile: null,\n currentFileProgress: 0,\n queue: [],\n queueIndex: 0,\n }),\n\n // Progress updates\n setCurrentFile: (fileName: string | null, progress: number) =>\n set({\n currentFile: fileName,\n currentFileProgress: Math.max(0, Math.min(100, progress)),\n }),\n\n onFileProgress: (fileName: string, progress: number) => {\n const state = get()\n const clampedProgress = Math.max(0, Math.min(100, progress))\n // Throttle: skip update if same file and same percentage (prevents Zustand flood)\n if (clampedProgress === state.currentFileProgress && fileName === state.currentFile) {\n return\n }\n set({\n currentFile: fileName,\n currentFileProgress: clampedProgress,\n })\n },\n\n onFileComplete: (_fileName: string) => {\n const state = get()\n const newCompletedFiles = state.completedFiles + 1\n const newQueueIndex = state.queueIndex + 1\n const nextFile = state.queue[newQueueIndex]\n\n set({\n completedFiles: newCompletedFiles,\n queueIndex: newQueueIndex,\n currentFile: nextFile?.name || null,\n currentFileProgress: 0,\n })\n },\n\n onFileFailed: (fileName: string, _error?: string) => {\n const state = get()\n const newQueueIndex = state.queueIndex + 1\n const nextFile = state.queue[newQueueIndex]\n\n set({\n failedFiles: [...state.failedFiles, fileName],\n queueIndex: newQueueIndex,\n currentFile: nextFile?.name || null,\n currentFileProgress: 0,\n })\n },\n\n onFileProcessing: (fileName: string) => {\n const state = get()\n const newSet = new Set(state.processingFiles)\n newSet.add(fileName)\n set({processingFiles: newSet})\n },\n\n onFileProcessed: (fileName: string) => {\n const state = get()\n const newSet = new Set(state.processingFiles)\n newSet.delete(fileName)\n set({processingFiles: newSet, processedFiles: state.processedFiles + 1})\n },\n\n updateFileInQueue: (fileName: string, updatedFile: PhotoInfo) => {\n const state = get()\n const updatedQueue = state.queue.map((file) => (file.name === fileName ? updatedFile : file))\n set({queue: updatedQueue})\n },\n\n removeFilesFromQueue: (fileNames: string[]) => {\n if (fileNames.length === 0) return\n\n const filesToRemove = new Set(fileNames)\n const state = get()\n const failedFilesSet = new Set(state.failedFiles)\n const filesBeforeQueueIndex = state.queue\n .slice(0, state.queueIndex)\n .filter((file) => filesToRemove.has(file.name))\n const removedBeforeQueueIndex = filesBeforeQueueIndex.length\n const removedCompletedBeforeQueueIndex = filesBeforeQueueIndex.filter(\n (file) => !failedFilesSet.has(file.name),\n ).length\n const filteredQueue = state.queue.filter((file) => !filesToRemove.has(file.name))\n const removedCount = state.queue.length - filteredQueue.length\n\n if (removedCount === 0) return\n\n const nextQueueIndex = state.queueIndex - removedBeforeQueueIndex\n const currentFileRemoved = state.currentFile !== null && filesToRemove.has(state.currentFile)\n\n set({\n queue: filteredQueue,\n totalFiles: state.totalFiles - removedCount,\n completedFiles: Math.max(0, state.completedFiles - removedCompletedBeforeQueueIndex),\n queueIndex: nextQueueIndex,\n failedFiles: state.failedFiles.filter((fileName) => !filesToRemove.has(fileName)),\n processingFiles: new Set(Array.from(state.processingFiles).filter((fileName) => !filesToRemove.has(fileName))),\n currentFile: currentFileRemoved ? filteredQueue[nextQueueIndex]?.name || null : state.currentFile,\n })\n },\n\n // Hotspot management\n setHotspotInfo: (info: HotspotInfo | null) => set({hotspotInfo: info}),\n\n setSyncServiceOpenedHotspot: (opened: boolean) => set({syncServiceOpenedHotspot: opened}),\n\n // Gallery status from glasses\n setGlassesGalleryStatus: (photos: number, videos: number, total: number, hasContent: boolean) => {\n const state = get()\n // Reset to idle if sync is in a terminal state and new content is available\n // This allows syncing again after taking new photos\n const shouldResetToIdle =\n hasContent && (state.syncState === \"complete\" || state.syncState === \"error\" || state.syncState === \"cancelled\")\n\n set({\n glassesPhotoCount: photos,\n glassesVideoCount: videos,\n glassesTotalCount: total,\n glassesHasContent: hasContent,\n ...(shouldResetToIdle ? {syncState: \"idle\" as SyncState} : {}),\n })\n },\n\n clearGlassesGalleryStatus: () =>\n set({\n glassesPhotoCount: 0,\n glassesVideoCount: 0,\n glassesTotalCount: 0,\n glassesHasContent: false,\n }),\n\n // Queue management\n setQueue: (files: PhotoInfo[], startIndex: number = 0) =>\n set({\n // C4: Strip thumbnail_data (base64) from store to prevent OOM\n queue: files.map(({thumbnail_data: _thumbnailData, ...rest}) => rest),\n queueIndex: startIndex,\n totalFiles: files.length,\n completedFiles: startIndex,\n }),\n\n advanceQueue: () => {\n const state = get()\n set({queueIndex: state.queueIndex + 1})\n },\n\n clearQueue: () =>\n set({\n queue: [],\n queueIndex: 0,\n totalFiles: 0,\n completedFiles: 0,\n }),\n\n // Full reset\n reset: () => set({...initialState, processingFiles: new Set<string>()}),\n })),\n)\n\n// Selector helpers for common subscriptions\nexport const selectSyncProgress = (state: GallerySyncState) => ({\n syncState: state.syncState,\n currentFile: state.currentFile,\n currentFileProgress: state.currentFileProgress,\n completedFiles: state.completedFiles,\n totalFiles: state.totalFiles,\n failedFiles: state.failedFiles,\n processingFiles: state.processingFiles,\n})\n\nexport const selectIssyncing = (state: GallerySyncState) =>\n state.syncState === \"syncing\" ||\n state.syncState === \"preparing\" ||\n state.syncState === \"requesting_hotspot\" ||\n state.syncState === \"connecting_wifi\"\n\nexport const selectGlassesGalleryStatus = (state: GallerySyncState) => ({\n photos: state.glassesPhotoCount,\n videos: state.glassesVideoCount,\n total: state.glassesTotalCount,\n hasContent: state.glassesHasContent,\n})\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mentra/engine",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.1-dev.276",
|
|
4
4
|
"description": "Mentra Engine — miniapp registry, WebView bridge, and miniapp store",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -97,13 +97,13 @@
|
|
|
97
97
|
"registry": "https://registry.npmjs.org/"
|
|
98
98
|
},
|
|
99
99
|
"dependencies": {
|
|
100
|
-
"@mentra/acs-meeting": "3.2.
|
|
101
|
-
"@mentra/glasses-media": "3.2.
|
|
102
|
-
"@mentra/bluetooth-sdk": "3.2.
|
|
103
|
-
"@mentra/cloud-client": "3.2.
|
|
104
|
-
"@mentra/cloud-protocol": "3.2.
|
|
105
|
-
"@mentra/crust": "3.2.
|
|
106
|
-
"@mentra/miniapp": "3.2.
|
|
100
|
+
"@mentra/acs-meeting": "3.2.1-dev.276",
|
|
101
|
+
"@mentra/glasses-media": "3.2.1-dev.276",
|
|
102
|
+
"@mentra/bluetooth-sdk": "3.2.1-dev.276",
|
|
103
|
+
"@mentra/cloud-client": "3.2.1-dev.276",
|
|
104
|
+
"@mentra/cloud-protocol": "3.2.1-dev.276",
|
|
105
|
+
"@mentra/crust": "3.2.1-dev.276",
|
|
106
|
+
"@mentra/miniapp": "3.2.1-dev.276",
|
|
107
107
|
"buffer": "^6.0.3",
|
|
108
108
|
"events": "^3.3.0",
|
|
109
109
|
"react-native-marked": "8.1.1",
|
|
@@ -11,10 +11,10 @@ export interface EngineReleaseMetadata {
|
|
|
11
11
|
|
|
12
12
|
export const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({
|
|
13
13
|
"schemaVersion": 1,
|
|
14
|
-
"familyBaseVersion": "3.2.
|
|
15
|
-
"releaseIdentity": "3.2.
|
|
16
|
-
"releaseSetId": "mentra-3.2.
|
|
17
|
-
"sourceCommit": "
|
|
18
|
-
"otaManifestUrl": "https://
|
|
19
|
-
"otaManifestSha256": "
|
|
14
|
+
"familyBaseVersion": "3.2.1",
|
|
15
|
+
"releaseIdentity": "3.2.1-dev.276",
|
|
16
|
+
"releaseSetId": "mentra-3.2.1-dev.276",
|
|
17
|
+
"sourceCommit": "b74cc190367ec2cd3aa44b43562648920adaba67",
|
|
18
|
+
"otaManifestUrl": "https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.2.1/mentra-live-ota-3.2.1-dev.276.json",
|
|
19
|
+
"otaManifestSha256": "91c76567180dbda2c90b8679725bccd237b46a954b8af50ef417633694c35563"
|
|
20
20
|
})
|
|
@@ -73,12 +73,12 @@ const DEFAULT_THEME: MentraLiveOtaFlowTheme = {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
const ENGLISH_COPY: Record<string, string> = {
|
|
76
|
-
"ota:downloadingToPhone": "Downloading update to phone
|
|
77
|
-
"ota:startingGlassesHotspot": "Starting glasses hotspot
|
|
78
|
-
"ota:connectingPhoneToGlasses": "Connecting phone to glasses
|
|
79
|
-
"ota:startingHotspotUpdate": "Starting update
|
|
80
|
-
"ota:transferringToGlasses": "Transferring update to glasses
|
|
81
|
-
"ota:installingOnGlasses": "Installing update on glasses
|
|
76
|
+
"ota:downloadingToPhone": "Downloading update to phone…",
|
|
77
|
+
"ota:startingGlassesHotspot": "Starting glasses hotspot…",
|
|
78
|
+
"ota:connectingPhoneToGlasses": "Connecting phone to glasses…",
|
|
79
|
+
"ota:startingHotspotUpdate": "Starting update…",
|
|
80
|
+
"ota:transferringToGlasses": "Transferring update to glasses…",
|
|
81
|
+
"ota:installingOnGlasses": "Installing update on glasses…",
|
|
82
82
|
"ota:componentApk": "Glasses software",
|
|
83
83
|
"ota:componentMtk": "System firmware",
|
|
84
84
|
"ota:componentBes": "Bluetooth firmware",
|
|
@@ -90,7 +90,7 @@ const ENGLISH_COPY: Record<string, string> = {
|
|
|
90
90
|
"common:done": "Done",
|
|
91
91
|
"ota:checkingForUpdates": "Checking for updates",
|
|
92
92
|
"ota:checkingForUpdatesMessage":
|
|
93
|
-
"Connected devices will perform automatic updates. Automatic updates can be disabled in Device Settings",
|
|
93
|
+
"Connected devices will perform automatic updates. Automatic updates can be disabled in Device Settings.",
|
|
94
94
|
"ota:finishingUpdate": "Finishing your update",
|
|
95
95
|
"ota:checkingAdditionalUpdates": "Checking whether your glasses need any additional updates.",
|
|
96
96
|
"ota:updateAvailable": "{{deviceName}} Update Available",
|
|
@@ -98,8 +98,8 @@ const ENGLISH_COPY: Record<string, string> = {
|
|
|
98
98
|
"ota:batteryRequiredMessage":
|
|
99
99
|
"{{deviceName}} is currently at {{batteryLevel}}%. Charge it to at least {{minimumBatteryLevel}}% before updating.",
|
|
100
100
|
"ota:batteryRequiredLiveUpdate": "This screen will update automatically as the battery charges.",
|
|
101
|
-
"ota:updateConnectWifi": "Connect your {{deviceName}} to
|
|
102
|
-
"ota:wifiRequiredTitle": "
|
|
101
|
+
"ota:updateConnectWifi": "Connect your {{deviceName}} to Wi-Fi to install the update.",
|
|
102
|
+
"ota:wifiRequiredTitle": "Wi-Fi Needed for Update",
|
|
103
103
|
"ota:updateDescription":
|
|
104
104
|
"A new update is available for your glasses. We recommend updating now for the best experience.",
|
|
105
105
|
"ota:updateSequenceMessage":
|
|
@@ -111,11 +111,11 @@ const ENGLISH_COPY: Record<string, string> = {
|
|
|
111
111
|
"ota:downgradeDescription":
|
|
112
112
|
"This app requires an earlier glasses software version. Your photos and videos will be preserved, but glasses settings will be reset and restored automatically after the change.",
|
|
113
113
|
"ota:updateNow": "Update Now",
|
|
114
|
-
"ota:setupWifi": "
|
|
114
|
+
"ota:setupWifi": "Set up Wi-Fi",
|
|
115
115
|
"ota:updateLater": "Later",
|
|
116
116
|
"ota:updateComplete": "Update complete",
|
|
117
117
|
"ota:whatsNew": "What's new",
|
|
118
|
-
"ota:upToDate": "Up
|
|
118
|
+
"ota:upToDate": "Up to Date",
|
|
119
119
|
"ota:devBuild": "Development Build",
|
|
120
120
|
"ota:devBuildNoOta":
|
|
121
121
|
"This mobile app is a development build, so automatic glasses updates are disabled. Use the developer settings manifest override to update them manually.",
|
|
@@ -500,7 +500,7 @@ function OtaFlowContent({
|
|
|
500
500
|
{state.hotspotPhase === "downloading" ? (
|
|
501
501
|
<BodyText colors={colors}>{translate("ota:phoneFileProgress")}</BodyText>
|
|
502
502
|
) : null}
|
|
503
|
-
<BodyText colors={colors}>Do not disconnect your glasses
|
|
503
|
+
<BodyText colors={colors}>Do not disconnect your glasses.</BodyText>
|
|
504
504
|
</FlowPage>
|
|
505
505
|
)
|
|
506
506
|
}
|
|
@@ -510,8 +510,8 @@ function OtaFlowContent({
|
|
|
510
510
|
const title = hotspot
|
|
511
511
|
? translate(state.phase === "download" ? "ota:transferringToGlasses" : "ota:installingOnGlasses")
|
|
512
512
|
: state.phase === "download"
|
|
513
|
-
? "Downloading
|
|
514
|
-
: "Installing
|
|
513
|
+
? "Downloading…"
|
|
514
|
+
: "Installing…"
|
|
515
515
|
const component = state.step ? translate(componentCopyKey[state.step]) : null
|
|
516
516
|
const hasStepCount =
|
|
517
517
|
state.currentStep !== null &&
|
|
@@ -543,7 +543,7 @@ function OtaFlowContent({
|
|
|
543
543
|
</View>
|
|
544
544
|
</>
|
|
545
545
|
)}
|
|
546
|
-
<BodyText colors={colors}>Do not disconnect your glasses
|
|
546
|
+
<BodyText colors={colors}>Do not disconnect your glasses.</BodyText>
|
|
547
547
|
{state.versionChange && state.phase === "install" ? (
|
|
548
548
|
<BodyText colors={colors}>{translate("ota:downgradeDuration")}</BodyText>
|
|
549
549
|
) : null}
|
|
@@ -607,7 +607,7 @@ function OtaFlowContent({
|
|
|
607
607
|
onPress={state.canRetry ? controller.retryInstall : controller.finish}
|
|
608
608
|
/>
|
|
609
609
|
{state.canOpenWifiSetup ? (
|
|
610
|
-
<FlowButton colors={colors} label="Change
|
|
610
|
+
<FlowButton colors={colors} label="Change Wi-Fi" onPress={controller.openWifiSetup} secondary />
|
|
611
611
|
) : null}
|
|
612
612
|
</>
|
|
613
613
|
}
|
|
@@ -634,7 +634,7 @@ function OtaFlowContent({
|
|
|
634
634
|
colors={colors}
|
|
635
635
|
icon="bluetooth"
|
|
636
636
|
title="Glasses disconnected">
|
|
637
|
-
<BodyText colors={colors}>Reconnecting
|
|
637
|
+
<BodyText colors={colors}>Reconnecting…</BodyText>
|
|
638
638
|
<ActivityIndicator size="large" color={colors.foreground} />
|
|
639
639
|
</FlowPage>
|
|
640
640
|
)
|
|
@@ -33,10 +33,10 @@ export const OTA_ERROR_BES_RESTART_REQUIRED_COPY_KEY = "ota:errorBesRestartRequi
|
|
|
33
33
|
|
|
34
34
|
/** English copy for every OTA error key above. Mirrored in the Mentra App's `ota` i18n namespace. */
|
|
35
35
|
export const OTA_ERROR_ENGLISH_COPY: Readonly<Record<string, string>> = {
|
|
36
|
-
"ota:errorNoInternet": "Glasses
|
|
36
|
+
"ota:errorNoInternet": "Glasses Wi-Fi has no internet connection",
|
|
37
37
|
"ota:errorClockSkew": "Glasses clock is wrong — syncing time from your phone, then retrying update check",
|
|
38
|
-
"ota:errorSslError": "Secure connection failed — try a different
|
|
39
|
-
"ota:errorDownloadFailed": "Download failed — check glasses
|
|
38
|
+
"ota:errorSslError": "Secure connection failed — try a different Wi-Fi network",
|
|
39
|
+
"ota:errorDownloadFailed": "Download failed — check glasses Wi-Fi connection",
|
|
40
40
|
"ota:errorInsufficientStorage": "Not enough storage on your glasses — free up space before trying again",
|
|
41
41
|
"ota:errorFirmwareTooLarge": "Firmware file is unexpectedly large — please contact support",
|
|
42
42
|
"ota:errorFirmwareVerifyFailed": "Firmware verification failed — please try again or contact support",
|
|
@@ -11,7 +11,7 @@ import {AppState, AppStateStatus, Platform} from "react-native"
|
|
|
11
11
|
import BleManager from "react-native-ble-manager"
|
|
12
12
|
import WifiManager from "react-native-wifi-reborn"
|
|
13
13
|
|
|
14
|
-
import {useGallerySyncStore, HotspotInfo} from "../../stores/gallerySync"
|
|
14
|
+
import {useGallerySyncStore, HotspotInfo, selectIssyncing} from "../../stores/gallerySync"
|
|
15
15
|
import {selectGlassesConnected, useGlassesStore} from "../../stores/glasses"
|
|
16
16
|
import {isGlassesConnected} from "../GlassesReadiness"
|
|
17
17
|
import {SETTINGS, useSettingsStore} from "../../stores/settings"
|
|
@@ -561,11 +561,7 @@ class GallerySyncService {
|
|
|
561
561
|
: null
|
|
562
562
|
|
|
563
563
|
// R1: Check if already syncing (including requesting_hotspot to prevent double-tap)
|
|
564
|
-
if (
|
|
565
|
-
store.syncState === "syncing" ||
|
|
566
|
-
store.syncState === "connecting_wifi" ||
|
|
567
|
-
store.syncState === "requesting_hotspot"
|
|
568
|
-
) {
|
|
564
|
+
if (this.isSyncing()) {
|
|
569
565
|
console.log(`[GallerySyncService] ⚠️ Already syncing (state: ${store.syncState}), ignoring start request`)
|
|
570
566
|
return
|
|
571
567
|
}
|
|
@@ -1555,6 +1551,11 @@ class GallerySyncService {
|
|
|
1555
1551
|
asgCameraApi.setServer(hotspotInfo.ip, 8089)
|
|
1556
1552
|
console.log("[GallerySyncService] ✅ API client configured")
|
|
1557
1553
|
|
|
1554
|
+
// Wi-Fi is ready. Inventory/recovery can take time for large galleries and must
|
|
1555
|
+
// render as preparation. Preserve the display queue until a new manifest is ready;
|
|
1556
|
+
// setSyncing([]) would discard retained thumbnails and recovery progress on failure.
|
|
1557
|
+
store.setSyncState("preparing")
|
|
1558
|
+
|
|
1558
1559
|
const recovery = await mediaProcessingQueue.retryPending()
|
|
1559
1560
|
if (recovery.retried > 0 || recovery.failed > 0) {
|
|
1560
1561
|
console.log(
|
|
@@ -2412,14 +2413,11 @@ class GallerySyncService {
|
|
|
2412
2413
|
}
|
|
2413
2414
|
|
|
2414
2415
|
/**
|
|
2415
|
-
* Check if sync is currently in progress (hotspot/WiFi/download phases).
|
|
2416
|
+
* Check if sync is currently in progress (hotspot/WiFi/preparation/download phases).
|
|
2416
2417
|
* Does not include pre-flight — use isSyncStarting() for that.
|
|
2417
2418
|
*/
|
|
2418
2419
|
isSyncing(): boolean {
|
|
2419
|
-
|
|
2420
|
-
return (
|
|
2421
|
-
store.syncState === "syncing" || store.syncState === "connecting_wifi" || store.syncState === "requesting_hotspot"
|
|
2422
|
-
)
|
|
2420
|
+
return selectIssyncing(useGallerySyncStore.getState())
|
|
2423
2421
|
}
|
|
2424
2422
|
}
|
|
2425
2423
|
|
|
@@ -32,6 +32,7 @@ export type SyncState =
|
|
|
32
32
|
| "idle"
|
|
33
33
|
| "requesting_hotspot"
|
|
34
34
|
| "connecting_wifi"
|
|
35
|
+
| "preparing"
|
|
35
36
|
| "syncing"
|
|
36
37
|
| "complete"
|
|
37
38
|
| "error"
|
|
@@ -374,7 +375,10 @@ export const selectSyncProgress = (state: GallerySyncState) => ({
|
|
|
374
375
|
})
|
|
375
376
|
|
|
376
377
|
export const selectIssyncing = (state: GallerySyncState) =>
|
|
377
|
-
state.syncState === "syncing" ||
|
|
378
|
+
state.syncState === "syncing" ||
|
|
379
|
+
state.syncState === "preparing" ||
|
|
380
|
+
state.syncState === "requesting_hotspot" ||
|
|
381
|
+
state.syncState === "connecting_wifi"
|
|
378
382
|
|
|
379
383
|
export const selectGlassesGalleryStatus = (state: GallerySyncState) => ({
|
|
380
384
|
photos: state.glassesPhotoCount,
|