mirror of
https://github.com/Boof2015/astra-mobile.git
synced 2026-08-19 12:14:47 +02:00
m5, subsonic/jellyfin support
This commit is contained in:
@@ -34,6 +34,8 @@ export interface Track {
|
||||
sourceId?: number;
|
||||
sourceTrackId?: string;
|
||||
sourcePath?: string;
|
||||
/** Server cover-art id for remote tracks (resolved to a URL via remoteUrls). */
|
||||
artworkSourceId?: string;
|
||||
isAvailable?: boolean;
|
||||
availabilityReason?: string;
|
||||
}
|
||||
|
||||
+14
-2
@@ -5,8 +5,8 @@ export type TrackSourceType = 'local' | 'subsonic' | 'jellyfin';
|
||||
|
||||
export interface DbTrack {
|
||||
id: number;
|
||||
path: string; // SAF document content:// URI for local tracks
|
||||
folder_id: number;
|
||||
path: string; // SAF content:// URI (local), or subsonic://|jellyfin:// identity URI (remote)
|
||||
folder_id: number | null; // NULL for remote tracks (no SAF folder)
|
||||
title: string;
|
||||
artist: string;
|
||||
album: string;
|
||||
@@ -25,6 +25,12 @@ export interface DbTrack {
|
||||
channels: number | null;
|
||||
codec: string | null;
|
||||
source_type: TrackSourceType;
|
||||
// Remote-source linkage (NULL for local tracks). source_id -> remote_sources.id;
|
||||
// source_track_id is the server's track id; artwork_source_id is its cover-art id.
|
||||
source_id: number | null;
|
||||
source_track_id: string | null;
|
||||
source_path: string | null;
|
||||
artwork_source_id: string | null;
|
||||
file_name: string;
|
||||
size: number | null;
|
||||
mtime: number;
|
||||
@@ -57,6 +63,12 @@ export interface Album {
|
||||
track_count: number;
|
||||
/** Newest track import timestamp in this album, used by Home recently-added. */
|
||||
latest_added_at: number;
|
||||
// Representative remote-source linkage (absent/NULL for local albums) so the album
|
||||
// grid / detail can resolve a server cover-art URL when there's no cached artwork_hash.
|
||||
// Optional so locally-derived album shapes (e.g. artist-detail aggregates) still fit.
|
||||
source_type?: TrackSourceType;
|
||||
source_id?: number | null;
|
||||
artwork_source_id?: string | null;
|
||||
}
|
||||
|
||||
export interface Artist {
|
||||
|
||||
@@ -15,6 +15,8 @@ export interface Playlist {
|
||||
track_count: number;
|
||||
/** Entries whose track is gone (folder removed / file deleted). */
|
||||
missing_track_count: number;
|
||||
/** Set when this playlist mirrors a remote server playlist (-> remote_sources.id). */
|
||||
remote_source_id: number | null;
|
||||
}
|
||||
|
||||
export interface PlaylistTrackEntry {
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
// Shared types for remote music sources (Subsonic / Jellyfin). The catalog-track
|
||||
// and connection-config shapes are ported verbatim from desktop Astra
|
||||
// (src/main/services/{subsonic,jellyfin}.ts) — they were already identical across
|
||||
// both providers, so they unify here.
|
||||
|
||||
export type RemoteSourceType = 'subsonic' | 'jellyfin';
|
||||
|
||||
export type RemoteSourceStatus = 'unknown' | 'ok' | 'error' | 'disabled' | 'syncing';
|
||||
|
||||
/** Credentials needed to talk to a server. */
|
||||
export interface RemoteConnectionConfig {
|
||||
baseUrl: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* One catalog track as produced by a client sync. Maps 1:1 onto the `tracks` table
|
||||
* (plus remote-only id/path fields). Mirrors desktop `SubsonicCatalogTrack` /
|
||||
* `JellyfinCatalogTrack`.
|
||||
*/
|
||||
export interface RemoteCatalogTrack {
|
||||
/** Stable identity URI: `subsonic://{sourceId}/track/{id}` (stored as tracks.path). */
|
||||
path: string;
|
||||
source_track_id: string;
|
||||
source_path: string | null;
|
||||
artwork_source_id: string | null;
|
||||
title: string;
|
||||
artist: string;
|
||||
album: string;
|
||||
album_artist: string | null;
|
||||
duration: number;
|
||||
track_number: number | null;
|
||||
disc_number: number | null;
|
||||
year: number | null;
|
||||
genre: string | null;
|
||||
artwork_hash: string | null;
|
||||
format: string;
|
||||
sample_rate: number | null;
|
||||
bit_depth: number | null;
|
||||
bitrate: number | null;
|
||||
channels: number | null;
|
||||
codec: string | null;
|
||||
codec_profile: string | null;
|
||||
is_atmos_joc: number | null;
|
||||
replaygain_track_gain_db: number | null;
|
||||
replaygain_album_gain_db: number | null;
|
||||
bpm: number | null;
|
||||
musical_key: string | null;
|
||||
}
|
||||
|
||||
/** Unified sync-progress event across providers. */
|
||||
export interface RemoteSyncProgress {
|
||||
phase: 'connecting' | 'artists' | 'albums' | 'tracks' | 'items' | 'playlists' | 'saving';
|
||||
current: number;
|
||||
total: number;
|
||||
detail: string | null;
|
||||
}
|
||||
|
||||
/** A track entry within a synced remote playlist. */
|
||||
export interface RemotePlaylistTrack {
|
||||
/** subsonic://|jellyfin:// identity URI (matches a tracks.path). */
|
||||
path: string;
|
||||
source_track_id: string;
|
||||
title: string | null;
|
||||
artist: string | null;
|
||||
album: string | null;
|
||||
}
|
||||
|
||||
/** A playlist as defined on the remote server. */
|
||||
export interface RemotePlaylist {
|
||||
source_playlist_id: string;
|
||||
name: string;
|
||||
tracks: RemotePlaylistTrack[];
|
||||
}
|
||||
|
||||
/** A configured server, as stored in the `remote_sources` table (no secret). */
|
||||
export interface RemoteSourceRow {
|
||||
id: number;
|
||||
type: RemoteSourceType;
|
||||
name: string;
|
||||
base_url: string;
|
||||
username: string;
|
||||
enabled: number; // 0 | 1
|
||||
last_status: RemoteSourceStatus;
|
||||
last_error: string | null;
|
||||
last_sync_at: number | null;
|
||||
last_checked_at: number | null;
|
||||
/** Jellyfin-only cached auth (Subsonic re-derives a salted token per request). */
|
||||
access_token: string | null;
|
||||
user_id: string | null;
|
||||
device_id: string | null;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
}
|
||||
|
||||
export interface RemoteSourceCreateInput {
|
||||
type: RemoteSourceType;
|
||||
name: string;
|
||||
baseUrl: string;
|
||||
username: string;
|
||||
password: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface RemoteSourceUpdateInput {
|
||||
name?: string;
|
||||
baseUrl?: string;
|
||||
username?: string;
|
||||
/** Only set when the user enters a new password. */
|
||||
password?: string;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
export interface RemoteSourceTestInput {
|
||||
type: RemoteSourceType;
|
||||
baseUrl: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface RemoteSourceTestResult {
|
||||
ok: boolean;
|
||||
message: string;
|
||||
}
|
||||
Reference in New Issue
Block a user