327 lines
8.1 KiB
Markdown
327 lines
8.1 KiB
Markdown
# 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)
|