import RestModel from "discourse/models/rest"; import I18n from "I18n"; import User from "discourse/models/user"; import UserChatChannelMembership from "discourse/plugins/chat/discourse/models/user-chat-channel-membership"; import { ajax } from "discourse/lib/ajax"; import { escapeExpression } from "discourse/lib/utilities"; import { tracked } from "@glimmer/tracking"; import slugifyChannel from "discourse/plugins/chat/discourse/lib/slugify-channel"; export const CHATABLE_TYPES = { directMessageChannel: "DirectMessage", categoryChannel: "Category", }; export const CHANNEL_STATUSES = { open: "open", readOnly: "read_only", closed: "closed", archived: "archived", }; export function channelStatusName(channelStatus) { switch (channelStatus) { case CHANNEL_STATUSES.open: return I18n.t("chat.channel_status.open"); case CHANNEL_STATUSES.readOnly: return I18n.t("chat.channel_status.read_only"); case CHANNEL_STATUSES.closed: return I18n.t("chat.channel_status.closed"); case CHANNEL_STATUSES.archived: return I18n.t("chat.channel_status.archived"); } } export function channelStatusIcon(channelStatus) { if (channelStatus === CHANNEL_STATUSES.open) { return null; } switch (channelStatus) { case CHANNEL_STATUSES.closed: return "lock"; case CHANNEL_STATUSES.readOnly: return "comment-slash"; case CHANNEL_STATUSES.archived: return "archive"; } } const STAFF_READONLY_STATUSES = [ CHANNEL_STATUSES.readOnly, CHANNEL_STATUSES.archived, ]; const READONLY_STATUSES = [ CHANNEL_STATUSES.closed, CHANNEL_STATUSES.readOnly, CHANNEL_STATUSES.archived, ]; export default class ChatChannel extends RestModel { @tracked currentUserMembership = null; @tracked isDraft = false; @tracked title; @tracked description; @tracked chatableType; @tracked status; get escapedTitle() { return escapeExpression(this.title); } get escapedDescription() { return escapeExpression(this.description); } get slugifiedTitle() { return this.slug || slugifyChannel(this); } get routeModels() { return [this.slugifiedTitle, this.id]; } get isDirectMessageChannel() { return this.chatable_type === CHATABLE_TYPES.directMessageChannel; } get isCategoryChannel() { return this.chatable_type === CHATABLE_TYPES.categoryChannel; } get isOpen() { return !this.status || this.status === CHANNEL_STATUSES.open; } get isReadOnly() { return this.status === CHANNEL_STATUSES.readOnly; } get isClosed() { return this.status === CHANNEL_STATUSES.closed; } get isArchived() { return this.status === CHANNEL_STATUSES.archived; } get isJoinable() { return this.isOpen && !this.isArchived; } get isFollowing() { return this.currentUserMembership.following; } canModifyMessages(user) { if (user.staff) { return !STAFF_READONLY_STATUSES.includes(this.status); } return !READONLY_STATUSES.includes(this.status); } updateMembership(membership) { this.currentUserMembership.following = membership.following; this.currentUserMembership.muted = membership.muted; this.currentUserMembership.desktop_notification_level = membership.desktop_notification_level; this.currentUserMembership.mobile_notification_level = membership.mobile_notification_level; } updateLastReadMessage(messageId) { if (!this.isFollowing || !messageId) { return; } return ajax(`/chat/${this.id}/read/${messageId}.json`, { method: "PUT", }).then(() => { this.currentUserMembership.last_read_message_id = messageId; }); } } ChatChannel.reopenClass({ create(args) { args = args || {}; this._initUserModels(args); this._initUserMembership(args); args.chatableType = args.chatable_type; args.membershipsCount = args.memberships_count; return this._super(args); }, _initUserModels(args) { if (args.chatable?.users?.length) { for (let i = 0; i < args.chatable?.users?.length; i++) { const userData = args.chatable.users[i]; args.chatable.users[i] = User.create(userData); } } }, _initUserMembership(args) { if (args.currentUserMembership instanceof UserChatChannelMembership) { return; } args.currentUserMembership = UserChatChannelMembership.create( args.current_user_membership || { following: false, muted: false, unread_count: 0, unread_mentions: 0, } ); delete args.current_user_membership; }, }); export function createDirectMessageChannelDraft() { return ChatChannel.create({ isDraft: true, chatable_type: CHATABLE_TYPES.directMessageChannel, chatable: { users: [], }, }); }