app/controllers/api/v1/events_controller.rb
class API::V1::EventsController < API::V1::RestfulController
def position_keys
load_and_authorize(:discussion)
keys = Event.where(discussion_id: params[:discussion_id]).pluck(:position_key).sort
render json: keys, root: 'position_keys'
end
def timeline
load_and_authorize(:discussion)
data = Event.where(discussion_id: params[:discussion_id])
.order(:position_key)
.pluck(:position_key, :sequence_id, :created_at, :user_id, :depth, :descendant_count)
render json: data.to_json, root: 'timeline'
end
def remove_from_thread
service.remove_from_thread(event: load_resource, actor: current_user)
respond_with_resource
end
def comment
load_and_authorize(:discussion)
self.resource = Event.find_by!(kind: "new_comment", eventable_type: "Comment", eventable_id: params[:comment_id])
respond_with_resource
end
def pin
@event = Event.find(params[:id])
current_user.ability.authorize!(:pin, @event)
@event.update(pinned: true, pinned_title: params[:pinned_title])
render json: MessageChannelService.serialize_models(@event, scope: default_scope)
end
def unpin
@event = Event.find(params[:id])
current_user.ability.authorize!(:unpin, @event)
@event.update(pinned: false)
render json: MessageChannelService.serialize_models(@event, scope: default_scope)
end
private
def order
%w(sequence_id position position_key).detect {|col| col == params[:order] } || "sequence_id"
end
def per
(params[:per] || default_page_size).to_i
end
def from
if params[:from_sequence_id_of_position]
position = [params[:from_sequence_id_of_position].to_i, 1].max
Event.find_by!(discussion: @discussion, depth: 1, position: position)&.sequence_id
elsif params[:comment_id]
Event.find_by!(kind: "new_comment", eventable_type: "Comment", eventable_id: params[:comment_id])&.sequence_id
else
params[:from] || 0
end
end
def accessible_records
load_and_authorize(:discussion)
records = Event.where(discussion_id: @discussion.id)
if %w[position_key sequence_id].include?(params[:order_by])
records = records.order("#{params[:order_by]}#{params[:order_desc] ? " DESC" : ''}")
else
records = records.where("#{order} >= ?", from)
end
if params[:unread] == 'true'
reader = DiscussionReader.for(user: current_user, discussion: @discussion)
# could also be where in unread_ranges, but there is a bug on http://localhost:8080/s/njwV5RpS
records = records.where.not(sequence_id: reader.read_ranges.map{ |range| range[0]..range[1] })
end
if params[:pinned] == 'true'
records = records.where(pinned: true)
end
if params[:kind]
records = records.where("kind in (?)", params[:kind].split(','))
end
%w(parent_id depth sequence_id position position_key).each do |name|
records = records.where(name => params[name]) if params[name]
# records = records.where("#{name} >= ?", params["min_#{name}"]) if params["min_#{name}"]
# records = records.where("#{name} <= ?", params["max_#{name}"]) if params["max_#{name}"]
records = records.where("#{name} = ?", params["#{name}"]) if params["#{name}"]
records = records.where("#{name} < ?", params["#{name}_lt"]) if params["#{name}_lt"]
records = records.where("#{name} > ?", params["#{name}_gt"]) if params["#{name}_gt"]
records = records.where("#{name} <= ?", params["#{name}_lte"]) if params["#{name}_lte"]
records = records.where("#{name} >= ?", params["#{name}_gte"]) if params["#{name}_gte"]
records = records.where("#{name} like ?", params["#{name}_sw"]+"%") if params["#{name}_sw"]
end
# records = records.where("position_key like ?", params["position_key_sw"]+"%") if params["position_key_sw"]
records
end
def page_collection(collection)
if params[:until_sequence_id_of_position]
position = [params[:until_sequence_id_of_position].to_i, @discussion.created_event.child_count].min
event = Event.find_by!(discussion: @discussion, depth: 1, position: position)
max_sequence_id = event.sequence_id + event.child_count
collection.where("sequence_id <= ?", max_sequence_id).order('depth, position').limit(per)
else
collection.order(order).limit(per)
end
end
def default_page_size
30
end
end