diff --git a/web/store/updateOs.ts b/web/store/updateOs.ts index 5892574c7..1dd22b74e 100644 --- a/web/store/updateOs.ts +++ b/web/store/updateOs.ts @@ -2,37 +2,45 @@ import dayjs, { extend } from 'dayjs'; import customParseFormat from 'dayjs/plugin/customParseFormat'; import relativeTime from 'dayjs/plugin/relativeTime'; import { defineStore, createPinia, setActivePinia } from 'pinia'; +import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; import { computed } from 'vue'; +import { WebguiCheckForUpdate } from '~/composables/services/webgui'; import { useServerStore } from '~/store/server'; +import type { ServerUpdateOsResponse } from '~/types/server'; /** * @see https://stackoverflow.com/questions/73476371/using-pinia-with-vue-js-web-components * @see https://github.com/vuejs/pinia/discussions/1085 */ -setActivePinia(createPinia()); +const pinia = createPinia(); +pinia.use(piniaPluginPersistedstate); +setActivePinia(pinia); // dayjs plugins extend(customParseFormat); extend(relativeTime); export const useUpdateOsStore = defineStore('updateOs', () => { + // state + const checkForUpdatesLoading = ref(false); + const modalOpen = ref(false); + const ignoredReleases = ref([]); + + // getters from other stores const serverStore = useServerStore(); const regExp = computed(() => serverStore.regExp); const regUpdatesExpired = computed(() => serverStore.regUpdatesExpired); const updateOsResponse = computed(() => serverStore.updateOsResponse); - - const releaseDateGtRegExpDate = (releaseDate: number | string, regExpDate: number): boolean => { - const parsedReleaseDate = dayjs(releaseDate, 'YYYY-MM-DD'); - const parsedUpdateExpirationDate = dayjs(regExpDate ?? undefined); - - return parsedReleaseDate.isAfter(parsedUpdateExpirationDate, 'day'); - }; - + // local getters const available = computed(() => { if (!updateOsResponse.value) { return undefined; } + // ignore any releases that are in the ignoredReleases array + if (ignoredReleases.value.includes(updateOsResponse.value.version)) { + return undefined; + } return updateOsResponse.value.isNewer ? updateOsResponse.value.version : undefined; }); const availableWithRenewal = computed(() => { @@ -40,13 +48,56 @@ export const useUpdateOsStore = defineStore('updateOs', () => { return undefined; } - return releaseDateGtRegExpDate(updateOsResponse.value.date, regExp.value) + return updateOsResponse.value.isNewer && releaseDateGtRegExpDate(updateOsResponse.value.date, regExp.value) ? updateOsResponse.value.version : undefined; }); + const availableReleaseDate = computed(() => updateOsResponse.value?.date ? dayjs(updateOsResponse.value.date, 'YYYY-MM-DD') : undefined); + + // actions + const releaseDateGtRegExpDate = (releaseDate: number | string, regExpDate: number): boolean => { + const parsedReleaseDate = dayjs(releaseDate, 'YYYY-MM-DD'); + const parsedUpdateExpirationDate = dayjs(regExpDate ?? undefined); + + return parsedReleaseDate.isAfter(parsedUpdateExpirationDate, 'day'); + }; + + const localCheckForUpdate = async (): Promise => { + checkForUpdatesLoading.value = true; + setModalOpen(true); + try { + const response = await WebguiCheckForUpdate(); + console.debug('[localCheckForUpdate] response', response); + serverStore.setUpdateOsResponse(response as ServerUpdateOsResponse); + checkForUpdatesLoading.value = false; + } catch (error) { + throw new Error('[localCheckForUpdate] Error checking for updates'); + } + }; + + const setModalOpen = (val: boolean) => { + modalOpen.value = val; + }; + + const ignoreRelease = (release: string) => ignoredReleases.value.push(release); + return { + // state available, availableWithRenewal, + checkForUpdatesLoading, + modalOpen, + // getters + availableReleaseDate, + // actions + localCheckForUpdate, + setModalOpen, + ignoreRelease, }; +}, { + persist: { + storage: localStorage, + paths: ['ignoredReleases'], + }, });