add: mark all notifications as read/unread
fix: anonymous avatar/username
This commit is contained in:
parent
37e68079d8
commit
3f6f1eda9f
7 changed files with 118 additions and 10 deletions
|
@ -134,6 +134,8 @@ version = "1.0.0"
|
||||||
"notifs:action.mark_as_unread" = "Mark as unread"
|
"notifs:action.mark_as_unread" = "Mark as unread"
|
||||||
"notifs:action.clear" = "Clear"
|
"notifs:action.clear" = "Clear"
|
||||||
"notifs:label.notifications" = "Notifications"
|
"notifs:label.notifications" = "Notifications"
|
||||||
|
"notifs:label.mark_all_as_read" = "Mark all as read"
|
||||||
|
"notifs:label.mark_all_as_unread" = "Mark all as unread"
|
||||||
|
|
||||||
"settings:tab.general" = "General"
|
"settings:tab.general" = "General"
|
||||||
"settings:tab.account" = "Account"
|
"settings:tab.account" = "Account"
|
||||||
|
|
|
@ -124,7 +124,7 @@ expect_repost=false) -%} {% if community and show_community and community.id !=
|
||||||
config.town_square or question %}
|
config.town_square or question %}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
{% if question -%} {{ self::question(question=question[0],
|
{% if question -%} {{ self::question(question=question[0],
|
||||||
owner=question[1]) }} {% else %}
|
owner=question[1], profile=owner) }} {% else %}
|
||||||
<div class="card small">
|
<div class="card small">
|
||||||
<a
|
<a
|
||||||
href="/api/v1/communities/find/{{ post.community }}"
|
href="/api/v1/communities/find/{{ post.community }}"
|
||||||
|
@ -642,7 +642,7 @@ user %} {% if user.settings.theme_hue -%}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{%- endif %} {%- endmacro %} {% macro question(question, owner,
|
{%- endif %} {%- endmacro %} {% macro question(question, owner,
|
||||||
show_community=true, secondary=false) -%}
|
show_community=true, secondary=false, profile=false) -%}
|
||||||
<div class="card{% if secondary -%} secondary{%- endif %} flex gap-2">
|
<div class="card{% if secondary -%} secondary{%- endif %} flex gap-2">
|
||||||
{% if owner.id == 0 -%}
|
{% if owner.id == 0 -%}
|
||||||
<span>
|
<span>
|
||||||
|
|
|
@ -9,13 +9,43 @@
|
||||||
<span>{{ text "notifs:label.notifications" }}</span>
|
<span>{{ text "notifs:label.notifications" }}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<button
|
<div class="flex gap-2">
|
||||||
onclick="trigger('me::clear_notifs')"
|
<button
|
||||||
class="small red quaternary"
|
onclick="trigger('me::clear_notifs')"
|
||||||
>
|
class="small red quaternary"
|
||||||
{{ icon "bomb" }}
|
>
|
||||||
<span>{{ text "notifs:action.clear" }}</span>
|
{{ icon "bomb" }}
|
||||||
</button>
|
<span>{{ text "notifs:action.clear" }}</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="dropdown">
|
||||||
|
<button
|
||||||
|
class="small quaternary"
|
||||||
|
onclick="trigger('atto::hooks::dropdown', [event])"
|
||||||
|
exclude="dropdown"
|
||||||
|
>
|
||||||
|
{{ icon "ellipsis" }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="inner">
|
||||||
|
<button onclick="mark_all_as_read(true)">
|
||||||
|
{{ icon "bookmark-check" }}
|
||||||
|
<span
|
||||||
|
>{{ text "notifs:label.mark_all_as_read"
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onclick="mark_all_as_read(false)">
|
||||||
|
{{ icon "bookmark-x" }}
|
||||||
|
<span
|
||||||
|
>{{ text "notifs:label.mark_all_as_unread"
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card tertiary flex flex-col gap-4">
|
<div class="card tertiary flex flex-col gap-4">
|
||||||
|
@ -24,4 +54,33 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function mark_all_as_read(read) {
|
||||||
|
if (
|
||||||
|
!(await trigger("atto::confirm", [
|
||||||
|
"Are you sure you want to do this?",
|
||||||
|
]))
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch("/api/v1/notifications/all/read_status", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
read,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => {
|
||||||
|
trigger("atto::toast", [
|
||||||
|
res.ok ? "success" : "error",
|
||||||
|
res.message,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
{%- endif %} {% endfor %} {% for question in questions %}
|
{%- endif %} {% endfor %} {% for question in questions %}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
{{ components::question(question=question[0], owner=question[1]) }}
|
{{ components::question(question=question[0], owner=question[1], profile=user) }}
|
||||||
|
|
||||||
<form
|
<form
|
||||||
class="card flex flex-col gap-2"
|
class="card flex flex-col gap-2"
|
||||||
|
|
|
@ -237,6 +237,10 @@ pub fn routes() -> Router {
|
||||||
"/notifications/{id}/read_status",
|
"/notifications/{id}/read_status",
|
||||||
post(notifications::update_read_status_request),
|
post(notifications::update_read_status_request),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/notifications/all/read_status",
|
||||||
|
post(notifications::update_all_read_status_request),
|
||||||
|
)
|
||||||
// community memberships
|
// community memberships
|
||||||
.route(
|
.route(
|
||||||
"/communities/{id}/join",
|
"/communities/{id}/join",
|
||||||
|
|
|
@ -87,3 +87,24 @@ pub async fn update_read_status_request(
|
||||||
Err(e) => Json(e.into()),
|
Err(e) => Json(e.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn update_all_read_status_request(
|
||||||
|
jar: CookieJar,
|
||||||
|
Extension(data): Extension<State>,
|
||||||
|
Json(req): Json<UpdateNotificationRead>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let data = &(data.read().await).0;
|
||||||
|
let user = match get_user_from_token!(jar, data) {
|
||||||
|
Some(ua) => ua,
|
||||||
|
None => return Json(Error::NotAllowed.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
match data.update_all_notifications_read(&user, req.read).await {
|
||||||
|
Ok(_) => Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Notifications updated".to_string(),
|
||||||
|
payload: (),
|
||||||
|
}),
|
||||||
|
Err(e) => Json(e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -246,4 +246,26 @@ impl DataManager {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn update_all_notifications_read(&self, user: &User, read: bool) -> Result<()> {
|
||||||
|
let notifications = self.get_notifications_by_owner(user.id).await?;
|
||||||
|
|
||||||
|
if notifications.len() > 1000 {
|
||||||
|
return Err(Error::MiscError(
|
||||||
|
"Too many notifications to do this".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
for notification in notifications {
|
||||||
|
if notification.read == read {
|
||||||
|
// no need to update this
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.update_notification_read(notification.id, read, user)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue