android.rs (5288B)
1 //#[cfg(target_os = "android")] 2 //use egui_android::run_android; 3 4 use egui_winit::winit::platform::android::activity::AndroidApp; 5 use notedeck_columns::Damus; 6 use notedeck_dave::Dave; 7 8 use crate::{app::NotedeckApp, chrome::Chrome, setup::setup_chrome}; 9 use notedeck::Notedeck; 10 11 #[no_mangle] 12 #[tokio::main] 13 pub async fn android_main(app: AndroidApp) { 14 //use tracing_logcat::{LogcatMakeWriter, LogcatTag}; 15 use tracing_subscriber::{prelude::*, EnvFilter}; 16 17 std::env::set_var("RUST_BACKTRACE", "full"); 18 //std::env::set_var("DAVE_ENDPOINT", "http://ollama.jb55.com/v1"); 19 //std::env::set_var("DAVE_MODEL", "hhao/qwen2.5-coder-tools:latest"); 20 std::env::set_var( 21 "RUST_LOG", 22 "egui=debug,egui-winit=debug,notedeck=debug,notedeck_columns=debug,notedeck_chrome=debug,enostr=debug,android_activity=debug", 23 ); 24 25 //std::env::set_var( 26 // "RUST_LOG", 27 // "enostr=debug,notedeck_columns=debug,notedeck_chrome=debug", 28 //); 29 30 //let writer = 31 //LogcatMakeWriter::new(LogcatTag::Target).expect("Failed to initialize logcat writer"); 32 33 let fmt_layer = tracing_subscriber::fmt::layer() 34 .with_level(false) 35 .with_target(false) 36 .without_time(); 37 38 let filter_layer = EnvFilter::try_from_default_env() 39 .or_else(|_| EnvFilter::try_new("info")) 40 .unwrap(); 41 42 tracing_subscriber::registry() 43 .with(filter_layer) 44 .with(fmt_layer) 45 .init(); 46 47 let path = app.internal_data_path().expect("data path"); 48 let mut options = eframe::NativeOptions { 49 depth_buffer: 24, 50 ..eframe::NativeOptions::default() 51 }; 52 53 options.renderer = eframe::Renderer::Wgpu; 54 // Clone `app` to use it both in the closure and later in the function 55 //let app_clone_for_event_loop = app.clone(); 56 //options.event_loop_builder = Some(Box::new(move |builder| { 57 // builder.with_android_app(app_clone_for_event_loop); 58 //})); 59 60 options.android_app = Some(app.clone()); 61 62 let app_args = get_app_args(app); 63 64 let _res = eframe::run_native( 65 "Damus Notedeck", 66 options, 67 Box::new(move |cc| { 68 let ctx = &cc.egui_ctx; 69 let mut notedeck = Notedeck::new(ctx, path, &app_args); 70 setup_chrome(ctx, ¬edeck.args(), notedeck.theme()); 71 72 let context = &mut notedeck.app_context(); 73 let dave = Dave::new(cc.wgpu_render_state.as_ref()); 74 let columns = Damus::new(context, &app_args); 75 let mut chrome = Chrome::new(); 76 77 // ensure we recognized all the arguments 78 let completely_unrecognized: Vec<String> = notedeck 79 .unrecognized_args() 80 .intersection(columns.unrecognized_args()) 81 .cloned() 82 .collect(); 83 assert!( 84 completely_unrecognized.is_empty(), 85 "unrecognized args: {:?}", 86 completely_unrecognized 87 ); 88 89 chrome.add_app(NotedeckApp::Columns(columns)); 90 chrome.add_app(NotedeckApp::Dave(dave)); 91 92 // test dav 93 chrome.set_active(0); 94 95 notedeck.set_app(chrome); 96 97 Ok(Box::new(notedeck)) 98 }), 99 ); 100 } 101 /* 102 Read args from a config file: 103 - allows use of more interesting args w/o risk of checking them in by mistake 104 - allows use of different args w/o rebuilding the app 105 - uses compiled in defaults if config file missing or broken 106 107 Example android-config.json: 108 ``` 109 { 110 "args": [ 111 "argv0-placeholder", 112 "--npub", 113 "npub1h50pnxqw9jg7dhr906fvy4mze2yzawf895jhnc3p7qmljdugm6gsrurqev", 114 "-c", 115 "contacts", 116 "-c", 117 "notifications" 118 ] 119 } 120 ``` 121 122 Install/update android-config.json with: 123 ``` 124 adb push android-config.json /sdcard/Android/data/com.damus.notedeck/files/android-config.json 125 ``` 126 127 Using internal storage would be better but it seems hard to get the config file onto 128 the device ... 129 */ 130 131 fn get_app_args(_app: AndroidApp) -> Vec<String> { 132 vec!["argv0-placeholder".to_string()] 133 /* 134 use serde_json::value; 135 use std::fs; 136 use std::path::PathBuf; 137 138 let external_data_path: pathbuf = app 139 .external_data_path() 140 .expect("external data path") 141 .to_path_buf(); 142 let config_file = external_data_path.join("android-config.json"); 143 144 let initial_user = hex::encode(notedeck::FALLBACK_PUBKEY().bytes()); 145 let default_args = vec![ 146 "argv0-placeholder", 147 "--no-tmp-columns", 148 "--pub", 149 &initial_user, 150 "-c", 151 "contacts", 152 "-c", 153 "notifications", 154 ] 155 .into_iter() 156 .map(|s| s.to_string()) 157 .collect(); 158 159 if config_file.exists() { 160 if let Ok(config_contents) = fs::read_to_string(config_file) { 161 if let Ok(json) = serde_json::from_str::<Value>(&config_contents) { 162 if let Some(args_array) = json.get("args").and_then(|v| v.as_array()) { 163 let config_args = args_array 164 .iter() 165 .filter_map(|v| v.as_str().map(String::from)) 166 .collect(); 167 168 return config_args; 169 } 170 } 171 } 172 } 173 174 default_args // Return the default args if config is missing or invalid 175 */ 176 }