8.1 KiB
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 IDlocalId- Fast lookup by device IDownerId, 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
- Read current version
- Apply migrations sequentially
- Update version number
- Verify data integrity
Cleanup Operations
Free Up Space
Remove local copies of backed-up assets:
Settings:
cleanupKeepFavorites: Keep favorite assetscleanupKeepMediaType: Keep photos/videos/bothcleanupKeepAlbumIds: Keep assets in specific albumscleanupCutoffDaysAgo: 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:
- Clear database
- Clear cache
- Clear settings
- Return to login screen