Implement reaction create/destroy with Turbo Streams
This commit is contained in:
parent
35be02a1f0
commit
9872d3aace
|
@ -50,20 +50,19 @@
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&[name="ab-smile"],
|
&.smile {
|
||||||
&[name="ab-smile-comment"] {
|
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--success);
|
color: var(--success);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&[data-action="unsmile"] {
|
&.unsmile {
|
||||||
color: var(--success);
|
color: var(--success);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--danger);
|
color: var(--danger);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,65 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ReactionsController < ApplicationController
|
class ReactionsController < ApplicationController
|
||||||
|
include TurboStreamable
|
||||||
|
|
||||||
|
before_action :authenticate_user!, only: %w[create destroy]
|
||||||
|
|
||||||
|
turbo_stream_actions :create, :destroy
|
||||||
|
|
||||||
def index
|
def index
|
||||||
answer = Answer.includes([smiles: { user: :profile }]).find(params[:id])
|
answer = Answer.includes([smiles: { user: :profile }]).find(params[:id])
|
||||||
|
|
||||||
render "index", locals: { a: answer }
|
render "index", locals: { a: answer }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
params.require :id
|
||||||
|
params.require :type
|
||||||
|
|
||||||
|
target = params[:type].constantize.find_by!(id: params[:id])
|
||||||
|
|
||||||
|
UseCase::Reaction::Create.call(
|
||||||
|
source_user: current_user,
|
||||||
|
target:
|
||||||
|
)
|
||||||
|
|
||||||
|
target.reload
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.turbo_stream do
|
||||||
|
render turbo_stream: [
|
||||||
|
turbo_stream.replace("reaction-#{params[:type]}-#{params[:id]}", partial: "reactions/destroy", locals: { type: params[:type], target: }),
|
||||||
|
render_toast(t(".#{params[:type].downcase}.success"))
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
format.html { redirect_back(fallback_location: root_path) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
params.require :id
|
||||||
|
params.require :type
|
||||||
|
|
||||||
|
target = params[:type].constantize.find_by!(id: params[:id])
|
||||||
|
|
||||||
|
UseCase::Reaction::Destroy.call(
|
||||||
|
source_user: current_user,
|
||||||
|
target:
|
||||||
|
)
|
||||||
|
|
||||||
|
target.reload
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.turbo_stream do
|
||||||
|
render turbo_stream: [
|
||||||
|
turbo_stream.replace("reaction-#{params[:type]}-#{params[:id]}", partial: "reactions/create", locals: { type: params[:type], target: }),
|
||||||
|
render_toast(t(".#{params[:type].downcase}.success"))
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
format.html { redirect_back(fallback_location: root_path) }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
%button.btn.btn-link.answerbox__action{ type: :button, name: "ab-smile", data: { a_id: a.id, action: a.has_reacted ? :unsmile : :smile, selection_hotkey: "s" }, disabled: !user_signed_in? }
|
- if a.has_reacted
|
||||||
%i.fa.fa-fw.fa-smile-o
|
= render "reactions/destroy", type: "Answer", target: a
|
||||||
%span{ id: "ab-smile-count-#{a.id}" }= a.smile_count
|
- else
|
||||||
|
= render "reactions/create", type: "Answer", target: a
|
||||||
- unless display_all
|
- unless display_all
|
||||||
%button.btn.btn-link.answerbox__action{ type: :button, name: "ab-comments", data: { a_id: a.id, state: :hidden, selection_hotkey: "x" } }
|
%button.btn.btn-link.answerbox__action{ type: :button, name: "ab-comments", data: { a_id: a.id, state: :hidden, selection_hotkey: "x" } }
|
||||||
%i.fa.fa-fw.fa-comments
|
%i.fa.fa-fw.fa-comments
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
.comment__content
|
.comment__content
|
||||||
= markdown comment.content
|
= markdown comment.content
|
||||||
.flex-shrink-0.ms-auto
|
.flex-shrink-0.ms-auto
|
||||||
%button.btn.btn-link.answerbox__action{ type: :button, name: "ab-smile-comment", data: { c_id: comment.id, action: current_user&.smiled?(comment) ? :unsmile : :smile }, disabled: !user_signed_in? }
|
- if current_user&.smiled?(comment)
|
||||||
%i.fa.fa-fw.fa-smile-o
|
= render "reactions/destroy", type: "Comment", target: comment
|
||||||
%span{ id: "ab-comment-smile-count-#{comment.id}" }= comment.smile_count
|
- else
|
||||||
|
= render "reactions/create", type: "Comment", target: comment
|
||||||
.btn-group
|
.btn-group
|
||||||
%button.btn.btn-link.btn-sm.dropdown-toggle{ data: { bs_toggle: :dropdown }, aria: { expanded: false } }
|
%button.btn.btn-link.btn-sm.dropdown-toggle{ data: { bs_toggle: :dropdown }, aria: { expanded: false } }
|
||||||
%span.caret
|
%span.caret
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
- if type == "Answer"
|
||||||
|
= button_to create_reactions_path(id: target.id, username: target.user.screen_name),
|
||||||
|
form: { class: "d-inline-block", id: "reaction-#{type}-#{target.id}" },
|
||||||
|
class: "btn btn-link answerbox__action smile" do
|
||||||
|
%i.fa.fa-fw.fa-smile-o
|
||||||
|
%span= target.smile_count
|
||||||
|
|
||||||
|
- if type == "Comment"
|
||||||
|
= button_to create_comment_reactions_path(id: target.id, username: target.user.screen_name),
|
||||||
|
form: { class: "d-inline-block", id: "reaction-#{type}-#{target.id}" },
|
||||||
|
class: "btn btn-link answerbox__action smile" do
|
||||||
|
%i.fa.fa-fw.fa-smile-o
|
||||||
|
%span= target.smile_count
|
|
@ -0,0 +1,15 @@
|
||||||
|
- if type == "Answer"
|
||||||
|
= button_to destroy_reactions_path(id: target.id, username: target.user.screen_name),
|
||||||
|
method: :delete,
|
||||||
|
form: { class: "d-inline-block", id: "reaction-#{type}-#{target.id}" },
|
||||||
|
class: "btn btn-link answerbox__action unsmile" do
|
||||||
|
%i.fa.fa-fw.fa-smile-o
|
||||||
|
%span= target.smile_count
|
||||||
|
|
||||||
|
- if type == "Comment"
|
||||||
|
= button_to destroy_comment_reactions_path(id: target.id, username: target.user.screen_name),
|
||||||
|
method: :delete,
|
||||||
|
form: { class: "d-inline-block", id: "reaction-#{type}-#{target.id}" },
|
||||||
|
class: "btn btn-link answerbox__action unsmile" do
|
||||||
|
%i.fa.fa-fw.fa-smile-o
|
||||||
|
%span= target.smile_count
|
|
@ -156,8 +156,12 @@ Rails.application.routes.draw do
|
||||||
delete "/@:username/a/:id/pin", to: "answer#unpin", as: :unpin_answer
|
delete "/@:username/a/:id/pin", to: "answer#unpin", as: :unpin_answer
|
||||||
get "/@:username/a/:id/comments", to: "comments#index", as: :comments
|
get "/@:username/a/:id/comments", to: "comments#index", as: :comments
|
||||||
get "/@:username/a/:id/reactions", to: "reactions#index", as: :reactions
|
get "/@:username/a/:id/reactions", to: "reactions#index", as: :reactions
|
||||||
|
post "/@:username/a/:id/reactions", to: "reactions#create", as: :create_reactions, defaults: { type: "Answer" }
|
||||||
|
delete "/@:username/a/:id/reactions", to: "reactions#destroy", as: :destroy_reactions, defaults: { type: "Answer" }
|
||||||
get "/@:username/q/:id", to: "question#show", as: :question
|
get "/@:username/q/:id", to: "question#show", as: :question
|
||||||
get "/@:username/c/:id/reactions", to: "comments/reactions#index", as: :comment_reactions
|
get "/@:username/c/:id/reactions", to: "comments/reactions#index", as: :comment_reactions
|
||||||
|
post "/@:username/c/:id/reactions", to: "reactions#create", as: :create_comment_reactions, defaults: { type: "Comment" }
|
||||||
|
delete "/@:username/c/:id/reactions", to: "reactions#destroy", as: :destroy_comment_reactions, defaults: { type: "Comment" }
|
||||||
get "/@:username/followers", to: "user#followers", as: :show_user_followers
|
get "/@:username/followers", to: "user#followers", as: :show_user_followers
|
||||||
get "/@:username/followings", to: "user#followings", as: :show_user_followings
|
get "/@:username/followings", to: "user#followings", as: :show_user_followings
|
||||||
get "/@:username/friends", to: redirect("/@%{username}/followings")
|
get "/@:username/friends", to: redirect("/@%{username}/followings")
|
||||||
|
|
Loading…
Reference in New Issue