Merge pull request #808 from basecamp/update-badge-counts
Update badge counts clientside
This commit is contained in:
@@ -28,8 +28,8 @@ module NotificationsHelper
|
||||
tag.div id: dom_id(notification), class: "tray__item" do
|
||||
concat(
|
||||
link_to(notification,
|
||||
class: [ "card card--notification", { "card--closed": notification.card.closed? } ],
|
||||
data: { turbo_frame: "_top" },
|
||||
class: [ "card card--notification", { "card--closed": notification.card.closed? }, { "unread": !notification.read? } ],
|
||||
data: { turbo_frame: "_top", badge_target: "unread", action: "badge#update" },
|
||||
style: { "--card-color:": notification.card.color },
|
||||
&)
|
||||
)
|
||||
@@ -42,7 +42,7 @@ module NotificationsHelper
|
||||
method: :delete,
|
||||
class: "card__notification-unread-indicator btn btn--circle borderless",
|
||||
title: "Mark as unread",
|
||||
data: { action: "form#submit:stop", form_target: "submit" },
|
||||
data: { action: "form#submit:stop badge#update:stop", form_target: "submit" },
|
||||
form: { data: { controller: "form" } } do
|
||||
concat(icon_tag("unseen"))
|
||||
concat(tag.span("Mark as unread", class: "for-screen-reader"))
|
||||
@@ -51,7 +51,7 @@ module NotificationsHelper
|
||||
button_to read_notification_path(notification),
|
||||
class: "card__notification-unread-indicator btn btn--circle borderless",
|
||||
title: "Mark as read",
|
||||
data: { action: "form#submit:stop", form_target: "submit" },
|
||||
data: { action: "form#submit:stop badge#update:stop", form_target: "submit" },
|
||||
form: { data: { controller: "form" } } do
|
||||
concat(icon_tag("remove-med"))
|
||||
concat(tag.span("Mark as read", class: "for-screen-reader"))
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
import { onNextEventLoopTick } from "helpers/timing_helpers"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = [ "unread" ]
|
||||
static classes = [ "unread" ]
|
||||
|
||||
connect() {
|
||||
onNextEventLoopTick(() => this.update())
|
||||
}
|
||||
|
||||
update() {
|
||||
onNextEventLoopTick(() => {
|
||||
if (this.#available) {
|
||||
const unreadCount = this.#unreadCount
|
||||
|
||||
if (unreadCount > 0) {
|
||||
navigator.setAppBadge(unreadCount)
|
||||
} else {
|
||||
navigator.clearAppBadge()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
clear() {
|
||||
onNextEventLoopTick(() => {
|
||||
if (this.#available) {
|
||||
navigator.clearAppBadge()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get #unreadCount() {
|
||||
return this.unreadTargets.filter(unreadTarget => unreadTarget.classList.contains(this.unreadClass)).length
|
||||
}
|
||||
|
||||
get #available() {
|
||||
return "setAppBadge" in navigator
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<%= turbo_stream_from Current.user, :notifications %>
|
||||
|
||||
<section class="tray tray--notifications" data-controller="dialog">
|
||||
<section class="tray tray--notifications" data-controller="dialog badge" data-badge-unread-class="unread" data-action="turbo:render#update">
|
||||
<dialog class="tray__dialog"
|
||||
data-dialog-modal-value="false" data-dialog-target="dialog"
|
||||
data-action="keydown.esc->dialog#close:stop click@document->dialog#closeOnClickOutside">
|
||||
@@ -10,7 +10,7 @@
|
||||
<%= link_to settings_notifications_path,
|
||||
class: "btn borderless tray__notification-settings",
|
||||
title: "Notification settings",
|
||||
data: { action: "click->dialog#close" } do %>
|
||||
data: { action: "dialog#close" } do %>
|
||||
<%= icon_tag "settings" %>
|
||||
<span class="translucent">Settings</span>
|
||||
<% end %>
|
||||
@@ -28,7 +28,7 @@
|
||||
<%= button_to read_all_notifications_path,
|
||||
class: "btn borderless tray__clear-notifications",
|
||||
title: "Mark all notifications as read",
|
||||
data: { action: "click->dialog#close", turbo_frame: "notifications" } do %>
|
||||
data: { action: "dialog#close badge#clear", turbo_frame: "notifications" } do %>
|
||||
<%= icon_tag "check" %>
|
||||
<span class="translucent">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
@@ -17,29 +17,31 @@
|
||||
</nav>
|
||||
<% end %>
|
||||
|
||||
<section class="notifications-list panel center borderless unpad flex flex-column gap-half">
|
||||
<% if @unread.any? %>
|
||||
<div class="flex align-center justify-space-between margin-block-start margin-block-end-half">
|
||||
<h2 class="txt-medium txt-uppercase txt-alert">New for you</h2>
|
||||
<%= button_to "Mark all as read", read_all_notifications_path, class: "btn txt-small", form: { data: { turbo: false } } %>
|
||||
<div data-controller="badge" data-badge-unread-class="unread">
|
||||
<section class="notifications-list panel center borderless unpad flex flex-column gap-half">
|
||||
<% if @unread.any? %>
|
||||
<div class="flex align-center justify-space-between margin-block-start margin-block-end-half">
|
||||
<h2 class="txt-medium txt-uppercase txt-alert">New for you</h2>
|
||||
<%= button_to "Mark all as read", read_all_notifications_path, class: "btn txt-small", form: { data: { turbo: false } }, data: { action: "badge#clear" } %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="notifications-list__empty-message pad border-radius border translucent" style="--border-style: dashed; --border-color: var(--color-ink); --border-radius: 0.2em;">
|
||||
<strong>Nothing new for you.</strong>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div id="notifications_list" contents>
|
||||
<%= render partial: "notifications/notification", collection: @unread, cached: true %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="notifications-list__empty-message pad border-radius border translucent" style="--border-style: dashed; --border-color: var(--color-ink); --border-radius: 0.2em;">
|
||||
<strong>Nothing new for you.</strong>
|
||||
</section>
|
||||
|
||||
<section class="notifications-list notifications-list--read panel center borderless unpad flex flex-column gap-half margin-block-start">
|
||||
<h2 class="txt-medium margin-block-start-double margin-block-end-half txt-uppercase translucent">Previously seen</h2>
|
||||
|
||||
<div id="notifications_list_read" contents>
|
||||
<%= render partial: "notifications/notification", collection: @page.records, cached: true %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div id="notifications_list" contents>
|
||||
<%= render partial: "notifications/notification", collection: @unread, cached: true %>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="notifications-list notifications-list--read panel center borderless unpad flex flex-column gap-half margin-block-start">
|
||||
<h2 class="txt-medium margin-block-start-double margin-block-end-half txt-uppercase translucent">Previously seen</h2>
|
||||
|
||||
<div id="notifications_list_read" contents>
|
||||
<%= render partial: "notifications/notification", collection: @page.records, cached: true %>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<%= notifications_next_page_link(@page) if @page.records.any? %>
|
||||
|
||||
Reference in New Issue
Block a user