Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mute threads #604

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions crates/notedeck/src/accounts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use tracing::{debug, error, info};

use crate::{
KeyStorageResponse, KeyStorageType, Muted, SingleUnkIdAction, UnknownIds, UserAccount,
KeyStorageResponse, KeyStorageType, MuteFun, Muted, SingleUnkIdAction, UnknownIds, UserAccount,
};
use enostr::{ClientMessage, FilledKeypair, Keypair, RelayPool};
use nostrdb::{Filter, Ndb, Note, NoteKey, Subscription, Transaction};
Expand Down Expand Up @@ -382,17 +382,19 @@ impl Accounts {
self.key_store.select_key(None);
}

pub fn mutefun(&self) -> Box<dyn Fn(&Note) -> bool> {
pub fn mutefun(&self) -> Box<MuteFun> {
if let Some(index) = self.currently_selected_account {
if let Some(account) = self.accounts.get(index) {
let pubkey = account.pubkey.bytes();
if let Some(account_data) = self.account_data.get(pubkey) {
let muted = Arc::clone(&account_data.muted.muted);
return Box::new(move |note: &Note| muted.is_muted(note));
return Box::new(move |note: &Note, thread: &[u8; 32]| {
muted.is_muted(note, thread)
});
}
}
}
Box::new(|_: &Note| false)
Box::new(|_: &Note, _: &[u8; 32]| false)
}

pub fn send_initial_filters(&mut self, pool: &mut RelayPool, relay_url: &str) {
Expand Down
23 changes: 19 additions & 4 deletions crates/notedeck/src/muted.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use nostrdb::Note;
use std::collections::BTreeSet;

use tracing::debug;
use tracing::{debug, trace};

pub type MuteFun = dyn Fn(&Note) -> bool;
pub type MuteFun = dyn Fn(&Note, &[u8; 32]) -> bool;

#[derive(Default)]
pub struct Muted {
Expand Down Expand Up @@ -32,7 +32,13 @@ impl std::fmt::Debug for Muted {
}

impl Muted {
pub fn is_muted(&self, note: &Note) -> bool {
pub fn is_muted(&self, note: &Note, thread: &[u8; 32]) -> bool {
trace!(
"{}: thread: {}",
hex::encode(note.id()),
hex::encode(thread)
);

if self.pubkeys.contains(note.pubkey()) {
debug!(
"{}: MUTED pubkey: {}",
Expand All @@ -55,7 +61,16 @@ impl Muted {
// }
// }

// FIXME - Implement thread muting here
if self.threads.contains(thread) {
debug!(
"{}: MUTED thread: {}",
hex::encode(note.id()),
hex::encode(thread)
);
return true;
}

// if we get here it's not muted
false
}
}
2 changes: 2 additions & 0 deletions crates/notedeck_chrome/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ path = "src/preview.rs"
[features]
default = []
profiling = ["notedeck_columns/puffin"]
debug-widget-callstack = ["egui/callstack"]
debug-interactive-widgets = []

[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.11.1"
Expand Down
21 changes: 19 additions & 2 deletions crates/notedeck_chrome/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,26 @@ pub fn add_custom_style(is_mobile: bool, style: &mut Style) {
..Interaction::default()
};

#[cfg(debug_assertions)]
// debug: show callstack for the current widget on hover if all
// modifier keys are pressed down.
#[cfg(feature = "debug-widget-callstack")]
{
style.debug.show_interactive_widgets = true;
#[cfg(not(debug_assertions))]
compile_error!(
"The `debug-widget-callstack` feature requires a debug build, \
release builds are unsupported."
);
style.debug.debug_on_hover_with_all_modifiers = true;
}

// debug: show an overlay on all interactive widgets
#[cfg(feature = "debug-interactive-widgets")]
{
#[cfg(not(debug_assertions))]
compile_error!(
"The `debug-interactive-widgets` feature requires a debug build, \
release builds are unsupported."
);
style.debug.show_interactive_widgets = true;
}
}
13 changes: 9 additions & 4 deletions crates/notedeck_columns/src/actionbar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
};

use enostr::{NoteId, Pubkey, RelayPool};
use nostrdb::{Ndb, Transaction};
use nostrdb::{Ndb, NoteBuilder, Transaction};
use notedeck::{note::root_note_id_from_selected_id, MuteFun, NoteCache, NoteRef};

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
Expand Down Expand Up @@ -43,10 +43,15 @@ fn open_thread(
selected_note: &[u8; 32],
is_muted: &MuteFun,
) -> Option<NotesHolderResult> {
router.route_to(Route::thread(NoteId::new(selected_note.to_owned())));

let root_id = root_note_id_from_selected_id(ndb, note_cache, txn, selected_note);
Thread::open(ndb, note_cache, txn, pool, threads, root_id, is_muted)
// we only need to check if the thread is muted so use a dummy note
let dummy_note = NoteBuilder::new().build().unwrap();
if is_muted(&dummy_note, root_id) {
None
} else {
router.route_to(Route::thread(NoteId::new(selected_note.to_owned())));
Thread::open(ndb, note_cache, txn, pool, threads, root_id, is_muted)
}
}

impl NoteAction {
Expand Down
10 changes: 8 additions & 2 deletions crates/notedeck_columns/src/multi_subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use tracing::{debug, error, info};
use uuid::Uuid;

use crate::Error;
use notedeck::{MuteFun, NoteRef, UnifiedSubscription};
use notedeck::{
note::root_note_id_from_selected_id, MuteFun, NoteCache, NoteRef, UnifiedSubscription,
};

pub struct MultiSubscriber {
filters: Vec<Filter>,
Expand Down Expand Up @@ -109,6 +111,7 @@ impl MultiSubscriber {
pub fn poll_for_notes(
&mut self,
ndb: &Ndb,
note_cache: &mut NoteCache,
txn: &Transaction,
is_muted: &MuteFun,
) -> Result<Vec<NoteRef>, Error> {
Expand All @@ -129,7 +132,10 @@ impl MultiSubscriber {
continue;
};

if is_muted(&note) {
if is_muted(
&note,
root_note_id_from_selected_id(ndb, note_cache, txn, note.id()),
) {
continue;
}

Expand Down
4 changes: 3 additions & 1 deletion crates/notedeck_columns/src/notes_holder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,13 @@ pub trait NotesHolder {
&mut self,
txn: &Transaction,
ndb: &Ndb,
note_cache: &mut NoteCache,
is_muted: &MuteFun,
) -> Result<NoteRefsUnkIdAction> {
if let Some(multi_subscriber) = self.get_multi_subscriber() {
let reversed = true;
let note_refs: Vec<NoteRef> = multi_subscriber.poll_for_notes(ndb, txn, is_muted)?;
let note_refs: Vec<NoteRef> =
multi_subscriber.poll_for_notes(ndb, note_cache, txn, is_muted)?;
self.get_view().insert(&note_refs, reversed);
Ok(NoteRefsUnkIdAction::new(note_refs))
} else {
Expand Down
14 changes: 10 additions & 4 deletions crates/notedeck_columns/src/timeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::{
};

use notedeck::{
filter, CachedNote, FilterError, FilterState, FilterStates, MuteFun, NoteCache, NoteRef,
UnknownIds,
filter, note::root_note_id_from_selected_id, CachedNote, FilterError, FilterState,
FilterStates, MuteFun, NoteCache, NoteRef, UnknownIds,
};

use std::fmt;
Expand Down Expand Up @@ -312,7 +312,10 @@ impl Timeline {
error!("hit race condition in poll_notes_into_view: https://github.com/damus-io/nostrdb/issues/35 note {:?} was not added to timeline", key);
continue;
};
if is_muted(&note) {
if is_muted(
&note,
root_note_id_from_selected_id(ndb, note_cache, txn, note.id()),
) {
continue;
}

Expand Down Expand Up @@ -585,7 +588,10 @@ pub fn copy_notes_into_timeline(
for note_ref in notes {
for (view, filter) in filters.iter().enumerate() {
if let Ok(note) = ndb.get_note_by_key(txn, note_ref.key) {
if is_muted(&note) {
if is_muted(
&note,
root_note_id_from_selected_id(ndb, note_cache, txn, note.id()),
) {
continue;
}
if filter(
Expand Down
2 changes: 1 addition & 1 deletion crates/notedeck_columns/src/timeline/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub fn render_timeline_route(
img_cache,
note_options,
)
.ui(ui);
.ui(ui, &accounts.mutefun());

note_action.map(RenderNavAction::NoteAction)
}
Expand Down
6 changes: 4 additions & 2 deletions crates/notedeck_columns/src/ui/profile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ impl<'a> ProfileView<'a> {
tabs_ui(ui, profile.timeline.selected_view, &profile.timeline.views);

// poll for new notes and insert them into our existing notes
if let Err(e) = profile.poll_notes_into_view(&txn, self.ndb, is_muted) {
if let Err(e) =
profile.poll_notes_into_view(&txn, self.ndb, self.note_cache, is_muted)
{
error!("Profile::poll_notes_into_view: {e}");
}

Expand All @@ -86,7 +88,7 @@ impl<'a> ProfileView<'a> {
self.note_cache,
self.img_cache,
)
.show(ui)
.show(ui, is_muted)
})
.inner
}
Expand Down
4 changes: 2 additions & 2 deletions crates/notedeck_columns/src/ui/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl<'a> ThreadView<'a> {
// TODO(jb55): skip poll if ThreadResult is fresh?

// poll for new notes and insert them into our existing notes
match thread.poll_notes_into_view(&txn, self.ndb, is_muted) {
match thread.poll_notes_into_view(&txn, self.ndb, self.note_cache, is_muted) {
Ok(action) => {
action.process_action(&txn, self.ndb, self.unknown_ids, self.note_cache)
}
Expand All @@ -120,7 +120,7 @@ impl<'a> ThreadView<'a> {
self.note_cache,
self.img_cache,
)
.show(ui)
.show(ui, is_muted)
})
.inner
}
Expand Down
18 changes: 14 additions & 4 deletions crates/notedeck_columns/src/ui/timeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use egui::containers::scroll_area::ScrollBarVisibility;
use egui::{Direction, Layout};
use egui_tabs::TabColor;
use nostrdb::{Ndb, Transaction};
use notedeck::{ImageCache, NoteCache};
use notedeck::note::root_note_id_from_selected_id;
use notedeck::{ImageCache, MuteFun, NoteCache};
use tracing::{error, warn};

pub struct TimelineView<'a> {
Expand Down Expand Up @@ -44,7 +45,7 @@ impl<'a> TimelineView<'a> {
}
}

pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> {
pub fn ui(&mut self, ui: &mut egui::Ui, is_muted: &MuteFun) -> Option<NoteAction> {
timeline_ui(
ui,
self.ndb,
Expand All @@ -54,6 +55,7 @@ impl<'a> TimelineView<'a> {
self.img_cache,
self.reverse,
self.note_options,
is_muted,
)
}

Expand All @@ -73,6 +75,7 @@ fn timeline_ui(
img_cache: &mut ImageCache,
reversed: bool,
note_options: NoteOptions,
is_muted: &MuteFun,
) -> Option<NoteAction> {
//padding(4.0, ui, |ui| ui.heading("Notifications"));
/*
Expand Down Expand Up @@ -124,7 +127,7 @@ fn timeline_ui(
note_cache,
img_cache,
)
.show(ui)
.show(ui, is_muted)
})
.inner
}
Expand Down Expand Up @@ -247,7 +250,7 @@ impl<'a> TimelineTabView<'a> {
}
}

pub fn show(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> {
pub fn show(&mut self, ui: &mut egui::Ui, is_muted: &MuteFun) -> Option<NoteAction> {
let mut action: Option<NoteAction> = None;
let len = self.tab.notes.len();

Expand All @@ -274,6 +277,13 @@ impl<'a> TimelineTabView<'a> {
return 0;
};

if is_muted(
&note,
root_note_id_from_selected_id(self.ndb, self.note_cache, self.txn, note.id()),
) {
return 0;
}

ui::padding(8.0, ui, |ui| {
let resp = ui::NoteView::new(self.ndb, self.note_cache, self.img_cache, &note)
.note_options(self.note_options)
Expand Down
Loading