Profiles: notify followers on submission publish

Expose API for paging notifications
This commit is contained in:
asonix 2021-01-23 22:03:39 -06:00
parent a8ef1d4ac9
commit f9596fd743
3 changed files with 78 additions and 0 deletions

View file

@ -146,6 +146,24 @@ impl Action for UpdateSubmission {
let newly_published = !initial_published && submission.published().is_some();
let profile_id = submission.profile_id();
if newly_published {
if let Some(published) = submission.published() {
let ctx_clone = ctx.clone();
ctx.spawn_blocking(move || {
for follower_id in ctx_clone.store.view.follows.forward_iter(profile_id) {
if let Ok(Some(true)) = ctx_clone.store.profiles.is_local(follower_id) {
ctx_clone.store.view.submissions.new(
follower_id,
submission_id,
published,
);
}
}
});
}
}
if ctx.is_local(profile_id)? {
if newly_published {
return Ok(Some(Box::new(crate::apub::results::SubmissionCreated {

View file

@ -330,6 +330,7 @@ impl Store {
let range_end = range_end.as_bytes().to_vec();
this.date_range(..range_end)
})
.rev()
}
pub fn is_local(&self, id: Uuid) -> Result<Option<bool>, StoreError> {

View file

@ -301,6 +301,60 @@ impl NotificationStore {
.values()
.filter_map(|res| res.ok())
.filter_map(uuid_from_ivec)
.rev()
}
pub fn older_than_for_profile<'a>(
&'a self,
profile_id: Uuid,
notification_id: Uuid,
) -> impl DoubleEndedIterator<Item = Uuid> + 'a {
let keys = self.keys();
self.dates
.get(keys.date_key(profile_id, notification_id))
.ok()
.and_then(|opt| opt)
.and_then(date_from_ivec)
.into_iter()
.flat_map(move |date| {
let keys = keys.clone();
self.notifications
.range(
..keys
.notification_key(profile_id, date, notification_id)
.as_bytes(),
)
.values()
.filter_map(|res| res.ok())
.filter_map(uuid_from_ivec)
})
.rev()
}
pub fn newer_than_for_profile<'a>(
&'a self,
profile_id: Uuid,
notification_id: Uuid,
) -> impl DoubleEndedIterator<Item = Uuid> + 'a {
let keys = self.keys();
self.dates
.get(keys.date_key(profile_id, notification_id))
.ok()
.and_then(|opt| opt)
.and_then(date_from_ivec)
.into_iter()
.flat_map(move |date| {
self.notifications
.range(
keys.notification_key(profile_id, date, notification_id)
.as_bytes()..,
)
.values()
.filter_map(|res| res.ok())
.filter_map(uuid_from_ivec)
})
}
fn notification_keys(&self, profile_id: Uuid) -> impl DoubleEndedIterator<Item = sled::IVec> {
@ -337,3 +391,8 @@ fn uuid_from_ivec(ivec: sled::IVec) -> Option<Uuid> {
.map_err(|e| log::warn!("Failed to parse ivec {}", e))
.ok()
}
fn date_from_ivec(ivec: sled::IVec) -> Option<DateTime<Utc>> {
let s = String::from_utf8_lossy(&ivec);
s.parse().ok()
}