From a3ac07b9d074a8bd5d644399d6301676de604aeb Mon Sep 17 00:00:00 2001 From: ljlvink Date: Thu, 5 Mar 2026 18:55:56 +0800 Subject: [PATCH 01/19] feat: add settings for setting audio buffer size option. Including all platform. --- phira/locales/en-US/settings.ftl | 1 + phira/locales/zh-CN/settings.ftl | 1 + phira/src/page/settings.rs | 14 ++++++++++++++ prpr/src/ext.rs | 6 +++--- prpr/src/ui.rs | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/phira/locales/en-US/settings.ftl b/phira/locales/en-US/settings.ftl index 4c3bbb983..d4f00b7fb 100644 --- a/phira/locales/en-US/settings.ftl +++ b/phira/locales/en-US/settings.ftl @@ -41,6 +41,7 @@ item-sfx = SFX Volume item-bgm = BGM Volume item-cali = Adjust Offset item-preferred-sample-rate = Preferred Sample Rate +item-audio-buffer-size = Audio Buffer Size item-show-acc = Real-Time Accuracy item-show-avg-fps = Show AVG FPS diff --git a/phira/locales/zh-CN/settings.ftl b/phira/locales/zh-CN/settings.ftl index 1f76869d2..08c920a53 100644 --- a/phira/locales/zh-CN/settings.ftl +++ b/phira/locales/zh-CN/settings.ftl @@ -41,6 +41,7 @@ item-sfx = 音效音量 item-bgm = BGM 音量 item-cali = 调整延迟 item-preferred-sample-rate = 首选采样率 +item-audio-buffer-size = 音频缓冲区大小 item-show-acc = 显示实时准度 item-show-avg-fps = 显示平均帧率 diff --git a/phira/src/page/settings.rs b/phira/src/page/settings.rs index a914ba26e..dfbfa6ff4 100644 --- a/phira/src/page/settings.rs +++ b/phira/src/page/settings.rs @@ -536,6 +536,7 @@ struct AudioList { cali_btn: DRectButton, #[cfg(not(target_os = "android"))] preferred_sample_rate_btn: DRectButton, + audio_buffer_size_btn: DRectButton, cali_task: LocalTask>, next_page: Option, } @@ -550,6 +551,7 @@ impl AudioList { cali_btn: DRectButton::new(), #[cfg(not(target_os = "android"))] preferred_sample_rate_btn: DRectButton::new(), + audio_buffer_size_btn: DRectButton::new(), cali_task: None, next_page: None, @@ -592,6 +594,13 @@ impl AudioList { config.preferred_sample_rate = options[(selected + 1) % options.len()]; return Ok(Some(true)); } + if self.audio_buffer_size_btn.touch(touch, t) { + let options = [128u32, 256u32, 512u32]; + let current = config.audio_buffer_size.unwrap_or(256); + let selected = options.iter().position(|&r| r == current).unwrap_or(1); + config.audio_buffer_size = Some(options[(selected + 1) % options.len()]); + return Ok(Some(true)); + } Ok(None) } @@ -649,6 +658,11 @@ impl AudioList { render_title(ui, tl!("item-preferred-sample-rate"), None); self.preferred_sample_rate_btn.render_text(ui, rr, t, format!("{} Hz", config.preferred_sample_rate), 0.5, false); } + item! { + render_title(ui, tl!("item-audio-buffer-size"), None); + let buf_size = config.audio_buffer_size.unwrap_or(256); + self.audio_buffer_size_btn.render_text(ui, rr, t, format!("{}", buf_size), 0.5, false); + } (w, h) } diff --git a/prpr/src/ext.rs b/prpr/src/ext.rs index 7807b3b87..cc11875ac 100644 --- a/prpr/src/ext.rs +++ b/prpr/src/ext.rs @@ -389,7 +389,7 @@ pub fn screen_aspect() -> f32 { let vp = get_viewport(); vp.2 as f32 / vp.3 as f32 } - +// this function is used for creating InGame audio manager pub fn create_audio_manger(config: &Config) -> Result { #[cfg(target_os = "android")] { @@ -404,8 +404,8 @@ pub fn create_audio_manger(config: &Config) -> Result { { use sasa::backend::ohos::*; AudioManager::new(OhosBackend::new(OhosSettings { - buffer_size: Some(256), - sample_rate: Some(config.preferred_sample_rate), + sample_rate: config.preferred_sample_rate.into(), + buffer_size: config.audio_buffer_size.or(Some(256)), channels: 2, })) } diff --git a/prpr/src/ui.rs b/prpr/src/ui.rs index 67c9ac92c..762be6685 100644 --- a/prpr/src/ui.rs +++ b/prpr/src/ui.rs @@ -1245,7 +1245,7 @@ impl<'a> From<(Option, &'a mut f32)> for LoadingParams<'a> { } } } - +// this function is used for creating UI audio manager. #[allow(clippy::blocks_in_conditions)] fn build_audio() -> AudioManager { match { From 1f69abea148787c118e6b9a3612f789d46912a9c Mon Sep 17 00:00:00 2001 From: ljlvink Date: Thu, 5 Mar 2026 19:55:33 +0800 Subject: [PATCH 02/19] feat: enable password input for ohos --- prpr/src/scene.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/prpr/src/scene.rs b/prpr/src/scene.rs index 0ce76f2be..b0f6ca411 100644 --- a/prpr/src/scene.rs +++ b/prpr/src/scene.rs @@ -220,7 +220,12 @@ pub fn request_input_full(id: impl Into, #[allow(unused_variables)] text ]; } }else if #[cfg(target_env = "ohos")] { - miniquad::native::call_request_callback(r#"{"action": "show_input_window"}"#.to_string()); + let json = if is_password { + r#"{"action": "show_input_window", "isPassword": true}"# + } else { + r#"{"action": "show_input_window"}"# + }; + miniquad::native::call_request_callback(json.to_string()); } else { // if let Some(text) = tfd::InputBox::new(ttl!("input"), ttl!("input-msg")).with_default(text).run_modal() { // INPUT_TEXT.lock().unwrap().1 = Some(text); From 63a6e3bc92840cd43688874314dcf334d560b4d8 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Sat, 7 Mar 2026 12:30:56 +0800 Subject: [PATCH 03/19] feat: use photo picker in ohos when selecting avatar ref: https://github.com/TeamFlos/phira-ohos/commit/c9ff919e630b2a30944204ca11322e62f4f8bdf2 --- prpr/src/scene.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/prpr/src/scene.rs b/prpr/src/scene.rs index b0f6ca411..96c297232 100644 --- a/prpr/src/scene.rs +++ b/prpr/src/scene.rs @@ -246,7 +246,8 @@ pub fn return_input(id: String, text: String) { #[cfg(not(target_arch = "wasm32"))] pub fn request_file(id: impl Into) { - *CHOSEN_FILE.lock().unwrap() = (Some(id.into()), None); + let id: String = id.into(); + *CHOSEN_FILE.lock().unwrap() = (Some(id.clone()), None); cfg_if! { if #[cfg(target_os = "android")] { unsafe { @@ -324,7 +325,8 @@ pub fn request_file(id: impl Into) { ]; } } else if #[cfg(target_env = "ohos")] { - miniquad::native::call_request_callback(r#"{"action": "chooseFile"}"#.to_string()); + let is_photo = id == "avatar"; + miniquad::native::call_request_callback(format!(r#"{{"action": "chooseFile", "isPhoto": {}}}"#, is_photo)); } else { // desktop CHOSEN_FILE.lock().unwrap().1 = rfd::FileDialog::new().pick_file().map(|it| it.display().to_string()); } From b1aca9863bf8919a6edad012c439a83f4aaaa99b Mon Sep 17 00:00:00 2001 From: ljlvink Date: Mon, 9 Mar 2026 17:55:35 +0800 Subject: [PATCH 04/19] feat: add auto import for ohos --- phira/src/lib.rs | 11 ++--------- phira/src/scene/main.rs | 13 +++++++++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/phira/src/lib.rs b/phira/src/lib.rs index 9a7afe955..6ce25036a 100644 --- a/phira/src/lib.rs +++ b/phira/src/lib.rs @@ -471,14 +471,7 @@ pub fn set_chosen_file(file: String) { #[cfg(target_env = "ohos")] #[napi] -pub fn mark_import() { +pub fn mark_auto_import() { use prpr::scene::CHOSEN_FILE; - CHOSEN_FILE.lock().unwrap().0 = Some("_import".to_owned()); -} - -#[cfg(target_env = "ohos")] -#[napi] -pub fn mark_import_respack() { - use prpr::scene::CHOSEN_FILE; - CHOSEN_FILE.lock().unwrap().0 = Some("_import_respack".to_owned()); + CHOSEN_FILE.lock().unwrap().0 = Some("_import_auto".to_owned()); } diff --git a/phira/src/scene/main.rs b/phira/src/scene/main.rs index 7634701c3..167a058b6 100644 --- a/phira/src/scene/main.rs +++ b/phira/src/scene/main.rs @@ -331,6 +331,19 @@ impl Scene for MainScene { } if let Some((id, file)) = take_file() { match id.as_str() { + "_import_auto" => { + let new_id = match File::open(&file).map(BufReader::new).map(zip::ZipArchive::new) { + Ok(Ok(zip)) => { + if zip.file_names().any(|name| name.ends_with("click.png")) { + "_import_respack" + } else { + "_import" + } + } + _ => "_import", + }; + return_file(new_id.to_owned(), file); + } "_import" => { self.import_task = Some(Task::new(import_chart(file))); } From fff66f10b71ce976ab2940c092cca837d2ab0706 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Tue, 10 Mar 2026 00:32:22 +0800 Subject: [PATCH 05/19] feat: adapt inputbox for ohos --- Cargo.lock | 4 +++- Cargo.toml | 2 +- phira/src/page/library.rs | 13 +++++++++++++ prpr/src/scene.rs | 14 +------------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1656b844..4dd7bb977 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1696,12 +1696,14 @@ dependencies = [ [[package]] name = "inputbox" version = "0.0.1" -source = "git+https://github.com/Mivik/inputbox.git?rev=910c465#910c4652ec23fd4eb69f545b6823fce17b7dde3c" +source = "git+https://github.com/Mivik/inputbox.git?rev=f41dc19#f41dc19684ee13002e4f69a7d39e863a2bb149cd" dependencies = [ "block2", "cfg-if", "jni 0.22.3", "log", + "napi-derive-ohos", + "napi-ohos", "objc2", "objc2-core-foundation", "objc2-foundation", diff --git a/Cargo.toml b/Cargo.toml index c7428f569..f73e90104 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ futures-util = "0.3.31" hex = "0.4.3" image = { version = "0.25.9", default-features = false } # inputbox = "0.0.1" -inputbox = { git = "https://github.com/Mivik/inputbox.git", rev = "910c465" } +inputbox = { git = "https://github.com/Mivik/inputbox.git", rev = "f41dc19" } lru = "0.16.3" lyon = "1.0.16" nalgebra = "0.34.1" diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index 63950b504..d42fb1849 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -17,6 +17,7 @@ use crate::{ use anyhow::{anyhow, Error, Result}; use inputbox::InputBox; use macroquad::prelude::*; +use napi_derive_ohos::napi; use prpr::{ ext::{poll_future, semi_black, JoinToString, LocalTask, RectExt, SafeTexture, ScaleType}, scene::{request_file, request_input, return_input, show_error, show_message, take_input, NextScene}, @@ -418,6 +419,8 @@ fn request_export() { } } else if #[cfg(target_os = "ios")] { todo!() + } else if #[cfg(target_env = "ohos")]{ + miniquad::native::call_request_callback(format!("{{\"action\":\"request_export\",\"filename\":\"{}\"}}", suggested_name)); } else { if let Some(output_path) = rfd::FileDialog::new().set_title(tl!("multi-export-title")).set_file_name(&suggested_name).save_file() { let config = File::create(&output_path).map(|file| ExportConfig { @@ -451,6 +454,16 @@ extern "system" fn process_export_fd(env: jni::JNIEnv, _: jni::objects::JClass, })); } +#[napi] +fn process_export_fd_ohos(fd: u32) { + use std::os::fd::FromRawFd; + let file = unsafe { File::from_raw_fd(fd as _) }; + EXPORT_CONFIG.lock().unwrap().replace(Ok(ExportConfig { + file, + deleter: Box::new(|| Ok(())), + })); +} + impl Page for LibraryPage { fn label(&self) -> Cow<'static, str> { tl!("label") diff --git a/prpr/src/scene.rs b/prpr/src/scene.rs index f9e7d272e..fda2e8e5b 100644 --- a/prpr/src/scene.rs +++ b/prpr/src/scene.rs @@ -170,19 +170,7 @@ fn show_inputbox(config: InputBox, backend: &dyn Backend) { #[inline] pub fn request_input(id: impl Into, mut config: InputBox) { *INPUT_TEXT.lock().unwrap() = (Some(id.into()), None); - if config.title.is_none() { - config = config.title(ttl!("input")); - } - if config.prompt.is_none() { - config = config.prompt(ttl!("input-msg")); - } - cfg_if! { - if #[cfg(target_env = "ohos")] { - miniquad::native::call_request_callback(r#"{"action": "show_input_window"}"#.to_string()); - } else { - show_inputbox(config, &*default_backend()); - } - } + show_inputbox(config, &*default_backend()); } pub fn take_input() -> Option<(String, String)> { From 481aaa0f269b2c79bb7510563438fa720a076dab Mon Sep 17 00:00:00 2001 From: ljlvink Date: Tue, 10 Mar 2026 00:41:23 +0800 Subject: [PATCH 06/19] chore: fix cliippy and cargo fmt --- phira/src/page/favorites.rs | 7 +------ phira/src/page/library.rs | 5 ++++- prpr/src/scene.rs | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/phira/src/page/favorites.rs b/phira/src/page/favorites.rs index 55f137092..53f845389 100644 --- a/phira/src/page/favorites.rs +++ b/phira/src/page/favorites.rs @@ -678,12 +678,7 @@ impl Page for FavoritesPage { request_input("fav_rename", InputBox::new().default_text(&col.name)); } "set-description" => { - request_input( - "fav_description", - InputBox::new() - .default_text(&col.description) - .mode(InputMode::Multiline), - ); + request_input("fav_description", InputBox::new().default_text(&col.description).mode(InputMode::Multiline)); } "set-cover" => { if col.id.is_none() { diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index d42fb1849..4615842ab 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -753,7 +753,10 @@ impl Page for LibraryPage { } } } - Ok(CreateFavorite { name: text, charts: selected }) + Ok(CreateFavorite { + name: text, + charts: selected, + }) })); } } diff --git a/prpr/src/scene.rs b/prpr/src/scene.rs index fda2e8e5b..82264b5f0 100644 --- a/prpr/src/scene.rs +++ b/prpr/src/scene.rs @@ -168,7 +168,7 @@ fn show_inputbox(config: InputBox, backend: &dyn Backend) { } #[inline] -pub fn request_input(id: impl Into, mut config: InputBox) { +pub fn request_input(id: impl Into, config: InputBox) { *INPUT_TEXT.lock().unwrap() = (Some(id.into()), None); show_inputbox(config, &*default_backend()); } From 364e9e93dcd6687ce4e2e5cba1544acf4fd40530 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Tue, 10 Mar 2026 00:43:49 +0800 Subject: [PATCH 07/19] chore: fix deps --- phira/src/page/library.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index 4615842ab..f120fa881 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -17,6 +17,7 @@ use crate::{ use anyhow::{anyhow, Error, Result}; use inputbox::InputBox; use macroquad::prelude::*; +#[cfg(target_env = "ohos")] use napi_derive_ohos::napi; use prpr::{ ext::{poll_future, semi_black, JoinToString, LocalTask, RectExt, SafeTexture, ScaleType}, From 285ae70dad7bb7f4babc946ffa87280aa7f4ca44 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Tue, 10 Mar 2026 00:47:07 +0800 Subject: [PATCH 08/19] chore: fix clippy --- phira/src/page/library.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index f120fa881..ae86c911d 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -455,6 +455,7 @@ extern "system" fn process_export_fd(env: jni::JNIEnv, _: jni::objects::JClass, })); } +#[cfg(target_env = "ohos")] #[napi] fn process_export_fd_ohos(fd: u32) { use std::os::fd::FromRawFd; From 609290a18456791a8462832c804a33351ba1494e Mon Sep 17 00:00:00 2001 From: ljlvink Date: Wed, 11 Mar 2026 22:00:49 +0800 Subject: [PATCH 09/19] fix: formats --- phira/src/page/library.rs | 2 +- prpr/src/ext.rs | 2 +- prpr/src/scene.rs | 8 +++++++- prpr/src/ui.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index ae86c911d..9ed1f6c32 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -420,7 +420,7 @@ fn request_export() { } } else if #[cfg(target_os = "ios")] { todo!() - } else if #[cfg(target_env = "ohos")]{ + } else if #[cfg(target_env = "ohos")] { miniquad::native::call_request_callback(format!("{{\"action\":\"request_export\",\"filename\":\"{}\"}}", suggested_name)); } else { if let Some(output_path) = rfd::FileDialog::new().set_title(tl!("multi-export-title")).set_file_name(&suggested_name).save_file() { diff --git a/prpr/src/ext.rs b/prpr/src/ext.rs index ffd935767..614488cd9 100644 --- a/prpr/src/ext.rs +++ b/prpr/src/ext.rs @@ -389,7 +389,7 @@ pub fn screen_aspect() -> f32 { let vp = get_viewport(); vp.2 as f32 / vp.3 as f32 } -// this function is used for creating InGame audio manager +// This function is used to create in-game audio manager pub fn create_audio_manger(config: &Config) -> Result { #[cfg(target_os = "android")] { diff --git a/prpr/src/scene.rs b/prpr/src/scene.rs index 82264b5f0..7f16dc965 100644 --- a/prpr/src/scene.rs +++ b/prpr/src/scene.rs @@ -168,8 +168,14 @@ fn show_inputbox(config: InputBox, backend: &dyn Backend) { } #[inline] -pub fn request_input(id: impl Into, config: InputBox) { +pub fn request_input(id: impl Into, mut config: InputBox) { *INPUT_TEXT.lock().unwrap() = (Some(id.into()), None); + if config.title.is_none() { + config = config.title(ttl!("input")); + } + if config.prompt.is_none() { + config = config.prompt(ttl!("input-msg")); + } show_inputbox(config, &*default_backend()); } diff --git a/prpr/src/ui.rs b/prpr/src/ui.rs index f335dbe15..29b6a9484 100644 --- a/prpr/src/ui.rs +++ b/prpr/src/ui.rs @@ -1246,7 +1246,7 @@ impl<'a> From<(Option, &'a mut f32)> for LoadingParams<'a> { } } } -// this function is used for creating UI audio manager. +// This function is used to create UI audio manager. #[allow(clippy::blocks_in_conditions)] fn build_audio() -> AudioManager { match { From b6abe6e232e0d59eed91886beb0abddad0f8b774 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Wed, 11 Mar 2026 22:22:52 +0800 Subject: [PATCH 10/19] fix: add allow dead_code tag for napi --- phira/src/page/library.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index 2c9c7783d..2f727cd74 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -547,6 +547,7 @@ extern "system" fn process_export_fd(env: jni::JNIEnv, _: jni::objects::JClass, } #[cfg(target_env = "ohos")] +#[allow(dead_code)] #[napi] fn process_export_fd_ohos(fd: u32) { use std::os::fd::FromRawFd; From 4ef848a06e34e73248b6b6b5d897d02b2bf927a4 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Wed, 11 Mar 2026 22:24:43 +0800 Subject: [PATCH 11/19] fix: move checks to front to avoid checks --- prpr/src/scene.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prpr/src/scene.rs b/prpr/src/scene.rs index 7f16dc965..098c664df 100644 --- a/prpr/src/scene.rs +++ b/prpr/src/scene.rs @@ -191,7 +191,8 @@ pub fn return_input(id: String, text: String) { #[cfg(not(target_arch = "wasm32"))] pub fn request_file(id: impl Into) { let id: String = id.into(); - *CHOSEN_FILE.lock().unwrap() = (Some(id.clone()), None); + let is_photo = id == "avatar"; + *CHOSEN_FILE.lock().unwrap() = (Some(id), None); cfg_if! { if #[cfg(target_os = "android")] { unsafe { @@ -294,7 +295,6 @@ pub fn request_file(id: impl Into) { .unwrap() .presentViewController_animated_completion(&picker, true, None); } else if #[cfg(target_env = "ohos")] { - let is_photo = id == "avatar"; miniquad::native::call_request_callback(format!(r#"{{"action": "chooseFile", "isPhoto": {}}}"#, is_photo)); } else { // desktop CHOSEN_FILE.lock().unwrap().1 = rfd::FileDialog::new().pick_file().map(|it| it.display().to_string()); From 26af1231779c0fbc67eaf25dbe9ad3d914a70420 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Wed, 11 Mar 2026 22:26:39 +0800 Subject: [PATCH 12/19] feat: move napi_derive_ohos in single usage --- phira/src/page/library.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index 2f727cd74..a38b0ae20 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -18,8 +18,6 @@ use anyhow::{anyhow, Error, Result}; use chrono::{DateTime, Utc}; use inputbox::InputBox; use macroquad::prelude::*; -#[cfg(target_env = "ohos")] -use napi_derive_ohos::napi; use prpr::{ ext::{poll_future, semi_black, JoinToString, LocalTask, RectExt, SafeTexture, ScaleType}, scene::{request_file, request_input, return_input, show_error, show_message, take_input, NextScene}, @@ -547,6 +545,7 @@ extern "system" fn process_export_fd(env: jni::JNIEnv, _: jni::objects::JClass, } #[cfg(target_env = "ohos")] +use napi_derive_ohos::napi; #[allow(dead_code)] #[napi] fn process_export_fd_ohos(fd: u32) { From c55fdb28a74cc8c2f03e28a0a16e6983656d09d0 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Wed, 11 Mar 2026 22:32:24 +0800 Subject: [PATCH 13/19] fix: change audio_buffer_size_btn only for ohos platform --- phira/src/page/settings.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phira/src/page/settings.rs b/phira/src/page/settings.rs index 8999badd5..9ba3e402b 100644 --- a/phira/src/page/settings.rs +++ b/phira/src/page/settings.rs @@ -537,6 +537,7 @@ struct AudioList { cali_btn: DRectButton, #[cfg(not(target_os = "android"))] preferred_sample_rate_btn: DRectButton, + #[cfg(target_env = "ohos")] audio_buffer_size_btn: DRectButton, cali_task: LocalTask>, next_page: Option, @@ -552,6 +553,7 @@ impl AudioList { cali_btn: DRectButton::new(), #[cfg(not(target_os = "android"))] preferred_sample_rate_btn: DRectButton::new(), + #[cfg(target_env = "ohos")] audio_buffer_size_btn: DRectButton::new(), cali_task: None, @@ -595,6 +597,7 @@ impl AudioList { config.preferred_sample_rate = options[(selected + 1) % options.len()]; return Ok(Some(true)); } + #[cfg(target_env = "ohos")] if self.audio_buffer_size_btn.touch(touch, t) { let options = [128u32, 256u32, 512u32]; let current = config.audio_buffer_size.unwrap_or(256); @@ -659,6 +662,7 @@ impl AudioList { render_title(ui, tl!("item-preferred-sample-rate"), None); self.preferred_sample_rate_btn.render_text(ui, rr, t, format!("{} Hz", config.preferred_sample_rate), 0.5, false); } + #[cfg(target_env = "ohos")] item! { render_title(ui, tl!("item-audio-buffer-size"), None); let buf_size = config.audio_buffer_size.unwrap_or(256); From 0e424e21f42a09f5ea48bf63a1900f8d348dfb09 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Wed, 11 Mar 2026 22:33:41 +0800 Subject: [PATCH 14/19] chore: cargo fmt --- phira/src/page/library.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index a38b0ae20..eb169d236 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -846,7 +846,10 @@ impl Page for LibraryPage { } } } - Ok(CreateFavorite { name: text, charts: selected }) + Ok(CreateFavorite { + name: text, + charts: selected, + }) })); } } From 15a493c48319d3cdeec97c4f25a181766945d963 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Wed, 11 Mar 2026 22:37:36 +0800 Subject: [PATCH 15/19] chore: fix clippy --- prpr/src/scene.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/prpr/src/scene.rs b/prpr/src/scene.rs index 098c664df..2591c3b4f 100644 --- a/prpr/src/scene.rs +++ b/prpr/src/scene.rs @@ -191,6 +191,7 @@ pub fn return_input(id: String, text: String) { #[cfg(not(target_arch = "wasm32"))] pub fn request_file(id: impl Into) { let id: String = id.into(); + #[cfg(target_env = "ohos")] let is_photo = id == "avatar"; *CHOSEN_FILE.lock().unwrap() = (Some(id), None); cfg_if! { From 190be6d1ff0f6f477ff0996240414ccf5464a921 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Wed, 11 Mar 2026 22:45:22 +0800 Subject: [PATCH 16/19] chore: fix clippy --- phira/src/page/library.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/phira/src/page/library.rs b/phira/src/page/library.rs index eb169d236..08c3c4a02 100644 --- a/phira/src/page/library.rs +++ b/phira/src/page/library.rs @@ -545,16 +545,19 @@ extern "system" fn process_export_fd(env: jni::JNIEnv, _: jni::objects::JClass, } #[cfg(target_env = "ohos")] -use napi_derive_ohos::napi; -#[allow(dead_code)] -#[napi] -fn process_export_fd_ohos(fd: u32) { - use std::os::fd::FromRawFd; - let file = unsafe { File::from_raw_fd(fd as _) }; - EXPORT_CONFIG.lock().unwrap().replace(Ok(ExportConfig { - file, - deleter: Box::new(|| Ok(())), - })); +mod ohos_export { + use super::*; + use napi_derive_ohos::napi; + #[napi] + #[allow(dead_code)] + pub fn process_export_fd_ohos(fd: u32) { + use std::os::fd::FromRawFd; + let file = unsafe { File::from_raw_fd(fd as _) }; + EXPORT_CONFIG.lock().unwrap().replace(Ok(ExportConfig { + file, + deleter: Box::new(|| Ok(())), + })); + } } impl Page for LibraryPage { From 0345d0c3b4ef3e012f353850553437ba550fad30 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Thu, 12 Mar 2026 11:32:23 +0800 Subject: [PATCH 17/19] fix: fullscreen not on ohos --- phira/src/page/settings.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phira/src/page/settings.rs b/phira/src/page/settings.rs index 9ba3e402b..5262c16e3 100644 --- a/phira/src/page/settings.rs +++ b/phira/src/page/settings.rs @@ -272,7 +272,7 @@ struct GeneralList { lang_btn: ChooseButton, - #[cfg(any(target_os = "windows", target_os = "linux"))] + #[cfg(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))] fullscreen_btn: DRectButton, cache_btn: DRectButton, @@ -306,7 +306,7 @@ impl GeneralList { .unwrap_or_default(), ), - #[cfg(any(target_os = "windows", target_os = "linux"))] + #[cfg(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))] fullscreen_btn: DRectButton::new(), cache_btn: DRectButton::new(), @@ -364,7 +364,7 @@ impl GeneralList { return Ok(Some(false)); } - #[cfg(any(target_os = "windows", target_os = "linux"))] + #[cfg(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))] if self.fullscreen_btn.touch(touch, t) { config.fullscreen_mode ^= true; @@ -475,7 +475,7 @@ impl GeneralList { self.lang_btn.render(ui, rr, t); } - #[cfg(any(target_os = "windows", target_os = "linux"))] + #[cfg(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))] item! { render_title(ui, tl!("item-fullscreen"), None); render_switch(ui, rr, t, &mut self.fullscreen_btn, config.fullscreen_mode); From 8f3406b2cd85a489b9f478b020f0b797ca96f963 Mon Sep 17 00:00:00 2001 From: ljlvink Date: Thu, 12 Mar 2026 11:50:39 +0800 Subject: [PATCH 18/19] fix: preferred sample rate default 48000 for ohos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 经过测试,44100对华为设备性能影响非常大 --- prpr/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prpr/src/config.rs b/prpr/src/config.rs index 2e58a5c35..ebca62602 100644 --- a/prpr/src/config.rs +++ b/prpr/src/config.rs @@ -80,7 +80,7 @@ impl Default for Config { particle: true, player_name: "Mivik".to_string(), player_rks: 15., - preferred_sample_rate: 44100, + preferred_sample_rate: if cfg!(target_env = "ohos") { 48000 } else { 44100 }, res_pack_path: None, sample_count: 1, show_acc: false, From 7cfbf03b792a90b1120ecd1137655bfeaffe161a Mon Sep 17 00:00:00 2001 From: ljlvink Date: Thu, 12 Mar 2026 13:05:33 +0800 Subject: [PATCH 19/19] fix: inner deps for ohos --- prpr/src/judge.rs | 8 ++++---- prpr/src/lib.rs | 2 +- prpr/src/scene/game.rs | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/prpr/src/judge.rs b/prpr/src/judge.rs index 65fdda932..a3dbfc861 100644 --- a/prpr/src/judge.rs +++ b/prpr/src/judge.rs @@ -151,7 +151,7 @@ pub enum Judgement { Miss, } -#[cfg(any(not(closed), target_os = "windows", target_os = "linux"))] +#[cfg(any(not(closed), all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos"))))] #[derive(Default)] pub(crate) struct JudgeInner { diffs: Vec, @@ -162,7 +162,7 @@ pub(crate) struct JudgeInner { num_of_notes: u32, } -#[cfg(any(not(closed), target_os = "windows", target_os = "linux"))] +#[cfg(any(not(closed), all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos"))))] impl JudgeInner { pub fn new(num_of_notes: u32) -> Self { Self { @@ -247,9 +247,9 @@ impl JudgeInner { } #[rustfmt::skip] -#[cfg(all(closed, not(any(target_os = "windows", target_os = "linux"))))] +#[cfg(all(closed, not(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))))] pub mod inner; -#[cfg(all(closed, not(any(target_os = "windows", target_os = "linux"))))] +#[cfg(all(closed, not(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))))] use inner::*; type Judgements = Vec<(f32, u32, u32, Result)>; diff --git a/prpr/src/lib.rs b/prpr/src/lib.rs index 03c1270ed..dd999a823 100644 --- a/prpr/src/lib.rs +++ b/prpr/src/lib.rs @@ -17,7 +17,7 @@ pub mod ui; pub mod log; #[rustfmt::skip] -#[cfg(all(closed, not(any(target_os = "windows", target_os = "linux"))))] +#[cfg(all(closed, not(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))))] pub mod inner; pub use scene::Main; diff --git a/prpr/src/scene/game.rs b/prpr/src/scene/game.rs index 6aaad8152..7dff135d9 100644 --- a/prpr/src/scene/game.rs +++ b/prpr/src/scene/game.rs @@ -45,9 +45,9 @@ use tracing::{debug, warn}; const PAUSE_CLICK_INTERVAL: f32 = 0.7; #[rustfmt::skip] -#[cfg(all(closed, not(any(target_os = "windows", target_os = "linux"))))] +#[cfg(all(closed, not(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))))] mod inner; -#[cfg(all(closed, not(any(target_os = "windows", target_os = "linux"))))] +#[cfg(all(closed, not(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))))] use inner::*; const WAIT_TIME: f32 = 0.5; @@ -916,7 +916,7 @@ impl Scene for GameScene { if t >= AFTER_TIME + 0.3 { let mut record_data = None; // TODO strengthen the protection - #[cfg(all(closed, not(any(target_os = "windows", target_os = "linux"))))] + #[cfg(all(closed, not(all(any(target_os = "windows", target_os = "linux"), not(target_env = "ohos")))))] if let Some(upload_fn) = &self.upload_fn { if !self.res.config.offline_mode && !self.res.config.autoplay() && self.res.config.speed >= 1.0 - 1e-3 { if let Some(player) = &self.player {