aboutsummaryrefslogtreecommitdiffstats
path: root/pages/live.vue
diff options
context:
space:
mode:
authorLeonardo Bishop <me@leonardobishop.com>2025-01-24 01:53:42 +0000
committerLeonardo Bishop <me@leonardobishop.com>2025-01-24 01:53:42 +0000
commited3faf85e6a6e8083128ec68894533738c762b04 (patch)
treee8bb6ddc4b0d470c024667ab3ccacd3e2f85cf50 /pages/live.vue
parent0248517c6845a6c755d40c89d3d769ce7d60bd03 (diff)
Add /live
Diffstat (limited to 'pages/live.vue')
-rw-r--r--pages/live.vue100
1 files changed, 95 insertions, 5 deletions
diff --git a/pages/live.vue b/pages/live.vue
index 1c5679f..092f99f 100644
--- a/pages/live.vue
+++ b/pages/live.vue
@@ -1,29 +1,52 @@
<script setup lang="ts">
+import { Radio } from 'lucide-vue-next';
+import EventListing from '~/components/EventListing.vue';
import Panel from '~/components/Panel.vue';
import { type Event } from '~/stores/schedule';
const favouritesStore = useFavouritesStore();
const scheduleStore = useScheduleStore();
-const errorStore = useErrorStore();
-const favouriteEvents = computed(() => {
- return scheduleStore.events.filter((event) => favouritesStore.isFavourite(event));
-});
+const showAllHappeningNow = ref(false);
+const showAllUpcoming = ref(false);
+const timer = ref();
+const refreshKey = ref(0);
+
const todayEvents = computed(() => {
return scheduleStore.events.filter((event) => isToday(new Date(event.start)));
});
const happeningNow = computed(() => {
+ refreshKey.value;
return todayEvents.value.filter((event) => isEventHappeningNow(event));
});
const favouritesHappeningNow = computed(() => {
+ refreshKey.value;
return happeningNow.value.filter((event) => favouritesStore.isFavourite(event));
});
+const upcomingToday = computed(() => {
+ refreshKey.value;
+ return todayEvents.value.filter((event) => !isEventHappeningNow(event) && isInFuture(event));
+});
+const favouritesUpcomingToday = computed(() => {
+ refreshKey.value;
+ return upcomingToday.value.filter((event) => favouritesStore.isFavourite(event));
+});
+
+onMounted(() => {
+ timer.value = setInterval(() => {
+ refreshKey.value++;
+ }, 1000);
+});
function isEventHappeningNow(event: Event): boolean {
const now = new Date();
return event.start <= now && event.end >= now;
}
+function isInFuture(event: Event): boolean {
+ return event.start > new Date();
+}
+
function isToday(date: Date): boolean {
const today = new Date();
return date.getDate() === today.getDate() &&
@@ -33,11 +56,78 @@ function isToday(date: Date): boolean {
</script>
<template>
- <Panel kind="success" class="ongoing" v-if="happeningNow.length > 0">
+ <Panel kind="emphasis" class="ongoing" v-if="happeningNow.length > 0" title="Now" :icon="Radio">
+ <ul class="events-list">
+ <li v-for="event in showAllHappeningNow ? happeningNow : favouritesHappeningNow" :key="event.id">
+ <EventListing :event="event" />
+ </li>
+ <span class="other" v-if="!showAllHappeningNow && happeningNow.length != favouritesHappeningNow.length">{{ happeningNow.length }} other events happening right now</span>
+ </ul>
+ <template #actions>
+ <div class="actions">
+ <span class="status" v-if="!showAllHappeningNow">Showing only agenda items</span>
+ <Button @click="showAllHappeningNow = !showAllHappeningNow" :kind="showAllHappeningNow ? 'secondary' : 'primary'">
+ {{ showAllHappeningNow ? 'Show only agenda items' : 'Show all' }}
+ </Button>
+ </div>
+ </template>
+ </Panel>
+
+ <Panel class="upcoming" v-if="upcomingToday.length > 0" title="Upcoming">
+ <ul class="events-list">
+ <li v-for="event in showAllUpcoming ? upcomingToday : favouritesUpcomingToday" :key="event.id">
+ <EventListing :event="event" :show-relative-time="true" />
+ </li>
+ <span class="other" v-if="!showAllUpcoming">{{ upcomingToday.length }} other upcoming events today</span>
+ </ul>
+
+ <template #actions>
+ <div class="actions">
+ <span class="status" v-if="!showAllUpcoming">Showing only agenda items</span>
+ <Button @click="showAllUpcoming = !showAllUpcoming" :kind="showAllUpcoming ? 'secondary' : 'primary'">
+ {{ showAllUpcoming ? 'Show only agenda items' : 'Show all' }}
+ </Button>
+ </div>
+ </template>
+ </Panel>
+
+ <Panel kind="error" v-if="todayEvents.length === 0">
+ <span>There are no more events today</span>
</Panel>
</template>
<style scoped>
+ul.events-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: grid;
+ margin-top: -1rem;
+}
+
+ul.events-list > .other {
+ font-style: italic;
+}
+
+ul.events-list > li {
+ border-bottom: 1px solid var(--color-hover);
+}
+
+ul.events-list > li:last-of-type {
+ border-bottom: none;
+}
+
+div.actions {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+}
+
+div.actions > span.status {
+ color: var(--color-text);
+ font-style: italic;
+ font-size: var(--text-small);
+}
</style> \ No newline at end of file