add docs part 2
This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user