Skip to content
This repository was archived by the owner on Feb 6, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/controllers/api/chat_channel_memberships_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class DiscourseChat::Api::ChatChannelMembershipsController < DiscourseChat::Api::ChatChannelsController
def index
channel = find_chat_channel

offset = (params[:offset] || 0).to_i
limit = (params[:limit] || 50).to_i.clamp(1, 50)

memberships = ChatChannelMembershipsQuery.call(
channel,
offset: offset,
limit: limit,
username: params[:username]
)

render_serialized(memberships, UserChatChannelMembershipSerializer, root: false)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

MEMBERSHIP_EDITABLE_PARAMS = [:muted, :desktop_notification_level, :mobile_notification_level]

class DiscourseChat::Api::ChatChannelNotificationsSettingsController < DiscourseChat::Api::ChatChannelsController
def update
settings_params = params.permit(MEMBERSHIP_EDITABLE_PARAMS)
membership = find_membership
membership.update!(settings_params.to_h)
render_serialized(membership, UserChatChannelMembershipSerializer, root: false)
end
end
40 changes: 40 additions & 0 deletions app/controllers/api/chat_channels_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

CHAT_CHANNEL_EDITABLE_PARAMS = [:name, :description]

class DiscourseChat::Api::ChatChannelsController < DiscourseChat::Api
def update
guardian.ensure_can_edit_chat_channel!

chat_channel = find_chat_channel

if chat_channel.direct_message_channel?
raise Discourse::InvalidParameters.new(I18n.t("chat.errors.cant_update_direct_message_channel"))
end

editable_params = params.permit(*CHAT_CHANNEL_EDITABLE_PARAMS)
editable_params[:name] = editable_params[:name].presence
editable_params[:description] = editable_params[:description].presence
chat_channel.update!(editable_params)

ChatPublisher.publish_chat_channel_edit(chat_channel, current_user)

render_serialized(chat_channel, ChatChannelSerializer, root: false)
end

private

def find_chat_channel
chat_channel = ChatChannel.find(params.require(:chat_channel_id))
guardian.ensure_can_see_chat_channel!(chat_channel)
chat_channel
end

def find_membership
membership = UserChatChannelMembership
.includes(:user, :chat_channel)
.find_by!(user: current_user, chat_channel_id: params.require(:chat_channel_id))
guardian.ensure_can_see_chat_channel!(membership.chat_channel)
membership
end
end
13 changes: 13 additions & 0 deletions app/controllers/api_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

class DiscourseChat::Api < DiscourseChat::ChatBaseController
before_action :ensure_logged_in
before_action :ensure_can_chat

private

def ensure_can_chat
raise Discourse::NotFound unless SiteSetting.chat_enabled
guardian.ensure_can_chat!(current_user)
end
end
77 changes: 24 additions & 53 deletions app/controllers/chat_channels_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,65 +28,36 @@ def show
end

def follow
membership = UserChatChannelMembership
.includes(:chat_channel)
.find_or_create_by(
user_id: current_user.id,
chat_channel_id: params[:chat_channel_id]
)

if membership.following
return render_serialized(membership, UserChatChannelMembershipSerializer, root: false)
end
ActiveRecord::Base.transaction do
membership = UserChatChannelMembership
.includes(:chat_channel)
.find_or_initialize_by(
user_id: current_user.id,
chat_channel_id: params[:chat_channel_id]
)

unless membership.following
membership.following = true
membership.save!
membership.chat_channel.update!(user_count: (membership.chat_channel.user_count || 0) + 1)
end

# Need to set following and `save` rather than `update` because it's possible this is a new
# record, since the membership is fetched with `find_or_create_by`.
membership.following = true
if (membership.save)
membership.chat_channel.update(user_count: (membership.chat_channel.user_count || 0) + 1)
render_serialized(membership, UserChatChannelMembershipSerializer, root: false)
else
render_json_error(membership)
end
end

def unfollow
membership = UserChatChannelMembership
.includes(:chat_channel)
.find_by(
user_id: current_user.id,
chat_channel_id: params[:chat_channel_id]
)
if (membership && membership.update(following: false))
ActiveRecord::Base.transaction do
membership = UserChatChannelMembership
.includes(:chat_channel)
.find_by!(
user_id: current_user.id,
chat_channel_id: params[:chat_channel_id]
)
membership.update!(following: false)
new_user_count = [(membership.chat_channel.user_count || 0) - 1, 0].max
membership.chat_channel.update(user_count: new_user_count)
render json: success_json
else
render_json_error(membership)
end
end

def notification_settings
params.require([
:muted,
:desktop_notification_level,
:mobile_notification_level
])

membership = UserChatChannelMembership.find_by(
user_id: current_user.id,
chat_channel_id: params[:chat_channel_id]
)
raise Discourse::NotFound unless membership

if membership.update(
muted: params[:muted],
desktop_notification_level: params[:desktop_notification_level],
mobile_notification_level: params[:mobile_notification_level]
)
render json: success_json
else
render_json_error(membership)
membership.chat_channel.update!(user_count: new_user_count)
render_serialized(membership, UserChatChannelMembershipSerializer, root: false)
end
end

