- Implemented a new Player class in player.js to handle audio playback, including HLS support using hls.js. - Created a shared API module in api.js for making HTTP requests with proper error handling. - Added DOM utility functions in dom.js for creating and clearing elements. - Introduced WebSocket connection handling in ws.js for real-time updates. - Developed a comprehensive CSS stylesheet for styling the application, including a high-contrast theme.
81 lines
3.0 KiB
SQL
81 lines
3.0 KiB
SQL
CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
username TEXT NOT NULL UNIQUE,
|
|
password_hash TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('admin','user')),
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
token TEXT PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
expires_at TEXT NOT NULL,
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS profiles (
|
|
user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
display_name TEXT,
|
|
theme TEXT DEFAULT 'dark',
|
|
default_volume REAL DEFAULT 0.7
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS stations (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
uuid TEXT UNIQUE,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL UNIQUE,
|
|
homepage TEXT,
|
|
country TEXT,
|
|
genres TEXT, -- JSON array
|
|
description TEXT,
|
|
image_url TEXT,
|
|
source TEXT NOT NULL CHECK (source IN ('seed','radiobrowser','manual')),
|
|
source_ref TEXT,
|
|
category TEXT,
|
|
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_stations_enabled ON stations(enabled);
|
|
CREATE INDEX IF NOT EXISTS idx_stations_source ON stations(source);
|
|
CREATE INDEX IF NOT EXISTS idx_stations_category ON stations(category);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_stations_uuid ON stations(uuid);
|
|
|
|
CREATE TABLE IF NOT EXISTS streams (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
uuid TEXT UNIQUE,
|
|
station_id INTEGER NOT NULL REFERENCES stations(id) ON DELETE CASCADE,
|
|
url TEXT NOT NULL,
|
|
format TEXT NOT NULL CHECK (format IN ('mp3','aac','hls','m3u','pls','ogg','unknown')),
|
|
bitrate INTEGER,
|
|
label TEXT,
|
|
priority INTEGER NOT NULL DEFAULT 0,
|
|
last_checked_at TEXT,
|
|
last_status TEXT
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_streams_station ON streams(station_id);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_streams_uuid ON streams(uuid);
|
|
|
|
CREATE TABLE IF NOT EXISTS favorites (
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
station_id INTEGER NOT NULL REFERENCES stations(id) ON DELETE CASCADE,
|
|
position INTEGER NOT NULL DEFAULT 0,
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (user_id, station_id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS play_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
station_id INTEGER NOT NULL REFERENCES stations(id) ON DELETE CASCADE,
|
|
stream_id INTEGER REFERENCES streams(id) ON DELETE SET NULL,
|
|
started_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
ended_at TEXT
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_history_user ON play_history(user_id, started_at DESC);
|