Skip to content

Commit

Permalink
#79 showing rooms stats on schedule-talk component
Browse files Browse the repository at this point in the history
  • Loading branch information
fcamblor committed Apr 1, 2024
1 parent 6aa1d5b commit 8002eee
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 16 deletions.
65 changes: 63 additions & 2 deletions mobile/src/components/talk-card/ScheduleTalk.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
<template>
<div v-if="enabledRoomStats" class="above-talkCard"
:style="{
'--room-stats-bgcolor':
enabledRoomStats.capacityFillingRatio < 0.60 ? 'green'
: enabledRoomStats.capacityFillingRatio < 0.80 ? 'orange'
: enabledRoomStats.capacityFillingRatio < 0.99 ? 'red' : 'black',
'--room-stats-color':
enabledRoomStats.capacityFillingRatio < 0.60 ? 'white'
: enabledRoomStats.capacityFillingRatio < 0.80 ? 'black'
: enabledRoomStats.capacityFillingRatio < 0.99 ? 'white' : 'white'
}"
>
<span v-if="enabledRoomStats.capacityFillingRatio < 0.60">{{ LL.Still_plenty_of_seats_available() }}</span>
<span v-if="enabledRoomStats.capacityFillingRatio >= 0.60 && enabledRoomStats.capacityFillingRatio < 0.80">{{ LL.Room_is_becoming_crowded() }}</span>
<span v-if="enabledRoomStats.capacityFillingRatio >= 0.80 && enabledRoomStats.capacityFillingRatio < 0.99">{{ LL.Only_few_seats_left() }}</span>
<span v-if="enabledRoomStats.capacityFillingRatio >= 0.99">{{ LL.No_seats_available() }}</span>
<span v-if="enabledRoomStats.since === 0">{{LL.few_seconds_ago()}}</span>
<span v-if="enabledRoomStats.since !== 0">{{LL.xx_minutes_ago({ minutes: enabledRoomStats.since })}}</span>
</div>
<ion-card class="talkCard"
v-if="talkNotes"
:class="{ container: true, '_is-highlighted': isHighlighted(talk, talkNotes), '_has-favorited': talkNotes.isFavorite, '_has-to-watch-later': talkNotes.watchLater }"
Expand Down Expand Up @@ -66,8 +85,8 @@
</template>

