Likes and dislikes without a network are kept in a pending_reactions table (last reaction per track wins) and sent when the connection returns, instead of being rolled back. Downloaded track DTOs pick up the new reaction so the offline wave and Downloads reflect it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
import * as SQLite from 'expo-sqlite';
|
|
|
|
let db: Promise<SQLite.SQLiteDatabase> | null = null;
|
|
|
|
/**
|
|
* Локальная база офлайн-режима (docs/mobile.md#офлайн). `owner` — хэш «сервер + пользователь»:
|
|
* скачанное, неотправленные события и реакции одного аккаунта не видны другому.
|
|
*/
|
|
export function getDb(): Promise<SQLite.SQLiteDatabase> {
|
|
db ??= (async () => {
|
|
const d = await SQLite.openDatabaseAsync('pipu.db');
|
|
await d.execAsync(`
|
|
PRAGMA journal_mode = WAL;
|
|
CREATE TABLE IF NOT EXISTS downloads (
|
|
owner TEXT NOT NULL,
|
|
track_id TEXT NOT NULL,
|
|
track TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
bytes INTEGER NOT NULL DEFAULT 0,
|
|
added_at INTEGER NOT NULL,
|
|
PRIMARY KEY (owner, track_id)
|
|
);
|
|
CREATE TABLE IF NOT EXISTS pending_events (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
owner TEXT NOT NULL,
|
|
body TEXT NOT NULL
|
|
);
|
|
CREATE TABLE IF NOT EXISTS pending_reactions (
|
|
owner TEXT NOT NULL,
|
|
track_id TEXT NOT NULL,
|
|
reaction TEXT,
|
|
PRIMARY KEY (owner, track_id)
|
|
);
|
|
`);
|
|
return d;
|
|
})();
|
|
return db;
|
|
}
|