replace global PersonRegistry with per-view person directories
This commit is contained in:
@@ -11,7 +11,7 @@ use gpui::{
|
||||
};
|
||||
use nip29::{Group, GroupEvent, GroupKey, GroupsRegistry, Membership, Pin, Row};
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::PersonRegistry;
|
||||
use person::Directory;
|
||||
use serde::Deserialize;
|
||||
use settings::AppSettings;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
@@ -308,6 +308,8 @@ pub struct GroupPanel {
|
||||
id: SharedString,
|
||||
focus_handle: FocusHandle,
|
||||
group: WeakEntity<Group>,
|
||||
/// Person directory for members, message authors, and activity subjects
|
||||
directory: Entity<Directory>,
|
||||
list_state: ListState,
|
||||
head: Option<EventId>,
|
||||
/// The message the composer is replying to, if any.
|
||||
@@ -356,12 +358,14 @@ impl GroupPanel {
|
||||
subscriptions.push(cx.subscribe(&group, |this, _group, event, cx| {
|
||||
if !matches!(event, GroupEvent::Sent(_)) {
|
||||
this.sync(cx);
|
||||
this.track_participants(cx);
|
||||
cx.notify();
|
||||
}
|
||||
}));
|
||||
|
||||
subscriptions.push(cx.observe(&group, |this, _group, cx| {
|
||||
this.sync(cx);
|
||||
this.track_participants(cx);
|
||||
cx.notify();
|
||||
}));
|
||||
|
||||
@@ -376,10 +380,11 @@ impl GroupPanel {
|
||||
));
|
||||
});
|
||||
|
||||
Self {
|
||||
let mut this = Self {
|
||||
id,
|
||||
focus_handle: cx.focus_handle(),
|
||||
group: group.downgrade(),
|
||||
directory: Directory::new(cx),
|
||||
list_state: ListState::new(count + 2, ListAlignment::Bottom, px(1024.)),
|
||||
head,
|
||||
reply_to: None,
|
||||
@@ -389,7 +394,29 @@ impl GroupPanel {
|
||||
uploading: false,
|
||||
tasks: smallvec![],
|
||||
_subscriptions: subscriptions,
|
||||
}
|
||||
};
|
||||
|
||||
this.track_participants(cx);
|
||||
|
||||
this
|
||||
}
|
||||
|
||||
/// Track the keys rendered by this panel: members, message authors, and
|
||||
/// activity subjects
|
||||
fn track_participants(&mut self, cx: &mut Context<Self>) {
|
||||
let Some(group) = self.group.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let group = group.read(cx);
|
||||
let mut keys: Vec<PublicKey> = group.members().iter().copied().collect();
|
||||
keys.extend(group.rows().iter().map(|row| match row {
|
||||
Row::Message(message) => message.author,
|
||||
Row::Activity(activity) => activity.subject(),
|
||||
}));
|
||||
|
||||
self.directory
|
||||
.update(cx, |directory, cx| directory.track(keys, cx));
|
||||
}
|
||||
|
||||
fn item_count(&self, cx: &App) -> usize {
|
||||
@@ -877,11 +904,13 @@ impl GroupPanel {
|
||||
|
||||
let message = match row {
|
||||
Row::Message(message) => message,
|
||||
Row::Activity(activity) => return message::render_activity(ix, activity, cx),
|
||||
Row::Activity(activity) => {
|
||||
return message::render_activity(ix, activity, &self.directory, cx);
|
||||
}
|
||||
};
|
||||
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let directory = self.directory.clone();
|
||||
|
||||
let content = self
|
||||
.rendered_texts_by_id
|
||||
@@ -891,7 +920,7 @@ impl GroupPanel {
|
||||
&message.content,
|
||||
&message.mentions,
|
||||
&message.emojis,
|
||||
&persons,
|
||||
&directory,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
@@ -916,6 +945,7 @@ impl GroupPanel {
|
||||
panel: cx.weak_entity(),
|
||||
admin,
|
||||
pinned,
|
||||
persons: self.directory.clone(),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
@@ -990,8 +1020,7 @@ impl GroupPanel {
|
||||
let context = self.group.upgrade().and_then(|entity| {
|
||||
entity.read_with(cx, |group, cx| {
|
||||
let message = group.message(target)?;
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let author = persons.read(cx).get(&message.author, cx);
|
||||
let author = self.directory.read(cx).person(&message.author, cx);
|
||||
let preview = message.preview();
|
||||
let line = preview.lines().next().unwrap_or_default().trim();
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ use chat::Message;
|
||||
use common::TimestampExt;
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
AnyElement, App, InteractiveElement, IntoElement, ParentElement, SharedString, Styled,
|
||||
AnyElement, App, Entity, InteractiveElement, IntoElement, ParentElement, SharedString, Styled,
|
||||
WeakEntity, div, px,
|
||||
};
|
||||
use nip29::{Activity, Group, Reaction};
|
||||
use nostr_sdk::prelude::{EventId, Kind};
|
||||
use person::PersonRegistry;
|
||||
use person::{Directory, PersonRegistry};
|
||||
use settings::AppSettings;
|
||||
use state::NostrRegistry;
|
||||
use theme::{ActiveTheme, TextStyle, Typeset as _};
|
||||
@@ -25,6 +25,7 @@ pub(crate) struct Actions {
|
||||
pub panel: WeakEntity<GroupPanel>,
|
||||
pub admin: bool,
|
||||
pub pinned: bool,
|
||||
pub persons: Entity<Directory>,
|
||||
}
|
||||
|
||||
pub(crate) fn render(
|
||||
@@ -37,10 +38,10 @@ pub(crate) fn render(
|
||||
cx: &App,
|
||||
) -> AnyElement {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let hide_avatar = AppSettings::get_hide_avatar(cx);
|
||||
|
||||
let author = persons.read(cx).get(&message.author, cx);
|
||||
let persons = actions.persons.clone();
|
||||
let author = persons.read(cx).person(&message.author, cx);
|
||||
|
||||
let reaction_groups = group_reactions(
|
||||
reactions.iter().map(|reaction| {
|
||||
@@ -66,6 +67,7 @@ pub(crate) fn render(
|
||||
.when(!message.replies_to.is_empty(), |this| {
|
||||
this.children(replies(
|
||||
&message.replies_to,
|
||||
&persons,
|
||||
&actions.group,
|
||||
&actions.panel,
|
||||
cx,
|
||||
@@ -185,9 +187,13 @@ fn react_menu(
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn render_activity(ix: usize, activity: &Activity, cx: &App) -> AnyElement {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let subject = persons.read(cx).get(&activity.subject(), cx);
|
||||
pub(crate) fn render_activity(
|
||||
ix: usize,
|
||||
activity: &Activity,
|
||||
persons: &Entity<Directory>,
|
||||
cx: &App,
|
||||
) -> AnyElement {
|
||||
let subject = persons.read(cx).person(&activity.subject(), cx);
|
||||
let hide_avatar = AppSettings::get_hide_avatar(cx);
|
||||
|
||||
h_flex()
|
||||
@@ -262,6 +268,7 @@ fn action(activity: &Activity) -> String {
|
||||
|
||||
fn replies(
|
||||
targets: &[EventId],
|
||||
persons: &Entity<Directory>,
|
||||
group: &WeakEntity<Group>,
|
||||
panel: &WeakEntity<GroupPanel>,
|
||||
cx: &App,
|
||||
@@ -275,8 +282,7 @@ fn replies(
|
||||
for (ix, id) in targets.iter().enumerate() {
|
||||
let context = entity.read_with(cx, |group, cx| {
|
||||
let message = group.message(*id)?;
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let author = persons.read(cx).get(&message.author, cx);
|
||||
let author = persons.read(cx).person(&message.author, cx);
|
||||
|
||||
Some((author.name(), message.preview()))
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user