Expand Down Expand Up @@ -136,7 +107,7 @@ def edit
chat_channel.description = params[:description] if params[:description]
chat_channel.save!

ChatPublisher.publish_channel_edit(chat_channel, current_user)
ChatPublisher.publish_chat_channel_edit(chat_channel, current_user)
render_serialized(chat_channel, ChatChannelSerializer)
end

Expand Down
2 changes: 2 additions & 0 deletions app/models/chat_channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class ChatChannel < ActiveRecord::Base
archived: 3
}, _scopes: false

validates :name, length: { maximum: Proc.new { SiteSetting.max_topic_title_length } }, presence: true, allow_nil: true

def open?
self.status.to_sym == :open
end
Expand Down
29 changes: 29 additions & 0 deletions app/queries/chat_channel_memberships_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

class ChatChannelMembershipsQuery
def self.call(channel, limit: 50, offset: 0, username: nil)
query = UserChatChannelMembership
.includes(:user)
.where(chat_channel: channel, following: true)

if username.present?
if SiteSetting.prioritize_username_in_ux
query = query
.where('users.username_lower ILIKE ?', "%#{username}%")
else
query = query
.where('LOWER(users.name) ILIKE ? OR users.username_lower ILIKE ?', "%#{username}%", "%#{username}%")
end
end

if SiteSetting.enable_names
query = query.order('users.username_lower DESC')
else
query = query.order('users.name DESC')
end

query
.offset(offset)
.limit(limit)
end
end
10 changes: 9 additions & 1 deletion app/serializers/chat_channel_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ class ChatChannelSerializer < ApplicationSerializer
:archive_completed,
:archived_messages,
:total_messages,
:archive_topic_id
:archive_topic_id,
:memberships_count,
:desktop_notification_level,
:mobile_notification_level,
:following

def include_description?
object.description.present?
end

def memberships_count
object.user_count
end

def include_muted?
!object.direct_message_channel?
end
Expand Down
9 changes: 6 additions & 3 deletions app/serializers/user_chat_channel_membership_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ class UserChatChannelMembershipSerializer < ApplicationSerializer
:desktop_notification_level,
:mobile_notification_level,
:chat_channel_id,
:chatable_type
:user_count,
:last_read_message_id

def chatable_type
object.chat_channel.chatable_type
has_one :user, serializer: BasicUserSerializer, embed: :objects

def user_count
object.chat_channel.user_count
end
end
2 changes: 1 addition & 1 deletion app/services/chat_publisher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def self.publish_inaccessible_mentions(user_id, chat_message, cannot_chat_users,
)
end

def self.publish_channel_edit(chat_channel, acting_user)
def self.publish_chat_channel_edit(chat_channel, acting_user)
MessageBus.publish("/chat/channel-edits", {
chat_channel_id: chat_channel.id,
name: chat_channel.title(acting_user),
Expand Down
14 changes: 13 additions & 1 deletion assets/javascripts/discourse/chat-route-map.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
export default function () {
this.route("chat", { path: "/chat" }, function () {
this.route("channel", { path: "/channel/:channelId/:channelTitle" });
this.route(
"channel",
{ path: "/channel/:channelId/:channelTitle" },
function () {
this.route("info", { path: "/info" }, function () {
this.route("about", { path: "/about" });
this.route("members", { path: "/members" });
this.route("settings", { path: "/settings" });
});
}
);

this.route("draft-channel", { path: "/draft-channel" });
this.route("browse", { path: "/browse" });
this.route("message", { path: "/message/:messageId" });
this.route("channelByName", { path: "/chat_channels/:channelName" });
Expand Down
11 changes: 9 additions & 2 deletions assets/javascripts/discourse/components/channels-list.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createDirectMessageChannelDraft } from "discourse/plugins/discourse-chat/discourse/models/chat-channel";
import Component from "@ember/component";
import showModal from "discourse/lib/show-modal";
import { action, computed } from "@ember/object";
import { inject as service } from "@ember/service";
import { empty, reads } from "@ember/object/computed";
import I18n from "I18n";
import { DRAFT_CHANNEL_VIEW } from "discourse/plugins/discourse-chat/discourse/services/chat";

export default class ChannelsList extends Component {
@service chat;
Expand Down Expand Up @@ -75,7 +75,14 @@ export default class ChannelsList extends Component {

@action
startCreatingDmChannel() {
return this.onSelect(createDirectMessageChannelDraft());
if (
this.site.mobileView ||
this.router.currentRouteName.startsWith("chat.")
) {
this.router.transitionTo("chat.draft-channel");
} else {
this.appEvents.trigger("chat:open-view", DRAFT_CHANNEL_VIEW);
}
}

@action
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Component from "@ember/component";

export default class ChatChannelAboutView extends Component {
tagName = "";
channel = null;
onEditChatChannelTitle = null;
onEditChatChannelDescription = null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ export default Component.extend({
messageClass: "success",
});
this.appEvents.trigger("chat-channel:deleted", this.chatChannel);
later(() => {
if (!isTesting()) {

if (!isTesting()) {
later(() => {
this.closeModal();
}
}, 3000);
}, 3000);
}
})
.catch(popupAjaxError)
.finally(() => this.set("deleting", false));
Expand Down
Loading