util.rs
⎇
Raw
1//! Formatting + small browser helpers.
2
3use chrono::{DateTime, Utc};
4
5pub fn format_size(bytes: u64) -> String {
6 const UNITS: [&str; 5] = ["B", "KB", "MB", "GB", "TB"];
7 let mut v = bytes as f64;
8 let mut i = 0;
9 while v >= 1024.0 && i < UNITS.len() - 1 {
10 v /= 1024.0;
11 i += 1;
12 }
13 if i == 0 {
14 format!("{bytes} B")
15 } else {
16 format!("{v:.1} {}", UNITS[i])
17 }
18}
19
20pub fn format_date(rfc3339: &str) -> String {
21 match DateTime::parse_from_rfc3339(rfc3339) {
22 Ok(dt) => dt.with_timezone(&Utc).format("%Y-%m-%d %H:%M").to_string(),
23 Err(_) => rfc3339.to_string(),
24 }
25}
26
27pub fn storage_get(key: &str) -> Option<String> {
28 let w = web_sys::window()?;
29 let storage_opt = w.local_storage().ok()?;
30 let storage = storage_opt.as_ref()?;
31 storage.get_item(key).ok().flatten()
32}
33
34pub fn storage_set(key: &str, value: &str) {
35 if let Some(s) = web_sys::window().and_then(|w| w.local_storage().ok().flatten()) {
36 let _ = s.set_item(key, value);
37 }
38}
39
40#[derive(Clone, Copy, PartialEq, Debug)]
41pub enum ViewMode {
42 Grid,
43 List,
44}
45
46impl ViewMode {
47 const KEY: &'static str = "fbng.view";
48
49 pub fn load() -> Self {
50 match storage_get(Self::KEY).as_deref() {
51 Some("list") => ViewMode::List,
52 _ => ViewMode::Grid,
53 }
54 }
55
56 pub fn save(self) {
57 storage_set(Self::KEY, if self == ViewMode::List { "list" } else { "grid" });
58 }
59}
60