Skip to content

Commit

Permalink
Merge pull request #164 from marvin-wtt/viewing-rate
Browse files Browse the repository at this point in the history
Viewing rate
  • Loading branch information
marvin-wtt authored Jun 21, 2024
2 parents 66d12ad + 74d79ad commit 95dda1a
Show file tree
Hide file tree
Showing 17 changed files with 765 additions and 9 deletions.
4 changes: 4 additions & 0 deletions common/gameSettings/ViewingRateSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ViewingRateSettings {
startViewing: boolean;
readyCheck: boolean;
}
32 changes: 32 additions & 0 deletions common/gameState/ViewingRateState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export type ViewingRateState =
| ViewingRatePreparingState
| ViewingRateRunningState
| ViewingRateCompletedState
| ViewingRatePausedState;

interface ViewingRateBase {
game: 'viewing-rates';
}

export interface ViewingRatePreparingState extends ViewingRateBase {
name: 'preparing';
controllersReady: string[];
}

export interface ViewingRateRunningState extends ViewingRateBase {
name: 'running';
time: number;
changeTimes: Record<string, number[]>;
}

export interface ViewingRatePausedState extends ViewingRateBase {
name: 'paused';
time: number;
changeTimes: Record<string, number[]>;
}

export interface ViewingRateCompletedState extends ViewingRateBase {
name: 'completed';
time: number;
changeTimes: Record<string, number[]>;
}
4 changes: 3 additions & 1 deletion common/gameState/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { BuzzerState } from 'app/common/gameState/BuzzerState';
import { QuizState } from 'app/common/gameState/QuizState';
import { StopwatchState } from 'app/common/gameState/StopwatchState';
import { LeaderboardState } from 'app/common/gameState/LeaderboardState';
import { ViewingRateState } from 'app/common/gameState/ViewingRateState';

