Skip to content
Open
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
57 changes: 32 additions & 25 deletions app/channels/room_channel.rb
Original file line number Diff line number Diff line change
@@ -1,43 +1,47 @@
class RoomChannel < ApplicationCable::Channel
attr_reader :log
attr_reader :subscriber

def subscribed
room = Room.find_by(key: params[:room_key])
return reject if room.blank? || room.banned?(current_user)

@log = UserRoomLog.create! user: current_user,
room: room,
ip_address: ip_address
@subscriber = UserRoomLog.create! user: current_user,
room: room,
ip_address: ip_address

stream_for @log.uuid
stream_for @subscriber.uuid
stream_from "room_#{room.id}"
end

def unsubscribed
# 既に強制退出されているときは退出処理を行わない
return if @log.blank? || @log.room.banned?(current_user)
@log.exit
return if @subscriber.blank? || @subscriber.room.banned?(@subscriber.user)
@subscriber.exit
end

def now_playing_video
RoomChannel.broadcast_to @log.uuid,
render_now_playing_video_json(@log.room)
@subscriber.touch # rubocop:disable Rails/SkipsModelValidations
RoomChannel.broadcast_to @subscriber.uuid,
render_now_playing_video_json(@subscriber.room)
end

def play_list
RoomChannel.broadcast_to @log.uuid,
render_play_list_json(@log.room)
@subscriber.touch # rubocop:disable Rails/SkipsModelValidations
RoomChannel.broadcast_to @subscriber.uuid,
render_play_list_json(@subscriber.room)
end

def past_chats
RoomChannel.broadcast_to @log.uuid,
render_past_chats_json(@log.room)
@subscriber.touch # rubocop:disable Rails/SkipsModelValidations
RoomChannel.broadcast_to @subscriber.uuid,
render_past_chats_json(@subscriber.room)
end

def add_video(data)
return if current_user.blank?
@subscriber.touch # rubocop:disable Rails/SkipsModelValidations
return if @subscriber.user.blank?

video = @log.room.add_video(data["youtube_video_id"], current_user)
video = @subscriber.room.add_video(data["youtube_video_id"], @subscriber.user)
return video if video.blank?
add_message = video.add_user.name + "さんが「" + video.title + "」を追加しました。"
Chat.create! room: video.room,
Expand All @@ -48,28 +52,31 @@ def add_video(data)
end

def exit_force(data)
return if current_user.blank?
@subscriber.touch # rubocop:disable Rails/SkipsModelValidations
return if @subscriber.user.blank?

target = User.find(data["user_id"])
logs = @log.room.user_room_logs.online.where(user: target)
logs.each do |log|
RoomChannel.broadcast_to log.uuid,
online_subscribers = @subscriber.room.user_room_logs.online
target_subscribers = online_subscribers.where(user: target)
target_subscribers.each do |target_subscriber|
RoomChannel.broadcast_to target_subscriber.uuid,
render_error_json("force exit")
log.exit
target_subscriber.exit
end
BanReport.create! target: target,
reporter: current_user,
room: @log.room,
reporter: @subscriber.user,
room: @subscriber.room,
expiration_at: Time.now.utc + 60 * 60 * 24
end

def message(data)
return if current_user.blank?
@subscriber.touch # rubocop:disable Rails/SkipsModelValidations
return if @subscriber.user.blank?

Chat.create! room: @log.room,
Chat.create! room: @subscriber.room,
chat_type: "user",
message: data["message"],
user: current_user
user: @subscriber.user
end

private
Expand Down
2 changes: 1 addition & 1 deletion app/models/user_room_log.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class UserRoomLog < ApplicationRecord
after_create :send_enter_message
after_update :send_exit_message, if: proc { |log| log.exit_at_before_last_save.blank? && log.exit_at.present? }

scope :online, -> { where exit_at: nil }
scope :online, -> { where(exit_at: nil).where(updated_at: 1.hour.ago..Time.current) }

def exit
update! exit_at: Time.now.utc
Expand Down
10 changes: 5 additions & 5 deletions spec/channels/room_channel_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
let(:room) { create(:room) }
let(:room_key) { room.key }
let(:user) { create(:user) }
let(:log) { subscription.log }
let(:target) { RoomChannel.broadcasting_for([RoomChannel.channel_name, log.uuid]) }
let(:subscriber) { subscription.subscriber }
let(:target) { RoomChannel.broadcasting_for([RoomChannel.channel_name, subscriber.uuid]) }
let(:stream_from) { "room_" + room.id.to_s }
let(:current_user) { user }
before { stub_connection current_user: current_user, ip_address: "0.0.0.0" }
Expand Down Expand Up @@ -103,7 +103,7 @@
before { subscribe room_key: room.key }
it { expect { subject }.to change(Chat, :count).by(1) }
it { expect { subject }.to change { room.online_users.count }.by(-1) }
it { expect { subject }.to change { log.exit_at }.from(nil).to(Time) }
it { expect { subject }.to change { subscriber.exit_at }.from(nil).to(Time) }

context "without login" do
let(:current_user) { nil }
Expand All @@ -113,7 +113,7 @@
to change(Chat, :count).by(0).
and change { room.online_users.count }.by(0)
}
it { expect { subject }.to change { log.exit_at }.from(nil).to(Time) }
it { expect { subject }.to change { subscriber.exit_at }.from(nil).to(Time) }
end

context "of duplicate subscription" do
Expand All @@ -124,7 +124,7 @@
to change(Chat, :count).by(0).
and change { room.online_users.count }.by(0)
}
it { expect { subject }.to change { log.exit_at }.from(nil).to(Time) }
it { expect { subject }.to change { subscriber.exit_at }.from(nil).to(Time) }
end
end

Expand Down
32 changes: 32 additions & 0 deletions spec/models/user_room_log_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,36 @@
log = build(:user_room_log)
expect(log).to be_valid
end

describe "#online" do
subject { UserRoomLog.online }

let(:updated_at) { Time.now.utc }

before { create(:user_room_log, exit_at: exit_at, updated_at: updated_at) }

context "when exit_at is nil" do
let(:exit_at) { nil }

it "returns a log" do
expect(subject.size).to eq 1
end

context "and updated_at is out of date" do
let(:updated_at) { Time.now.utc - 60 * 60 - 10 }

it "did not returns a log" do
expect(subject.size).to eq 0
end
end
end

context "when exit_at exist" do
let(:exit_at) { Time.now.utc - 10 }

it "did not returns a log" do
expect(subject.size).to eq 0
end
end
end
end