Skip to content

Commit

Permalink
Merge branch 'load-more' into unstable
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedilger committed Jan 7, 2024
2 parents 8bc20c4 + 115eece commit af515f9
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 28 deletions.
45 changes: 40 additions & 5 deletions gossip-bin/src/ui/feed/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::theme::FeedProperties;
use super::{widgets, GossipUi, Page};
use eframe::egui;
use egui::{Context, Frame, RichText, Ui, Vec2};
use gossip_lib::comms::ToOverlordMessage;
use gossip_lib::FeedKind;
use gossip_lib::GLOBALS;
use nostr_types::Id;
Expand Down Expand Up @@ -50,6 +51,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram
}

let feed_kind = GLOBALS.feed.get_feed_kind();
let load_more = feed_kind.can_load_more();

match feed_kind {
FeedKind::List(list, with_replies) => {
Expand Down Expand Up @@ -104,7 +106,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram
},
);
ui.add_space(6.0);
render_a_feed(app, ctx, frame, ui, feed, false, &id);
render_a_feed(app, ctx, frame, ui, feed, false, &id, load_more);
}
FeedKind::Inbox(indirect) => {
if app.settings.public_key.is_none() {
Expand Down Expand Up @@ -150,11 +152,11 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram
},
);
ui.add_space(6.0);
render_a_feed(app, ctx, frame, ui, feed, false, id);
render_a_feed(app, ctx, frame, ui, feed, false, id, load_more);
}
FeedKind::Thread { id, .. } => {
if let Some(parent) = GLOBALS.feed.get_thread_parent() {
render_a_feed(app, ctx, frame, ui, vec![parent], true, &id.as_hex_string());
render_a_feed(app, ctx, frame, ui, vec![parent], true, &id.as_hex_string(), load_more);
}
}
FeedKind::Person(pubkey) => {
Expand All @@ -171,7 +173,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram
ui.add_space(6.0);

let feed = GLOBALS.feed.get_person_feed();
render_a_feed(app, ctx, frame, ui, feed, false, &pubkey.as_hex_string());
render_a_feed(app, ctx, frame, ui, feed, false, &pubkey.as_hex_string(), load_more);
}
FeedKind::DmChat(channel) => {
if !GLOBALS.signer.is_ready() {
Expand All @@ -194,7 +196,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram

let feed = GLOBALS.feed.get_dm_chat_feed();
let id = channel.unique_id();
render_a_feed(app, ctx, frame, ui, feed, false, &id);
render_a_feed(app, ctx, frame, ui, feed, false, &id, load_more);
}
}

Expand All @@ -210,6 +212,7 @@ fn render_a_feed(
feed: Vec<Id>,
threaded: bool,
scroll_area_id: &str,
offer_load_more: bool,
) {
let feed_properties = FeedProperties {
is_thread: threaded,
Expand Down Expand Up @@ -242,6 +245,38 @@ fn render_a_feed(
},
);
}

if !feed.is_empty() && offer_load_more {
ui.add_space(50.0);
ui.with_layout(
egui::Layout::top_down(egui::Align::Center)
.with_cross_align(egui::Align::Center),
|ui| {
app.theme.accent_button_1_style(ui.style_mut());
ui.spacing_mut().button_padding.x *= 3.0;
ui.spacing_mut().button_padding.y *= 2.0;
let response = ui.add(egui::Button::new("Load More"));
if response.clicked() {
let _ = GLOBALS
.to_overlord
.send(ToOverlordMessage::LoadMoreCurrentFeed);
}

// draw some nice lines left and right of the button
let stroke = egui::Stroke::new(1.5, ui.visuals().extreme_bg_color);
let width =
(ui.available_width() - response.rect.width()) / 2.0 - 20.0;
let left_start =
response.rect.left_center() - egui::vec2(10.0, 0.0);
let left_end = left_start - egui::vec2(width, 0.0);
ui.painter().line_segment([left_start, left_end], stroke);
let right_start =
response.rect.right_center() + egui::vec2(10.0, 0.0);
let right_end = right_start + egui::vec2(width, 0.0);
ui.painter().line_segment([right_start, right_end], stroke);
},
);
}
});
ui.add_space(100.0);
});
Expand Down
2 changes: 1 addition & 1 deletion gossip-bin/src/ui/settings/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr

ui.horizontal(|ui| {
ui.label("Feed Chunk: ").on_hover_text("This is the amount of time backwards from now that we will load events from. You'll eventually be able to load more, one chunk at a time. Mostly takes effect on restart.");
ui.add(Slider::new(&mut app.settings.feed_chunk, 600..=86400).text("seconds, "));
ui.add(Slider::new(&mut app.settings.feed_chunk, 1800..=43200).text("seconds, "));
ui.label(secs_to_string(app.settings.feed_chunk));
});

Expand Down
13 changes: 12 additions & 1 deletion gossip-lib/src/comms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::dm_channel::DmChannel;
use crate::people::PersonList;
use nostr_types::{
Event, EventAddr, Id, IdHex, Metadata, MilliSatoshi, Profile, PublicKey, RelayUrl, Tag,
UncheckedUrl,
UncheckedUrl, Unixtime,
};
use std::fmt;

Expand Down Expand Up @@ -80,6 +80,9 @@ pub enum ToOverlordMessage {
/// Calls [like](crate::Overlord::like)
Like(Id, PublicKey),

/// Calls [load_more_current_feed](crate::Overlord::load_more_current_feed)
LoadMoreCurrentFeed,

/// internal (minions use this channel too)
MinionJobComplete(RelayUrl, u64),

Expand Down Expand Up @@ -211,6 +214,14 @@ pub(crate) enum ToMinionPayloadDetail {
SubscribePersonFeed(PublicKey),
SubscribeThreadFeed(IdHex, Vec<IdHex>),
SubscribeDmChannel(DmChannel),
TempSubscribeGeneralFeedChunk {
pubkeys: Vec<PublicKey>,
start: Unixtime,
},
TempSubscribePersonFeedChunk {
pubkey: PublicKey,
start: Unixtime,
},
TempSubscribeMetadata(Vec<PublicKey>),
UnsubscribePersonFeed,
UnsubscribeThreadFeed,
Expand Down
51 changes: 47 additions & 4 deletions gossip-lib/src/feed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ impl std::fmt::Display for FeedKind {
}
}

impl FeedKind {
pub fn can_load_more(&self) -> bool {
match self {
&Self::List(_, _) => true,
&Self::Inbox(_) => false, // at the moment
&Self::Thread { .. } => false, // always full
&Self::Person(_) => true,
&Self::DmChat(_) => false, // always full
}
}
}

/// The system that computes feeds as an ordered list of event Ids.
pub struct Feed {
/// Consumers of gossip-lib should only read this, not write to it.
Expand All @@ -58,6 +70,10 @@ pub struct Feed {
person_feed: RwLock<Vec<Id>>,
dm_chat_feed: RwLock<Vec<Id>>,

// When feeds start
general_feed_start: RwLock<Unixtime>,
person_feed_start: RwLock<Unixtime>,

// We only recompute the feed at specified intervals (or when they switch)
interval_ms: RwLock<u32>,
last_computed: RwLock<Option<Instant>>,
Expand All @@ -80,12 +96,40 @@ impl Feed {
inbox_feed: RwLock::new(Vec::new()),
person_feed: RwLock::new(Vec::new()),
dm_chat_feed: RwLock::new(Vec::new()),
general_feed_start: RwLock::new(Unixtime::now().unwrap()),
person_feed_start: RwLock::new(Unixtime::now().unwrap()),
interval_ms: RwLock::new(10000), // Every 10 seconds, until we load from settings
last_computed: RwLock::new(None),
thread_parent: RwLock::new(None),
}
}

/// Done during startup
pub(crate) fn set_feed_starts(
&self,
general_feed_start: Unixtime,
person_feed_start: Unixtime,
) {
*self.general_feed_start.write() = general_feed_start;
*self.person_feed_start.write() = person_feed_start;
}

/// This only looks further back in stored events, it doesn't deal with minion subscriptions.
pub(crate) fn load_more_general_feed(&self) -> Unixtime {
let mut start = *self.general_feed_start.read();
start = start - Duration::from_secs(GLOBALS.storage.read_setting_feed_chunk());
*self.general_feed_start.write() = start;
start
}

/// This only looks further back in stored events, it doesn't deal with minion subscriptions.
pub(crate) fn load_more_person_feed(&self) -> Unixtime {
let mut start = *self.person_feed_start.read();
start = start - Duration::from_secs(GLOBALS.storage.read_setting_person_feed_chunk());
*self.person_feed_start.write() = start;
start
}

fn unlisten(&self) {
let feed_kind = self.current_feed_kind.read().to_owned();

Expand Down Expand Up @@ -311,7 +355,7 @@ impl Feed {
.map(|(pk, _)| pk)
.collect();

let since = now - Duration::from_secs(GLOBALS.storage.read_setting_feed_chunk());
let since: Unixtime = *self.general_feed_start.read();

// FIXME we don't include delegated events. We should look for all events
// delegated to people we follow and include those in the feed too.
Expand Down Expand Up @@ -432,8 +476,7 @@ impl Feed {
}
}
FeedKind::Person(person_pubkey) => {
let since =
now - Duration::from_secs(GLOBALS.storage.read_setting_person_feed_chunk());
let start: Unixtime = *self.person_feed_start.read();

let pphex: PublicKeyHex = person_pubkey.into();

Expand All @@ -452,7 +495,7 @@ impl Feed {
.find_events(
&kinds_without_dms,
&[person_pubkey],
Some(since),
Some(start),
filter,
false,
)?
Expand Down
Loading

0 comments on commit af515f9

Please sign in to comment.