Merge tombstone muted notes #606
Changelog-Changed: Tombstone muted notes
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1032,6 +1032,7 @@ checksum = "53eafabcce0cb2325a59a98736efe0bf060585b437763f8c476957fb274bb974"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"accesskit",
|
"accesskit",
|
||||||
"ahash",
|
"ahash",
|
||||||
|
"backtrace",
|
||||||
"emath",
|
"emath",
|
||||||
"epaint",
|
"epaint",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use tracing::{debug, error, info};
|
use tracing::{debug, error, info};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
KeyStorageResponse, KeyStorageType, Muted, SingleUnkIdAction, UnknownIds, UserAccount,
|
KeyStorageResponse, KeyStorageType, MuteFun, Muted, SingleUnkIdAction, UnknownIds, UserAccount,
|
||||||
};
|
};
|
||||||
use enostr::{ClientMessage, FilledKeypair, Keypair, RelayPool};
|
use enostr::{ClientMessage, FilledKeypair, Keypair, RelayPool};
|
||||||
use nostrdb::{Filter, Ndb, Note, NoteKey, Subscription, Transaction};
|
use nostrdb::{Filter, Ndb, Note, NoteKey, Subscription, Transaction};
|
||||||
@@ -409,17 +409,19 @@ impl Accounts {
|
|||||||
self.key_store.select_key(None);
|
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(index) = self.currently_selected_account {
|
||||||
if let Some(account) = self.accounts.get(index) {
|
if let Some(account) = self.accounts.get(index) {
|
||||||
let pubkey = account.pubkey.bytes();
|
let pubkey = account.pubkey.bytes();
|
||||||
if let Some(account_data) = self.account_data.get(pubkey) {
|
if let Some(account_data) = self.account_data.get(pubkey) {
|
||||||
let muted = Arc::clone(&account_data.muted.muted);
|
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]| None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_initial_filters(&mut self, pool: &mut RelayPool, relay_url: &str) {
|
pub fn send_initial_filters(&mut self, pool: &mut RelayPool, relay_url: &str) {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use nostrdb::Note;
|
use nostrdb::Note;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use tracing::debug;
|
use tracing::{debug, trace};
|
||||||
|
|
||||||
pub type MuteFun = dyn Fn(&Note) -> bool;
|
// If the note is muted return a reason string, otherwise None
|
||||||
|
pub type MuteFun = dyn Fn(&Note, &[u8; 32]) -> Option<String>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Muted {
|
pub struct Muted {
|
||||||
@@ -32,14 +33,21 @@ impl std::fmt::Debug for Muted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Muted {
|
impl Muted {
|
||||||
pub fn is_muted(&self, note: &Note) -> bool {
|
// If the note is muted return a reason string, otherwise None
|
||||||
|
pub fn is_muted(&self, note: &Note, thread: &[u8; 32]) -> Option<String> {
|
||||||
|
trace!(
|
||||||
|
"{}: thread: {}",
|
||||||
|
hex::encode(note.id()),
|
||||||
|
hex::encode(thread)
|
||||||
|
);
|
||||||
|
|
||||||
if self.pubkeys.contains(note.pubkey()) {
|
if self.pubkeys.contains(note.pubkey()) {
|
||||||
debug!(
|
debug!(
|
||||||
"{}: MUTED pubkey: {}",
|
"{}: MUTED pubkey: {}",
|
||||||
hex::encode(note.id()),
|
hex::encode(note.id()),
|
||||||
hex::encode(note.pubkey())
|
hex::encode(note.pubkey())
|
||||||
);
|
);
|
||||||
return true;
|
return Some(format!("pubkey {}", hex::encode(note.pubkey())));
|
||||||
}
|
}
|
||||||
// FIXME - Implement hashtag muting here
|
// FIXME - Implement hashtag muting here
|
||||||
|
|
||||||
@@ -51,11 +59,20 @@ impl Muted {
|
|||||||
// for word in &self.words {
|
// for word in &self.words {
|
||||||
// if content.contains(&word.to_lowercase()) {
|
// if content.contains(&word.to_lowercase()) {
|
||||||
// debug!("{}: MUTED word: {}", hex::encode(note.id()), word);
|
// debug!("{}: MUTED word: {}", hex::encode(note.id()), word);
|
||||||
// return true;
|
// return Some(format!("muted word {}", word));
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// FIXME - Implement thread muting here
|
if self.threads.contains(thread) {
|
||||||
false
|
debug!(
|
||||||
|
"{}: MUTED thread: {}",
|
||||||
|
hex::encode(note.id()),
|
||||||
|
hex::encode(thread)
|
||||||
|
);
|
||||||
|
return Some(format!("thread {}", hex::encode(thread)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we get here it's not muted
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ path = "src/preview.rs"
|
|||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
profiling = ["notedeck_columns/puffin", "puffin", "puffin_egui"]
|
profiling = ["notedeck_columns/puffin", "puffin", "puffin_egui"]
|
||||||
|
debug-widget-callstack = ["egui/callstack"]
|
||||||
|
debug-interactive-widgets = []
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
tracing-logcat = "0.1.0"
|
tracing-logcat = "0.1.0"
|
||||||
|
|||||||
@@ -124,9 +124,26 @@ pub fn add_custom_style(is_mobile: bool, style: &mut Style) {
|
|||||||
..Interaction::default()
|
..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;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
|
|
||||||
use enostr::{NoteId, Pubkey, RelayPool};
|
use enostr::{NoteId, Pubkey, RelayPool};
|
||||||
use nostrdb::{Ndb, Transaction};
|
use nostrdb::{Ndb, Transaction};
|
||||||
use notedeck::{note::root_note_id_from_selected_id, MuteFun, NoteCache, NoteRef};
|
use notedeck::{note::root_note_id_from_selected_id, NoteCache, NoteRef};
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||||
pub enum NoteAction {
|
pub enum NoteAction {
|
||||||
@@ -41,12 +41,11 @@ fn open_thread(
|
|||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
threads: &mut NotesHolderStorage<Thread>,
|
threads: &mut NotesHolderStorage<Thread>,
|
||||||
selected_note: &[u8; 32],
|
selected_note: &[u8; 32],
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Option<NotesHolderResult> {
|
) -> Option<NotesHolderResult> {
|
||||||
router.route_to(Route::thread(NoteId::new(selected_note.to_owned())));
|
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);
|
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)
|
Thread::open(ndb, note_cache, txn, pool, threads, root_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NoteAction {
|
impl NoteAction {
|
||||||
@@ -60,7 +59,6 @@ impl NoteAction {
|
|||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Option<NotesHolderResult> {
|
) -> Option<NotesHolderResult> {
|
||||||
match self {
|
match self {
|
||||||
NoteAction::Reply(note_id) => {
|
NoteAction::Reply(note_id) => {
|
||||||
@@ -68,28 +66,13 @@ impl NoteAction {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
NoteAction::OpenThread(note_id) => open_thread(
|
NoteAction::OpenThread(note_id) => {
|
||||||
ndb,
|
open_thread(ndb, txn, router, note_cache, pool, threads, note_id.bytes())
|
||||||
txn,
|
}
|
||||||
router,
|
|
||||||
note_cache,
|
|
||||||
pool,
|
|
||||||
threads,
|
|
||||||
note_id.bytes(),
|
|
||||||
is_muted,
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteAction::OpenProfile(pubkey) => {
|
NoteAction::OpenProfile(pubkey) => {
|
||||||
router.route_to(Route::profile(pubkey));
|
router.route_to(Route::profile(pubkey));
|
||||||
Profile::open(
|
Profile::open(ndb, note_cache, txn, pool, profiles, pubkey.bytes())
|
||||||
ndb,
|
|
||||||
note_cache,
|
|
||||||
txn,
|
|
||||||
pool,
|
|
||||||
profiles,
|
|
||||||
pubkey.bytes(),
|
|
||||||
is_muted,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NoteAction::Quote(note_id) => {
|
NoteAction::Quote(note_id) => {
|
||||||
@@ -111,13 +94,10 @@ impl NoteAction {
|
|||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) {
|
) {
|
||||||
let router = columns.column_mut(col).router_mut();
|
let router = columns.column_mut(col).router_mut();
|
||||||
if let Some(br) = self.execute(
|
if let Some(br) = self.execute(ndb, router, threads, profiles, note_cache, pool, txn) {
|
||||||
ndb, router, threads, profiles, note_cache, pool, txn, is_muted,
|
br.process(ndb, note_cache, txn, threads);
|
||||||
) {
|
|
||||||
br.process(ndb, note_cache, txn, threads, is_muted);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,13 +113,12 @@ impl NotesHolderResult {
|
|||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
storage: &mut NotesHolderStorage<N>,
|
storage: &mut NotesHolderStorage<N>,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
// update the thread for next render if we have new notes
|
// update the thread for next render if we have new notes
|
||||||
NotesHolderResult::NewNotes(new_notes) => {
|
NotesHolderResult::NewNotes(new_notes) => {
|
||||||
let holder = storage
|
let holder = storage
|
||||||
.notes_holder_mutated(ndb, note_cache, txn, &new_notes.id, is_muted)
|
.notes_holder_mutated(ndb, note_cache, txn, &new_notes.id)
|
||||||
.get_ptr();
|
.get_ptr();
|
||||||
new_notes.process(holder);
|
new_notes.process(holder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,6 @@ fn try_process_event(
|
|||||||
app_ctx.pool,
|
app_ctx.pool,
|
||||||
app_ctx.note_cache,
|
app_ctx.note_cache,
|
||||||
timeline,
|
timeline,
|
||||||
&app_ctx.accounts.mutefun(),
|
|
||||||
app_ctx
|
app_ctx
|
||||||
.accounts
|
.accounts
|
||||||
.get_selected_account()
|
.get_selected_account()
|
||||||
@@ -159,7 +158,6 @@ fn try_process_event(
|
|||||||
&txn,
|
&txn,
|
||||||
app_ctx.unknown_ids,
|
app_ctx.unknown_ids,
|
||||||
app_ctx.note_cache,
|
app_ctx.note_cache,
|
||||||
&app_ctx.accounts.mutefun(),
|
|
||||||
) {
|
) {
|
||||||
error!("poll_notes_into_view: {err}");
|
error!("poll_notes_into_view: {err}");
|
||||||
}
|
}
|
||||||
@@ -200,7 +198,6 @@ fn update_damus(damus: &mut Damus, app_ctx: &mut AppContext<'_>, ctx: &egui::Con
|
|||||||
app_ctx.ndb,
|
app_ctx.ndb,
|
||||||
app_ctx.note_cache,
|
app_ctx.note_cache,
|
||||||
&mut damus.decks_cache,
|
&mut damus.decks_cache,
|
||||||
&app_ctx.accounts.mutefun(),
|
|
||||||
) {
|
) {
|
||||||
warn!("update_damus init: {err}");
|
warn!("update_damus init: {err}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use tracing::{debug, error, info};
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use notedeck::{MuteFun, NoteRef, UnifiedSubscription};
|
use notedeck::{NoteRef, UnifiedSubscription};
|
||||||
|
|
||||||
pub struct MultiSubscriber {
|
pub struct MultiSubscriber {
|
||||||
filters: Vec<Filter>,
|
filters: Vec<Filter>,
|
||||||
@@ -106,12 +106,7 @@ impl MultiSubscriber {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_for_notes(
|
pub fn poll_for_notes(&mut self, ndb: &Ndb, txn: &Transaction) -> Result<Vec<NoteRef>, Error> {
|
||||||
&mut self,
|
|
||||||
ndb: &Ndb,
|
|
||||||
txn: &Transaction,
|
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Result<Vec<NoteRef>, Error> {
|
|
||||||
let sub = self.sub.as_ref().ok_or(notedeck::Error::no_active_sub())?;
|
let sub = self.sub.as_ref().ok_or(notedeck::Error::no_active_sub())?;
|
||||||
let new_note_keys = ndb.poll_for_notes(sub.local, 500);
|
let new_note_keys = ndb.poll_for_notes(sub.local, 500);
|
||||||
|
|
||||||
@@ -129,10 +124,6 @@ impl MultiSubscriber {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_muted(¬e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
notes.push(note);
|
notes.push(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ impl RenderNavResponse {
|
|||||||
ctx.note_cache,
|
ctx.note_cache,
|
||||||
ctx.pool,
|
ctx.pool,
|
||||||
&txn,
|
&txn,
|
||||||
&ctx.accounts.mutefun(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +208,6 @@ impl RenderNavResponse {
|
|||||||
&mut app.threads,
|
&mut app.threads,
|
||||||
ctx.pool,
|
ctx.pool,
|
||||||
root_id,
|
root_id,
|
||||||
&ctx.accounts.mutefun(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +219,6 @@ impl RenderNavResponse {
|
|||||||
&mut app.profiles,
|
&mut app.profiles,
|
||||||
ctx.pool,
|
ctx.pool,
|
||||||
pubkey.bytes(),
|
pubkey.bytes(),
|
||||||
&ctx.accounts.mutefun(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use enostr::{Filter, RelayPool};
|
use enostr::{Filter, RelayPool};
|
||||||
use nostrdb::{Ndb, Transaction};
|
use nostrdb::{Ndb, Transaction};
|
||||||
use notedeck::{MuteFun, NoteCache, NoteRef, NoteRefsUnkIdAction};
|
use notedeck::{NoteCache, NoteRef, NoteRefsUnkIdAction};
|
||||||
use tracing::{debug, info, warn};
|
use tracing::{debug, info, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -56,7 +56,6 @@ impl<M: NotesHolder> NotesHolderStorage<M> {
|
|||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
id: &[u8; 32],
|
id: &[u8; 32],
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Vitality<'a, M> {
|
) -> Vitality<'a, M> {
|
||||||
// we can't use the naive hashmap entry API here because lookups
|
// we can't use the naive hashmap entry API here because lookups
|
||||||
// require a copy, wait until we have a raw entry api. We could
|
// require a copy, wait until we have a raw entry api. We could
|
||||||
@@ -90,7 +89,7 @@ impl<M: NotesHolder> NotesHolderStorage<M> {
|
|||||||
|
|
||||||
self.id_to_object.insert(
|
self.id_to_object.insert(
|
||||||
id.to_owned(),
|
id.to_owned(),
|
||||||
M::new_notes_holder(txn, ndb, note_cache, id, M::filters(id), notes, is_muted),
|
M::new_notes_holder(txn, ndb, note_cache, id, M::filters(id), notes),
|
||||||
);
|
);
|
||||||
Vitality::Fresh(self.id_to_object.get_mut(id).unwrap())
|
Vitality::Fresh(self.id_to_object.get_mut(id).unwrap())
|
||||||
}
|
}
|
||||||
@@ -109,7 +108,6 @@ pub trait NotesHolder {
|
|||||||
id: &[u8; 32],
|
id: &[u8; 32],
|
||||||
filters: Vec<Filter>,
|
filters: Vec<Filter>,
|
||||||
notes: Vec<NoteRef>,
|
notes: Vec<NoteRef>,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Self;
|
) -> Self;
|
||||||
|
|
||||||
#[must_use = "process_action must be handled in the Ok(action) case"]
|
#[must_use = "process_action must be handled in the Ok(action) case"]
|
||||||
@@ -117,11 +115,10 @@ pub trait NotesHolder {
|
|||||||
&mut self,
|
&mut self,
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Result<NoteRefsUnkIdAction> {
|
) -> Result<NoteRefsUnkIdAction> {
|
||||||
if let Some(multi_subscriber) = self.get_multi_subscriber() {
|
if let Some(multi_subscriber) = self.get_multi_subscriber() {
|
||||||
let reversed = true;
|
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, txn)?;
|
||||||
self.get_view().insert(¬e_refs, reversed);
|
self.get_view().insert(¬e_refs, reversed);
|
||||||
Ok(NoteRefsUnkIdAction::new(note_refs))
|
Ok(NoteRefsUnkIdAction::new(note_refs))
|
||||||
} else {
|
} else {
|
||||||
@@ -160,10 +157,9 @@ pub trait NotesHolder {
|
|||||||
notes_holder_storage: &mut NotesHolderStorage<M>,
|
notes_holder_storage: &mut NotesHolderStorage<M>,
|
||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
id: &[u8; 32],
|
id: &[u8; 32],
|
||||||
is_muted: &MuteFun,
|
|
||||||
) {
|
) {
|
||||||
let notes_holder = notes_holder_storage
|
let notes_holder = notes_holder_storage
|
||||||
.notes_holder_mutated(ndb, note_cache, txn, id, is_muted)
|
.notes_holder_mutated(ndb, note_cache, txn, id)
|
||||||
.get_ptr();
|
.get_ptr();
|
||||||
|
|
||||||
if let Some(multi_subscriber) = notes_holder.get_multi_subscriber() {
|
if let Some(multi_subscriber) = notes_holder.get_multi_subscriber() {
|
||||||
@@ -178,9 +174,8 @@ pub trait NotesHolder {
|
|||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
storage: &mut NotesHolderStorage<M>,
|
storage: &mut NotesHolderStorage<M>,
|
||||||
id: &[u8; 32],
|
id: &[u8; 32],
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Option<NotesHolderResult> {
|
) -> Option<NotesHolderResult> {
|
||||||
let vitality = storage.notes_holder_mutated(ndb, note_cache, txn, id, is_muted);
|
let vitality = storage.notes_holder_mutated(ndb, note_cache, txn, id);
|
||||||
|
|
||||||
let (holder, result) = match vitality {
|
let (holder, result) = match vitality {
|
||||||
Vitality::Stale(holder) => {
|
Vitality::Stale(holder) => {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use nostrdb::{
|
|||||||
FilterBuilder, Ndb, Note, NoteBuildOptions, NoteBuilder, ProfileRecord, Transaction,
|
FilterBuilder, Ndb, Note, NoteBuildOptions, NoteBuilder, ProfileRecord, Transaction,
|
||||||
};
|
};
|
||||||
|
|
||||||
use notedeck::{filter::default_limit, FilterState, MuteFun, NoteCache, NoteRef};
|
use notedeck::{filter::default_limit, FilterState, NoteCache, NoteRef};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -91,7 +91,6 @@ impl Profile {
|
|||||||
source: PubkeySource,
|
source: PubkeySource,
|
||||||
filters: Vec<Filter>,
|
filters: Vec<Filter>,
|
||||||
notes: Vec<NoteRef>,
|
notes: Vec<NoteRef>,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut timeline = Timeline::new(
|
let mut timeline = Timeline::new(
|
||||||
TimelineKind::profile(source),
|
TimelineKind::profile(source),
|
||||||
@@ -99,7 +98,7 @@ impl Profile {
|
|||||||
TimelineTab::full_tabs(),
|
TimelineTab::full_tabs(),
|
||||||
);
|
);
|
||||||
|
|
||||||
copy_notes_into_timeline(&mut timeline, txn, ndb, note_cache, notes, is_muted);
|
copy_notes_into_timeline(&mut timeline, txn, ndb, note_cache, notes);
|
||||||
|
|
||||||
Profile {
|
Profile {
|
||||||
timeline,
|
timeline,
|
||||||
@@ -145,7 +144,6 @@ impl NotesHolder for Profile {
|
|||||||
id: &[u8; 32],
|
id: &[u8; 32],
|
||||||
filters: Vec<Filter>,
|
filters: Vec<Filter>,
|
||||||
notes: Vec<NoteRef>,
|
notes: Vec<NoteRef>,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Profile::new(
|
Profile::new(
|
||||||
txn,
|
txn,
|
||||||
@@ -154,7 +152,6 @@ impl NotesHolder for Profile {
|
|||||||
PubkeySource::Explicit(Pubkey::new(*id)),
|
PubkeySource::Explicit(Pubkey::new(*id)),
|
||||||
filters,
|
filters,
|
||||||
notes,
|
notes,
|
||||||
is_muted,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use nostrdb::{Filter, FilterBuilder, Ndb, Transaction};
|
use nostrdb::{Filter, FilterBuilder, Ndb, Transaction};
|
||||||
use notedeck::{MuteFun, NoteCache, NoteRef};
|
use notedeck::{NoteCache, NoteRef};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
@@ -74,7 +74,6 @@ impl NotesHolder for Thread {
|
|||||||
_: &[u8; 32],
|
_: &[u8; 32],
|
||||||
_: Vec<Filter>,
|
_: Vec<Filter>,
|
||||||
notes: Vec<NoteRef>,
|
notes: Vec<NoteRef>,
|
||||||
_: &MuteFun,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Thread::new(notes)
|
Thread::new(notes)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use notedeck::{
|
use notedeck::{
|
||||||
filter, CachedNote, FilterError, FilterState, FilterStates, MuteFun, NoteCache, NoteRef,
|
filter, CachedNote, FilterError, FilterState, FilterStates, NoteCache, NoteRef, UnknownIds,
|
||||||
UnknownIds,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -287,7 +286,6 @@ impl Timeline {
|
|||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
unknown_ids: &mut UnknownIds,
|
unknown_ids: &mut UnknownIds,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let timeline = timelines
|
let timeline = timelines
|
||||||
.get_mut(timeline_idx)
|
.get_mut(timeline_idx)
|
||||||
@@ -312,9 +310,6 @@ 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);
|
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;
|
continue;
|
||||||
};
|
};
|
||||||
if is_muted(¬e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
UnknownIds::update_from_note(txn, ndb, unknown_ids, note_cache, ¬e);
|
UnknownIds::update_from_note(txn, ndb, unknown_ids, note_cache, ¬e);
|
||||||
|
|
||||||
@@ -412,12 +407,11 @@ pub fn setup_new_timeline(
|
|||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
since_optimize: bool,
|
since_optimize: bool,
|
||||||
is_muted: &MuteFun,
|
|
||||||
our_pk: Option<&Pubkey>,
|
our_pk: Option<&Pubkey>,
|
||||||
) {
|
) {
|
||||||
// if we're ready, setup local subs
|
// if we're ready, setup local subs
|
||||||
if is_timeline_ready(ndb, pool, note_cache, timeline, is_muted, our_pk) {
|
if is_timeline_ready(ndb, pool, note_cache, timeline, our_pk) {
|
||||||
if let Err(err) = setup_timeline_nostrdb_sub(ndb, note_cache, timeline, is_muted) {
|
if let Err(err) = setup_timeline_nostrdb_sub(ndb, note_cache, timeline) {
|
||||||
error!("setup_new_timeline: {err}");
|
error!("setup_new_timeline: {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -547,7 +541,6 @@ fn setup_initial_timeline(
|
|||||||
timeline: &mut Timeline,
|
timeline: &mut Timeline,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
filters: &[Filter],
|
filters: &[Filter],
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
timeline.subscription = Some(ndb.subscribe(filters)?);
|
timeline.subscription = Some(ndb.subscribe(filters)?);
|
||||||
let txn = Transaction::new(ndb)?;
|
let txn = Transaction::new(ndb)?;
|
||||||
@@ -562,7 +555,7 @@ fn setup_initial_timeline(
|
|||||||
.map(NoteRef::from_query_result)
|
.map(NoteRef::from_query_result)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
copy_notes_into_timeline(timeline, &txn, ndb, note_cache, notes, is_muted);
|
copy_notes_into_timeline(timeline, &txn, ndb, note_cache, notes);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -573,7 +566,6 @@ pub fn copy_notes_into_timeline(
|
|||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
notes: Vec<NoteRef>,
|
notes: Vec<NoteRef>,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) {
|
) {
|
||||||
let filters = {
|
let filters = {
|
||||||
let views = &timeline.views;
|
let views = &timeline.views;
|
||||||
@@ -585,9 +577,6 @@ pub fn copy_notes_into_timeline(
|
|||||||
for note_ref in notes {
|
for note_ref in notes {
|
||||||
for (view, filter) in filters.iter().enumerate() {
|
for (view, filter) in filters.iter().enumerate() {
|
||||||
if let Ok(note) = ndb.get_note_by_key(txn, note_ref.key) {
|
if let Ok(note) = ndb.get_note_by_key(txn, note_ref.key) {
|
||||||
if is_muted(¬e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if filter(
|
if filter(
|
||||||
note_cache.cached_note_or_insert_mut(note_ref.key, ¬e),
|
note_cache.cached_note_or_insert_mut(note_ref.key, ¬e),
|
||||||
¬e,
|
¬e,
|
||||||
@@ -603,12 +592,11 @@ pub fn setup_initial_nostrdb_subs(
|
|||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
decks_cache: &mut DecksCache,
|
decks_cache: &mut DecksCache,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for decks in decks_cache.get_all_decks_mut() {
|
for decks in decks_cache.get_all_decks_mut() {
|
||||||
for deck in decks.decks_mut() {
|
for deck in decks.decks_mut() {
|
||||||
for timeline in deck.columns_mut().timelines_mut() {
|
for timeline in deck.columns_mut().timelines_mut() {
|
||||||
if let Err(err) = setup_timeline_nostrdb_sub(ndb, note_cache, timeline, is_muted) {
|
if let Err(err) = setup_timeline_nostrdb_sub(ndb, note_cache, timeline) {
|
||||||
error!("setup_initial_nostrdb_subs: {err}");
|
error!("setup_initial_nostrdb_subs: {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -622,7 +610,6 @@ fn setup_timeline_nostrdb_sub(
|
|||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
timeline: &mut Timeline,
|
timeline: &mut Timeline,
|
||||||
is_muted: &MuteFun,
|
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let filter_state = timeline
|
let filter_state = timeline
|
||||||
.filter
|
.filter
|
||||||
@@ -630,7 +617,7 @@ fn setup_timeline_nostrdb_sub(
|
|||||||
.ok_or(Error::App(notedeck::Error::empty_contact_list()))?
|
.ok_or(Error::App(notedeck::Error::empty_contact_list()))?
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
setup_initial_timeline(ndb, timeline, note_cache, &filter_state, is_muted)?;
|
setup_initial_timeline(ndb, timeline, note_cache, &filter_state)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -644,7 +631,6 @@ pub fn is_timeline_ready(
|
|||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
timeline: &mut Timeline,
|
timeline: &mut Timeline,
|
||||||
is_muted: &MuteFun,
|
|
||||||
our_pk: Option<&Pubkey>,
|
our_pk: Option<&Pubkey>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// TODO: we should debounce the filter states a bit to make sure we have
|
// TODO: we should debounce the filter states a bit to make sure we have
|
||||||
@@ -705,8 +691,7 @@ pub fn is_timeline_ready(
|
|||||||
// we just switched to the ready state, we should send initial
|
// we just switched to the ready state, we should send initial
|
||||||
// queries and setup the local subscription
|
// queries and setup the local subscription
|
||||||
info!("Found contact list! Setting up local and remote contact list query");
|
info!("Found contact list! Setting up local and remote contact list query");
|
||||||
setup_initial_timeline(ndb, timeline, note_cache, &filter, is_muted)
|
setup_initial_timeline(ndb, timeline, note_cache, &filter).expect("setup init");
|
||||||
.expect("setup init");
|
|
||||||
timeline
|
timeline
|
||||||
.filter
|
.filter
|
||||||
.set_relay_state(relay_id, FilterState::ready(filter.clone()));
|
.set_relay_state(relay_id, FilterState::ready(filter.clone()));
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ pub fn render_timeline_route(
|
|||||||
note_cache,
|
note_cache,
|
||||||
img_cache,
|
img_cache,
|
||||||
note_options,
|
note_options,
|
||||||
|
&accounts.mutefun(),
|
||||||
)
|
)
|
||||||
.ui(ui);
|
.ui(ui);
|
||||||
|
|
||||||
@@ -77,9 +78,10 @@ pub fn render_timeline_route(
|
|||||||
img_cache,
|
img_cache,
|
||||||
id.bytes(),
|
id.bytes(),
|
||||||
textmode,
|
textmode,
|
||||||
|
&accounts.mutefun(),
|
||||||
)
|
)
|
||||||
.id_source(egui::Id::new(("threadscroll", col)))
|
.id_source(egui::Id::new(("threadscroll", col)))
|
||||||
.ui(ui, &accounts.mutefun())
|
.ui(ui)
|
||||||
.map(Into::into),
|
.map(Into::into),
|
||||||
|
|
||||||
TimelineRoute::Reply(id) => {
|
TimelineRoute::Reply(id) => {
|
||||||
@@ -173,9 +175,10 @@ pub fn render_profile_route(
|
|||||||
ndb,
|
ndb,
|
||||||
note_cache,
|
note_cache,
|
||||||
img_cache,
|
img_cache,
|
||||||
|
is_muted,
|
||||||
NoteOptions::default(),
|
NoteOptions::default(),
|
||||||
)
|
)
|
||||||
.ui(ui, is_muted);
|
.ui(ui);
|
||||||
|
|
||||||
if let Some(action) = action {
|
if let Some(action) = action {
|
||||||
match action {
|
match action {
|
||||||
|
|||||||
@@ -503,7 +503,6 @@ pub fn render_add_column_routes(
|
|||||||
ctx.pool,
|
ctx.pool,
|
||||||
ctx.note_cache,
|
ctx.note_cache,
|
||||||
app.since_optimize,
|
app.since_optimize,
|
||||||
&ctx.accounts.mutefun(),
|
|
||||||
ctx.accounts
|
ctx.accounts
|
||||||
.get_selected_account()
|
.get_selected_account()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ pub struct ProfileView<'a> {
|
|||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
note_cache: &'a mut NoteCache,
|
note_cache: &'a mut NoteCache,
|
||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
|
is_muted: &'a MuteFun,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ProfileViewAction {
|
pub enum ProfileViewAction {
|
||||||
@@ -46,6 +47,7 @@ impl<'a> ProfileView<'a> {
|
|||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
note_cache: &'a mut NoteCache,
|
note_cache: &'a mut NoteCache,
|
||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
|
is_muted: &'a MuteFun,
|
||||||
note_options: NoteOptions,
|
note_options: NoteOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ProfileView {
|
ProfileView {
|
||||||
@@ -57,10 +59,11 @@ impl<'a> ProfileView<'a> {
|
|||||||
note_cache,
|
note_cache,
|
||||||
img_cache,
|
img_cache,
|
||||||
note_options,
|
note_options,
|
||||||
|
is_muted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui, is_muted: &MuteFun) -> Option<ProfileViewAction> {
|
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<ProfileViewAction> {
|
||||||
let scroll_id = egui::Id::new(("profile_scroll", self.col_id, self.pubkey));
|
let scroll_id = egui::Id::new(("profile_scroll", self.col_id, self.pubkey));
|
||||||
|
|
||||||
ScrollArea::vertical()
|
ScrollArea::vertical()
|
||||||
@@ -75,20 +78,14 @@ impl<'a> ProfileView<'a> {
|
|||||||
}
|
}
|
||||||
let profile = self
|
let profile = self
|
||||||
.profiles
|
.profiles
|
||||||
.notes_holder_mutated(
|
.notes_holder_mutated(self.ndb, self.note_cache, &txn, self.pubkey.bytes())
|
||||||
self.ndb,
|
|
||||||
self.note_cache,
|
|
||||||
&txn,
|
|
||||||
self.pubkey.bytes(),
|
|
||||||
is_muted,
|
|
||||||
)
|
|
||||||
.get_ptr();
|
.get_ptr();
|
||||||
|
|
||||||
profile.timeline.selected_view =
|
profile.timeline.selected_view =
|
||||||
tabs_ui(ui, profile.timeline.selected_view, &profile.timeline.views);
|
tabs_ui(ui, profile.timeline.selected_view, &profile.timeline.views);
|
||||||
|
|
||||||
// poll for new notes and insert them into our existing notes
|
// 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) {
|
||||||
error!("Profile::poll_notes_into_view: {e}");
|
error!("Profile::poll_notes_into_view: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,11 +99,13 @@ impl<'a> ProfileView<'a> {
|
|||||||
self.ndb,
|
self.ndb,
|
||||||
self.note_cache,
|
self.note_cache,
|
||||||
self.img_cache,
|
self.img_cache,
|
||||||
|
self.is_muted,
|
||||||
)
|
)
|
||||||
.show(ui)
|
.show(ui)
|
||||||
{
|
{
|
||||||
action = Some(ProfileViewAction::Note(note_action));
|
action = Some(ProfileViewAction::Note(note_action));
|
||||||
}
|
}
|
||||||
|
|
||||||
action
|
action
|
||||||
})
|
})
|
||||||
.inner
|
.inner
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pub struct ThreadView<'a> {
|
|||||||
selected_note_id: &'a [u8; 32],
|
selected_note_id: &'a [u8; 32],
|
||||||
textmode: bool,
|
textmode: bool,
|
||||||
id_source: egui::Id,
|
id_source: egui::Id,
|
||||||
|
is_muted: &'a MuteFun,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ThreadView<'a> {
|
impl<'a> ThreadView<'a> {
|
||||||
@@ -32,6 +33,7 @@ impl<'a> ThreadView<'a> {
|
|||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
selected_note_id: &'a [u8; 32],
|
selected_note_id: &'a [u8; 32],
|
||||||
textmode: bool,
|
textmode: bool,
|
||||||
|
is_muted: &'a MuteFun,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let id_source = egui::Id::new("threadscroll_threadview");
|
let id_source = egui::Id::new("threadscroll_threadview");
|
||||||
ThreadView {
|
ThreadView {
|
||||||
@@ -43,6 +45,7 @@ impl<'a> ThreadView<'a> {
|
|||||||
selected_note_id,
|
selected_note_id,
|
||||||
textmode,
|
textmode,
|
||||||
id_source,
|
id_source,
|
||||||
|
is_muted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +54,7 @@ impl<'a> ThreadView<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui, is_muted: &MuteFun) -> Option<NoteAction> {
|
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> {
|
||||||
let txn = Transaction::new(self.ndb).expect("txn");
|
let txn = Transaction::new(self.ndb).expect("txn");
|
||||||
|
|
||||||
let selected_note_key =
|
let selected_note_key =
|
||||||
@@ -93,13 +96,13 @@ impl<'a> ThreadView<'a> {
|
|||||||
|
|
||||||
let thread = self
|
let thread = self
|
||||||
.threads
|
.threads
|
||||||
.notes_holder_mutated(self.ndb, self.note_cache, &txn, root_id, is_muted)
|
.notes_holder_mutated(self.ndb, self.note_cache, &txn, root_id)
|
||||||
.get_ptr();
|
.get_ptr();
|
||||||
|
|
||||||
// TODO(jb55): skip poll if ThreadResult is fresh?
|
// TODO(jb55): skip poll if ThreadResult is fresh?
|
||||||
|
|
||||||
// poll for new notes and insert them into our existing notes
|
// 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) {
|
||||||
Ok(action) => {
|
Ok(action) => {
|
||||||
action.process_action(&txn, self.ndb, self.unknown_ids, self.note_cache)
|
action.process_action(&txn, self.ndb, self.unknown_ids, self.note_cache)
|
||||||
}
|
}
|
||||||
@@ -119,6 +122,7 @@ impl<'a> ThreadView<'a> {
|
|||||||
self.ndb,
|
self.ndb,
|
||||||
self.note_cache,
|
self.note_cache,
|
||||||
self.img_cache,
|
self.img_cache,
|
||||||
|
self.is_muted,
|
||||||
)
|
)
|
||||||
.show(ui)
|
.show(ui)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ use crate::{
|
|||||||
ui::note::NoteOptions,
|
ui::note::NoteOptions,
|
||||||
};
|
};
|
||||||
use egui::containers::scroll_area::ScrollBarVisibility;
|
use egui::containers::scroll_area::ScrollBarVisibility;
|
||||||
use egui::{Direction, Layout};
|
use egui::{Color32, Direction, Layout};
|
||||||
use egui_tabs::TabColor;
|
use egui_tabs::TabColor;
|
||||||
use nostrdb::{Ndb, Transaction};
|
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};
|
use tracing::{error, warn};
|
||||||
|
|
||||||
pub struct TimelineView<'a> {
|
pub struct TimelineView<'a> {
|
||||||
@@ -21,6 +22,7 @@ pub struct TimelineView<'a> {
|
|||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
note_options: NoteOptions,
|
note_options: NoteOptions,
|
||||||
reverse: bool,
|
reverse: bool,
|
||||||
|
is_muted: &'a MuteFun,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TimelineView<'a> {
|
impl<'a> TimelineView<'a> {
|
||||||
@@ -31,6 +33,7 @@ impl<'a> TimelineView<'a> {
|
|||||||
note_cache: &'a mut NoteCache,
|
note_cache: &'a mut NoteCache,
|
||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
note_options: NoteOptions,
|
note_options: NoteOptions,
|
||||||
|
is_muted: &'a MuteFun,
|
||||||
) -> TimelineView<'a> {
|
) -> TimelineView<'a> {
|
||||||
let reverse = false;
|
let reverse = false;
|
||||||
TimelineView {
|
TimelineView {
|
||||||
@@ -41,6 +44,7 @@ impl<'a> TimelineView<'a> {
|
|||||||
img_cache,
|
img_cache,
|
||||||
reverse,
|
reverse,
|
||||||
note_options,
|
note_options,
|
||||||
|
is_muted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +58,7 @@ impl<'a> TimelineView<'a> {
|
|||||||
self.img_cache,
|
self.img_cache,
|
||||||
self.reverse,
|
self.reverse,
|
||||||
self.note_options,
|
self.note_options,
|
||||||
|
self.is_muted,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +78,7 @@ fn timeline_ui(
|
|||||||
img_cache: &mut ImageCache,
|
img_cache: &mut ImageCache,
|
||||||
reversed: bool,
|
reversed: bool,
|
||||||
note_options: NoteOptions,
|
note_options: NoteOptions,
|
||||||
|
is_muted: &MuteFun,
|
||||||
) -> Option<NoteAction> {
|
) -> Option<NoteAction> {
|
||||||
//padding(4.0, ui, |ui| ui.heading("Notifications"));
|
//padding(4.0, ui, |ui| ui.heading("Notifications"));
|
||||||
/*
|
/*
|
||||||
@@ -123,6 +129,7 @@ fn timeline_ui(
|
|||||||
ndb,
|
ndb,
|
||||||
note_cache,
|
note_cache,
|
||||||
img_cache,
|
img_cache,
|
||||||
|
is_muted,
|
||||||
)
|
)
|
||||||
.show(ui)
|
.show(ui)
|
||||||
})
|
})
|
||||||
@@ -224,9 +231,11 @@ pub struct TimelineTabView<'a> {
|
|||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
note_cache: &'a mut NoteCache,
|
note_cache: &'a mut NoteCache,
|
||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
|
is_muted: &'a MuteFun,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TimelineTabView<'a> {
|
impl<'a> TimelineTabView<'a> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
tab: &'a TimelineTab,
|
tab: &'a TimelineTab,
|
||||||
reversed: bool,
|
reversed: bool,
|
||||||
@@ -235,6 +244,7 @@ impl<'a> TimelineTabView<'a> {
|
|||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
note_cache: &'a mut NoteCache,
|
note_cache: &'a mut NoteCache,
|
||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
|
is_muted: &'a MuteFun,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tab,
|
tab,
|
||||||
@@ -244,6 +254,7 @@ impl<'a> TimelineTabView<'a> {
|
|||||||
ndb,
|
ndb,
|
||||||
note_cache,
|
note_cache,
|
||||||
img_cache,
|
img_cache,
|
||||||
|
is_muted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +262,7 @@ impl<'a> TimelineTabView<'a> {
|
|||||||
let mut action: Option<NoteAction> = None;
|
let mut action: Option<NoteAction> = None;
|
||||||
let len = self.tab.notes.len();
|
let len = self.tab.notes.len();
|
||||||
|
|
||||||
|
let is_muted = self.is_muted;
|
||||||
self.tab
|
self.tab
|
||||||
.list
|
.list
|
||||||
.clone()
|
.clone()
|
||||||
@@ -275,17 +287,30 @@ impl<'a> TimelineTabView<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ui::padding(8.0, ui, |ui| {
|
ui::padding(8.0, ui, |ui| {
|
||||||
let resp = ui::NoteView::new(self.ndb, self.note_cache, self.img_cache, ¬e)
|
if let Some(muted_reason) = is_muted(
|
||||||
.note_options(self.note_options)
|
¬e,
|
||||||
.show(ui);
|
root_note_id_from_selected_id(
|
||||||
|
self.ndb,
|
||||||
|
self.note_cache,
|
||||||
|
self.txn,
|
||||||
|
note.id(),
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
ui.colored_label(Color32::RED, format!("MUTED {}", muted_reason));
|
||||||
|
} else {
|
||||||
|
let resp =
|
||||||
|
ui::NoteView::new(self.ndb, self.note_cache, self.img_cache, ¬e)
|
||||||
|
.note_options(self.note_options)
|
||||||
|
.show(ui);
|
||||||
|
|
||||||
if let Some(note_action) = resp.action {
|
if let Some(note_action) = resp.action {
|
||||||
action = Some(note_action)
|
action = Some(note_action)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(context) = resp.context_selection {
|
if let Some(context) = resp.context_selection {
|
||||||
context.process(ui, ¬e);
|
context.process(ui, ¬e);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
ui::hline(ui);
|
ui::hline(ui);
|
||||||
|
|||||||
Reference in New Issue
Block a user