Skip to content

Commit fbbfcb6

Browse files
committed
Added auto-load configuration options
1 parent 5c75148 commit fbbfcb6

File tree

6 files changed

+92
-37
lines changed

6 files changed

+92
-37
lines changed

src/commands.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
AppState,
1212
accounts::{start_add_account_flow, start_streaming_for_timeline, switch_to_account, try_oob_oauth},
1313
auth,
14-
config::{self, Account, ContentWarningDisplay, SortOrder},
14+
config::{self, Account, AutoloadMode, ContentWarningDisplay, SortOrder},
1515
html, live_region,
1616
mastodon::{MastodonClient, Status},
1717
network::{self, NetworkCommand},
@@ -97,7 +97,7 @@ pub(crate) fn handle_ui_command(
9797
suppress_selection: &Cell<bool>,
9898
live_region: &StaticText,
9999
quick_action_keys_enabled: &Cell<bool>,
100-
autoload_enabled: &Cell<bool>,
100+
autoload_mode: &Cell<AutoloadMode>,
101101
sort_order_cell: &Cell<SortOrder>,
102102
tray_hidden: &Cell<bool>,
103103
ui_tx: &mpsc::Sender<UiCommand>,
@@ -423,7 +423,7 @@ pub(crate) fn handle_ui_command(
423423
suppress_selection,
424424
live_region,
425425
quick_action_keys_enabled,
426-
autoload_enabled,
426+
autoload_mode,
427427
sort_order_cell,
428428
tray_hidden,
429429
ui_tx,
@@ -504,7 +504,7 @@ pub(crate) fn handle_ui_command(
504504
state.cw_expanded.clear();
505505
}
506506
quick_action_keys_enabled.set(quick_action_keys);
507-
autoload_enabled.set(autoload);
507+
autoload_mode.set(autoload);
508508
sort_order_cell.set(sort_order);
509509
if let Some(mb) = frame.get_menu_bar() {
510510
update_menu_labels(&mb, state);
@@ -548,7 +548,7 @@ pub(crate) fn handle_ui_command(
548548
suppress_selection,
549549
live_region,
550550
quick_action_keys_enabled,
551-
autoload_enabled,
551+
autoload_mode,
552552
sort_order_cell,
553553
tray_hidden,
554554
ui_tx,
@@ -564,7 +564,7 @@ pub(crate) fn handle_ui_command(
564564
suppress_selection,
565565
live_region,
566566
quick_action_keys_enabled,
567-
autoload_enabled,
567+
autoload_mode,
568568
sort_order_cell,
569569
tray_hidden,
570570
ui_tx,
@@ -602,7 +602,7 @@ pub(crate) fn handle_ui_command(
602602
suppress_selection,
603603
live_region,
604604
quick_action_keys_enabled,
605-
autoload_enabled,
605+
autoload_mode,
606606
sort_order_cell,
607607
tray_hidden,
608608
ui_tx,
@@ -629,7 +629,7 @@ pub(crate) fn handle_ui_command(
629629
suppress_selection,
630630
live_region,
631631
quick_action_keys_enabled,
632-
autoload_enabled,
632+
autoload_mode,
633633
sort_order_cell,
634634
tray_hidden,
635635
ui_tx,
@@ -653,7 +653,7 @@ pub(crate) fn handle_ui_command(
653653
suppress_selection,
654654
live_region,
655655
quick_action_keys_enabled,
656-
autoload_enabled,
656+
autoload_mode,
657657
sort_order_cell,
658658
tray_hidden,
659659
ui_tx,
@@ -677,7 +677,7 @@ pub(crate) fn handle_ui_command(
677677
suppress_selection,
678678
live_region,
679679
quick_action_keys_enabled,
680-
autoload_enabled,
680+
autoload_mode,
681681
sort_order_cell,
682682
tray_hidden,
683683
ui_tx,
@@ -766,7 +766,7 @@ pub(crate) fn handle_ui_command(
766766
suppress_selection,
767767
live_region,
768768
quick_action_keys_enabled,
769-
autoload_enabled,
769+
autoload_mode,
770770
sort_order_cell,
771771
tray_hidden,
772772
ui_tx,
@@ -1032,7 +1032,7 @@ pub(crate) fn handle_ui_command(
10321032
suppress_selection,
10331033
live_region,
10341034
quick_action_keys_enabled,
1035-
autoload_enabled,
1035+
autoload_mode,
10361036
sort_order_cell,
10371037
tray_hidden,
10381038
ui_tx,

src/config.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ pub struct Config {
2222
pub always_show_link_dialog: bool,
2323
#[serde(default = "default_quick_action_keys")]
2424
pub quick_action_keys: bool,
25-
#[serde(default = "default_autoload")]
26-
pub autoload: bool,
25+
#[serde(default, deserialize_with = "deserialize_autoload_mode")]
26+
pub autoload: AutoloadMode,
2727
#[serde(default = "default_fetch_limit")]
2828
pub fetch_limit: u8,
2929
#[serde(default)]
@@ -56,6 +56,14 @@ pub enum ContentWarningDisplay {
5656
WarningOnly,
5757
}
5858

59+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
60+
pub enum AutoloadMode {
61+
Never,
62+
#[default]
63+
AtEnd,
64+
AtBoundary,
65+
}
66+
5967
fn default_enter_to_send() -> bool {
6068
true
6169
}
@@ -68,8 +76,22 @@ fn default_quick_action_keys() -> bool {
6876
false
6977
}
7078

71-
fn default_autoload() -> bool {
72-
true
79+
fn deserialize_autoload_mode<'de, D>(deserializer: D) -> Result<AutoloadMode, D::Error>
80+
where
81+
D: serde::Deserializer<'de>,
82+
{
83+
use serde::de::Error;
84+
let value = serde_json::Value::deserialize(deserializer)?;
85+
match value {
86+
serde_json::Value::Bool(b) => Ok(if b { AutoloadMode::AtBoundary } else { AutoloadMode::Never }),
87+
serde_json::Value::String(s) => match s.as_str() {
88+
"Never" => Ok(AutoloadMode::Never),
89+
"AtEnd" => Ok(AutoloadMode::AtEnd),
90+
"AtBoundary" => Ok(AutoloadMode::AtBoundary),
91+
_ => Err(D::Error::custom(format!("unknown autoload mode: {}", s))),
92+
},
93+
_ => Err(D::Error::custom("expected bool or string for autoload")),
94+
}
7395
}
7496

7597
fn default_fetch_limit() -> u8 {
@@ -85,7 +107,7 @@ impl Default for Config {
85107
enter_to_send: true,
86108
always_show_link_dialog: false,
87109
quick_action_keys: false,
88-
autoload: true,
110+
autoload: AutoloadMode::default(),
89111
fetch_limit: default_fetch_limit(),
90112
sort_order: SortOrder::default(),
91113
timestamp_format: TimestampFormat::default(),

src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ fn drain_ui_commands(
102102
suppress_selection: &Cell<bool>,
103103
live_region: &StaticText,
104104
quick_action_keys_enabled: &Cell<bool>,
105-
autoload_enabled: &Cell<bool>,
105+
autoload_mode: &Cell<config::AutoloadMode>,
106106
sort_order_cell: &Cell<config::SortOrder>,
107107
tray_hidden: &Cell<bool>,
108108
ui_tx: &mpsc::Sender<UiCommand>,
@@ -117,7 +117,7 @@ fn drain_ui_commands(
117117
suppress_selection,
118118
live_region,
119119
quick_action_keys_enabled,
120-
autoload_enabled,
120+
autoload_mode,
121121
sort_order_cell,
122122
tray_hidden,
123123
ui_tx,
@@ -140,7 +140,7 @@ fn main() {
140140
let store = config::ConfigStore::new();
141141
let config = store.load();
142142
let quick_action_keys_enabled = Rc::new(Cell::new(config.quick_action_keys));
143-
let autoload_enabled = Rc::new(Cell::new(config.autoload));
143+
let autoload_mode = Rc::new(Cell::new(config.autoload));
144144
let sort_order_cell = Rc::new(Cell::new(config.sort_order));
145145
let mut state = AppState::new(config);
146146

@@ -172,7 +172,7 @@ fn main() {
172172
let mut state = state;
173173
let timer_tick = timer.clone();
174174
let quick_action_keys_drain = quick_action_keys_enabled.clone();
175-
let autoload_drain = autoload_enabled.clone();
175+
let autoload_drain = autoload_mode.clone();
176176
let sort_order_drain = sort_order_cell.clone();
177177
let tray_hidden_drain = tray_hidden.clone();
178178
let ui_tx_timer = ui_tx.clone();
@@ -239,7 +239,7 @@ fn main() {
239239
is_shutting_down.clone(),
240240
suppress_selection.clone(),
241241
quick_action_keys_enabled.clone(),
242-
autoload_enabled.clone(),
242+
autoload_mode.clone(),
243243
sort_order_cell.clone(),
244244
timer.clone(),
245245
);

src/responses.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use wxdragon::prelude::*;
44

55
use crate::{
66
AppState, UiCommand,
7-
config::SortOrder,
7+
config::{AutoloadMode, SortOrder},
88
live_region,
99
mastodon::{Poll, Status},
1010
network::{NetworkCommand, NetworkResponse, TimelineData},
@@ -100,7 +100,7 @@ pub(crate) fn process_network_responses(
100100
suppress_selection: &Cell<bool>,
101101
live_region: &StaticText,
102102
quick_action_keys_enabled: &Cell<bool>,
103-
autoload_enabled: &Cell<bool>,
103+
autoload_mode: &Cell<AutoloadMode>,
104104
sort_order_cell: &Cell<SortOrder>,
105105
tray_hidden: &Cell<bool>,
106106
ui_tx: &mpsc::Sender<UiCommand>,
@@ -218,7 +218,7 @@ pub(crate) fn process_network_responses(
218218
suppress_selection,
219219
live_region,
220220
quick_action_keys_enabled,
221-
autoload_enabled,
221+
autoload_mode,
222222
sort_order_cell,
223223
tray_hidden,
224224
ui_tx,

src/ui/dialogs.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use url::Url;
44
use wxdragon::prelude::*;
55

66
use crate::{
7-
config::{Account, ContentWarningDisplay, SortOrder, TimestampFormat},
7+
config::{Account, AutoloadMode, ContentWarningDisplay, SortOrder, TimestampFormat},
88
html::{self, Link},
99
mastodon::{Account as MastodonAccount, PollLimits, Status},
1010
network::{NetworkCommand, ProfileUpdate},
@@ -656,12 +656,12 @@ pub fn prompt_for_options(
656656
enter_to_send: bool,
657657
always_show_link_dialog: bool,
658658
quick_action_keys: bool,
659-
autoload: bool,
659+
autoload: AutoloadMode,
660660
fetch_limit: u8,
661661
content_warning_display: ContentWarningDisplay,
662662
sort_order: SortOrder,
663663
timestamp_format: TimestampFormat,
664-
) -> Option<(bool, bool, bool, bool, u8, ContentWarningDisplay, SortOrder, TimestampFormat)> {
664+
) -> Option<(bool, bool, bool, AutoloadMode, u8, ContentWarningDisplay, SortOrder, TimestampFormat)> {
665665
let dialog = Dialog::builder(frame, "Options").with_size(400, 450).build();
666666
let panel = Panel::builder(&dialog).build();
667667
let main_sizer = BoxSizer::builder(Orientation::Vertical).build();
@@ -671,8 +671,20 @@ pub fn prompt_for_options(
671671
link_checkbox.set_value(always_show_link_dialog);
672672
let quick_action_checkbox = CheckBox::builder(&panel).with_label("Use &quick action keys in timelines").build();
673673
quick_action_checkbox.set_value(quick_action_keys);
674-
let autoload_checkbox = CheckBox::builder(&panel).with_label("&Autoload posts when scrolling").build();
675-
autoload_checkbox.set_value(autoload);
674+
let autoload_label = StaticText::builder(&panel).with_label("&Autoload posts:").build();
675+
let autoload_choices =
676+
vec!["Never".to_string(), "When reaching the end".to_string(), "When navigating past the end".to_string()];
677+
let autoload_choice =
678+
ComboBox::builder(&panel).with_choices(autoload_choices).with_style(ComboBoxStyle::ReadOnly).build();
679+
let autoload_index = match autoload {
680+
AutoloadMode::Never => 0,
681+
AutoloadMode::AtEnd => 1,
682+
AutoloadMode::AtBoundary => 2,
683+
};
684+
autoload_choice.set_selection(autoload_index);
685+
let autoload_sizer = BoxSizer::builder(Orientation::Horizontal).build();
686+
autoload_sizer.add(&autoload_label, 0, SizerFlag::AlignCenterVertical | SizerFlag::Right, 8);
687+
autoload_sizer.add(&autoload_choice, 1, SizerFlag::Expand, 0);
676688
let fetch_limit_label = StaticText::builder(&panel).with_label("Posts to &fetch when loading more:").build();
677689
let fetch_limit_spin = SpinCtrl::builder(&panel).with_range(1, 40).with_initial_value(fetch_limit as i32).build();
678690
let fetch_limit_sizer = BoxSizer::builder(Orientation::Horizontal).build();
@@ -704,7 +716,7 @@ pub fn prompt_for_options(
704716
main_sizer.add(&enter_checkbox, 0, SizerFlag::Expand | SizerFlag::All, 8);
705717
main_sizer.add(&link_checkbox, 0, SizerFlag::Expand | SizerFlag::All, 8);
706718
main_sizer.add(&quick_action_checkbox, 0, SizerFlag::Expand | SizerFlag::All, 8);
707-
main_sizer.add(&autoload_checkbox, 0, SizerFlag::Expand | SizerFlag::All, 8);
719+
main_sizer.add_sizer(&autoload_sizer, 0, SizerFlag::Expand | SizerFlag::All, 8);
708720
main_sizer.add_sizer(&fetch_limit_sizer, 0, SizerFlag::Expand | SizerFlag::All, 8);
709721
main_sizer.add_sizer(&cw_sizer, 0, SizerFlag::Expand | SizerFlag::All, 8);
710722
main_sizer.add(&timestamp_checkbox, 0, SizerFlag::Expand | SizerFlag::All, 8);
@@ -731,12 +743,18 @@ pub fn prompt_for_options(
731743
Some(2) => ContentWarningDisplay::WarningOnly,
732744
_ => content_warning_display,
733745
};
746+
let new_autoload = match autoload_choice.get_selection() {
747+
Some(0) => AutoloadMode::Never,
748+
Some(1) => AutoloadMode::AtEnd,
749+
Some(2) => AutoloadMode::AtBoundary,
750+
_ => autoload,
751+
};
734752
let new_fetch_limit = (fetch_limit_spin.value() as u8).clamp(1, 40);
735753
Some((
736754
enter_checkbox.get_value(),
737755
link_checkbox.get_value(),
738756
quick_action_checkbox.get_value(),
739-
autoload_checkbox.get_value(),
757+
new_autoload,
740758
new_fetch_limit,
741759
new_cw_display,
742760
new_sort,

src/ui/window.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use crate::{
66
ID_BOOST, ID_CLOSE_TIMELINE, ID_DELETE_POST, ID_EDIT_POST, ID_EDIT_PROFILE, ID_FAVORITE, ID_FEDERATED_TIMELINE,
77
ID_LOAD_MORE, ID_LOCAL_TIMELINE, ID_MANAGE_ACCOUNTS, ID_NEW_POST, ID_OPEN_LINKS, ID_OPEN_USER_TIMELINE_BY_INPUT,
88
ID_OPTIONS, ID_REFRESH, ID_REPLY, ID_REPLY_AUTHOR, ID_VIEW_HASHTAGS, ID_VIEW_IN_BROWSER, ID_VIEW_MENTIONS,
9-
ID_VIEW_PROFILE, ID_VIEW_THREAD, ID_VIEW_USER_TIMELINE, KEY_DELETE, UiCommand, config::SortOrder, live_region,
9+
ID_VIEW_PROFILE, ID_VIEW_THREAD, ID_VIEW_USER_TIMELINE, KEY_DELETE, UiCommand,
10+
config::{AutoloadMode, SortOrder},
11+
live_region,
1012
ui::menu::build_menu_bar,
1113
};
1214

@@ -57,7 +59,7 @@ pub fn bind_input_handlers(
5759
is_shutting_down: Rc<Cell<bool>>,
5860
suppress_selection: Rc<Cell<bool>>,
5961
quick_action_keys_enabled: Rc<Cell<bool>>,
60-
autoload_enabled: Rc<Cell<bool>>,
62+
autoload_mode: Rc<Cell<AutoloadMode>>,
6163
sort_order_cell: Rc<Cell<SortOrder>>,
6264
timer: Rc<Timer<Frame>>,
6365
) {
@@ -120,7 +122,7 @@ pub fn bind_input_handlers(
120122
let ui_tx_list_key = ui_tx.clone();
121123
let shutdown_list_key = is_shutting_down.clone();
122124
let quick_action_keys_list = quick_action_keys_enabled.clone();
123-
let autoload_list = autoload_enabled.clone();
125+
let autoload_mode_list = autoload_mode.clone();
124126
let sort_order_list = sort_order_cell.clone();
125127
timeline_list_state.bind_internal(EventType::KEY_DOWN, move |event| {
126128
if shutdown_list_key.get() {
@@ -164,7 +166,7 @@ pub fn bind_input_handlers(
164166
_ => {}
165167
}
166168

167-
if autoload_list.get() {
169+
if autoload_mode_list.get() == AutoloadMode::AtBoundary {
168170
let sort_order = sort_order_list.get();
169171
let selection = timeline_list_state.get_selection().map(|s| s as usize);
170172
let count = timeline_list_state.get_count() as usize;
@@ -357,6 +359,8 @@ pub fn bind_input_handlers(
357359
event.skip(true);
358360
});
359361

362+
let autoload_mode_selection = autoload_mode.clone();
363+
let sort_order_selection = sort_order_cell.clone();
360364
timeline_list_state.on_selection_changed(move |event| {
361365
if shutdown_list.get() {
362366
return;
@@ -368,9 +372,20 @@ pub fn bind_input_handlers(
368372
&& selection >= 0
369373
{
370374
let _ = ui_tx_list.send(UiCommand::TimelineEntrySelectionChanged(selection as usize));
375+
if autoload_mode_selection.get() == AutoloadMode::AtEnd {
376+
let count = timeline_list_state.get_count() as usize;
377+
let index = selection as usize;
378+
let sort_order = sort_order_selection.get();
379+
let at_load_position = match sort_order {
380+
SortOrder::NewestToOldest => index + 1 == count,
381+
SortOrder::OldestToNewest => index == 0,
382+
};
383+
if at_load_position {
384+
let _ = ui_tx_list.send(UiCommand::LoadMore);
385+
}
386+
}
371387
}
372388
});
373-
374389
let ui_tx_menu = ui_tx.clone();
375390
let shutdown_menu = is_shutting_down.clone();
376391
let frame_menu = parts.frame;

0 commit comments

Comments
 (0)