docbrown/app/controllers/chat_channels_controller.rb
Sarthak Sharma 90d60bf73f
[deploy] 🚀 Feature: Ability to search discoverable channels and send request to join (#7385)
* Feature 🚀 : Ability to delete messages in chat channels

- Sending message ID to frontend
- Deleting Message
- Use pusher to delete message realtime

* Minor Bug 🐞: Show message action only for current user

- User can delete or edit their own messages

* Test cases added

* Bug 🐞: Update message id for receiver

Message id was not sent to receiver by pusher

* Refactoring🛠: Message controller refactoring

* Test Cases📝 : Specs for Delete message added

* Feature 🚀 : Ability to edit messages

* Test Cases📝 : Specs for Edit message added

* added new column discoverable for public channel and changes in elasticsearch

* fix corrections

* changes in serializer file, added channel_discoverable

* added checkbox with discoverable policy

* changes in code for discoverable channels

* accept and reject member invitation by mod

* add joining request to closed groups

* fixed merge error

* changes in joining member to closed groups

* join to closed group

* changes in message action of joining

* changes in chat upopened json

* 🚀Feature : Ability to search Global Channels

* touch updated_at in after commit update

* 🚀Feature : Ability to send request to discoverable channel

* 🚀Feature : Ability to send request to discoverable channel

* created new route for joining closed channel

* 🚀 Success handle on joining request sent

* removed redundant code

* join_channel improvement, removed authorization for join channel

* list of joining requests

* added joining_request status channels on search list

* changes in mailer and query builder optimized

* 🛠 Adding filter for new Query

* added rspec for add membership method in controller

* rspec for sending join channel request

* invite join request channel list rspec

* test case for query builder discoverable

* viewable and discoverable channel list

* refactored logic for search channels

* 🚀 Check if Request already sent

* 🛠 Optimizing code and making channelButton Component

* 🛠 Optimizing codefor SVG problem

* 🛠 Optimized action.js

* changes in search controller query

* hot fix

* removed unwanted code

* 🛠  Fix the Channel Name problem

* 🛠  Optimizing code further for CodeClimate

* added new column discoverable for public channel and changes in elasticsearch

* fix corrections

* changes in serializer file, added channel_discoverable

* added checkbox with discoverable policy

* changes in code for discoverable channels

* accept and reject member invitation by mod

* add joining request to closed groups

* fixed merge error

* changes in joining member to closed groups

* join to closed group

* changes in message action of joining

* changes in chat upopened json

* touch updated_at in after commit update

* 🚀Feature : Ability to search Global Channels

* 🚀Feature : Ability to send request to discoverable channel

* 🚀Feature : Ability to send request to discoverable channel

* created new route for joining closed channel

* 🚀 Success handle on joining request sent

* removed redundant code

* join_channel improvement, removed authorization for join channel

* list of joining requests

* added joining_request status channels on search list

* changes in mailer and query builder optimized

* added rspec for add membership method in controller

* rspec for sending join channel request

* invite join request channel list rspec

* 🛠 Adding filter for new Query

* test case for query builder discoverable

* viewable and discoverable channel list

* refactored logic for search channels

* 🚀 Check if Request already sent

* 🛠 Optimizing code and making channelButton Component

* 🛠 Optimizing codefor SVG problem

* 🛠 Optimized action.js

* changes in search controller query

* hot fix

* 🛠  Fix the Channel Name problem

* 🛠  Fixing merge problem

* 🛠  Optimizing code further for CodeClimate

* updated UI for membership edit

* fixed test casses and fixed UI for chat_channel_edit

* 🛠napshots added

* test cases fixed

* 🛠 Test cases added for new component

* channel settings accesible only by mod

* 🛠 More Test cases added

* 🛠 Svg code optimized

* 🛠 Svg code optimized in videocontent

* optimized code for search query

* fix test case for query builder

* changes in joining closed channel logic

* refactored join channel

* redirect to edit channel after joining request

* changes in test case for redirect

* optimized code

* 🛠 Eslint bugs fixed

* test case fixed

* optimization

* olving channel repetition problem

* optimization of code for query builder

* changes in query builder

* test cases fixed

* 🛠 Handling reduntant data on frontend

* 🛠  Don't show data if no filter query

* 🛠 Optimized code for fixing bugs and code coverage

* 🛠  Optimizing code further for CodeClimate

Co-authored-by: Parasgr-code <paras.gaur@skynox.tech>
2020-05-11 09:29:15 -04:00

221 lines
8.4 KiB
Ruby

class ChatChannelsController < ApplicationController
before_action :authenticate_user!, only: %i[moderate]
before_action :set_channel, only: %i[show update open moderate]
after_action :verify_authorized
def index
if params[:state] == "unopened"
authorize ChatChannel
render_unopened_json_response
elsif params[:state] == "unopened_ids"
authorize ChatChannel
render_unopened_ids_response
elsif params[:state] == "pending"
authorize ChatChannel
render_pending_json_response
elsif params[:state] == "joining_request"
authorize ChatChannel
render_joining_request_json_response
else
skip_authorization
render_channels_html
end
end
def show
@chat_messages = @chat_channel.messages.includes(:user).order("created_at DESC").offset(params[:message_offset]).limit(50)
end
def create
authorize ChatChannel
@chat_channel = ChatChannelCreationService.new(current_user, params[:chat_channel]).create
render_chat_channel
end
def update
if ChatChannelUpdateService.new(@chat_channel, chat_channel_params).update
if !chat_channel_params[:discoverable].to_i.zero?
ChatChannelMembership.create(user_id: SiteConfig.mascot_user_id, chat_channel_id: @chat_channel.id, role: "member", status: "active")
else
ChatChannelMembership.find_by(user_id: SiteConfig.mascot_user_id)&.destroy
end
flash[:settings_notice] = "Channel settings updated."
else
default_error_message = "Channel settings updation failed. Try again later."
flash[:error] = @chat_channel.errors.full_messages.to_sentence.presence || default_error_message
end
current_user_membership = @chat_channel.mod_memberships.find_by!(user: current_user)
redirect_to edit_chat_channel_membership_path(current_user_membership)
end
def open
membership = @chat_channel.chat_channel_memberships.where(user_id: current_user.id).first
membership.update(last_opened_at: 1.second.from_now, has_unopened_messages: false)
send_open_notification
render json: { status: "success", channel: params[:id] }, status: :ok
end
def moderate
command = chat_channel_params[:command].split
case command[0]
when "/ban"
banned_user = User.find_by(username: command[1])
if banned_user
banned_user.add_role :banned
banned_user.messages.delete_all
Pusher.trigger(@chat_channel.pusher_channels, "user-banned", { userId: banned_user.id }.to_json)
render json: { status: "success", message: "suspended!" }, status: :ok
else
render json: { status: "error", message: "username not found" }, status: :bad_request
end
when "/unban"
banned_user = User.find_by(username: command[1])
if banned_user
banned_user.remove_role :banned
render json: { status: "success", message: "unsuspended!" }, status: :ok
else
render json: { status: "error", message: "username not found" }, status: :bad_request
end
when "/clearchannel"
@chat_channel.clear_channel
render json: { status: "success", message: "cleared!" }, status: :ok
else
render json: { status: "error", message: "invalid command" }, status: :bad_request
end
end
def create_chat
chat_recipient = User.find(params[:user_id])
valid_listing = ClassifiedListing.where(user_id: params[:user_id], contact_via_connect: true).limit(1)
authorize ChatChannel
if chat_recipient.inbox_type == "open" || valid_listing.length == 1
chat = ChatChannel.create_with_users(users: [current_user, chat_recipient], channel_type: "direct")
message_markdown = params[:message]
message = Message.new(
chat_channel: chat,
message_markdown: message_markdown,
user: current_user,
)
chat.messages.append(message)
render json: { status: "success", message: "chat channel created!" }, status: :ok
else
render json: { status: "error", message: "not allowed!" }, status: :bad_request
end
rescue StandardError => e
render json: { status: "error", message: e.message }, status: :bad_request
end
def block_chat
chat_channel = ChatChannel.find(params[:chat_id])
authorize chat_channel
chat_channel.status = "blocked"
chat_channel.save
chat_channel.chat_channel_memberships.map(&:index_to_elasticsearch)
render json: { status: "success", message: "chat channel blocked" }, status: :ok
end
# Note: this is part of an effort of moving some things from the external to
# the internal API. No behavior was changes as part of this refactoring, so
# this action is a bit unusual.
def channel_info
skip_authorization
@chat_channel =
ChatChannel.
select(CHANNEL_ATTRIBUTES_FOR_SERIALIZATION).
find_by(id: params[:id])
return if @chat_channel&.has_member?(current_user)
render json: { error: "not found", status: 404 }, status: :not_found
end
CHANNEL_ATTRIBUTES_FOR_SERIALIZATION = %i[id description channel_name].freeze
private_constant :CHANNEL_ATTRIBUTES_FOR_SERIALIZATION
private
def set_channel
@chat_channel = ChatChannel.find_by(id: params[:id]) || not_found
authorize @chat_channel
end
def chat_channel_params
params.require(:chat_channel).permit(policy(ChatChannel).permitted_attributes)
end
def render_unopened_json_response
@chat_channels_memberships = if session_current_user_id
ChatChannelMembership.where(user_id: session_current_user_id).includes(:chat_channel).
where(has_unopened_messages: true).
where(show_global_badge_notification: true).
where.not(status: %w[removed_from_channel left_channel]).
order("chat_channel_memberships.updated_at DESC")
else
[]
end
render "index.json"
end
def render_pending_json_response
@chat_channels_memberships = if current_user
current_user.
chat_channel_memberships.includes(:chat_channel).
where(status: "pending").
order("chat_channel_memberships.updated_at DESC")
else
[]
end
render "index.json"
end
def render_unopened_ids_response
@unopened_ids = ChatChannelMembership.where(user_id: session_current_user_id).includes(:chat_channel).
where(has_unopened_messages: true).where.not(status: %w[removed_from_channel left_channel]).pluck(:chat_channel_id)
render json: { unopened_ids: @unopened_ids }
end
def render_joining_request_json_response
requested_memberships = current_user.chat_channel_memberships.includes(:chat_channel).
where(chat_channels: { discoverable: true }, role: "mod").pluck(:chat_channel_id).map { |membership_id| ChatChannel.find_by(id: membership_id).requested_memberships }
render json: { joining_requests: requested_memberships.flatten }
end
def render_channels_html
return unless current_user && params[:slug]
slug = if params[:slug]&.start_with?("@")
[current_user.username, params[:slug].delete("@")].sort.join("/")
else
params[:slug]
end
@active_channel = ChatChannel.find_by(slug: slug)
@active_channel.current_user = current_user if @active_channel
end
def generate_github_token
Rails.cache.fetch("user-github-token-#{current_user.id}", expires_in: 48.hours) do
Identity.where(user_id: current_user.id, provider: "github").first&.token
end
end
def render_chat_channel
if @chat_channel.valid?
render json: { status: "success",
chat_channel: @chat_channel.to_json(only: %i[channel_name slug]) },
status: :ok
else
render json: { errors: @chat_channel.errors.full_messages }
end
end
def send_open_notification
adjusted_slug = if @chat_channel.group?
@chat_channel.adjusted_slug
else
@chat_channel.adjusted_slug(current_user)
end
Pusher.trigger("private-message-notifications-#{session_current_user_id}", "message-opened", { channel_type: @chat_channel.channel_type, adjusted_slug: adjusted_slug }.to_json)
end
end