Skip to content
Snippets Groups Projects
Unverified Commit f68e4259 authored by Samuel Couillard's avatar Samuel Couillard Committed by GitHub
Browse files

Online Feedback - create online column in Room (#3943)

* Fix badges styling

* Remove isRunning query from Room

* Add online col to Room

* Fix rebase misses

* Put online filtering logic back into service

* Fix server rooms

* Rubocop

* Put room update in meeting starter service

* quickfix
parent ec294bed
Branches
Tags
No related merge requests found
Showing
with 60 additions and 35 deletions
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
margin: 0 -600rem; margin: 0 -600rem;
padding: 0.25rem 600rem; padding: 0.25rem 600rem;
//TODO - samuel: need to find a solution for this //TODO - samuel: need to find a solution for this
height: 317px; height: 302px;
} }
.wide-background-rooms { .wide-background-rooms {
......
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
cursor: pointer; cursor: pointer;
} }
} }
.room-card-badges {
margin-bottom: auto;
margin-left: auto;
}
} }
.tab-content { .tab-content {
......
...@@ -14,7 +14,17 @@ module Api ...@@ -14,7 +14,17 @@ module Api
pagy, rooms = pagy(rooms) pagy, rooms = pagy(rooms)
rooms = RunningMeetingChecker.new(rooms:).call active_rooms = BigBlueButtonApi.new.active_meetings
active_rooms_hash = {}
active_rooms.each do |active_room|
active_rooms_hash[active_room[:meetingID]] = active_room[:participantCount]
end
rooms.each do |room|
room.active = active_rooms_hash.key?(room.meeting_id)
room.participants = active_rooms_hash[room.meeting_id]
end
render_data data: rooms, meta: pagy_metadata(pagy), serializer: ServerRoomSerializer, status: :ok render_data data: rooms, meta: pagy_metadata(pagy), serializer: ServerRoomSerializer, status: :ok
end end
......
...@@ -81,6 +81,7 @@ module Api ...@@ -81,6 +81,7 @@ module Api
role: bbb_role role: bbb_role
) )
end end
render_data data:, status: :ok render_data data:, status: :ok
end end
......
...@@ -26,13 +26,17 @@ module Api ...@@ -26,13 +26,17 @@ module Api
room room
end end
rooms = RunningMeetingChecker.new(rooms: user_rooms + shared_rooms).call rooms = user_rooms + shared_rooms
RunningMeetingChecker.new(rooms:).call
render_data data: rooms, status: :ok render_data data: rooms, status: :ok
end end
# GET /api/v1/rooms/:friendly_id.json # GET /api/v1/rooms/:friendly_id.json
def show def show
RunningMeetingChecker.new(rooms: @room).call if @room.online
render_data data: @room, serializer: CurrentRoomSerializer, options: { include_owner: params[:include_owner] == 'true' }, status: :ok render_data data: @room, serializer: CurrentRoomSerializer, options: { include_owner: params[:include_owner] == 'true' }, status: :ok
end end
......
...@@ -44,7 +44,7 @@ class ExternalController < ApplicationController ...@@ -44,7 +44,7 @@ class ExternalController < ApplicationController
return render json: {} unless params[:recordingmarks] == 'true' return render json: {} unless params[:recordingmarks] == 'true'
@room = Room.find_by(meeting_id: params[:meetingID]) @room = Room.find_by(meeting_id: params[:meetingID])
@room.update(recordings_processing: @room.recordings_processing + 1) @room.update(recordings_processing: @room.recordings_processing + 1, online: false)
render json: {}, status: :ok render json: {}, status: :ok
end end
......
...@@ -4,11 +4,10 @@ import PropTypes from 'prop-types'; ...@@ -4,11 +4,10 @@ import PropTypes from 'prop-types';
import MeetingStatusBadge from './MeetingStatusBadge'; import MeetingStatusBadge from './MeetingStatusBadge';
import MeetingParticipantsBadge from './MeetingParticipantsBadge'; import MeetingParticipantsBadge from './MeetingParticipantsBadge';
export default function MeetingBadges({ active, count }) { export default function MeetingBadges({ count }) {
return ( return (
<Stack direction="horizontal" gap={0} className="room-card-badges ms-auto mb-auto"> <Stack direction="horizontal" gap={0} className="room-card-badges">
{ active <MeetingStatusBadge />
&& <MeetingStatusBadge />}
{ count >= 1 { count >= 1
&& <MeetingParticipantsBadge count={count} />} && <MeetingParticipantsBadge count={count} />}
</Stack> </Stack>
...@@ -16,6 +15,5 @@ export default function MeetingBadges({ active, count }) { ...@@ -16,6 +15,5 @@ export default function MeetingBadges({ active, count }) {
} }
MeetingBadges.propTypes = { MeetingBadges.propTypes = {
active: PropTypes.bool.isRequired,
count: PropTypes.number.isRequired, count: PropTypes.number.isRequired,
}; };
...@@ -31,7 +31,8 @@ export default function RoomCard({ room }) { ...@@ -31,7 +31,8 @@ export default function RoomCard({ room }) {
<UserIcon className="hi-m text-brand pt-4 d-block mx-auto" /> <UserIcon className="hi-m text-brand pt-4 d-block mx-auto" />
)} )}
</div> </div>
<MeetingBadges active={room.active} count={room.participants} /> { room.online
&& <MeetingBadges active={room.online} count={room.participants} />}
</Stack> </Stack>
<Stack className="my-4"> <Stack className="my-4">
...@@ -54,7 +55,7 @@ export default function RoomCard({ room }) { ...@@ -54,7 +55,7 @@ export default function RoomCard({ room }) {
<DocumentDuplicateIcon className="hi-m text-brand mt-1" /> <DocumentDuplicateIcon className="hi-m text-brand mt-1" />
</Button> </Button>
<Button variant="brand-outline" className="btn btn-md float-end" onClick={startMeeting.mutate} disabled={startMeeting.isLoading}> <Button variant="brand-outline" className="btn btn-md float-end" onClick={startMeeting.mutate} disabled={startMeeting.isLoading}>
{ room.active ? ( { room.online ? (
t('join') t('join')
) : ( ) : (
t('start') t('start')
...@@ -79,7 +80,7 @@ RoomCard.propTypes = { ...@@ -79,7 +80,7 @@ RoomCard.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
last_session: PropTypes.string, last_session: PropTypes.string,
shared_owner: PropTypes.string, shared_owner: PropTypes.string,
active: PropTypes.bool, online: PropTypes.bool,
participants: PropTypes.number, participants: PropTypes.number,
}).isRequired, }).isRequired,
}; };
...@@ -36,7 +36,7 @@ export default function RoomsList() { ...@@ -36,7 +36,7 @@ export default function RoomsList() {
</Stack> </Stack>
<Row md={4} className="g-4 pb-4 mt-4"> <Row md={4} className="g-4 pb-4 mt-4">
{ {
rooms.sort((a, b) => b.active - a.active).filter((room) => { rooms.sort((a, b) => b.online - a.online).filter((room) => {
if (room.name.toLowerCase().includes(search.toLowerCase())) { if (room.name.toLowerCase().includes(search.toLowerCase())) {
return room; return room;
} }
......
...@@ -10,7 +10,6 @@ import FeatureTabs from './FeatureTabs'; ...@@ -10,7 +10,6 @@ import FeatureTabs from './FeatureTabs';
import Spinner from '../../shared_components/utilities/Spinner'; import Spinner from '../../shared_components/utilities/Spinner';
import useRoom from '../../../hooks/queries/rooms/useRoom'; import useRoom from '../../../hooks/queries/rooms/useRoom';
import useStartMeeting from '../../../hooks/mutations/rooms/useStartMeeting'; import useStartMeeting from '../../../hooks/mutations/rooms/useStartMeeting';
import useMeetingRunning from '../../../hooks/queries/rooms/useMeetingRunning';
import MeetingBadges from '../MeetingBadges'; import MeetingBadges from '../MeetingBadges';
function copyInvite() { function copyInvite() {
...@@ -23,9 +22,7 @@ export default function Room() { ...@@ -23,9 +22,7 @@ export default function Room() {
const { friendlyId } = useParams(); const { friendlyId } = useParams();
const { isLoading: isLoadingRoom, data: room } = useRoom(friendlyId); const { isLoading: isLoadingRoom, data: room } = useRoom(friendlyId);
const startMeeting = useStartMeeting(friendlyId); const startMeeting = useStartMeeting(friendlyId);
const { isLoading: isLoadingRunning, data: isRunning } = useMeetingRunning(friendlyId);
if (isLoadingRunning) return <Spinner />; // Todo: amir - Revisit this.
if (isLoadingRoom) return <Spinner />; // Todo: amir - Revisit this. if (isLoadingRoom) return <Spinner />; // Todo: amir - Revisit this.
return ( return (
...@@ -41,10 +38,10 @@ export default function Room() { ...@@ -41,10 +38,10 @@ export default function Room() {
<Col className="col-xxl-8"> <Col className="col-xxl-8">
<Stack direction="horizontal" gap={2}> <Stack direction="horizontal" gap={2}>
<h1>{room.name}</h1> <h1>{room.name}</h1>
{ isRunning <div className="mb-1">
&& ( { room.online
<MeetingBadges active={room.active} count={room.participants} /> && <MeetingBadges active={room.online} count={room.participants} />}
)} </div>
</Stack> </Stack>
{ room.last_session ? ( { room.last_session ? (
<span className="text-muted"> { t('room.last_session', { room }) } </span> <span className="text-muted"> { t('room.last_session', { room }) } </span>
...@@ -54,7 +51,7 @@ export default function Room() { ...@@ -54,7 +51,7 @@ export default function Room() {
</Col> </Col>
<Col> <Col>
<Button variant="brand" className="mt-1 mx-2 float-end" onClick={startMeeting.mutate} disabled={startMeeting.isLoading}> <Button variant="brand" className="mt-1 mx-2 float-end" onClick={startMeeting.mutate} disabled={startMeeting.isLoading}>
{ isRunning ? ( { room.online ? (
t('room.meeting.join_meeting') t('room.meeting.join_meeting')
) : ( ) : (
t('room.meeting.start_meeting') t('room.meeting.start_meeting')
......
...@@ -4,7 +4,7 @@ class CurrentRoomSerializer < ApplicationSerializer ...@@ -4,7 +4,7 @@ class CurrentRoomSerializer < ApplicationSerializer
include Presentable include Presentable
include Avatarable include Avatarable
attributes :id, :name, :presentation_name, :thumbnail attributes :id, :name, :presentation_name, :thumbnail, :online, :participants
attribute :owner_name, if: -> { @instance_options[:options][:include_owner] } attribute :owner_name, if: -> { @instance_options[:options][:include_owner] }
attribute :owner_avatar, if: -> { @instance_options[:options][:include_owner] } attribute :owner_avatar, if: -> { @instance_options[:options][:include_owner] }
......
# frozen_string_literal: true # frozen_string_literal: true
class RoomSerializer < ApplicationSerializer class RoomSerializer < ApplicationSerializer
attributes :id, :name, :friendly_id, :active, :participants attributes :id, :name, :friendly_id, :online, :participants
attribute :shared_owner, if: -> { object.shared } attribute :shared_owner, if: -> { object.shared }
attribute :last_session, if: -> { object.last_session } attribute :last_session, if: -> { object.last_session }
......
...@@ -44,6 +44,10 @@ class BigBlueButtonApi ...@@ -44,6 +44,10 @@ class BigBlueButtonApi
bbb_server.get_meetings[:meetings] bbb_server.get_meetings[:meetings]
end end
def get_meeting_info(meeting_id:)
bbb_server.get_meeting_info(meeting_id, nil)
end
# Retrieve the recordings that belong to room with given record_id # Retrieve the recordings that belong to room with given record_id
def get_recording(record_id:) def get_recording(record_id:)
bbb_server.get_recordings(recordID: record_id)[:recordings][0] bbb_server.get_recordings(recordID: record_id)[:recordings][0]
......
...@@ -21,7 +21,7 @@ class MeetingStarter ...@@ -21,7 +21,7 @@ class MeetingStarter
begin begin
meeting = BigBlueButtonApi.new.start_meeting room: @room, options: options, presentation_url: @presentation_url meeting = BigBlueButtonApi.new.start_meeting room: @room, options: options, presentation_url: @presentation_url
@room.update!(last_session: DateTime.strptime(meeting[:createTime].to_s, '%Q')) @room.update!(online: true, last_session: DateTime.strptime(meeting[:createTime].to_s, '%Q'))
ActionCable.server.broadcast "#{@room.friendly_id}_rooms_channel", 'started' ActionCable.server.broadcast "#{@room.friendly_id}_rooms_channel", 'started'
rescue BigBlueButton::BigBlueButtonException => e rescue BigBlueButton::BigBlueButtonException => e
......
# frozen_string_literal: true # frozen_string_literal: true
# Pass the rooms to the service and it will return the rooms with the active and participants attributes # Pass the room(s) to the service and it will confirm if the meeting is online or not and will return the # of participants
class RunningMeetingChecker class RunningMeetingChecker
def initialize(rooms:) def initialize(rooms:)
@rooms = rooms @rooms = rooms
end end
def call def call
active_rooms = BigBlueButtonApi.new.active_meetings online_rooms = Array(@rooms).select { |room| room.online == true }
active_rooms_hash = {}
active_rooms.each do |active_room| online_rooms.each do |online_room|
active_rooms_hash[active_room[:meetingID]] = active_room[:participantCount] bbb_meeting = BigBlueButtonApi.new.get_meeting_info(meeting_id: online_room.meeting_id)
end online_room.participants = bbb_meeting[:participantCount]
rescue BigBlueButton::BigBlueButtonException
@rooms.each do |room| online_room.update(online: false)
room.active = active_rooms_hash.key?(room.meeting_id)
room.participants = active_rooms_hash[room.meeting_id]
end end
end end
end end
# frozen_string_literal: true
class AddOnlineToRoom < ActiveRecord::Migration[7.0]
def change
add_column :rooms, :online, :boolean, default: false
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2022_09_14_190934) do ActiveRecord::Schema[7.0].define(version: 2022_09_28_193827) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto" enable_extension "pgcrypto"
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -119,6 +119,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_09_14_190934) do ...@@ -119,6 +119,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_09_14_190934) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.integer "recordings_processing", default: 0 t.integer "recordings_processing", default: 0
t.boolean "online"
t.index ["friendly_id"], name: "index_rooms_on_friendly_id", unique: true t.index ["friendly_id"], name: "index_rooms_on_friendly_id", unique: true
t.index ["meeting_id"], name: "index_rooms_on_meeting_id", unique: true t.index ["meeting_id"], name: "index_rooms_on_meeting_id", unique: true
t.index ["user_id"], name: "index_rooms_on_user_id" t.index ["user_id"], name: "index_rooms_on_user_id"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment