DEV: sets an icon_upload_id on a channel (#29566)

There's no UI for it at the moment but when creating a channel or updating it, it's now possible to pass `icon_upload_id` as param. This will be available on the channel as `icon_upload_url`.
This commit is contained in:
Joffrey JAFFEUX 2024-11-04 17:19:44 +09:00 committed by GitHub
parent 932bd6ba85
commit 88eb96b315
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 74 additions and 13 deletions

View File

@ -28,6 +28,7 @@ module Chat
class_name: "Chat::Message",
foreign_key: :last_message_id,
optional: true
has_one :icon_upload, class_name: "Upload", foreign_key: :id, primary_key: :icon_upload_id
def last_message
super || NullMessage.new
@ -300,12 +301,13 @@ end
# user_count :integer default(0), not null
# auto_join_users :boolean default(FALSE), not null
# user_count_stale :boolean default(FALSE), not null
# slug :string
# type :string
# slug :string
# allow_channel_wide_mentions :boolean default(TRUE), not null
# messages_count :integer default(0), not null
# threading_enabled :boolean default(FALSE), not null
# last_message_id :bigint
# icon_upload_id :integer
#
# Indexes
#
@ -313,6 +315,6 @@ end
# index_chat_channels_on_chatable_id_and_chatable_type (chatable_id,chatable_type)
# index_chat_channels_on_last_message_id (last_message_id)
# index_chat_channels_on_messages_count (messages_count)
# index_chat_channels_on_slug (slug) UNIQUE
# index_chat_channels_on_slug (slug) UNIQUE WHERE ((slug)::text <> ''::text)
# index_chat_channels_on_status (status)
#

View File

@ -21,7 +21,8 @@ module Chat
:memberships_count,
:current_user_membership,
:meta,
:threading_enabled
:threading_enabled,
:icon_upload_url
has_one :last_message, serializer: Chat::LastMessageSerializer, embed: :objects
@ -32,6 +33,10 @@ module Chat
@current_user_membership = opts[:membership]
end
def icon_upload_url
object.icon_upload&.url
end
def include_description?
object.description.present?
end

View File

@ -38,6 +38,7 @@ module Chat
attribute :category_id, :integer
attribute :auto_join_users, :boolean, default: false
attribute :threading_enabled, :boolean, default: false
attribute :icon_upload_id, :integer
before_validation do
self.auto_join_users = auto_join_users.presence || false
@ -76,7 +77,14 @@ module Chat
def create_channel(category:, params:)
category.create_chat_channel(
user_count: 1,
**params.slice(:name, :slug, :description, :auto_join_users, :threading_enabled),
**params.slice(
:name,
:slug,
:icon_upload_id,
:description,
:auto_join_users,
:threading_enabled,
),
)
end

View File

@ -30,6 +30,7 @@ module Chat
attribute :target_usernames, :array
attribute :target_groups, :array
attribute :upsert, :boolean, default: false
attribute :icon_upload_id, :integer
validate :target_presence
@ -47,7 +48,7 @@ module Chat
class_name: Chat::DirectMessageChannel::Policy::CanCommunicateAllParties
model :direct_message, :fetch_or_create_direct_message
model :channel, :fetch_or_create_channel
step :set_optional_name
step :set_optional_params
step :update_memberships
step :recompute_users_count
@ -93,8 +94,10 @@ module Chat
::Chat::DirectMessageChannel.find_or_create_by(chatable: direct_message)
end
def set_optional_name(channel:, params:)
channel.update!(params.slice(:name)) if params.name&.size&.positive?
def set_optional_params(channel:, params:)
optional_params =
params.slice(:name, :icon_upload_id).reject { |_, value| value.nil? || value == "" }
channel.update!(optional_params) if !optional_params.empty?
end
def update_memberships(channel:, target_users:)

View File

@ -29,6 +29,7 @@ module Chat
# @option params [String,nil] :name
# @option params [String,nil] :description
# @option params [String,nil] :slug
# @option params [Integer,nil] :icon_upload_id
# @option params [Boolean] :threading_enabled
# @option params [Boolean] :auto_join_users Only valid for {CategoryChannel}. Whether active users with permission to see the category should automatically join the channel.
# @option params [Boolean] :allow_channel_wide_mentions Allow the use of @here and @all in the channel.
@ -43,6 +44,7 @@ module Chat
attribute :threading_enabled, :boolean, default: false
attribute :auto_join_users, :boolean, default: false
attribute :allow_channel_wide_mentions, :boolean, default: true
attribute :icon_upload_id, :integer, default: nil
before_validation do
assign_attributes(

View File

@ -26,7 +26,11 @@ export default class ChatChannelIcon extends Component {
<template>
{{#if @channel.isDirectMessageChannel}}
<div class="chat-channel-icon">
{{#if this.groupDirectMessage}}
{{#if @channel.iconUploadUrl}}
<span class="chat-channel-icon --avatar --custom-icon">
<img src={{@channel.iconUploadUrl}} />
</span>
{{else if this.groupDirectMessage}}
<span class="chat-channel-icon --users-count">
{{@channel.membershipsCount}}
</span>

View File

@ -388,7 +388,9 @@ export default {
}
get prefixType() {
if (this.channel.chatable.group) {
if (this.channel.iconUploadUrl) {
return "image";
} else if (this.channel.chatable.group) {
return "text";
} else {
return "image";
@ -396,7 +398,9 @@ export default {
}
get prefixValue() {
if (this.channel.chatable.group) {
if (this.channel.iconUploadUrl) {
return this.channel.iconUploadUrl;
} else if (this.channel.chatable.group) {
return this.channel.membershipsCount;
} else {
return avatarUrl(

View File

@ -3,6 +3,7 @@ import guid from "pretty-text/guid";
import { escapeExpression } from "discourse/lib/utilities";
import Category from "discourse/models/category";
import { getOwnerWithFallback } from "discourse-common/lib/get-owner";
import { getURLWithCDN } from "discourse-common/lib/get-url";
import ChatMessagesManager from "discourse/plugins/chat/discourse/lib/chat-messages-manager";
import ChatThreadsManager from "discourse/plugins/chat/discourse/lib/chat-threads-manager";
import slugifyChannel from "discourse/plugins/chat/discourse/lib/slugify-channel";
@ -94,6 +95,9 @@ export default class ChatChannel {
this.currentUserMembership = args.current_user_membership;
this.lastMessage = args.last_message;
this.meta = args.meta;
this.iconUploadUrl = args.icon_upload_url
? getURLWithCDN(args.icon_upload_url)
: null;
this.chatable = this.#initChatable(args.chatable ?? []);
this.tracking = new ChatTrackingState(getOwnerWithFallback(this));

View File

@ -28,6 +28,12 @@
}
}
&.--custom-icon img {
width: 24px;
height: 24px;
border-radius: 50%;
}
&.--category-badge {
color: var(--primary-medium);
display: flex;

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
#
class AddIconUploadIdToChatChannel < ActiveRecord::Migration[7.1]
def change
add_column :chat_channels, :icon_upload_id, :integer
end
end

View File

@ -198,6 +198,7 @@ module Chat
.strict_loading
.where(id: scoped_channels)
.includes(
:icon_upload,
last_message: [:uploads],
chatable: [{ direct_message_users: [user: %i[user_option group_users]] }, :users],
)

View File

@ -13,8 +13,10 @@ RSpec.describe Chat::CreateCategoryChannel do
fab!(:category)
let(:category_id) { category.id }
let(:name) { "cool channel" }
let(:icon_upload_id) { 2 }
let(:guardian) { Guardian.new(current_user) }
let(:params) { { category_id:, name: "cool channel" } }
let(:params) { { category_id:, name: name, icon_upload_id: icon_upload_id } }
let(:dependencies) { { guardian: } }
context "when public channels are disabled" do
@ -52,8 +54,9 @@ RSpec.describe Chat::CreateCategoryChannel do
expect { result }.to change { Chat::Channel.count }.by(1)
expect(result.channel).to have_attributes(
chatable: category,
name: "cool channel",
name: name,
slug: "cool-channel",
icon_upload_id: icon_upload_id,
)
end

View File

@ -40,7 +40,8 @@ RSpec.describe Chat::CreateDirectMessageChannel do
let(:guardian) { Guardian.new(current_user) }
let(:target_usernames) { [user_1.username, user_2.username] }
let(:name) { "" }
let(:params) { { target_usernames:, name: } }
let(:icon_upload_id) { nil }
let(:params) { { target_usernames:, name:, icon_upload_id: } }
let(:dependencies) { { guardian: } }
context "when all steps pass" do
@ -169,6 +170,14 @@ RSpec.describe Chat::CreateDirectMessageChannel do
expect(result.channel.name).to eq(name)
end
end
context "when an icon_upload_id is given" do
let(:icon_upload_id) { 2 }
it "sets it as the channel icon_upload_id" do
expect(result.channel.icon_upload_id).to eq(icon_upload_id)
end
end
end
context "when target_usernames exceeds chat_max_direct_message_users" do

View File

@ -5,6 +5,7 @@ RSpec.describe Chat::UpdateChannel do
fab!(:channel) { Fabricate(:chat_channel) }
fab!(:current_user) { Fabricate(:admin) }
fab!(:upload) { Fabricate(:upload) }
let(:guardian) { Guardian.new(current_user) }
let(:params) do
@ -15,6 +16,7 @@ RSpec.describe Chat::UpdateChannel do
slug: "snail",
allow_channel_wide_mentions: true,
auto_join_users: false,
icon_upload_id: upload.id,
}
end
let(:dependencies) { { guardian: } }
@ -43,6 +45,7 @@ RSpec.describe Chat::UpdateChannel do
description: "a channel description",
allow_channel_wide_mentions: true,
auto_join_users: false,
icon_upload_id: upload.id,
)
end