diff --git a/Cargo.lock b/Cargo.lock index 37f13b9..17c5563 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,6 +18,15 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + [[package]] name = "adler2" version = "2.0.0" @@ -129,126 +138,6 @@ dependencies = [ "libloading", ] -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" -dependencies = [ - "async-lock", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-io" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 0.38.44", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-net" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" -dependencies = [ - "async-io", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-process" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix 0.38.44", - "tracing", -] - -[[package]] -name = "async-signal" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 0.38.44", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - [[package]] name = "atomic-waker" version = "1.1.2" @@ -290,6 +179,21 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -356,19 +260,6 @@ dependencies = [ "objc2", ] -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - [[package]] name = "built" version = "0.7.7" @@ -905,27 +796,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "event-listener" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - [[package]] name = "exr" version = "1.73.0" @@ -956,6 +826,12 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "file-format" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ef3d5e8ae27277c8285ac43ed153158178ef0f79567f32024ca8140a0c7cd8" + [[package]] name = "flate2" version = "1.1.1" @@ -1088,19 +964,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" -[[package]] -name = "futures-lite" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - [[package]] name = "futures-macro" version = "0.3.31" @@ -1195,6 +1058,12 @@ dependencies = [ "weezl", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "gio-sys" version = "0.20.9" @@ -1542,7 +1411,7 @@ dependencies = [ "iced_core", "log", "rustc-hash 2.1.1", - "smol", + "tokio", "wasm-bindgen-futures", "wasmtimer", ] @@ -2552,6 +2421,15 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -2600,12 +2478,6 @@ dependencies = [ "ttf-parser 0.25.1", ] -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - [[package]] name = "parking_lot" version = "0.12.3" @@ -2673,17 +2545,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - [[package]] name = "pkg-config" version = "0.3.32" @@ -2977,6 +2838,7 @@ name = "reversed-rooms-launcher" version = "0.1.0" dependencies = [ "directories", + "file-format", "iced", "iced_video_player", "image", @@ -3033,6 +2895,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -3198,15 +3066,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - [[package]] name = "simd-adler32" version = "0.3.7" @@ -3292,23 +3151,6 @@ dependencies = [ "wayland-backend", ] -[[package]] -name = "smol" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" -dependencies = [ - "async-channel", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-net", - "async-process", - "blocking", - "futures-lite", -] - [[package]] name = "smol_str" version = "0.2.2" @@ -3616,6 +3458,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.44.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +dependencies = [ + "backtrace", + "pin-project-lite", +] + [[package]] name = "toml" version = "0.8.20" diff --git a/Cargo.toml b/Cargo.toml index 99e3cbb..0587959 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,18 @@ edition = "2024" [dependencies] directories = "6.0.0" -iced = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e", features = ["smol", "tiny-skia", "image"], default-features = false } +iced = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e", features = ["tokio", "tiny-skia", "wgpu", "image"], default-features = false } image = "0.25.6" serde = { version = "1.0.219", features = ["serde_derive"] } serde_json = "1.0.140" tempfile = "3.19.1" iced_video_player = {path = "./iced_video_player"} url = "2.5.4" -rust-embed = "8.7.0" \ No newline at end of file +rust-embed = "8.7.0" +file-format = "0.26.0" + +[profile.release] +strip = true # Automatically strip symbols from the binary. +lto = true # Link-time optimization. +opt-level = 3 # Optimize for speed. +codegen-units = 1 # Maximum size reduction optimizations. diff --git a/iced_video_player/Cargo.toml b/iced_video_player/Cargo.toml index 27b3d15..63653cd 100644 --- a/iced_video_player/Cargo.toml +++ b/iced_video_player/Cargo.toml @@ -16,7 +16,7 @@ exclude = [ ] [dependencies] -iced = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e", features = ["smol", "wgpu", "image", "advanced"], default-features = false } +iced = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e", features = ["tokio", "wgpu", "image", "advanced"], default-features = false } iced_wgpu = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e" } gstreamer = "0.23.5" gstreamer-app = "0.23.5" # appsink diff --git a/resources/genshinimpact-icon.png b/resources/genshinimpact-icon.png new file mode 100644 index 0000000..b101929 Binary files /dev/null and b/resources/genshinimpact-icon.png differ diff --git a/resources/honkaistarrail-icon.png b/resources/honkaistarrail-icon.png new file mode 100644 index 0000000..fced2d8 Binary files /dev/null and b/resources/honkaistarrail-icon.png differ diff --git a/resources/wutheringwaves-icon.png b/resources/wutheringwaves-icon.png new file mode 100644 index 0000000..358fda2 Binary files /dev/null and b/resources/wutheringwaves-icon.png differ diff --git a/resources/zenlesszonezero-icon.png b/resources/zenlesszonezero-icon.png new file mode 100644 index 0000000..0e9fe05 Binary files /dev/null and b/resources/zenlesszonezero-icon.png differ diff --git a/src/main.rs b/src/main.rs index 8c25e9a..a237d3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ #![feature(let_chains)] +use file_format::FileFormat; use ::image::ImageReader; use iced::{ Alignment::Center, @@ -11,9 +12,7 @@ use iced::{ use iced_video_player::{Video, VideoPlayer}; use serde::{Deserialize, Serialize}; use std::{ - fs::{self, create_dir_all, read_to_string}, - io::{Cursor, Write}, - thread::sleep, + fs::{self, create_dir_all, read_to_string}, io::{Cursor, Write}, path::PathBuf, thread::sleep }; use tempfile::NamedTempFile; @@ -52,7 +51,6 @@ pub fn main() -> iced::Result { }; iced::application(Launcher::boot, Launcher::update, Launcher::view) - // .subscription(Launcher::subscription) .title(Launcher::title) .window(settings) .window_size((1280.0, 760.0)) @@ -79,7 +77,7 @@ struct State { selected_game: PossibleGames, installed_games: Vec, installed_game_servers: Vec, - db_software_installed: bool, + db_software_installed: bool } #[derive(Debug, Default, Serialize, Deserialize)] @@ -109,7 +107,7 @@ enum Message { } impl State { - fn path() -> std::path::PathBuf { + fn path() -> PathBuf { let mut path = if let Some(project_dirs) = directories::ProjectDirs::from("rs", "reversed-rooms", "launcher") { @@ -162,12 +160,85 @@ impl State { } } -fn deg_to_rad(deg: f32) -> f32 { +fn rad(deg: f32) -> f32 { deg * std::f32::consts::PI / 180.0 } +fn get_game_background(game: &PossibleGames) -> Element { + let file_path: &str = match game { + PossibleGames::WutheringWaves => "wutheringwaves-bg.mp4", + PossibleGames::ZenlessZoneZero => "zenlesszonezero-bg.png", + PossibleGames::HonkaiStarRail => "honkaistarrail-bg.png", + PossibleGames::GenshinImpact => "genshinimpact-bg.png", + }; + + if let Some(file) = Assets::get(file_path) { + let file_format = FileFormat::from_bytes(file.data.clone()); + if file_format.extension() == "mp4" { + let mut temp_file = NamedTempFile::new().unwrap(); + temp_file.write_all(&file.data.clone()).unwrap(); + + let temp_path = temp_file.path().to_str().unwrap().to_string(); + let mut video = + Video::new(url::Url::from_file_path(temp_path).unwrap()).unwrap(); + video.set_looping(true); + + VideoPlayer::new(video).into() + } else { + let img = ImageReader::new(Cursor::new(&file.data)) + .with_guessed_format() + .unwrap() + .decode() + .unwrap(); + let handle = image::Handle::from_rgba( + img.width(), + img.height(), + img.to_rgba8().into_raw() + ); + image(handle).content_fit(iced::ContentFit::Fill).into() + } + + } else { + panic!("Missing icon for {:?}, path: {}", game, file_path) + } +} + +fn get_game_icon(game: &PossibleGames) -> Element { + let file_path: &str = match game { + PossibleGames::WutheringWaves => "wutheringwaves-icon.png", + PossibleGames::ZenlessZoneZero => "zenlesszonezero-icon.png", + PossibleGames::HonkaiStarRail => "honkaistarrail-icon.png", + PossibleGames::GenshinImpact => "genshinimpact-icon.png", + }; + if let Some(img_file) = Assets::get(file_path) { + let img = ImageReader::new(Cursor::new(img_file.data)) + .with_guessed_format() + .unwrap() + .decode() + .unwrap() + .resize(126, 126, ::image::imageops::FilterType::Lanczos3); + let handle = image::Handle::from_rgba( + img.width(), + img.height(), + img.to_rgba8().into_raw() + ); + container(image(handle).content_fit(iced::ContentFit::Contain).height(Length::Fixed(64.0)).filter_method(image::FilterMethod::Linear)) + .style(move |_| { + container::Style { + // text_color: Color::from_rgba8(0, 0, 0, 1.0).into(), + // background: Some(Color::from_rgba8(255, 255, 255, 1.0).into()), + border: border::rounded(20), + ..container::Style::default() + } + }) + .into() + } else { + panic!("Missing icon for {:?}, path: {}", game, file_path) + } +} + fn style_container(direction: f32) -> container::Style { - let angle = deg_to_rad(direction); + let angle = rad(direction); container::Style { text_color: Color::from_rgba8(255, 255, 255, 1.0).into(), background: Some( @@ -202,11 +273,30 @@ impl Launcher { } fn view(&self) -> Element { + let game_selector = container( + row![ + get_game_icon(&PossibleGames::WutheringWaves), + get_game_icon(&PossibleGames::ZenlessZoneZero), + get_game_icon(&PossibleGames::HonkaiStarRail), + get_game_icon(&PossibleGames::GenshinImpact), + // text("test").size(25), + // text("test").size(25), + ] + .spacing(10), + ) + // .padding(10) + .align_y(Top) + .align_x(Center) + .width(Length::Fill); + let topbar = container(row![ - text("launcher... goog...").size(25), + text("Reversed Rooms").size(25), + Space::new(Length::Fill, Length::Fixed(0.0)), + game_selector, Space::new(Length::Fill, Length::Fixed(0.0)), text("rabbydevs").size(25), ]) + .height(Length::Fill) .width(Length::Fill) .style(move |_| style_container(0.0)) .padding(10); @@ -233,121 +323,12 @@ impl Launcher { column![topbar, Space::new(Length::Fill, Length::Fill), bottom_bar].width(Length::Fill); let content = container(user_area).center(Length::Fill); - - let game_selector = container( - row![ - text("test").size(25), - text("test").size(25), - text("test").size(25), - ] - .spacing(10), - ) - .padding(10) - .align_y(Top) - .align_x(Center) - .width(Length::Fill); - - fn get_game_background(game: &PossibleGames, _video: Option