Merge remote-tracking branch 'fernando/feat/settings-view'
This commit is contained in:
@@ -38,6 +38,7 @@ pub enum DamusState {
|
||||
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
|
||||
pub struct Damus {
|
||||
state: DamusState,
|
||||
|
||||
pub decks_cache: DecksCache,
|
||||
pub view_state: ViewState,
|
||||
pub drafts: Drafts,
|
||||
@@ -393,13 +394,13 @@ fn determine_key_storage_type() -> KeyStorageType {
|
||||
|
||||
impl Damus {
|
||||
/// Called once before the first frame.
|
||||
pub fn new(ctx: &mut AppContext<'_>, args: &[String]) -> Self {
|
||||
pub fn new(app_context: &mut AppContext<'_>, args: &[String]) -> Self {
|
||||
// arg parsing
|
||||
|
||||
let (parsed_args, unrecognized_args) =
|
||||
ColumnsArgs::parse(args, Some(ctx.accounts.selected_account_pubkey()));
|
||||
ColumnsArgs::parse(args, Some(app_context.accounts.selected_account_pubkey()));
|
||||
|
||||
let account = ctx.accounts.selected_account_pubkey_bytes();
|
||||
let account = app_context.accounts.selected_account_pubkey_bytes();
|
||||
|
||||
let mut timeline_cache = TimelineCache::default();
|
||||
let mut options = AppOptions::default();
|
||||
@@ -409,31 +410,34 @@ impl Damus {
|
||||
let decks_cache = if tmp_columns {
|
||||
info!("DecksCache: loading from command line arguments");
|
||||
let mut columns: Columns = Columns::new();
|
||||
let txn = Transaction::new(ctx.ndb).unwrap();
|
||||
let txn = Transaction::new(app_context.ndb).unwrap();
|
||||
for col in &parsed_args.columns {
|
||||
let timeline_kind = col.clone().into_timeline_kind();
|
||||
if let Some(add_result) = columns.add_new_timeline_column(
|
||||
&mut timeline_cache,
|
||||
&txn,
|
||||
ctx.ndb,
|
||||
ctx.note_cache,
|
||||
ctx.pool,
|
||||
app_context.ndb,
|
||||
app_context.note_cache,
|
||||
app_context.pool,
|
||||
&timeline_kind,
|
||||
) {
|
||||
add_result.process(
|
||||
ctx.ndb,
|
||||
ctx.note_cache,
|
||||
app_context.ndb,
|
||||
app_context.note_cache,
|
||||
&txn,
|
||||
&mut timeline_cache,
|
||||
ctx.unknown_ids,
|
||||
app_context.unknown_ids,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
columns_to_decks_cache(ctx.i18n, columns, account)
|
||||
} else if let Some(decks_cache) =
|
||||
crate::storage::load_decks_cache(ctx.path, ctx.ndb, &mut timeline_cache, ctx.i18n)
|
||||
{
|
||||
columns_to_decks_cache(app_context.i18n, columns, account)
|
||||
} else if let Some(decks_cache) = crate::storage::load_decks_cache(
|
||||
app_context.path,
|
||||
app_context.ndb,
|
||||
&mut timeline_cache,
|
||||
app_context.i18n,
|
||||
) {
|
||||
info!(
|
||||
"DecksCache: loading from disk {}",
|
||||
crate::storage::DECKS_CACHE_FILE
|
||||
@@ -441,13 +445,13 @@ impl Damus {
|
||||
decks_cache
|
||||
} else {
|
||||
info!("DecksCache: creating new with demo configuration");
|
||||
DecksCache::new_with_demo_config(&mut timeline_cache, ctx)
|
||||
//for (pk, _) in &ctx.accounts.cache {
|
||||
DecksCache::new_with_demo_config(&mut timeline_cache, app_context)
|
||||
//for (pk, _) in &app_context.accounts.cache {
|
||||
// cache.add_deck_default(*pk);
|
||||
//}
|
||||
};
|
||||
|
||||
let support = Support::new(ctx.path);
|
||||
let support = Support::new(app_context.path);
|
||||
let mut note_options = NoteOptions::default();
|
||||
note_options.set(
|
||||
NoteOptions::Textmode,
|
||||
@@ -462,10 +466,14 @@ impl Damus {
|
||||
parsed_args.is_flag_set(ColumnsFlag::NoMedia),
|
||||
);
|
||||
note_options.set(
|
||||
NoteOptions::ShowNoteClient,
|
||||
parsed_args.is_flag_set(ColumnsFlag::ShowNoteClient),
|
||||
NoteOptions::ShowNoteClientTop,
|
||||
parsed_args.is_flag_set(ColumnsFlag::ShowNoteClientTop),
|
||||
);
|
||||
options.set(AppOptions::Debug, ctx.args.debug);
|
||||
note_options.set(
|
||||
NoteOptions::ShowNoteClientBottom,
|
||||
parsed_args.is_flag_set(ColumnsFlag::ShowNoteClientBottom),
|
||||
);
|
||||
options.set(AppOptions::Debug, app_context.args.debug);
|
||||
options.set(
|
||||
AppOptions::SinceOptimize,
|
||||
parsed_args.is_flag_set(ColumnsFlag::SinceOptimize),
|
||||
@@ -662,6 +670,7 @@ fn should_show_compose_button(decks: &DecksCache, accounts: &Accounts) -> bool {
|
||||
Route::Reply(_) => false,
|
||||
Route::Quote(_) => false,
|
||||
Route::Relays => false,
|
||||
Route::Settings => false,
|
||||
Route::ComposeNote => false,
|
||||
Route::AddColumn(_) => false,
|
||||
Route::EditProfile(_) => false,
|
||||
|
||||
@@ -11,7 +11,8 @@ pub enum ColumnsFlag {
|
||||
Textmode,
|
||||
Scramble,
|
||||
NoMedia,
|
||||
ShowNoteClient,
|
||||
ShowNoteClientTop,
|
||||
ShowNoteClientBottom,
|
||||
}
|
||||
|
||||
pub struct ColumnsArgs {
|
||||
@@ -53,8 +54,10 @@ impl ColumnsArgs {
|
||||
res.clear_flag(ColumnsFlag::SinceOptimize);
|
||||
} else if arg == "--scramble" {
|
||||
res.set_flag(ColumnsFlag::Scramble);
|
||||
} else if arg == "--show-note-client" {
|
||||
res.set_flag(ColumnsFlag::ShowNoteClient);
|
||||
} else if arg == "--show-note-client=top" {
|
||||
res.set_flag(ColumnsFlag::ShowNoteClientTop);
|
||||
} else if arg == "--show-note-client=bottom" {
|
||||
res.set_flag(ColumnsFlag::ShowNoteClientBottom);
|
||||
} else if arg == "--no-media" {
|
||||
res.set_flag(ColumnsFlag::NoMedia);
|
||||
} else if arg == "--filter" {
|
||||
|
||||
@@ -20,9 +20,10 @@ use crate::{
|
||||
note::{custom_zap::CustomZapView, NewPostAction, PostAction, PostType},
|
||||
profile::EditProfileView,
|
||||
search::{FocusState, SearchView},
|
||||
settings::{SettingsAction, ShowNoteClientOptions},
|
||||
support::SupportView,
|
||||
wallet::{get_default_zap_state, WalletAction, WalletState, WalletView},
|
||||
RelayView,
|
||||
RelayView, SettingsView,
|
||||
},
|
||||
Damus,
|
||||
};
|
||||
@@ -34,6 +35,7 @@ use notedeck::{
|
||||
get_current_default_msats, tr, ui::is_narrow, Accounts, AppContext, NoteAction, NoteContext,
|
||||
RelayAction,
|
||||
};
|
||||
use notedeck_ui::NoteOptions;
|
||||
use tracing::error;
|
||||
|
||||
/// The result of processing a nav response
|
||||
@@ -60,6 +62,7 @@ pub enum RenderNavAction {
|
||||
SwitchingAction(SwitchingAction),
|
||||
WalletAction(WalletAction),
|
||||
RelayAction(RelayAction),
|
||||
SettingsAction(SettingsAction),
|
||||
}
|
||||
|
||||
pub enum SwitchingAction {
|
||||
@@ -480,6 +483,10 @@ fn process_render_nav_action(
|
||||
.process_relay_action(ui.ctx(), ctx.pool, action);
|
||||
None
|
||||
}
|
||||
RenderNavAction::SettingsAction(action) => {
|
||||
action.process(app, ctx.theme, ctx.i18n, ctx.img_cache, ui.ctx());
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(action) = router_action {
|
||||
@@ -497,7 +504,7 @@ fn process_render_nav_action(
|
||||
fn render_nav_body(
|
||||
ui: &mut egui::Ui,
|
||||
app: &mut Damus,
|
||||
ctx: &mut AppContext<'_>,
|
||||
ctx: &mut AppContext,
|
||||
top: &Route,
|
||||
depth: usize,
|
||||
col: usize,
|
||||
@@ -571,6 +578,36 @@ fn render_nav_body(
|
||||
Route::Relays => RelayView::new(ctx.pool, &mut app.view_state.id_string_map, ctx.i18n)
|
||||
.ui(ui)
|
||||
.map(RenderNavAction::RelayAction),
|
||||
|
||||
Route::Settings => {
|
||||
let mut show_note_client = if app.note_options.contains(NoteOptions::ShowNoteClientTop)
|
||||
{
|
||||
ShowNoteClientOptions::Top
|
||||
} else if app.note_options.contains(NoteOptions::ShowNoteClientBottom) {
|
||||
ShowNoteClientOptions::Bottom
|
||||
} else {
|
||||
ShowNoteClientOptions::Hide
|
||||
};
|
||||
|
||||
let mut theme: String = (if ui.visuals().dark_mode {
|
||||
"Dark"
|
||||
} else {
|
||||
"Light"
|
||||
})
|
||||
.into();
|
||||
|
||||
let mut selected_language: String = ctx.i18n.get_current_locale().to_string();
|
||||
|
||||
SettingsView::new(
|
||||
ctx.img_cache,
|
||||
&mut selected_language,
|
||||
&mut theme,
|
||||
&mut show_note_client,
|
||||
ctx.i18n,
|
||||
)
|
||||
.ui(ui)
|
||||
.map(RenderNavAction::SettingsAction)
|
||||
}
|
||||
Route::Reply(id) => {
|
||||
let txn = if let Ok(txn) = Transaction::new(ctx.ndb) {
|
||||
txn
|
||||
|
||||
@@ -19,6 +19,7 @@ pub enum Route {
|
||||
Reply(NoteId),
|
||||
Quote(NoteId),
|
||||
Relays,
|
||||
Settings,
|
||||
ComposeNote,
|
||||
AddColumn(AddColumnRoute),
|
||||
EditProfile(Pubkey),
|
||||
@@ -47,6 +48,10 @@ impl Route {
|
||||
Route::Relays
|
||||
}
|
||||
|
||||
pub fn settings() -> Self {
|
||||
Route::Settings
|
||||
}
|
||||
|
||||
pub fn thread(thread_selection: ThreadSelection) -> Self {
|
||||
Route::Thread(thread_selection)
|
||||
}
|
||||
@@ -110,6 +115,9 @@ impl Route {
|
||||
Route::Relays => {
|
||||
writer.write_token("relay");
|
||||
}
|
||||
Route::Settings => {
|
||||
writer.write_token("settings");
|
||||
}
|
||||
Route::ComposeNote => {
|
||||
writer.write_token("compose");
|
||||
}
|
||||
@@ -169,6 +177,12 @@ impl Route {
|
||||
Ok(Route::Relays)
|
||||
})
|
||||
},
|
||||
|p| {
|
||||
p.parse_all(|p| {
|
||||
p.parse_token("settings")?;
|
||||
Ok(Route::Settings)
|
||||
})
|
||||
},
|
||||
|p| {
|
||||
p.parse_all(|p| {
|
||||
p.parse_token("quote")?;
|
||||
@@ -250,6 +264,9 @@ impl Route {
|
||||
Route::Relays => {
|
||||
ColumnTitle::formatted(tr!(i18n, "Relays", "Column title for relay management"))
|
||||
}
|
||||
Route::Settings => {
|
||||
ColumnTitle::formatted(tr!(i18n, "Settings", "Column title for app settings"))
|
||||
}
|
||||
Route::Accounts(amr) => match amr {
|
||||
AccountsRoute::Accounts => ColumnTitle::formatted(tr!(
|
||||
i18n,
|
||||
@@ -555,6 +572,7 @@ impl fmt::Display for Route {
|
||||
write!(f, "{}", tr!("Quote", "Display name for quote composition"))
|
||||
}
|
||||
Route::Relays => write!(f, "{}", tr!("Relays", "Display name for relay management")),
|
||||
Route::Settings => write!(f, "{}", tr!("Settings", "Display name for settings management")),
|
||||
Route::Accounts(amr) => match amr {
|
||||
AccountsRoute::Accounts => write!(
|
||||
f,
|
||||
|
||||
@@ -481,6 +481,7 @@ impl<'a> NavTitle<'a> {
|
||||
Route::AddColumn(_add_col_route) => None,
|
||||
Route::Support => None,
|
||||
Route::Relays => None,
|
||||
Route::Settings => None,
|
||||
Route::NewDeck => None,
|
||||
Route::EditDeck(_) => None,
|
||||
Route::EditProfile(pubkey) => Some(self.show_profile(ui, pubkey, pfp_size)),
|
||||
|
||||
@@ -12,6 +12,7 @@ pub mod profile;
|
||||
pub mod relay;
|
||||
pub mod search;
|
||||
pub mod search_results;
|
||||
pub mod settings;
|
||||
pub mod side_panel;
|
||||
pub mod support;
|
||||
pub mod thread;
|
||||
@@ -24,6 +25,7 @@ pub use note::{PostReplyView, PostView};
|
||||
pub use preview::{Preview, PreviewApp, PreviewConfig};
|
||||
pub use profile::ProfileView;
|
||||
pub use relay::RelayView;
|
||||
pub use settings::SettingsView;
|
||||
pub use side_panel::{DesktopSidePanel, SidePanelAction};
|
||||
pub use thread::ThreadView;
|
||||
pub use timeline::TimelineView;
|
||||
|
||||
448
crates/notedeck_columns/src/ui/settings.rs
Normal file
448
crates/notedeck_columns/src/ui/settings.rs
Normal file
@@ -0,0 +1,448 @@
|
||||
use egui::{vec2, Button, Color32, ComboBox, Frame, Margin, RichText, ThemePreference};
|
||||
use notedeck::{tr, Images, LanguageIdentifier, Localization, NotedeckTextStyle, ThemeHandler};
|
||||
use notedeck_ui::NoteOptions;
|
||||
use strum::Display;
|
||||
|
||||
use crate::{nav::RouterAction, Damus, Route};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Display)]
|
||||
pub enum ShowNoteClientOptions {
|
||||
Hide,
|
||||
Top,
|
||||
Bottom,
|
||||
}
|
||||
|
||||
pub enum SettingsAction {
|
||||
SetZoom(f32),
|
||||
SetTheme(ThemePreference),
|
||||
SetShowNoteClient(ShowNoteClientOptions),
|
||||
SetLocale(LanguageIdentifier),
|
||||
OpenRelays,
|
||||
OpenCacheFolder,
|
||||
ClearCacheFolder,
|
||||
}
|
||||
|
||||
impl SettingsAction {
|
||||
pub fn process<'a>(
|
||||
self,
|
||||
app: &mut Damus,
|
||||
theme_handler: &'a mut ThemeHandler,
|
||||
i18n: &'a mut Localization,
|
||||
img_cache: &mut Images,
|
||||
ctx: &egui::Context,
|
||||
) -> Option<RouterAction> {
|
||||
let mut route_action: Option<RouterAction> = None;
|
||||
|
||||
match self {
|
||||
SettingsAction::OpenRelays => {
|
||||
route_action = Some(RouterAction::route_to(Route::Relays))
|
||||
}
|
||||
SettingsAction::SetZoom(zoom_level) => {
|
||||
ctx.set_zoom_factor(zoom_level);
|
||||
}
|
||||
SettingsAction::SetShowNoteClient(newvalue) => match newvalue {
|
||||
ShowNoteClientOptions::Hide => {
|
||||
app.note_options.set(NoteOptions::ShowNoteClientTop, false);
|
||||
app.note_options
|
||||
.set(NoteOptions::ShowNoteClientBottom, false);
|
||||
}
|
||||
ShowNoteClientOptions::Bottom => {
|
||||
app.note_options.set(NoteOptions::ShowNoteClientTop, false);
|
||||
app.note_options
|
||||
.set(NoteOptions::ShowNoteClientBottom, true);
|
||||
}
|
||||
ShowNoteClientOptions::Top => {
|
||||
app.note_options.set(NoteOptions::ShowNoteClientTop, true);
|
||||
app.note_options
|
||||
.set(NoteOptions::ShowNoteClientBottom, false);
|
||||
}
|
||||
},
|
||||
SettingsAction::SetTheme(theme) => {
|
||||
ctx.options_mut(|o| {
|
||||
o.theme_preference = theme;
|
||||
});
|
||||
theme_handler.save(theme);
|
||||
}
|
||||
SettingsAction::SetLocale(language) => {
|
||||
_ = i18n.set_locale(language);
|
||||
}
|
||||
SettingsAction::OpenCacheFolder => {
|
||||
use opener;
|
||||
let _ = opener::open(img_cache.base_path.clone());
|
||||
}
|
||||
SettingsAction::ClearCacheFolder => {
|
||||
let _ = img_cache.clear_folder_contents();
|
||||
}
|
||||
}
|
||||
route_action
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SettingsView<'a> {
|
||||
theme: &'a mut String,
|
||||
selected_language: &'a mut String,
|
||||
show_note_client: &'a mut ShowNoteClientOptions,
|
||||
i18n: &'a mut Localization,
|
||||
img_cache: &'a mut Images,
|
||||
}
|
||||
|
||||
impl<'a> SettingsView<'a> {
|
||||
pub fn new(
|
||||
img_cache: &'a mut Images,
|
||||
selected_language: &'a mut String,
|
||||
theme: &'a mut String,
|
||||
show_note_client: &'a mut ShowNoteClientOptions,
|
||||
i18n: &'a mut Localization,
|
||||
) -> Self {
|
||||
Self {
|
||||
show_note_client,
|
||||
theme,
|
||||
img_cache,
|
||||
selected_language,
|
||||
i18n,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<SettingsAction> {
|
||||
let id = ui.id();
|
||||
let mut action = None;
|
||||
|
||||
Frame::default()
|
||||
.inner_margin(Margin::symmetric(10, 10))
|
||||
.show(ui, |ui| {
|
||||
Frame::group(ui.style())
|
||||
.fill(ui.style().visuals.widgets.open.bg_fill)
|
||||
.inner_margin(10.0)
|
||||
.show(ui, |ui| {
|
||||
ui.vertical(|ui| {
|
||||
ui.label(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Appearance",
|
||||
"Label for appearance settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Body.text_style()),
|
||||
);
|
||||
ui.separator();
|
||||
ui.spacing_mut().item_spacing = vec2(10.0, 10.0);
|
||||
|
||||
let current_zoom = ui.ctx().zoom_factor();
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Zoom Level:",
|
||||
"Label for zoom level, Appearance settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
);
|
||||
|
||||
if ui
|
||||
.button(
|
||||
RichText::new("-")
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
let new_zoom = (current_zoom - 0.1).max(0.1);
|
||||
action = Some(SettingsAction::SetZoom(new_zoom));
|
||||
};
|
||||
|
||||
ui.label(
|
||||
RichText::new(format!("{:.0}%", current_zoom * 100.0))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
);
|
||||
|
||||
if ui
|
||||
.button(
|
||||
RichText::new("+")
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
let new_zoom = (current_zoom + 0.1).min(10.0);
|
||||
action = Some(SettingsAction::SetZoom(new_zoom));
|
||||
};
|
||||
|
||||
if ui
|
||||
.button(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Reset",
|
||||
"Label for reset zoom level, Appearance settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
action = Some(SettingsAction::SetZoom(1.0));
|
||||
}
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Language:",
|
||||
"Label for language, Appearance settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
);
|
||||
ComboBox::from_label("")
|
||||
.selected_text(self.selected_language.to_owned())
|
||||
.show_ui(ui, |ui| {
|
||||
for lang in self.i18n.get_available_locales() {
|
||||
if ui
|
||||
.selectable_value(
|
||||
self.selected_language,
|
||||
lang.to_string(),
|
||||
lang.to_string(),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
action =
|
||||
Some(SettingsAction::SetLocale(lang.to_owned()))
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Theme:",
|
||||
"Label for theme, Appearance settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
);
|
||||
if ui
|
||||
.selectable_value(
|
||||
self.theme,
|
||||
"Light".into(),
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Light",
|
||||
"Label for Theme Light, Appearance settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
action = Some(SettingsAction::SetTheme(ThemePreference::Light));
|
||||
}
|
||||
if ui
|
||||
.selectable_value(
|
||||
self.theme,
|
||||
"Dark".into(),
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Dark",
|
||||
"Label for Theme Dark, Appearance settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
action = Some(SettingsAction::SetTheme(ThemePreference::Dark));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
ui.add_space(5.0);
|
||||
|
||||
Frame::group(ui.style())
|
||||
.fill(ui.style().visuals.widgets.open.bg_fill)
|
||||
.inner_margin(10.0)
|
||||
.show(ui, |ui| {
|
||||
ui.label(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Storage",
|
||||
"Label for storage settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Body.text_style()),
|
||||
);
|
||||
ui.separator();
|
||||
|
||||
ui.vertical(|ui| {
|
||||
ui.spacing_mut().item_spacing = vec2(10.0, 10.0);
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
let static_imgs_size = self
|
||||
.img_cache
|
||||
.static_imgs
|
||||
.cache_size
|
||||
.lock()
|
||||
.unwrap();
|
||||
|
||||
let gifs_size = self.img_cache.gifs.cache_size.lock().unwrap();
|
||||
|
||||
ui.label(
|
||||
RichText::new(format!("{} {}",
|
||||
tr!(
|
||||
self.i18n,
|
||||
"Image cache size:",
|
||||
"Label for Image cache size, Storage settings section"
|
||||
),
|
||||
format_size(
|
||||
[static_imgs_size, gifs_size]
|
||||
.iter()
|
||||
.fold(0_u64, |acc, cur| acc
|
||||
+ cur.unwrap_or_default())
|
||||
)
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
);
|
||||
|
||||
ui.end_row();
|
||||
|
||||
if !notedeck::ui::is_compiled_as_mobile() &&
|
||||
ui.button(RichText::new(tr!(self.i18n, "View folder:", "Label for view folder button, Storage settings section"))
|
||||
.text_style(NotedeckTextStyle::Small.text_style())).clicked() {
|
||||
action = Some(SettingsAction::OpenCacheFolder);
|
||||
}
|
||||
|
||||
let clearcache_resp = ui.button(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Clear cache",
|
||||
"Label for clear cache button, Storage settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style())
|
||||
.color(Color32::LIGHT_RED),
|
||||
);
|
||||
|
||||
let id_clearcache = id.with("clear_cache");
|
||||
if clearcache_resp.clicked() {
|
||||
ui.data_mut(|d| d.insert_temp(id_clearcache, true));
|
||||
}
|
||||
|
||||
if ui.data_mut(|d| *d.get_temp_mut_or_default(id_clearcache)) {
|
||||
let mut confirm_pressed = false;
|
||||
clearcache_resp.show_tooltip_ui(|ui| {
|
||||
let confirm_resp = ui.button(tr!(
|
||||
self.i18n,
|
||||
"Confirm",
|
||||
"Label for confirm clear cache, Storage settings section"
|
||||
));
|
||||
if confirm_resp.clicked() {
|
||||
confirm_pressed = true;
|
||||
}
|
||||
|
||||
if confirm_resp.clicked() || ui.button(tr!(
|
||||
self.i18n,
|
||||
"Cancel",
|
||||
"Label for cancel clear cache, Storage settings section"
|
||||
)).clicked() {
|
||||
ui.data_mut(|d| d.insert_temp(id_clearcache, false));
|
||||
}
|
||||
});
|
||||
|
||||
if confirm_pressed {
|
||||
action = Some(SettingsAction::ClearCacheFolder);
|
||||
} else if !confirm_pressed
|
||||
&& clearcache_resp.clicked_elsewhere()
|
||||
{
|
||||
ui.data_mut(|d| d.insert_temp(id_clearcache, false));
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
ui.add_space(5.0);
|
||||
|
||||
Frame::group(ui.style())
|
||||
.fill(ui.style().visuals.widgets.open.bg_fill)
|
||||
.inner_margin(10.0)
|
||||
.show(ui, |ui| {
|
||||
ui.label(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Others",
|
||||
"Label for others settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Body.text_style()),
|
||||
);
|
||||
ui.separator();
|
||||
ui.vertical(|ui| {
|
||||
ui.spacing_mut().item_spacing = vec2(10.0, 10.0);
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(
|
||||
RichText::new(
|
||||
tr!(
|
||||
self.i18n,
|
||||
"Show source client",
|
||||
"Label for Show source client, others settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
);
|
||||
|
||||
for option in [
|
||||
ShowNoteClientOptions::Hide,
|
||||
ShowNoteClientOptions::Top,
|
||||
ShowNoteClientOptions::Bottom,
|
||||
] {
|
||||
let label = option.clone().to_string();
|
||||
|
||||
if ui
|
||||
.selectable_value(
|
||||
self.show_note_client,
|
||||
option,
|
||||
RichText::new(label)
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
)
|
||||
.changed()
|
||||
{
|
||||
action = Some(SettingsAction::SetShowNoteClient(option));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
ui.add_space(10.0);
|
||||
|
||||
if ui
|
||||
.add_sized(
|
||||
[ui.available_width(), 30.0],
|
||||
Button::new(
|
||||
RichText::new(tr!(
|
||||
self.i18n,
|
||||
"Configure relays",
|
||||
"Label for configure relays, settings section"
|
||||
))
|
||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||
),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
action = Some(SettingsAction::OpenRelays);
|
||||
}
|
||||
});
|
||||
|
||||
action
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_size(size_bytes: u64) -> String {
|
||||
const KB: f64 = 1024.0;
|
||||
const MB: f64 = KB * 1024.0;
|
||||
const GB: f64 = MB * 1024.0;
|
||||
|
||||
let size = size_bytes as f64;
|
||||
|
||||
if size < KB {
|
||||
format!("{size:.0} Bytes")
|
||||
} else if size < MB {
|
||||
format!("{:.1} KB", size / KB)
|
||||
} else if size < GB {
|
||||
format!("{:.1} MB", size / MB)
|
||||
} else {
|
||||
format!("{:.2} GB", size / GB)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user