Cache inbox and notification counters
This commit is contained in:
parent
febcf42b61
commit
1ec5ffa6d2
|
@ -4,30 +4,6 @@ module ApplicationHelper
|
||||||
include ApplicationHelper::GraphMethods
|
include ApplicationHelper::GraphMethods
|
||||||
include ApplicationHelper::TitleMethods
|
include ApplicationHelper::TitleMethods
|
||||||
|
|
||||||
def inbox_count
|
|
||||||
return 0 unless user_signed_in?
|
|
||||||
|
|
||||||
count = Inbox.select("COUNT(id) AS count")
|
|
||||||
.where(new: true)
|
|
||||||
.where(user_id: current_user.id)
|
|
||||||
.group(:user_id)
|
|
||||||
.order(:count)
|
|
||||||
.first
|
|
||||||
return nil if count.nil?
|
|
||||||
return nil unless count.count.positive?
|
|
||||||
|
|
||||||
count.count
|
|
||||||
end
|
|
||||||
|
|
||||||
def notification_count
|
|
||||||
return 0 unless user_signed_in?
|
|
||||||
|
|
||||||
count = Notification.for(current_user).where(new: true).count
|
|
||||||
return nil unless count.positive?
|
|
||||||
|
|
||||||
count
|
|
||||||
end
|
|
||||||
|
|
||||||
def privileged?(user)
|
def privileged?(user)
|
||||||
!current_user.nil? && ((current_user == user) || current_user.mod?)
|
!current_user.nil? && ((current_user == user) || current_user.mod?)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Inbox < ApplicationRecord
|
class Inbox < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user, touch: :inbox_updated_at
|
||||||
belongs_to :question
|
belongs_to :question
|
||||||
|
|
||||||
attr_accessor :returning
|
attr_accessor :returning
|
||||||
|
@ -29,7 +29,6 @@ class Inbox < ApplicationRecord
|
||||||
|
|
||||||
def as_push_notification
|
def as_push_notification
|
||||||
{
|
{
|
||||||
type: :inbox,
|
|
||||||
title: I18n.t(
|
title: I18n.t(
|
||||||
"frontend.push_notifications.inbox.title",
|
"frontend.push_notifications.inbox.title",
|
||||||
user: if question.author_is_anonymous
|
user: if question.author_is_anonymous
|
||||||
|
@ -39,7 +38,10 @@ class Inbox < ApplicationRecord
|
||||||
end
|
end
|
||||||
),
|
),
|
||||||
icon: question.author_is_anonymous ? "/icons/maskable_icon_x128.png" : question.user.profile_picture.url(:small),
|
icon: question.author_is_anonymous ? "/icons/maskable_icon_x128.png" : question.user.profile_picture.url(:small),
|
||||||
body: question.content.truncate(Question::SHORT_QUESTION_MAX_LENGTH)
|
body: question.content.truncate(Question::SHORT_QUESTION_MAX_LENGTH),
|
||||||
|
data: {
|
||||||
|
click_url: "/inbox",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Notification < ApplicationRecord
|
class Notification < ApplicationRecord
|
||||||
belongs_to :recipient, class_name: "User"
|
belongs_to :recipient, class_name: "User", touch: :notifications_updated_at
|
||||||
belongs_to :target, polymorphic: true
|
belongs_to :target, polymorphic: true
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
|
@ -8,6 +8,7 @@ class User < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
||||||
include User::AnswerMethods
|
include User::AnswerMethods
|
||||||
include User::BanMethods
|
include User::BanMethods
|
||||||
include User::InboxMethods
|
include User::InboxMethods
|
||||||
|
include User::NotificationMethods
|
||||||
include User::QuestionMethods
|
include User::QuestionMethods
|
||||||
include User::PushNotificationMethods
|
include User::PushNotificationMethods
|
||||||
include User::ReactionMethods
|
include User::ReactionMethods
|
||||||
|
|
|
@ -12,4 +12,21 @@ module User::InboxMethods
|
||||||
.order(:created_at)
|
.order(:created_at)
|
||||||
.reverse_order
|
.reverse_order
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def unread_inbox_count
|
||||||
|
Rails.cache.fetch("#{inbox_cache_key}/unread_inbox_count") do
|
||||||
|
count = Inbox.select("COUNT(id) AS count")
|
||||||
|
.where(new: true)
|
||||||
|
.where(user_id: id)
|
||||||
|
.group(:user_id)
|
||||||
|
.order(:count)
|
||||||
|
.first
|
||||||
|
return nil if count.nil?
|
||||||
|
return nil unless count.count.positive?
|
||||||
|
|
||||||
|
count.count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def inbox_cache_key = "#{cache_key}-#{inbox_updated_at}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module User::NotificationMethods
|
||||||
|
def unread_notification_count
|
||||||
|
Rails.cache.fetch("#{notification_cache_key}/unread_notification_count") do
|
||||||
|
count = Notification.for(self).where(new: true).count
|
||||||
|
return nil unless count.positive?
|
||||||
|
|
||||||
|
count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def notification_cache_key = "#{cache_key}-#{notifications_updated_at}"
|
||||||
|
end
|
|
@ -1,6 +1,8 @@
|
||||||
- notifications = Notification.for(current_user).where(new: true).includes([:target]).limit(4)
|
- notifications = Notification.for(current_user).where(new: true).includes([:target]).limit(4)
|
||||||
= render 'navigation/desktop', notifications: notifications
|
- inbox_count = current_user.unread_inbox_count
|
||||||
= render 'navigation/mobile', notifications: notifications
|
- notification_count = current_user.unread_notification_count
|
||||||
|
= render 'navigation/desktop', notifications:, inbox_count:, notification_count:
|
||||||
|
= render 'navigation/mobile', inbox_count:, notification_count:
|
||||||
|
|
||||||
= render 'modal/ask'
|
= render 'modal/ask'
|
||||||
%button.btn.btn-primary.btn-fab.d-block.d-lg-none.d-print-none{ data: { bs_target: "#modal-ask-followers", bs_toggle: :modal }, type: "button" }
|
%button.btn.btn-primary.btn-fab.d-block.d-lg-none.d-print-none{ data: { bs_target: "#modal-ask-followers", bs_toggle: :modal }, type: "button" }
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddNotificationAndInboxTimestampsToUsers < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
change_table :users, bulk: true do |t|
|
||||||
|
t.timestamp :notifications_updated_at
|
||||||
|
t.timestamp :inbox_updated_at
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2023_02_18_142952) do
|
ActiveRecord::Schema.define(version: 2023_02_25_143633) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -364,6 +364,8 @@ ActiveRecord::Schema.define(version: 2023_02_18_142952) do
|
||||||
t.boolean "sharing_enabled", default: false
|
t.boolean "sharing_enabled", default: false
|
||||||
t.boolean "sharing_autoclose", default: false
|
t.boolean "sharing_autoclose", default: false
|
||||||
t.string "sharing_custom_url"
|
t.string "sharing_custom_url"
|
||||||
|
t.datetime "notifications_updated_at"
|
||||||
|
t.datetime "inbox_updated_at"
|
||||||
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||||
t.index ["email"], name: "index_users_on_email", unique: true
|
t.index ["email"], name: "index_users_on_email", unique: true
|
||||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||||
|
|
Loading…
Reference in New Issue