add video_protocol.rs, commands.rs, main.rs, and index.html
This commit is contained in:
@@ -1,5 +1,126 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use std::sync::Mutex;
|
||||
use tauri::Manager;
|
||||
use tutorialdock_lib::{commands, ffmpeg, fonts, library, prefs, video_protocol, AppPaths};
|
||||
|
||||
fn main() {
|
||||
tutorialdock_lib::run();
|
||||
// 1. Resolve exe directory for portability.
|
||||
let exe_dir = std::env::current_exe()
|
||||
.expect("cannot resolve exe path")
|
||||
.parent()
|
||||
.expect("exe has no parent")
|
||||
.to_path_buf();
|
||||
|
||||
let state_dir = exe_dir.join("state");
|
||||
|
||||
// 2. Create all subdirectories.
|
||||
let paths = AppPaths {
|
||||
exe_dir: exe_dir.clone(),
|
||||
state_dir: state_dir.clone(),
|
||||
fonts_dir: state_dir.join("fonts"),
|
||||
fa_dir: state_dir.join("fontawesome"),
|
||||
subs_dir: state_dir.join("subtitles"),
|
||||
};
|
||||
std::fs::create_dir_all(&paths.fonts_dir).ok();
|
||||
std::fs::create_dir_all(&paths.fa_dir.join("webfonts")).ok();
|
||||
std::fs::create_dir_all(&paths.subs_dir).ok();
|
||||
|
||||
// 3. Set WebView2 user data folder for portability (no AppData usage).
|
||||
let webview_profile = state_dir.join("webview_profile");
|
||||
std::fs::create_dir_all(&webview_profile).ok();
|
||||
unsafe {
|
||||
std::env::set_var("WEBVIEW2_USER_DATA_FOLDER", &webview_profile);
|
||||
}
|
||||
|
||||
// 4. Load preferences.
|
||||
let prefs_data = prefs::Prefs::load(&state_dir);
|
||||
|
||||
// 5. Initialize library (empty - loaded from last folder or frontend action).
|
||||
let mut lib = library::Library::new();
|
||||
|
||||
// Discover ffmpeg/ffprobe.
|
||||
let ff_paths = ffmpeg::discover(&paths.exe_dir, &paths.state_dir);
|
||||
lib.ffprobe = ff_paths.ffprobe;
|
||||
lib.ffmpeg = ff_paths.ffmpeg;
|
||||
|
||||
// Restore last folder if it exists.
|
||||
if let Some(ref last_path) = prefs_data.last_folder_path {
|
||||
if std::path::Path::new(last_path).is_dir() {
|
||||
let _ = lib.set_root(last_path, &state_dir);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Build Tauri app.
|
||||
let builder = tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.manage(Mutex::new(lib))
|
||||
.manage(Mutex::new(prefs_data))
|
||||
.manage(paths)
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
commands::select_folder,
|
||||
commands::open_folder_path,
|
||||
commands::get_recents,
|
||||
commands::remove_recent,
|
||||
commands::get_library,
|
||||
commands::set_current,
|
||||
commands::tick_progress,
|
||||
commands::set_folder_volume,
|
||||
commands::set_folder_autoplay,
|
||||
commands::set_folder_rate,
|
||||
commands::set_order,
|
||||
commands::start_duration_scan,
|
||||
commands::get_prefs,
|
||||
commands::set_prefs,
|
||||
commands::set_always_on_top,
|
||||
commands::save_window_state,
|
||||
commands::get_note,
|
||||
commands::set_note,
|
||||
commands::get_current_video_meta,
|
||||
commands::get_current_subtitle,
|
||||
commands::get_embedded_subtitles,
|
||||
commands::extract_embedded_subtitle,
|
||||
commands::get_available_subtitles,
|
||||
commands::load_sidecar_subtitle,
|
||||
commands::choose_subtitle_file,
|
||||
commands::reset_watch_progress,
|
||||
]);
|
||||
|
||||
// Register custom protocol for video/subtitle/font serving.
|
||||
let builder = video_protocol::register_protocol(builder);
|
||||
|
||||
// Configure window from saved prefs and launch.
|
||||
builder
|
||||
.setup(|app| {
|
||||
let prefs_state = app.state::<Mutex<prefs::Prefs>>();
|
||||
let p = prefs_state.lock().unwrap();
|
||||
let win = app.get_webview_window("main").unwrap();
|
||||
|
||||
if let Some(x) = p.window.x {
|
||||
if let Some(y) = p.window.y {
|
||||
let _ = win.set_position(tauri::Position::Physical(
|
||||
tauri::PhysicalPosition::new(x, y),
|
||||
));
|
||||
}
|
||||
}
|
||||
let _ = win.set_size(tauri::Size::Physical(tauri::PhysicalSize::new(
|
||||
p.window.width as u32,
|
||||
p.window.height as u32,
|
||||
)));
|
||||
let _ = win.set_always_on_top(p.always_on_top);
|
||||
drop(p);
|
||||
|
||||
// Spawn async font caching (silent, non-blocking).
|
||||
let app_paths = app.state::<AppPaths>();
|
||||
let fonts_dir = app_paths.fonts_dir.clone();
|
||||
let fa_dir = app_paths.fa_dir.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let _ = fonts::ensure_google_fonts_local(&fonts_dir).await;
|
||||
let _ = fonts::ensure_fontawesome_local(&fa_dir).await;
|
||||
});
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user