Merge remote-tracking branch 'dilger/unstable' into feature/pending-notifications

# Conflicts:
#	gossip-bin/src/ui/widgets/mod.rs
This commit is contained in:
Bu5hm4nn 2024-03-28 20:24:34 -06:00
commit 233d970596
18 changed files with 503 additions and 514 deletions

850
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -25,13 +25,13 @@ egui-winit = { git = "https://github.com/bu5hm4nn/egui", rev = "63dde4c9b311da0c
egui_extras = { git = "https://github.com/bu5hm4nn/egui", rev = "63dde4c9b311da0cae0cb9f9465bf7273227be6c", features = [ "syntect" ] }
#egui = { git = "https://github.com/bu5hm4nn/egui", rev = "63dde4c9b311da0cae0cb9f9465bf7273227be6c", features = [ "deadlock_detection" ] }
egui-video = { git = "https://github.com/mikedilger/egui-video", rev = "813192e17f5c0eed9bed6e78f40697ac0ff77639", features = [ "from_bytes" ], optional = true }
gossip-relay-picker = { git = "https://github.com/mikedilger/gossip-relay-picker", rev = "19d87ab9abf40ba9a7fa36e6d060ee38808c30e7" }
gossip-relay-picker = { git = "https://github.com/mikedilger/gossip-relay-picker", rev = "96680eb6cfd8ebda8e8fb3e69656a650d9ece850" }
gossip-lib = { path = "../gossip-lib" }
humansize = "2.1"
image = { version = "0.24.6", features = [ "png", "jpeg" ] }
lazy_static = "1.4"
memoize = "0.4"
nostr-types = { git = "https://github.com/mikedilger/nostr-types", rev = "265e6d15bd295ca60d3699bc7a7c64eaed86b429", features = [ "speedy" ] }
nostr-types = { git = "https://github.com/mikedilger/nostr-types", rev = "120c900b16a2f05182c7d716e78f44b081ef07da", features = [ "speedy" ] }
paste = "1.0"
qrcode = { git = "https://github.com/mikedilger/qrcode-rust", rev = "519b77b3efa3f84961169b47d3de08c5ddd86548" }
resvg = "0.35.0"

View File

@ -86,5 +86,7 @@ fn main() -> Result<(), Error> {
// Wait for the async thread to complete
async_thread.join().unwrap();
tracing::info!("Gossip end.");
Ok(())
}

View File

@ -303,7 +303,7 @@ pub fn render_note_inner(
ui.horizontal_wrapped(|ui| {
match note.event.replies_to() {
Some(EventReference::Id(irt, _, _)) => {
Some(EventReference::Id { id: irt, .. }) => {
ui.add_space(8.0);
ui.style_mut().override_text_style = Some(TextStyle::Small);
let idhex: IdHex = irt.into();
@ -1152,7 +1152,7 @@ fn render_content(
);
} else {
match event.mentions().first() {
Some(EventReference::Id(id, _, _)) => {
Some(EventReference::Id { id, .. }) => {
if let Some(note_data) = app.notes.try_update_and_get(id) {
// TODO block additional repost recursion
render_repost(

View File

@ -15,9 +15,8 @@ use eframe::egui::Galley;
use egui_winit::egui::text::LayoutJob;
use egui_winit::egui::text_edit::TextEditOutput;
use egui_winit::egui::{
self, vec2, Align, FontSelection, Rect, Response, RichText, Sense, Ui, WidgetText,
self, vec2, Align, FontSelection, Rect, Response, RichText, Rounding, Sense, Ui, WidgetText,
};
use crate::ui::egui::Rounding;
pub use nav_item::NavItem;
mod relay_entry;

View File

@ -50,7 +50,7 @@ fallible-iterator = "0.2"
filetime = "0.2"
futures = "0.3"
futures-util = "0.3"
gossip-relay-picker = { git = "https://github.com/mikedilger/gossip-relay-picker", rev = "19d87ab9abf40ba9a7fa36e6d060ee38808c30e7" }
gossip-relay-picker = { git = "https://github.com/mikedilger/gossip-relay-picker", rev = "96680eb6cfd8ebda8e8fb3e69656a650d9ece850" }
heed = { git = "https://github.com/meilisearch/heed", rev = "64fd6fec293c0dee94855b8267557ce03e7ce5d8" }
hex = "0.4"
http = "1.0"
@ -59,7 +59,7 @@ kamadak-exif = "0.5"
lazy_static = "1.4"
linkify = "0.9"
mime = "0.3"
nostr-types = { git = "https://github.com/mikedilger/nostr-types", rev = "265e6d15bd295ca60d3699bc7a7c64eaed86b429", features = [ "speedy" ] }
nostr-types = { git = "https://github.com/mikedilger/nostr-types", rev = "120c900b16a2f05182c7d716e78f44b081ef07da", features = [ "speedy" ] }
parking_lot = "0.12"
paste = "1.0"
rand = "0.8"

View File

@ -257,7 +257,7 @@ pub(crate) enum ToMinionPayloadDetail {
SubscribeGeneralFeed(Vec<PublicKey>),
SubscribeInbox,
SubscribePersonFeed(PublicKey),
SubscribeThreadFeed(IdHex, Vec<IdHex>),
SubscribeReplies(IdHex),
SubscribeDmChannel(DmChannel),
SubscribeNip46,
TempSubscribeGeneralFeedChunk(Unixtime),
@ -265,7 +265,7 @@ pub(crate) enum ToMinionPayloadDetail {
TempSubscribeInboxFeedChunk(Unixtime),
TempSubscribeMetadata(Vec<PublicKey>),
UnsubscribePersonFeed,
UnsubscribeThreadFeed,
UnsubscribeReplies,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]

View File

@ -150,7 +150,7 @@ impl Feed {
target: "all".to_string(),
payload: ToMinionPayload {
job_id: 0,
detail: ToMinionPayloadDetail::UnsubscribeThreadFeed,
detail: ToMinionPayloadDetail::UnsubscribeReplies,
},
});
}
@ -434,7 +434,7 @@ impl Feed {
// Include if it directly replies to one of my events
match e.replies_to() {
Some(EventReference::Id(id, _url, _marker)) => {
Some(EventReference::Id { id, .. }) => {
if my_event_ids.contains(&id) {
return true;
}

View File

@ -75,6 +75,14 @@ impl Fetcher {
}
pub(crate) fn start() {
// Initialize if not already
if GLOBALS.fetcher.client.read().unwrap().is_none() {
if let Err(e) = Self::init() {
tracing::error!("Fetcher failed to initialize: {e}");
return;
}
}
// Setup periodic queue management
tokio::task::spawn(async move {
let mut read_runstate = GLOBALS.read_runstate.clone();

View File

@ -175,23 +175,11 @@ pub fn person_feed(pubkey: PublicKey, since: Unixtime, until: Option<Unixtime>)
}]
}
pub fn thread(main: IdHex, ancestors: &[IdHex], spamsafe: bool) -> Vec<Filter> {
// ancestors can be done with FetchEvent, FetchEventAddr
pub fn replies(main: IdHex, spamsafe: bool) -> Vec<Filter> {
let mut filters: Vec<Filter> = Vec::new();
if !ancestors.is_empty() {
// We allow spammy ancestors since a descendant is sought, so spamsafe
// isn't relevant to these ancestor filters
// Get ancestors we know of so far
filters.push(Filter {
ids: ancestors.to_vec(),
..Default::default()
});
// NOTE: we do not need to query for reactions to ancestors anymore.
// We now use 'visible notes' to periodically update augmentation subscriptions
}
// Allow all feed related event kinds (excluding DMs)
let event_kinds = crate::feed::feed_displayable_event_kinds(false);

View File

@ -336,8 +336,8 @@ impl Minion {
ping_timer.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
ping_timer.tick().await; // use up the first immediate tick.
// Periodic Task timer (3 sec)
let mut task_timer = tokio::time::interval(std::time::Duration::new(3, 0));
// Periodic Task timer (1.5 sec)
let mut task_timer = tokio::time::interval(std::time::Duration::new(1, 500_000_000));
task_timer.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
task_timer.tick().await; // use up the first immediate tick.
@ -565,9 +565,8 @@ impl Minion {
ToMinionPayloadDetail::SubscribePersonFeed(pubkey) => {
self.subscribe_person_feed(message.job_id, pubkey).await?;
}
ToMinionPayloadDetail::SubscribeThreadFeed(main, parents) => {
self.subscribe_thread_feed(message.job_id, main, parents)
.await?;
ToMinionPayloadDetail::SubscribeReplies(main) => {
self.subscribe_replies(message.job_id, main).await?;
}
ToMinionPayloadDetail::SubscribeDmChannel(dmchannel) => {
self.subscribe_dm_channel(message.job_id, dmchannel).await?;
@ -594,8 +593,8 @@ impl Minion {
ToMinionPayloadDetail::UnsubscribePersonFeed => {
self.unsubscribe("person_feed").await?;
}
ToMinionPayloadDetail::UnsubscribeThreadFeed => {
self.unsubscribe("thread_feed").await?;
ToMinionPayloadDetail::UnsubscribeReplies => {
self.unsubscribe("replies").await?;
}
}
@ -860,19 +859,13 @@ impl Minion {
Ok(())
}
async fn subscribe_thread_feed(
&mut self,
job_id: u64,
main: IdHex,
ancestor_ids: Vec<IdHex>,
) -> Result<(), Error> {
async fn subscribe_replies(&mut self, job_id: u64, main: IdHex) -> Result<(), Error> {
// NOTE we do not unsubscribe to the general feed
// Replies
let spamsafe = self.dbrelay.has_usage_bits(Relay::SPAMSAFE);
let filters = filter_fns::thread(main, &ancestor_ids, spamsafe);
self.subscribe(filters, "thread_feed", job_id).await?;
let filters = filter_fns::replies(main, spamsafe);
self.subscribe(filters, "replies", job_id).await?;
Ok(())
}

View File

@ -173,9 +173,6 @@ impl Overlord {
.feed
.set_feed_starts(general_feed_start, person_feed_start, inbox_feed_start);
// Init the fetcher
crate::fetcher::Fetcher::init()?;
// Switch out of initializing RunState
if GLOBALS.storage.read_setting_offline() {
let _ = GLOBALS.write_runstate.send(RunState::Offline);
@ -1942,12 +1939,17 @@ impl Overlord {
// Possibly add a tag to the 'root'
let mut parent_is_root = true;
match parent.replies_to_root() {
Some(EventReference::Id(root, maybeurl, _marker)) => {
Some(EventReference::Id {
id: root,
author: _,
mut relays,
marker: _,
}) => {
// Add an 'e' tag for the root
add_event_to_tags(
&mut tags,
root,
maybeurl.map(|u| u.to_unchecked_url()),
relays.pop().map(|u| u.to_unchecked_url()),
"root",
)
.await;
@ -2749,11 +2751,14 @@ impl Overlord {
// Use relay hints in 'e' tags
for eref in highest_parent.referred_events() {
match eref {
EventReference::Id(id, opturl, _marker) => {
EventReference::Id {
id,
author: _,
relays: tagrelays,
marker: _,
} => {
missing_ancestors.push(id);
if let Some(url) = opturl {
relays.push(url);
}
relays.extend(tagrelays);
}
EventReference::Addr(_ea) => {
// FIXME - we should subscribe to these too
@ -2762,10 +2767,8 @@ impl Overlord {
}
}
let mut missing_ancestors_hex: Vec<IdHex> =
missing_ancestors.iter().map(|id| (*id).into()).collect();
missing_ancestors_hex.sort_by(|a, b| a.as_str().cmp(b.as_str()));
missing_ancestors_hex.dedup();
missing_ancestors.sort();
missing_ancestors.dedup();
// Subscribe on relays
if relays.is_empty() {
@ -2784,26 +2787,34 @@ impl Overlord {
target: "all".to_string(),
payload: ToMinionPayload {
job_id: 0,
detail: ToMinionPayloadDetail::UnsubscribeThreadFeed,
detail: ToMinionPayloadDetail::UnsubscribeReplies,
},
});
for url in relays.iter() {
// Subscribe
self.engage_minion(
url.to_owned(),
vec![RelayJob {
let mut jobs: Vec<RelayJob> = vec![];
// Subscribe ancestors
for ancestor_id in missing_ancestors.drain(..) {
jobs.push(RelayJob {
reason: RelayConnectionReason::ReadThread,
payload: ToMinionPayload {
job_id: rand::random::<u64>(),
detail: ToMinionPayloadDetail::SubscribeThreadFeed(
id.into(),
missing_ancestors_hex.clone(),
),
detail: ToMinionPayloadDetail::FetchEvent(ancestor_id),
},
}],
)
.await?;
});
}
// Subscribe replies
jobs.push(RelayJob {
reason: RelayConnectionReason::ReadThread,
payload: ToMinionPayload {
job_id: rand::random::<u64>(),
detail: ToMinionPayloadDetail::SubscribeReplies(id.into()),
},
});
self.engage_minion(url.to_owned(), jobs).await?;
}
}

View File

@ -295,7 +295,7 @@ pub fn start() {
task::spawn(async {
let mut read_runstate = GLOBALS.read_runstate.clone();
read_runstate.mark_unchanged();
if !read_runstate.borrow().going_online() {
if read_runstate.borrow().going_offline() {
return;
}
@ -307,7 +307,7 @@ pub fn start() {
_ = &mut sleep => {
sleep.as_mut().reset(Instant::now() + Duration::from_secs(15));
},
_ = read_runstate.wait_for(|runstate| !runstate.going_online()) => break,
_ = read_runstate.wait_for(|runstate| runstate.going_offline()) => break,
}
match GLOBALS.pending.compute_pending() {

View File

@ -78,7 +78,7 @@ impl People {
task::spawn(async {
let mut read_runstate = GLOBALS.read_runstate.clone();
read_runstate.mark_unchanged();
if !read_runstate.borrow().going_online() {
if read_runstate.borrow().going_offline() {
return;
}
@ -95,7 +95,7 @@ impl People {
GLOBALS.storage.read_setting_fetcher_metadata_looptime_ms();
sleep.as_mut().reset(Instant::now() + Duration::from_millis(fetch_metadata_looptime_ms));
},
_ = read_runstate.wait_for(|runstate| !runstate.going_online()) => break,
_ = read_runstate.wait_for(|runstate| runstate.going_offline()) => break,
}
// We fetch needed metadata

View File

@ -316,15 +316,13 @@ pub async fn process_new_event(
// If the content is a repost, seek the event it reposts
for eref in event.mentions().iter() {
match eref {
EventReference::Id(id, optrelay, _marker) => {
if let Some(rurl) = optrelay {
GLOBALS
.seeker
.seek_id_and_relays(*id, vec![rurl.to_owned()]);
} else {
EventReference::Id { id, relays, .. } => {
if relays.is_empty() {
// Even if the event tags the author, we have no way to coorelate
// the nevent with that tag.
GLOBALS.seeker.seek_id(*id);
} else {
GLOBALS.seeker.seek_id_and_relays(*id, relays.clone());
}
}
EventReference::Addr(ea) => {
@ -488,7 +486,7 @@ pub(crate) fn process_relationships_of_event<'a>(
let mut f = |txn: &mut RwTxn<'a>| -> Result<(), Error> {
// replies to
match event.replies_to() {
Some(EventReference::Id(id, _, _)) => {
Some(EventReference::Id { id, .. }) => {
GLOBALS.storage.write_relationship_by_id(
id,
event.id,
@ -525,7 +523,7 @@ pub(crate) fn process_relationships_of_event<'a>(
if let Some((vec, reason)) = event.deletes() {
for er in vec.iter() {
match er {
EventReference::Id(id, _, _) => {
EventReference::Id { id, .. } => {
// If we have the event,
// Actually delete at this point in some cases
if let Some(deleted_event) = GLOBALS.storage.read_event(*id)? {

View File

@ -46,7 +46,7 @@ impl Storage {
) -> Result<(), Error> {
// replies to
match event.replies_to() {
Some(EventReference::Id(id, _, _)) => {
Some(EventReference::Id { id, .. }) => {
self.write_relationship1(id, event.id, Relationship1::Reply, Some(txn))?;
}
Some(EventReference::Addr(_ea)) => {

View File

@ -1803,7 +1803,7 @@ impl Storage {
};
match event.replies_to() {
Some(EventReference::Id(parent_id, _opturl, _marker)) => {
Some(EventReference::Id { id: parent_id, .. }) => {
self.get_highest_local_parent_event_id(parent_id)
}
Some(EventReference::Addr(ea)) => {

2
run.sh
View File

@ -2,5 +2,5 @@
#RUSTFLAGS="-C target-cpu=native --cfg tokio_unstable"
cargo build --features=lang-cjk,video-ffmpeg --release && \
RUST_BACKTRACE=1 RUST_LOG="warn,gossip_bin=info,gossip_lib=info,nostr_types=info,gossip_relay_picker=info" ./target/release/gossip "$@"
RUST_BACKTRACE=1 RUST_LOG="warn,gossip=info,gossip_lib=info,nostr_types=info,gossip_relay_picker=info" ./target/release/gossip "$@"