<script setup lang="ts">
import {computed, PropType} from "vue";
import {managedRef as ref, toManagedRef as toRef} from "@/views/vue-utils";
import {computed, onMounted, PropType} from "vue";
import {managedRef as ref, toManagedRef as toRef, useInterval} from "@/views/vue-utils";
import {
IonBadge,
IonThumbnail,
Expand All @@ -80,6 +99,9 @@ import {TalkNote} from "../../../../shared/feedbacks.firestore";
import {VoxxrinConferenceDescriptor} from "@/models/VoxxrinConferenceDescriptor";
import {typesafeI18n} from "@/i18n/i18n-vue";
import {TalkStats} from "../../../../shared/event-stats";
import {VoxxrinRoomStats} from "@/models/VoxxrinRoomStats";
import {useCurrentClock} from "@/state/useCurrentClock";
import {Temporal} from "temporal-polyfill";
import {people, person} from "ionicons/icons";
const { LL } = typesafeI18n()
Expand Down Expand Up @@ -107,6 +129,10 @@ const props = defineProps({
required: false,
type: Object as PropType<TalkStats|undefined>
},
roomStats: {
required: false,
type: Object as PropType<VoxxrinRoomStats|undefined>
},
talkNotes: {
required: false,
type: Object as PropType<TalkNote|undefined>
Expand All @@ -117,6 +143,15 @@ defineEmits<{
(e: 'talk-clicked', talk: VoxxrinTalk): void,
}>()
const nowRef = ref<Temporal.ZonedDateTime|undefined>(undefined)
onMounted(async () => {
if(props.roomStats) {
useInterval(() => {
nowRef.value = useCurrentClock().zonedDateTimeISO()
}, {freq:"high-frequency"}, {immediate: true})
}
})
const talkLang = computed(() => {
return props.confDescriptor!.supportedTalkLanguages.find(lang => lang.id.isSameThan(props.talk!.language))
})
Expand All @@ -132,6 +167,27 @@ const speakerCount = props.talk!.speakers.length;
const hasTrack = (props.confDescriptor?.talkTracks.length || 0) > 1;
const enabledRoomStats = computed(() => {
const talkRoomId = props.talk?.room.id;
const talkId = props.talk?.id;
const roomStats = props.roomStats;
const now = nowRef.value
if(roomStats && now
&& roomStats.capacityFillingRatio !== 'unknown'
&& roomStats.roomId.isSameThan(talkRoomId)
&& roomStats.valid.forTalkId.isSameThan(talkId)
&& Date.parse(roomStats.valid.until) >= now.epochMilliseconds
){
return {
...roomStats,
since: Math.max(Math.round(now.toInstant().since(roomStats.persistedAt).total('minutes')), 0)
};
} else {
return undefined;
}
})
const theme = {
track: {
color: props.talk!.track.themeColor
Expand All @@ -141,6 +197,11 @@ const theme = {

<style lang="scss" scoped>
.above-talkCard {
background-color: var(--room-stats-bgcolor);
color: var(--room-stats-color);
}
//* Base styles card talk *//
.talkCard {
display: flex;
Expand Down
28 changes: 17 additions & 11 deletions mobile/src/i18n/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,23 @@ const en = {
Event_plans: "Event plans",
Event_summary: "Event summary",
Sponsors: "Sponsors",
Please_keep_this_token_private: "Please keep this token private",
User_uid: "User uid",
Profile: "Profile",
Logout: "Logout",
Anonymous_private_user_id: "Anonymous (private) user token",
Public_user_id: "Public user token",
How_and_where_can_I_contact_the_team: "How and where can I contact the team ?",
This_token_will_be_used_to_reference_you_in_APIs: "This token will be used to (anonymously) reference you in feedbacks",
App_settings: "App settings",
Configure_my_preferences_app: "Configure my preferences app",
Frequently_asked_questions: "Frequently asked questions",
Please_keep_this_token_private: "Please keep this token private",
User_uid: "User uid",
Profile: "Profile",
Logout: "Logout",
Anonymous_private_user_id: "Anonymous (private) user token",
Public_user_id: "Public user token",
How_and_where_can_I_contact_the_team: "How and where can I contact the team ?",
This_token_will_be_used_to_reference_you_in_APIs: "This token will be used to (anonymously) reference you in feedbacks",
App_settings: "App settings",
Configure_my_preferences_app: "Configure my preferences app",
Frequently_asked_questions: "Frequently asked questions",
Still_plenty_of_seats_available: "Still plenty of seats available",
Room_is_becoming_crowded: "Room is becoming crowded",
Only_few_seats_left: "Only few seats left",
No_seats_available: "No seats available",
xx_minutes_ago: "{minutes:number} minute{{minutes:s}} ago",
few_seconds_ago: "Few seconds ago",
} satisfies BaseTranslation

export default en
49 changes: 49 additions & 0 deletions mobile/src/i18n/i18n-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,31 @@ type RootTranslation = {
* F​r​e​q​u​e​n​t​l​y​ ​a​s​k​e​d​ ​q​u​e​s​t​i​o​n​s
*/
Frequently_asked_questions: string
/**
* S​t​i​l​l​ ​p​l​e​n​t​y​ ​o​f​ ​s​e​a​t​s​ ​a​v​a​i​l​a​b​l​e
*/
Still_plenty_of_seats_available: string
/**
* R​o​o​m​ ​i​s​ ​b​e​c​o​m​i​n​g​ ​c​r​o​w​d​e​d
*/
Room_is_becoming_crowded: string
/**
* O​n​l​y​ ​f​e​w​ ​s​e​a​t​s​ ​l​e​f​t
*/
Only_few_seats_left: string
/**
* N​o​ ​s​e​a​t​s​ ​a​v​a​i​l​a​b​l​e
*/
No_seats_available: string
/**
* {​m​i​n​u​t​e​s​}​ ​m​i​n​u​t​e​{​{​s​}​}​ ​a​g​o
* @param {number} minutes
*/
xx_minutes_ago: RequiredParams<'minutes'>
/**
* F​e​w​ ​s​e​c​o​n​d​s​ ​a​g​o
*/
few_seconds_ago: string
}

export type TranslationFunctions = {
Expand Down Expand Up @@ -989,6 +1014,30 @@ export type TranslationFunctions = {
* Frequently asked questions
*/
Frequently_asked_questions: () => LocalizedString
/**
* Still plenty of seats available
*/
Still_plenty_of_seats_available: () => LocalizedString
/**
* Room is becoming crowded
*/
Room_is_becoming_crowded: () => LocalizedString
/**
* Only few seats left
*/
Only_few_seats_left: () => LocalizedString
/**
* No seats available
*/
No_seats_available: () => LocalizedString
/**
* {minutes} minute{{s}} ago
*/
xx_minutes_ago: (arg: { minutes: number }) => LocalizedString
/**
* Few seconds ago
*/
few_seconds_ago: () => LocalizedString
}

export type Formatters = {
Expand Down
4 changes: 1 addition & 3 deletions mobile/src/state/useCurrentClock.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import {Ref} from "vue";
import {managedRef as ref} from "@/views/vue-utils";
import {Temporal} from "temporal-polyfill";
import {ISODatetime} from "../../../shared/type-utils";
import {match, P} from "ts-pattern";
import {Logger, PERF_LOGGER} from "@/services/Logger";
import {Logger} from "@/services/Logger";

const LOGGER = Logger.named("useCurrentClock");

Expand Down

0 comments on commit 8002eee

Please sign in to comment.