Skip to content

Commit

Permalink
refactor(term): use the filter of FilterableVec as the primary source
Browse files Browse the repository at this point in the history
  • Loading branch information
ymgyt committed Jul 9, 2024
1 parent 9f690c6 commit f1739fe
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 37 deletions.
10 changes: 9 additions & 1 deletion crates/synd_term/src/ui/components/collections/filterable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ where
F: Default,
{
pub(crate) fn new() -> Self {
Self::from_filter(F::default())
}

pub(crate) fn from_filter(filterer: F) -> Self {
Self {
items: Vec::new(),
effective_items: Vec::new(),
selected_item_index: 0,
filterer: F::default(),
filterer,
}
}
}
Expand Down Expand Up @@ -71,6 +75,10 @@ impl<T, F> FilterableVec<T, F> {
pub(crate) fn as_unfiltered_slice(&self) -> &[T] {
self.items.as_slice()
}

pub(crate) fn filter(&self) -> &F {
&self.filterer
}
}

impl<T, F> FilterableVec<T, F>
Expand Down
4 changes: 4 additions & 0 deletions crates/synd_term/src/ui/components/filter/composed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ impl<L, R> ComposedFilterer<L, R> {
pub(crate) fn and_then<F>(self, right: F) -> ComposedFilterer<Self, F> {
ComposedFilterer::new(self, right)
}

pub(crate) fn right(&self) -> &R {
&self.right
}
}

impl<L, R, T> Filterable<T> for ComposedFilterer<L, R>
Expand Down
39 changes: 22 additions & 17 deletions crates/synd_term/src/ui/components/gh_notifications/filter_popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ impl OptionFilterer {
pub(super) fn new(options: GhNotificationFilterOptions) -> Self {
Self { options }
}

pub(super) fn options(&self) -> &GhNotificationFilterOptions {
&self.options
}
}

impl Filterable<Notification> for OptionFilterer {
Expand Down Expand Up @@ -70,38 +74,33 @@ impl Filterable<Notification> for OptionFilterer {

pub(super) struct FilterPopup {
pub(super) is_active: bool,
options: GhNotificationFilterOptions,
pending_options: Option<GhNotificationFilterOptions>,
}

impl FilterPopup {
pub(super) fn new(options: GhNotificationFilterOptions) -> Self {
pub(super) fn new() -> Self {
Self {
is_active: false,
options,
pending_options: None,
}
}

pub(super) fn applied_options(&self) -> &GhNotificationFilterOptions {
&self.options
}

pub(super) fn commit(&mut self) -> GhNotificationFilterOptionsState {
if let Some(options) = self.pending_options.take() {
let org = std::mem::replace(&mut self.options, options);
if org != self.options {
return GhNotificationFilterOptionsState::Changed(self.options.clone());
}
match self.pending_options.take() {
Some(options) => GhNotificationFilterOptionsState::Changed(options),
None => GhNotificationFilterOptionsState::Unchanged,
}
GhNotificationFilterOptionsState::Unchanged
}

pub(super) fn update_options(&mut self, new: &GhNotificationFilterUpdater) {
pub(super) fn update_options(
&mut self,
new: &GhNotificationFilterUpdater,
current: &GhNotificationFilterOptions,
) {
let mut pending = self
.pending_options
.take()
.unwrap_or_else(|| self.options.clone());
.unwrap_or_else(|| current.clone());

if new.toggle_include {
pending.include = match pending.include {
Expand Down Expand Up @@ -144,7 +143,13 @@ impl FilterPopup {

impl FilterPopup {
#[allow(clippy::too_many_lines)]
pub(super) fn render(&self, area: Rect, buf: &mut Buffer, cx: &Context<'_>) {
pub(super) fn render(
&self,
area: Rect,
buf: &mut Buffer,
cx: &Context<'_>,
current: &GhNotificationFilterOptions,
) {
let area = {
let block = Block::new()
.title_top("Filter")
Expand Down Expand Up @@ -173,7 +178,7 @@ impl FilterPopup {
]);
let [status_area, participating_area, visibility_area, pull_request_area, reason_area] =
vertical.areas(area);
let options = self.pending_options.as_ref().unwrap_or(&self.options);
let options = self.pending_options.as_ref().unwrap_or(current);
let keyword = cx.theme.entries.selected_entry;

// Render status
Expand Down
39 changes: 20 additions & 19 deletions crates/synd_term/src/ui/components/gh_notifications/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,27 @@ impl GhNotifications {
}

pub(crate) fn with_filter_options(filter_options: GhNotificationFilterOptions) -> Self {
let filter_popup = FilterPopup::new(filter_options.clone());
let filterer =
CategoryAndMatcherFilterer::default().and_then(OptionFilterer::new(filter_options));

let mut slf = Self {
notifications: FilterableVec::new(),
Self {
notifications: FilterableVec::from_filter(filterer),
max_repository_name: 0,
#[allow(clippy::zero_sized_map_values)]
status: HashMap::new(),
limit: config::github::NOTIFICATION_PER_PAGE as usize,
next_page: Some(config::github::INITIAL_PAGE_NUM),
filter_popup,
};

slf.apply_filter_options(filter_options);
slf
filter_popup: FilterPopup::new(),
}
}

pub(crate) fn filter_options(&self) -> &GhNotificationFilterOptions {
self.filter_popup.applied_options()
self.notifications.filter().right().options()
}

pub(crate) fn update_filter_options(&mut self, updater: &GhNotificationFilterUpdater) {
self.filter_popup.update_options(updater);
let current = self.filter_options().clone();
self.filter_popup.update_options(updater, &current);
}

pub(crate) fn update_filterer(&mut self, filterer: CategoryAndMatcherFilterer) {
Expand Down Expand Up @@ -196,9 +195,8 @@ impl GhNotifications {
match self.next_page {
Some(page) if self.notifications.len() < self.limit => {
tracing::debug!(
"Should fetch more. notifications: {} next_page {:?}",
"Should fetch more. notifications: {} next_page {page}",
self.notifications.len(),
self.next_page
);
Some(Command::FetchGhNotifications {
populate: Populate::Append,
Expand All @@ -222,7 +220,7 @@ impl GhNotifications {
}

fn next_fetch_params(&self, page: u8) -> FetchNotificationsParams {
let options = self.filter_popup.applied_options();
let options = self.filter_options();
FetchNotificationsParams {
page,
include: options.include,
Expand Down Expand Up @@ -304,11 +302,13 @@ impl GhNotifications {
pub(crate) fn close_filter_popup(&mut self) -> Option<Command> {
self.filter_popup.is_active = false;
match self.filter_popup.commit() {
GhNotificationFilterOptionsState::Changed(options) => {
self.apply_filter_options(options);
Some(Command::FetchGhNotifications {
populate: Populate::Replace,
params: self.reload(),
GhNotificationFilterOptionsState::Changed(new_options) => {
(&new_options != self.filter_options()).then(|| {
self.apply_filter_options(new_options);
Command::FetchGhNotifications {
populate: Populate::Replace,
params: self.reload(),
}
})
}
GhNotificationFilterOptionsState::Unchanged => None,
Expand Down Expand Up @@ -645,7 +645,8 @@ impl GhNotifications {
area.reset(buf);
area
};
self.filter_popup.render(area, buf, cx);
self.filter_popup
.render(area, buf, cx, self.filter_options());
}
}

Expand Down

0 comments on commit f1739fe

Please sign in to comment.