Profiles: notify followers on submission publish
Expose API for paging notifications
This commit is contained in:
parent
a8ef1d4ac9
commit
f9596fd743
|
@ -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 {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue