notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

android.rs (4402B)


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