# Local Storage The app uses multiple storage mechanisms to persist data locally for offline access and performance. ## Storage Overview ``` ┌─────────────────────────────────────────┐ │ Local Storage │ ├─────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ Key-Value │ │ Database │ │ │ │ Store │ │ (Isar) │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ Image │ │ Secure │ │ │ │ Cache │ │ Storage │ │ │ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────┘ ``` ## Key-Value Store Simple key-value storage for settings and small data. ### Store Service The Store service provides typed access to stored values: ``` // Get a value with default value = Store.get(StoreKey.themeMode, "system") // Get a value (nullable) value = Store.tryGet(StoreKey.accessToken) // Save a value Store.put(StoreKey.themeMode, "dark") // Delete a value Store.delete(StoreKey.accessToken) ``` ### Store Keys | Key | Type | Description | |-----|------|-------------| | version | Integer | Store schema version | | assetETag | String | Last sync ETag | | currentUser | User | Logged in user object | | deviceId | String | Unique device identifier | | deviceIdHash | Integer | Hashed device ID | | serverUrl | String | Server URL | | serverEndpoint | String | API endpoint URL | | accessToken | String | Authentication token | | autoBackup | Boolean | Auto backup enabled | | backgroundBackup | Boolean | Background backup enabled | | backupRequireWifi | Boolean | Require WiFi for backup | | backupRequireCharging | Boolean | Require charging for backup | | backupTriggerDelay | Integer | Minutes before backup starts | | backupFailedSince | DateTime | When backup started failing | ### User Settings Keys | Key | Type | Default | Description | |-----|------|---------|-------------| | loadPreview | Boolean | true | Load preview images | | loadOriginal | Boolean | false | Load full resolution | | themeMode | String | "system" | light/dark/system | | primaryColor | String | Default | Theme accent color | | dynamicTheme | Boolean | false | Use dynamic colors | | colorfulInterface | Boolean | true | Colorful UI elements | | tilesPerRow | Integer | 4 | Grid columns | | dynamicLayout | Boolean | false | Dynamic grid layout | | groupAssetsBy | Integer | 0 | Grouping mode | | storageIndicator | Boolean | true | Show storage indicator | | loopVideo | Boolean | true | Loop video playback | | autoPlayVideo | Boolean | true | Auto-play videos | | enableHapticFeedback | Boolean | true | Haptic feedback | ### Cache Size Keys | Key | Type | Default | Description | |-----|------|---------|-------------| | thumbnailCacheSize | Integer | 10000 | Max thumbnail cache entries | | imageCacheSize | Integer | 350 | Max preview cache entries | | albumThumbnailCacheSize | Integer | 200 | Max album thumbnail entries | ## Database (Isar) Embedded NoSQL database for structured data. ### Collections #### Assets Collection Stores all asset metadata: ``` Assets: - id: Auto-increment primary key - remoteId: Indexed (unique hash) - localId: Indexed (unique hash) - ownerId + checksum: Composite unique index - All asset properties ``` **Indexes:** - `remoteId` - Fast lookup by server ID - `localId` - Fast lookup by device ID - `ownerId, checksum` - Composite unique constraint #### Albums Collection Stores album information: ``` Albums: - id: Auto-increment primary key - remoteId: Indexed - name, dates, ownership info - Links to assets and users ``` #### Backup Albums Collection Tracks device albums selected for backup: ``` BackupAlbum: - id: Device album ID (primary key) - name: Album name - selection: include/exclude/none - lastBackup: Last backup timestamp ``` #### Duplicated Assets Collection Tracks already-uploaded assets: ``` DuplicatedAsset: - id: Device asset ID - Prevents re-upload of same file ``` #### ETag Collection Stores sync ETags for incremental updates: ``` ETag: - id: User ID - assetCount: Number of assets - time: Last sync time ``` #### Device Asset Collections Platform-specific asset tracking: **Android:** ``` AndroidDeviceAsset: - id: Asset ID - hash: Content hash ``` **iOS:** ``` IOSDeviceAsset: - id: Asset ID - hash: Content hash - modifiedTime: Modification timestamp ``` ### Database Operations **Read Operations:** ``` // Find asset by remote ID asset = db.assets.where().remoteIdEqualTo(id).findFirst() // Get all assets for user assets = db.assets.filter().ownerIdEqualTo(userId).findAll() // Get assets in date range assets = db.assets.filter() .fileCreatedAtBetween(start, end) .findAll() ``` **Write Operations:** ``` // Insert/update asset db.writeTxn(() => db.assets.put(asset)) // Delete by remote IDs db.writeTxn(() => db.assets.deleteAllByRemoteId(ids)) // Batch insert db.writeTxn(() => db.assets.putAll(assets)) ``` ## Image Cache Caches downloaded images for performance. ### Cache Layers ``` ┌─────────────────┐ │ Memory Cache │ ← Hot images (limited size) ├─────────────────┤ │ Disk Cache │ ← Persistent storage └─────────────────┘ ``` ### Cache Types | Type | Purpose | Default Size | |------|---------|--------------| | Thumbnail | Grid view thumbnails | 10,000 entries | | Preview | Full-screen previews | 350 entries | | Album Thumbnail | Album cover images | 200 entries | ### Cache Management **Clear All Cache:** - Remove all cached thumbnails - Remove all cached previews - Free up storage space **Cache Invalidation:** - By asset ID when asset is deleted - By album ID when album changes - Manual clear from settings ## Secure Storage For sensitive data that needs encryption. ### Stored Securely | Data | Usage | |------|-------| | Access Token | Authentication | | SSL Client Certificate | mTLS authentication | | SSL Certificate Password | Certificate decryption | | Custom Headers | Proxy authentication | ### SSL Client Certificate Storage ``` SSLClientCertStoreVal: - data: Certificate binary (base64 encoded) - password: Certificate password Operations: - save(): Persist to secure storage - load(): Retrieve from secure storage - delete(): Remove from secure storage ``` ## Storage Location ### Per-Platform Paths **Android:** - Database: `/data/data/{app}/databases/` - Cache: `/data/data/{app}/cache/` - Secure: Android Keystore **iOS:** - Database: `~/Library/Application Support/` - Cache: `~/Library/Caches/` - Secure: iOS Keychain ## Data Migration When upgrading the app, data may need migration: ### Version Tracking - Store version in `StoreKey.version` - Compare with expected version - Run migration steps if needed ### Migration Steps 1. Read current version 2. Apply migrations sequentially 3. Update version number 4. Verify data integrity ## Cleanup Operations ### Free Up Space Remove local copies of backed-up assets: **Settings:** - `cleanupKeepFavorites`: Keep favorite assets - `cleanupKeepMediaType`: Keep photos/videos/both - `cleanupKeepAlbumIds`: Keep assets in specific albums - `cleanupCutoffDaysAgo`: Only remove older than X days ### Clear Cache Remove cached images without affecting synced data: - Thumbnails - Previews - Album covers ### Full Reset Remove all local data: 1. Clear database 2. Clear cache 3. Clear settings 4. Return to login screen --- [Previous: API Reference](api-reference.md) | [Next: Settings](settings.md)