forked from Keelrleek/SoulStream
Approved on research/home-redesign after four passes: the Desk layout, the Showcase polish, the welcome card, a 6-month feed window, news with reviews filtered, and all three of the sections I proposed. Nothing here is a new design. The release cards, their grid, the date chip and its accent-glass recipe, the upcoming wording and the missing play button on an unreleased record are the artist page's. The section heads, the featured card, the artist cards and the list rows are ArtistExtras'. The entrance is CatalogDiscography's edition deal with the same four approved numbers, and the arrival rule with it — a null from consumeScroll means a fresh arrival, which is the only thing that deals; coming Back is a return to something already read. Only the rails, the aside panels and the news list are new vocabulary, and those came off the mock verbatim. The styles are copies rather than imports for the same reason the discography page carries copies of the album page's: a page that reaches into another page's stylesheet couples them forever. The feed is what "new" honestly means. Deezer's release list merged with the MusicBrainz identity supplement — A ? of WHEN is a Panda Bear record that exists only in the supplement, and Weezer's upcoming album only carries its real name (Gold Album) there — then deduped per artist by cover and by base title, which collapses Weezer's BBC triplet and Röyksopp's four same-day remix drops to one card each. Upcoming first, then newest, with the age riding the artwork so the reader never has to work out whether "new" means this week or last spring. Jump back in is deliberately NOT deduped against it: a record can be new and also what you were just listening to, and it belongs in both. Everything reads caches. Assembling this feed cold costs one catalog_artist call per followed artist — 48 seconds for nine, measured — so home_warm walks the follows in the background through the same entry points the pages use and emits per artist as it goes. The page fills in progressively instead of waiting for the last one, and a follow change re-walks it. Three sections were mine to propose and are now in: the back catalogue (albums older than the window, one per artist first so a deep discography cannot own the row), the library rail, and Complete the set — you own two of sixteen Weezer albums and a new one lands in seventeen days.
167 lines
6.5 KiB
Rust
167 lines
6.5 KiB
Rust
mod commands;
|
|
mod config;
|
|
mod cover_logo;
|
|
mod diagnostics;
|
|
mod hero_crop;
|
|
mod hero_detector;
|
|
mod loudness;
|
|
mod pipeline;
|
|
mod playback;
|
|
mod preview;
|
|
mod smtc;
|
|
mod state;
|
|
mod thumbbar;
|
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
pub fn run() {
|
|
tauri::Builder::default()
|
|
.manage(state::AppState::default())
|
|
.setup(|app| {
|
|
app.handle().plugin(
|
|
tauri_plugin_log::Builder::default()
|
|
.level(log::LevelFilter::Info)
|
|
.clear_targets()
|
|
.target(tauri_plugin_log::Target::new(
|
|
tauri_plugin_log::TargetKind::Stdout,
|
|
))
|
|
.build(),
|
|
)?;
|
|
app.handle().plugin(tauri_plugin_dialog::init())?;
|
|
// Must run before anything touches the app-data dir.
|
|
config::migrate_app_data(app.handle());
|
|
// Prepare the small local vision model while the user is still on
|
|
// the app shell, so a first artist visit pays only warm inference.
|
|
hero_detector::warm_up(app.handle().clone());
|
|
// Before playback::init: the event pump it spawns starts pushing
|
|
// transport state at the card immediately, and the card has to be
|
|
// registered by then or the first track's status is dropped.
|
|
smtc::init(app.handle());
|
|
// Only subclasses the window here; the buttons themselves go up
|
|
// when the shell says the taskbar button exists.
|
|
thumbbar::init(app.handle());
|
|
playback::init(app.handle());
|
|
playback::prune_cache(app.handle());
|
|
preview::init(app.handle());
|
|
loudness::init(app.handle());
|
|
diagnostics::init(app.handle());
|
|
if let Err(e) = pipeline::init(app.handle()) {
|
|
log::error!("library init failed: {e}");
|
|
}
|
|
Ok(())
|
|
})
|
|
.invoke_handler(tauri::generate_handler![
|
|
commands::app_status,
|
|
commands::excluded_search_phrases,
|
|
commands::get_credentials,
|
|
commands::connect_and_login,
|
|
commands::connect_stored,
|
|
commands::disconnect,
|
|
commands::start_search,
|
|
commands::stop_search,
|
|
commands::download_file,
|
|
commands::copy_stream_to_folder,
|
|
commands::save_to_library,
|
|
commands::cancel_download,
|
|
commands::show_in_folder,
|
|
commands::refresh_artist_art,
|
|
commands::play_stream,
|
|
commands::play_local,
|
|
commands::preload_local,
|
|
commands::player_control,
|
|
commands::player_state,
|
|
commands::waveform,
|
|
commands::library_albums,
|
|
commands::album_tracks,
|
|
commands::album_art,
|
|
commands::refresh_album_art,
|
|
commands::refresh_all_album_art,
|
|
commands::get_settings,
|
|
commands::set_settings,
|
|
commands::forget_credentials,
|
|
commands::pick_folder,
|
|
commands::open_external,
|
|
commands::record_play,
|
|
commands::add_play_seconds,
|
|
commands::artist_play_stats,
|
|
commands::recent_albums,
|
|
commands::clear_play_history,
|
|
commands::play_row_count,
|
|
commands::followed_artists,
|
|
commands::follow_artist,
|
|
commands::unfollow_artist,
|
|
commands::home_artist_news,
|
|
commands::home_warm,
|
|
commands::list_playlists,
|
|
commands::create_playlist,
|
|
commands::delete_playlist,
|
|
commands::playlist_tracks,
|
|
commands::add_to_playlist,
|
|
commands::remove_from_playlist,
|
|
commands::catalog_search,
|
|
commands::catalog_artist,
|
|
commands::catalog_artist_art,
|
|
commands::catalog_artist_logos,
|
|
commands::catalog_artist_identity,
|
|
commands::catalog_artist_socials,
|
|
commands::remember_fused_artist_portrait,
|
|
commands::catalog_artist_bio,
|
|
commands::catalog_cached_cover_logo,
|
|
commands::catalog_cover_logo,
|
|
commands::catalog_cover_logo_debug,
|
|
commands::catalog_ocr_experiment,
|
|
commands::catalog_artist_hero_seed,
|
|
commands::catalog_artist_overview,
|
|
commands::catalog_artist_popular,
|
|
commands::pick_artist_hero,
|
|
commands::clear_artist_hero,
|
|
commands::catalog_related,
|
|
commands::catalog_track_listeners,
|
|
commands::catalog_artist_profile,
|
|
commands::catalog_album,
|
|
commands::catalog_album_info,
|
|
commands::catalog_art,
|
|
commands::catalog_cover,
|
|
commands::invalidate_catalog_cover,
|
|
commands::catalog_hero_preview,
|
|
commands::catalog_hero_gpu_source,
|
|
commands::catalog_cached_hero_art,
|
|
commands::catalog_hero_art,
|
|
commands::preload_stream,
|
|
commands::preload_cached_stream,
|
|
commands::stream_waveform,
|
|
commands::stream_cache_ready,
|
|
preview::preview_resolve,
|
|
preview::preview_prewarm,
|
|
preview::preview_load,
|
|
preview::preview_control,
|
|
preview::preview_dispose,
|
|
preview::player_pause_acked,
|
|
preview::player_fade_pause_acked,
|
|
preview::player_fade_resume,
|
|
diagnostics::debug_stats,
|
|
smtc::smtc_metadata,
|
|
])
|
|
.run({
|
|
#[allow(unused_mut)]
|
|
let mut context = tauri::generate_context!();
|
|
// Debug builds expose CDP on 9222 for instrumentation (see HANDOFF.md).
|
|
// wry always sets AdditionalBrowserArguments programmatically, so the
|
|
// WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS env var is ignored; the flag has
|
|
// to go through the window config. Explicit args replace wry's defaults,
|
|
// so those are restated here.
|
|
#[cfg(debug_assertions)]
|
|
{
|
|
for window in &mut context.config_mut().app.windows {
|
|
window.additional_browser_args = Some(
|
|
"--disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection \
|
|
--autoplay-policy=no-user-gesture-required \
|
|
--remote-debugging-port=9222"
|
|
.into(),
|
|
);
|
|
}
|
|
}
|
|
context
|
|
})
|
|
.expect("error while running tauri application");
|
|
}
|