DEV: Create UserChatThreadMembership table and model (#21481)

This will enable us to begin work on user tracking
state for a thread so we can show thread-specific
unreads and mentions indicators. In this case are following
the core notification_level paradigm rather than the solution
UserChatChannelMembership went with, and eventually we
will want to refactor the other table to match this as well.

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
This commit is contained in:
Martin Brennan 2023-05-10 17:19:48 +02:00 committed by GitHub
parent d3a5a493fa
commit cc2570fce3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 80 additions and 0 deletions

View File

@ -22,6 +22,7 @@ module Chat
foreign_key: :thread_id,
primary_key: :id,
class_name: "Chat::Message"
has_many :user_chat_thread_memberships
enum :status, { open: 0, read_only: 1, closed: 2, archived: 3 }, scopes: false

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
module Chat
class Chat::UserChatThreadMembership < ActiveRecord::Base
self.table_name = "user_chat_thread_memberships"
belongs_to :user
belongs_to :last_read_message, class_name: "Chat::Message", optional: true
belongs_to :thread, class_name: "Chat::Thread", foreign_key: :thread_id
enum :notification_level, NotificationLevels.chat_levels
end
end
# == Schema Information
#
# Table name: user_chat_thread_memberships
#
# id :bigint not null, primary key
# user_id :bigint not null
# thread_id :bigint not null
# last_read_message_id :bigint
# notification_level :integer default(2), not null
# created_at :datetime not null
# updated_at :datetime not null
#

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddUserChatThreadMemberships < ActiveRecord::Migration[7.0]
def change
create_table :user_chat_thread_memberships do |t|
t.bigint :user_id, null: false
t.bigint :thread_id, null: false
t.bigint :last_read_message_id
t.integer :notification_level, default: 2, null: false # default to tracking
t.timestamps
end
add_index :user_chat_thread_memberships,
%i[user_id thread_id],
unique: true,
name: "user_chat_thread_unique_memberships"
end
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
module Chat
module NotificationLevelsExtension
extend ActiveSupport::Concern
class_methods do
def chat_levels
@chat_levels ||= Enum.new(muted: 0, normal: 1, tracking: 2, watching: 3)
end
end
end
end

View File

@ -8,6 +8,9 @@ module Chat
has_many :user_chat_channel_memberships,
class_name: "Chat::UserChatChannelMembership",
dependent: :destroy
has_many :user_chat_thread_memberships,
class_name: "Chat::UserChatThreadMembership",
dependent: :destroy
has_many :chat_message_reactions, class_name: "Chat::MessageReaction", dependent: :destroy
has_many :chat_mentions, class_name: "Chat::Mention"
end

View File

@ -63,6 +63,7 @@ after_initialize do
User.prepend Chat::UserExtension
Jobs::UserEmail.prepend Chat::UserEmailExtension
Plugin::Instance.prepend Chat::PluginInstanceExtension
NotificationLevels.prepend Chat::NotificationLevelsExtension
end
if Oneboxer.respond_to?(:register_local_handler)

View File

@ -154,3 +154,5 @@ Fabricator(:chat_thread, class_name: "Chat::Thread") do
after_create { |thread| thread.original_message.update!(thread_id: thread.id) }
end
Fabricator(:user_chat_thread_membership, class_name: "Chat::UserChatThreadMembership") { user }

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
RSpec.describe Chat::UserChatThreadMembership do
it { is_expected.to belong_to(:user).class_name("User") }
it { is_expected.to belong_to(:last_read_message).class_name("Chat::Message") }
it { is_expected.to belong_to(:thread).class_name("Chat::Thread") }
it do
is_expected.to define_enum_for(:notification_level).with_values(
muted: 0,
normal: 1,
tracking: 2,
watching: 3,
)
end
end