export type GameState =
| BuzzerState
| QuizState
| StopwatchState
| LeaderboardState;
| LeaderboardState
| ViewingRateState;
1 change: 1 addition & 0 deletions src/components/CircleTimer.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<template>
<!-- TODO Can be replace by q-circular-progress -->
<div class="base-timer">
<svg
class="base-timer__svg"
Expand Down
1 change: 1 addition & 0 deletions src/components/SafeDeleteBtn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<q-btn
v-bind="$attrs"
icon="done"
label=""
@click="onConfirm"
/>
</template>
Expand Down
10 changes: 7 additions & 3 deletions src/components/TimerAnimated.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ interface Props {
}
const props = withDefaults(defineProps<Props>(), {
reverse: false,
animated: false,
precision: 0,
});
Expand All @@ -42,11 +41,16 @@ const formatTime = (time: number) => {
const date = new Date(time * 1000);
let timeString = '';
// Hours
if (date.getUTCHours() > 0) {
const hours = date.getUTCHours();
timeString = `${hours}:`;
}
// Minutes
if (date.getUTCMinutes() > 0) {
if (date.getUTCMinutes() > 0 || timeString) {
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
timeString = `${minutes}:`;
timeString += `${minutes}:`;
}
// Seconds
Expand Down
15 changes: 10 additions & 5 deletions src/components/gameModes/stopwatch/StopwatchSettingsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@
</a>
</q-card-section>

<q-card-section class="q-gutter-y-sm">
<q-toggle
:label="t('gameMode.stopwatch.settings.field.playSounds')"
v-model="settings.playSounds"
/>
<q-card-section>
<q-form
ref="form"
class="q-gutter-y-sm"
>
<q-toggle
:label="t('gameMode.stopwatch.settings.field.playSounds')"
v-model="settings.playSounds"
/>
</q-form>
</q-card-section>

<q-card-actions align="center">
Expand Down
56 changes: 56 additions & 0 deletions src/components/gameModes/viewingRate/ViewingRateResultItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<q-item class="column q-my-xs">
<div class="text-subtitle1">{{ props.name }}</div>

<div class="relative-position full-width row bg-grey rounded-borders">
<div
v-for="(slot, index) of timeSlots"
:key="index"
:style="{ width: `${slot.length * 100}%` }"
:class="slot.viewing ? 'bg-primary' : ''"
class="rounded-borders"
style="height: 15px"
/>
</div>
</q-item>
</template>

<script lang="ts" setup>
import { computed } from 'vue';
const props = defineProps<{
name: string;
times: number[];
totalTime: number;
default: boolean;
}>();
interface TimeSlot {
length: number;
viewing: boolean;
}
const timeSlots = computed<TimeSlot[]>(() => {
const times = [...props.times, props.totalTime];
const slots: TimeSlot[] = [];
let viewing: boolean = props.default;
let previousTime = 0;
for (const time of times) {
const diff = time - previousTime;
const length = diff / props.totalTime;
slots.push({
length,
viewing,
});
previousTime = time;
viewing = !viewing;
}
return slots;
});
</script>

<style scoped></style>
74 changes: 74 additions & 0 deletions src/components/gameModes/viewingRate/ViewingRateSettingsDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<template>
<q-dialog
ref="dialogRef"
@hide="onDialogHide"
>
<q-card
class="q-dialog-plugin"
style="max-width: 20rem"
>
<q-card-section>
<a class="text-h5">
{{ t('gameMode.viewingRate.settings.title') }}
</a>
</q-card-section>

<q-card-section>
<q-form
ref="form"
class="q-gutter-y-sm"
>
<q-toggle
:label="t('gameMode.viewingRate.settings.field.startViewing')"
v-model="settings.startViewing"
/>
<q-toggle
:label="t('gameMode.viewingRate.settings.field.readyCheck')"
v-model="settings.readyCheck"
/>
</q-form>
</q-card-section>

<q-card-actions align="center">
<q-btn
:label="t('gameMode.viewingRate.settings.action.ok')"
color="primary"
@click="onOk"
rounded
/>
</q-card-actions>
</q-card>
</q-dialog>
</template>

<script lang="ts" setup>
import { QForm, useDialogPluginComponent } from 'quasar';
import { useGameSettingsStore } from 'stores/game-settings-store';
import { useI18n } from 'vue-i18n';
import { ref, toRaw } from 'vue';
import { ViewingRateSettings } from 'app/common/gameSettings/ViewingRateSettings';
defineEmits([...useDialogPluginComponent.emits]);
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
const { t } = useI18n();
const gameSettingsStore = useGameSettingsStore();
const form = ref<QForm | null>(null);
const settings = ref<ViewingRateSettings>(
structuredClone(toRaw(gameSettingsStore.viewingRateSettings)),
);
const onOk = async () => {
const valid = await form.value?.validate();
if (!valid) {
return;
}
gameSettingsStore.viewingRateSettings = settings.value;
onDialogOK();
};
</script>

<style scoped></style>
3 changes: 3 additions & 0 deletions src/i18n/de-DE/gameMode/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import buzzer from './buzzer';
import quiz from './quiz';
import stopwatch from './stopwatch';
import viewingRate from './viewingRate';

export default {
title: 'Spielmodus',
Expand All @@ -9,9 +10,11 @@ export default {
buzzer: 'Buzzer',
quiz: 'Quiz',
stopwatch: 'Stoppuhr',
viewingRate: 'Einschaltquote',
},

buzzer,
quiz,
stopwatch,
viewingRate,
};
28 changes: 28 additions & 0 deletions src/i18n/de-DE/gameMode/viewingRate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export default {
title: 'Einschaltquote',

currentlyViewing: 'Aktuell eingeschaltet',
totalWatchRate: 'Totale Einschaltquote',

action: {
cancel: 'Abbrechen',
complete: 'Fertig',
pause: 'Pause',
resume: 'Vorsetzen',
reset: 'Zurücksetzen',
start: 'Start',
},

settings: {
title: 'Einstellungen',

field: {
startViewing: 'Zuschauend beginnen',
readyCheck: 'Bereitschaftsprüfung',
},

action: {
ok: 'Ok',
},
},
};
3 changes: 3 additions & 0 deletions src/i18n/en-US/gameMode/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import buzzer from './buzzer';
import quiz from './quiz';
import stopwatch from './stopwatch';
import viewingRate from './viewingRate';

export default {
title: 'Game Mode',
Expand All @@ -9,9 +10,11 @@ export default {
buzzer: 'Buzzer',
quiz: 'Quiz',
stopwatch: 'Stopwatch',
viewingRate: 'Viewing Rate',
},

buzzer,
quiz,
stopwatch,
viewingRate,
};
28 changes: 28 additions & 0 deletions src/i18n/en-US/gameMode/viewingRate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export default {
title: 'Viewing Rate',

currentlyViewing: 'Currently viewing',
totalWatchRate: 'Total viewing rate',

action: {
cancel: 'Cancel',
complete: 'Complete',
pause: 'Pause',
resume: 'Resume',
reset: 'Reset',
start: 'Start',
},

settings: {
title: 'Settings',

field: {
startViewing: 'Start viewing',
readyCheck: 'Ready check',
},

action: {
ok: 'Ok',
},
},
};
5 changes: 5 additions & 0 deletions src/pages/gameModes/GameModesIndexPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,10 @@ const items = computed<MenuItem[]>(() => [
label: t('gameMode.action.stopwatch'),
icon: 'timer',
},
{
routeName: 'viewing-rate-game',
label: t('gameMode.action.viewingRate'),
icon: 'trending_up',
},
]);
</script>
Loading

0 comments on commit 95dda1a

Please sign in to comment.