mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
automatic updating notifications
This commit is contained in:
parent
7be7ca8303
commit
e39a8eeccc
8 changed files with 43 additions and 30 deletions
|
@ -8,7 +8,6 @@ import { $ } from './utils/dom';
|
|||
import { fetchHtml, handleError } from './utils/requests';
|
||||
import { showBlock } from './utils/image';
|
||||
import { addTag } from './tagsinput';
|
||||
import { markRead } from './notifications';
|
||||
|
||||
// Event types and any qualifying conditions - return true to not run action
|
||||
const types = {
|
||||
|
@ -30,7 +29,8 @@ const actions = {
|
|||
|
||||
disable(data) { selectorCb(data.base, data.value, el => el.disabled = true); },
|
||||
|
||||
copy(data) { document.querySelector(data.value).select(); document.execCommand('copy'); },
|
||||
copy(data) { document.querySelector(data.value).select();
|
||||
document.execCommand('copy'); },
|
||||
|
||||
inputvalue(data) { document.querySelector(data.value).value = data.el.dataset.setValue; },
|
||||
|
||||
|
@ -46,8 +46,8 @@ const actions = {
|
|||
|
||||
tab(data) {
|
||||
const block = data.el.parentNode.parentNode,
|
||||
newTab = $(`.block__tab[data-tab="${data.value}"]`),
|
||||
loadTab = data.el.dataset.loadTab;
|
||||
newTab = $(`.block__tab[data-tab="${data.value}"]`),
|
||||
loadTab = data.el.dataset.loadTab;
|
||||
|
||||
// Switch tab
|
||||
const selectedTab = block.querySelector('.selected');
|
||||
|
@ -74,8 +74,6 @@ const actions = {
|
|||
|
||||
unfilter(data) { showBlock(data.el.closest('.image-show-container')); },
|
||||
|
||||
markRead,
|
||||
|
||||
};
|
||||
|
||||
// Use this function to apply a callback to elements matching the selectors
|
||||
|
@ -87,9 +85,9 @@ function matchAttributes(event) {
|
|||
if (!types[event.type](event)) {
|
||||
for (const action in actions) {
|
||||
|
||||
const attr = `data-${event.type}-${action.toLowerCase()}`,
|
||||
el = event.target && event.target.closest(`[${attr}]`),
|
||||
value = el && el.getAttribute(attr);
|
||||
const attr = `data-${event.type}-${action.toLowerCase()}`,
|
||||
el = event.target && event.target.closest(`[${attr}]`),
|
||||
value = el && el.getAttribute(attr);
|
||||
|
||||
if (el) {
|
||||
// Return true if you don't want to preventDefault
|
||||
|
@ -104,4 +102,4 @@ function registerEvents() {
|
|||
for (const type in types) document.addEventListener(type, matchAttributes);
|
||||
}
|
||||
|
||||
export { registerEvents };
|
||||
export { registerEvents };
|
|
@ -3,18 +3,17 @@
|
|||
*/
|
||||
|
||||
import { fetchJson, handleError } from './utils/requests';
|
||||
import { $, $$, hideEl, toggleEl } from './utils/dom';
|
||||
import { $ } from './utils/dom';
|
||||
import { delegate } from './utils/events';
|
||||
import store from './utils/store';
|
||||
|
||||
const NOTIFICATION_INTERVAL = 600000,
|
||||
NOTIFICATION_EXPIRES = 300000;
|
||||
NOTIFICATION_EXPIRES = 300000;
|
||||
|
||||
function makeRequest(verb, action, body) {
|
||||
return fetchJson(verb, `${window.booru.apiEndpoint}notifications/${action}.json`, body).then(handleError);
|
||||
function makeRequest(verb) {
|
||||
return fetchJson(verb, '/notifications/unread').then(handleError);
|
||||
}
|
||||
|
||||
|
||||
function bindSubscriptionLinks() {
|
||||
delegate(document, 'fetchcomplete', {
|
||||
'.js-subscription-link': event => {
|
||||
|
@ -26,28 +25,17 @@ function bindSubscriptionLinks() {
|
|||
});
|
||||
}
|
||||
|
||||
function markRead(data) {
|
||||
const notificationId = data.value;
|
||||
const notification = $(`.js-notification-id-${notificationId}`);
|
||||
|
||||
makeRequest('PUT', 'mark_read', { id: notificationId })
|
||||
.then(() => hideEl(notification))
|
||||
.catch(() => data.el.textContent = 'Error!');
|
||||
}
|
||||
|
||||
|
||||
function getNewNotifications() {
|
||||
if (document.hidden || !store.hasExpired('notificationCount')) {
|
||||
return;
|
||||
}
|
||||
|
||||
makeRequest('GET', 'unread').then(response => response.json()).then(({ data }) => {
|
||||
updateNotificationTicker(data.length);
|
||||
storeNotificationCount(data.length);
|
||||
makeRequest('GET').then(response => response.json()).then(({ notifications }) => {
|
||||
updateNotificationTicker(notifications);
|
||||
storeNotificationCount(notifications);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function updateNotificationTicker(notificationCount) {
|
||||
const ticker = $('.js-notification-ticker');
|
||||
const parsedNotificationCount = Number(notificationCount);
|
||||
|
@ -78,4 +66,4 @@ function setupNotifications() {
|
|||
bindSubscriptionLinks();
|
||||
}
|
||||
|
||||
export { setupNotifications, markRead };
|
||||
export { setupNotifications };
|
|
@ -1,6 +1,7 @@
|
|||
defmodule PhilomenaWeb.ConversationController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias PhilomenaWeb.NotificationCountPlug
|
||||
alias Philomena.{Conversations, Conversations.Conversation, Conversations.Message}
|
||||
alias Philomena.Textile.Renderer
|
||||
alias Philomena.Repo
|
||||
|
@ -47,6 +48,9 @@ defmodule PhilomenaWeb.ConversationController do
|
|||
conversation
|
||||
|> Conversations.mark_conversation_read(user)
|
||||
|
||||
# Update the conversation ticker in the header
|
||||
conn = NotificationCountPlug.call(conn)
|
||||
|
||||
render(conn, "show.html", conversation: conversation, messages: messages, changeset: changeset)
|
||||
end
|
||||
|
||||
|
|
|
@ -33,6 +33,9 @@ defmodule PhilomenaWeb.ImageController do
|
|||
|
||||
Images.clear_notification(image, user)
|
||||
|
||||
# Update the notification ticker in the header
|
||||
conn = NotificationCountPlug.call(conn)
|
||||
|
||||
comments =
|
||||
Comment
|
||||
|> where(image_id: ^image.id)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
defmodule PhilomenaWeb.Notification.UnreadController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
def index(conn, _params) do
|
||||
json(conn, %{
|
||||
notifications: conn.assigns.notification_count,
|
||||
conversations: conn.assigns.conversation_count
|
||||
})
|
||||
end
|
||||
end
|
|
@ -27,6 +27,9 @@ defmodule PhilomenaWeb.TopicController do
|
|||
Topics.clear_notification(topic, user)
|
||||
Forums.clear_notification(forum, user)
|
||||
|
||||
# Update the notification ticker in the header
|
||||
conn = NotificationCountPlug.call(conn)
|
||||
|
||||
conn = conn |> assign(:topic, topic)
|
||||
%{page_number: page} = conn.assigns.pagination
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@ defmodule PhilomenaWeb.NotificationCountPlug do
|
|||
@spec init(any()) :: any()
|
||||
def init(opts), do: opts
|
||||
|
||||
@doc false
|
||||
@spec call(Plug.Conn.t()) :: Plug.Conn.t()
|
||||
def call(conn), do: call(conn, nil)
|
||||
|
||||
@doc false
|
||||
@spec call(Plug.Conn.t(), any()) :: Plug.Conn.t()
|
||||
def call(conn, _opts) do
|
||||
|
|
|
@ -75,6 +75,9 @@ defmodule PhilomenaWeb.Router do
|
|||
scope "/", PhilomenaWeb do
|
||||
pipe_through [:browser, :ensure_totp, :protected]
|
||||
|
||||
scope "/notifications", Notification, as: :notification do
|
||||
resources "/unread", UnreadController, only: [:index]
|
||||
end
|
||||
resources "/notifications", NotificationController, only: [:index, :delete]
|
||||
resources "/conversations", ConversationController, only: [:index, :show, :new, :create] do
|
||||
resources "/messages", Conversation.MessageController, only: [:create]
|
||||
|
|
Loading…
Reference in a new issue