mirror of
https://github.com/aljazceru/notedeck.git
synced 2025-12-18 17:14:21 +01:00
249 lines
7.1 KiB
Rust
249 lines
7.1 KiB
Rust
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
|
// hide console window on Windows in release
|
|
|
|
#[cfg(feature = "memory")]
|
|
use re_memory::AccountingAllocator;
|
|
|
|
#[cfg(feature = "memory")]
|
|
#[global_allocator]
|
|
static GLOBAL: AccountingAllocator<std::alloc::System> =
|
|
AccountingAllocator::new(std::alloc::System);
|
|
|
|
use notedeck::{DataPath, DataPathType, Notedeck};
|
|
use notedeck_chrome::{setup::generate_native_options, Chrome};
|
|
use tracing_appender::non_blocking::WorkerGuard;
|
|
use tracing_subscriber::EnvFilter;
|
|
|
|
fn setup_logging(path: &DataPath) -> Option<WorkerGuard> {
|
|
#[allow(unused_variables)] // need guard to live for lifetime of program
|
|
let (maybe_non_blocking, maybe_guard) = {
|
|
let log_path = path.path(DataPathType::Log);
|
|
// Setup logging to file
|
|
|
|
use tracing_appender::{
|
|
non_blocking,
|
|
rolling::{RollingFileAppender, Rotation},
|
|
};
|
|
|
|
let file_appender = RollingFileAppender::new(
|
|
Rotation::DAILY,
|
|
log_path,
|
|
format!("notedeck-{}.log", env!("CARGO_PKG_VERSION")),
|
|
);
|
|
|
|
let (non_blocking, _guard) = non_blocking(file_appender);
|
|
|
|
(Some(non_blocking), Some(_guard))
|
|
};
|
|
|
|
// Log to stdout (if you run with `RUST_LOG=debug`).
|
|
if let Some(non_blocking_writer) = maybe_non_blocking {
|
|
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt};
|
|
|
|
let console_layer = fmt::layer().with_target(true).with_writer(std::io::stdout);
|
|
|
|
// Create the file layer (writes to the file)
|
|
let file_layer = fmt::layer()
|
|
.with_ansi(false)
|
|
.with_writer(non_blocking_writer);
|
|
|
|
let env_filter =
|
|
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("notedeck=info"));
|
|
|
|
// Set up the subscriber to combine both layers
|
|
tracing_subscriber::registry()
|
|
.with(console_layer)
|
|
.with(file_layer)
|
|
.with(env_filter)
|
|
.init();
|
|
} else {
|
|
tracing_subscriber::fmt()
|
|
.with_env_filter(EnvFilter::from_default_env())
|
|
.init();
|
|
}
|
|
|
|
maybe_guard
|
|
}
|
|
|
|
// Desktop
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
#[tokio::main]
|
|
async fn main() {
|
|
#[cfg(feature = "memory")]
|
|
re_memory::accounting_allocator::set_tracking_callstacks(true);
|
|
|
|
let base_path = DataPath::default_base_or_cwd();
|
|
let path = DataPath::new(base_path.clone());
|
|
|
|
// This guard must be scoped for the duration of the entire program so all logs will be written
|
|
let _guard = setup_logging(&path);
|
|
|
|
let _res = eframe::run_native(
|
|
"Damus Notedeck",
|
|
generate_native_options(path),
|
|
Box::new(|cc| {
|
|
let args: Vec<String> = std::env::args().collect();
|
|
let ctx = &cc.egui_ctx;
|
|
|
|
let mut notedeck = Notedeck::new(ctx, base_path, &args);
|
|
notedeck.setup(ctx);
|
|
let chrome = Chrome::new_with_apps(cc, &args, &mut notedeck)?;
|
|
notedeck.set_app(chrome);
|
|
|
|
Ok(Box::new(notedeck))
|
|
}),
|
|
);
|
|
}
|
|
|
|
/*
|
|
* TODO: nostrdb not supported on web
|
|
*
|
|
#[cfg(target_arch = "wasm32")]
|
|
pub fn main() {
|
|
// Make sure panics are logged using `console.error`.
|
|
console_error_panic_hook::set_once();
|
|
|
|
// Redirect tracing to console.log and friends:
|
|
tracing_wasm::set_as_global_default();
|
|
|
|
wasm_bindgen_futures::spawn_local(async {
|
|
let web_options = eframe::WebOptions::default();
|
|
eframe::start_web(
|
|
"the_canvas_id", // hardcode it
|
|
web_options,
|
|
Box::new(|cc| Box::new(Damus::new(cc, "."))),
|
|
)
|
|
.await
|
|
.expect("failed to start eframe");
|
|
});
|
|
}
|
|
*/
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::Notedeck;
|
|
use notedeck_columns::Damus;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
fn create_tmp_dir() -> PathBuf {
|
|
tempfile::TempDir::new()
|
|
.expect("tmp path")
|
|
.path()
|
|
.to_path_buf()
|
|
}
|
|
|
|
fn rmrf(path: impl AsRef<Path>) {
|
|
let _ = std::fs::remove_dir_all(path);
|
|
}
|
|
|
|
/// Ensure dbpath actually sets the dbpath correctly.
|
|
#[tokio::test]
|
|
async fn test_dbpath() {
|
|
let datapath = create_tmp_dir();
|
|
let dbpath = create_tmp_dir();
|
|
let args: Vec<String> = [
|
|
"--testrunner",
|
|
"--datapath",
|
|
&datapath.to_str().unwrap(),
|
|
"--dbpath",
|
|
&dbpath.to_str().unwrap(),
|
|
]
|
|
.iter()
|
|
.map(|s| s.to_string())
|
|
.collect();
|
|
|
|
let ctx = egui::Context::default();
|
|
let _app = Notedeck::new(&ctx, &datapath, &args);
|
|
|
|
assert!(Path::new(&dbpath.join("data.mdb")).exists());
|
|
assert!(Path::new(&dbpath.join("lock.mdb")).exists());
|
|
assert!(!Path::new(&datapath.join("db")).exists());
|
|
|
|
rmrf(datapath);
|
|
rmrf(dbpath);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_column_args() {
|
|
let tmpdir = create_tmp_dir();
|
|
let npub = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s";
|
|
let args: Vec<String> = [
|
|
"--testrunner",
|
|
"--no-keystore",
|
|
"--pub",
|
|
npub,
|
|
"-c",
|
|
"notifications",
|
|
"-c",
|
|
"contacts",
|
|
]
|
|
.iter()
|
|
.map(|s| s.to_string())
|
|
.collect();
|
|
|
|
let ctx = egui::Context::default();
|
|
let mut notedeck = Notedeck::new(&ctx, &tmpdir, &args);
|
|
let mut app_ctx = notedeck.app_context();
|
|
let app = Damus::new(&mut app_ctx, &args);
|
|
|
|
assert_eq!(app.columns(app_ctx.accounts).columns().len(), 2);
|
|
|
|
let tl1 = app
|
|
.columns(app_ctx.accounts)
|
|
.column(0)
|
|
.router()
|
|
.top()
|
|
.timeline_id()
|
|
.unwrap();
|
|
|
|
let tl2 = app
|
|
.columns(app_ctx.accounts)
|
|
.column(1)
|
|
.router()
|
|
.top()
|
|
.timeline_id()
|
|
.unwrap();
|
|
|
|
assert_eq!(app.timeline_cache.num_timelines(), 2);
|
|
assert!(app.timeline_cache.get(&tl1).is_some());
|
|
assert!(app.timeline_cache.get(&tl2).is_some());
|
|
|
|
rmrf(tmpdir);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_unknown_args() {
|
|
let tmpdir = create_tmp_dir();
|
|
let npub = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s";
|
|
let args: Vec<String> = [
|
|
"--testrunner",
|
|
"--no-keystore",
|
|
"--unknown-arg", // <-- UNKNOWN
|
|
"--pub",
|
|
npub,
|
|
"-c",
|
|
"notifications",
|
|
"-c",
|
|
"contacts",
|
|
]
|
|
.iter()
|
|
.map(|s| s.to_string())
|
|
.collect();
|
|
|
|
let ctx = egui::Context::default();
|
|
let mut notedeck = Notedeck::new(&ctx, &tmpdir, &args);
|
|
let mut app_ctx = notedeck.app_context();
|
|
let app = Damus::new(&mut app_ctx, &args);
|
|
|
|
// ensure we recognized all the arguments
|
|
let completely_unrecognized: Vec<String> = notedeck
|
|
.unrecognized_args()
|
|
.intersection(app.unrecognized_args())
|
|
.cloned()
|
|
.collect();
|
|
assert_eq!(completely_unrecognized, ["--unknown-arg"]);
|
|
|
|
rmrf(tmpdir);
|
|
}
|
|
}
|