Skip to content
Merged
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
4 changes: 3 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</v-row>
<template v-else>
<Breadcrumbs />
<RefreshAppBar />
<router-view />
</template>
</v-container>
Expand All @@ -26,11 +27,12 @@

<script setup>
import { onMounted, ref } from 'vue'
import { useEventsStore } from './stores/events.js'
import { useSnackbar } from './composables/useSnackbar.js'
import Header from './components/Header.vue'
import Breadcrumbs from './components/Breadcrumbs.vue'
import Footer from './components/Footer.vue'
import { useEventsStore } from './stores/events.js'
import RefreshAppBar from './components/RefreshAppBar.vue'

const eventsStore = useEventsStore()
const isPreloadingEvents = ref(true)
Expand Down
10 changes: 4 additions & 6 deletions src/components/Footer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<v-row no-gutters>
<v-col class="text-center">
<p>
{{ eventsCount }} séances.
{{ eventsStore.eventsCount }} séances.
<br v-if="!display.smAndUp.value" />
Dernière mise à jour {{ relativeLastSyncDate }}.
</p>
Expand All @@ -16,21 +16,19 @@

<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useDisplay } from 'vuetify'
import dateUtils from '../utils/date.js'
import { useEventsStore } from '../stores/events.js'
import dateUtils from '../utils/date.js'

const eventsStore = useEventsStore()
const { eventsCount, eventsLastSyncDate } = storeToRefs(eventsStore)
const display = useDisplay()
const now = ref(Date.now())
let intervalId = null

const relativeLastSyncDate = computed(() => {
now.value
return eventsLastSyncDate.value
? dateUtils.formatRelativeTime(eventsLastSyncDate.value)
return eventsStore.eventsLastSyncDate
? dateUtils.formatRelativeTime(eventsStore.eventsLastSyncDate)
: 'N/A'
})

Expand Down
62 changes: 62 additions & 0 deletions src/components/RefreshAppBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<v-app-bar v-if="isStale && !isRefreshAppBarDismissed" class="mb-4" color="secondary" variant="tonal" height="40" @click="refreshEvents">
<v-app-bar-title class="text-body-2">
<span v-if="!display.smAndDown.value">Dernière mise à jour {{ relativeLastSyncDate }}. Cliquez pour rafraîchir la liste.</span>
<span v-else>Dernière màj {{ relativeLastSyncDate }}. Cliquez pour rafraîchir.</span>
</v-app-bar-title>
<v-btn icon="mdi-close" variant="text" @click.stop="dismissRefreshAppBar" aria-label="Fermer" />
</v-app-bar>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useDisplay } from 'vuetify'
import { useEventsStore } from '../stores/events.js'
import dateUtils from '../utils/date.js'

const eventsStore = useEventsStore()
const { isRefreshAppBarDismissed } = storeToRefs(eventsStore)
const display = useDisplay()
const now = ref(Date.now())
const hoursForStale = 24
let intervalId = null

const relativeLastSyncDate = computed(() => {
now.value
return eventsStore.eventsLastSyncDate
? dateUtils.formatRelativeTime(eventsStore.eventsLastSyncDate)
: 'N/A'
})

// Determine if the events list is stale (older than 24 hours)
const isStale = computed(() => {
if (!eventsStore.eventsLastSyncDate) return false
const diffHours = (now.value - new Date(eventsStore.eventsLastSyncDate).getTime()) / 36e5
return diffHours > hoursForStale
})

const dismissRefreshAppBar = () => {
eventsStore.isRefreshAppBarDismissed = true
}

const refreshEvents = () => {
eventsStore.fetchEvents({ forceRefresh: true })
.catch((error) => {
console.error('Error refreshing events:', error)
})
}

onMounted(() => {
// Update the "now" value every 10 seconds to keep the relative time display accurate
intervalId = window.setInterval(() => {
now.value = Date.now()
}, 1000 * 10)
})

onUnmounted(() => {
if (intervalId) {
window.clearInterval(intervalId)
}
})
</script>
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default {
APP_NAME: 'CinéPleinAir',
APP_DESCRIPTION: 'Trouvez et partagez les séances de cinéma en plein air près de chez vous.',
APP_URL: 'https://cinepleinair.org',
APP_STORE_PREFIX: 'cinepleinair',
APP_GITHUB_URL: 'https://github.com/raphodn/open-air-events',
OEDB_WIKI_URL: 'https://wiki.openstreetmap.org/wiki/OpenEventDatabase',
OEDB_API_URL: 'https://api.openeventdatabase.org',
Expand Down
10 changes: 10 additions & 0 deletions src/stores/events.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import oedbService from '../services/openeventdatabase.js'
import constants from '../constants.js'

export const useEventsStore = defineStore('events', () => {
const events = ref([])
const eventsCount = ref(0)
const eventsLastSyncDate = ref(null)
const isRefreshAppBarDismissed = ref(false)

const upcomingEvents = computed(() => {
const now = new Date()
Expand Down Expand Up @@ -33,9 +35,17 @@ export const useEventsStore = defineStore('events', () => {
events,
eventsCount,
eventsLastSyncDate,
isRefreshAppBarDismissed,
upcomingEvents,
pastEvents,
fetchEvents,
getEventById
}
},
{
persist: {
key: `${constants.APP_STORE_PREFIX}-events`,
storage: localStorage,
paths: ['events', 'eventsCount', 'eventsLastSyncDate', 'isRefreshAppBarDismissed']
}
})
1 change: 1 addition & 0 deletions src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<v-btn :block="display.smAndDown.value" color="primary" to="/events">Trouver une séance</v-btn>

<br />
<br v-if="display.smAndUp.value" />

<h2 class="text-h6 font-weight-bold">Dernières séances ajoutées</h2>

Expand Down
Loading