mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-04-18 02:45:37 -04:00
refactor to simplify saving/state logic
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
:key="announcement.key"
|
:key="announcement.key"
|
||||||
:active="currentAnnouncement.key === announcement.key"
|
:active="currentAnnouncement.key === announcement.key"
|
||||||
rounded
|
rounded
|
||||||
@click="currentAnnouncement = announcement"
|
@click="setCurrentAnnouncement(announcement)"
|
||||||
>
|
>
|
||||||
<v-list-item-title class="text-body-2">
|
<v-list-item-title class="text-body-2">
|
||||||
{{ announcement.meta?.title }}
|
{{ announcement.meta?.title }}
|
||||||
@@ -73,13 +73,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAnnouncements } from "~/composables/use-announcements";
|
import { useAnnouncements } from "~/composables/use-announcements";
|
||||||
import type { Announcement } from "~/composables/use-announcements";
|
import type { Announcement } from "~/composables/use-announcements";
|
||||||
import { useUserApi } from "~/composables/api";
|
|
||||||
|
|
||||||
const dialog = defineModel<boolean>({ default: false });
|
const dialog = defineModel<boolean>({ default: false });
|
||||||
|
|
||||||
const auth = useMealieAuth();
|
const { newAnnouncements, allAnnouncements, setLastRead } = useAnnouncements();
|
||||||
const api = useUserApi();
|
|
||||||
const { newAnnouncements, allAnnouncements } = useAnnouncements();
|
|
||||||
|
|
||||||
const currentAnnouncement = shallowRef<Announcement | undefined>();
|
const currentAnnouncement = shallowRef<Announcement | undefined>();
|
||||||
watch(
|
watch(
|
||||||
@@ -91,46 +88,28 @@ watch(
|
|||||||
|
|
||||||
// If there are no new announcements, this is never set, so show the newest one
|
// If there are no new announcements, this is never set, so show the newest one
|
||||||
if (!currentAnnouncement.value) {
|
if (!currentAnnouncement.value) {
|
||||||
currentAnnouncement.value = allAnnouncements.at(-1);
|
setCurrentAnnouncement(allAnnouncements.at(-1)!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
async function setLastRead(key: string) {
|
function setCurrentAnnouncement(announcement: Announcement) {
|
||||||
const user = auth.user.value!;
|
currentAnnouncement.value = announcement;
|
||||||
if (user.lastReadAnnouncement && key <= user.lastReadAnnouncement) {
|
setLastRead(announcement.key);
|
||||||
// Don't update the last read announcement if it's older than the current one
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await api.users.updateOne(
|
|
||||||
user.id,
|
|
||||||
{
|
|
||||||
...user,
|
|
||||||
lastReadAnnouncement: null, // TODO: switch back to key
|
|
||||||
},
|
|
||||||
{ suppressAlert: true },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function markAllAsRead() {
|
function markAllAsRead() {
|
||||||
newAnnouncements.value = [];
|
setLastRead(allAnnouncements.at(-1)!.key);
|
||||||
|
|
||||||
const newestAnnouncement = allAnnouncements.at(-1)!;
|
|
||||||
setLastRead(newestAnnouncement.key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextAnnouncement() {
|
function nextAnnouncement() {
|
||||||
const nextAnnouncement = newAnnouncements.value.at(0);
|
const next = newAnnouncements.value.at(0);
|
||||||
newAnnouncements.value = newAnnouncements.value.slice(1);
|
if (!next) {
|
||||||
|
|
||||||
if (!nextAnnouncement) {
|
|
||||||
markAllAsRead();
|
markAllAsRead();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
currentAnnouncement.value = nextAnnouncement;
|
setCurrentAnnouncement(next);
|
||||||
setLastRead(currentAnnouncement.value.key);
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useHouseholdSelf } from "~/composables/use-households";
|
import { useHouseholdSelf } from "~/composables/use-households";
|
||||||
import { useGroupSelf } from "~/composables/use-groups";
|
import { useGroupSelf } from "~/composables/use-groups";
|
||||||
|
import { useUserApi } from "~/composables/api";
|
||||||
|
|
||||||
export type AnnouncementMeta = {
|
export type AnnouncementMeta = {
|
||||||
title: string | undefined;
|
title: string | undefined;
|
||||||
@@ -34,8 +35,13 @@ const allAnnouncements: Announcement[] = Object.entries(_announcementsUnsorted)
|
|||||||
|
|
||||||
const newAnnouncements = shallowRef<Announcement[]>([]);
|
const newAnnouncements = shallowRef<Announcement[]>([]);
|
||||||
|
|
||||||
|
function isWelcomeAnnouncement(key: string) {
|
||||||
|
return key === allAnnouncements.at(0)!.key;
|
||||||
|
}
|
||||||
|
|
||||||
export function useAnnouncements() {
|
export function useAnnouncements() {
|
||||||
const auth = useMealieAuth();
|
const auth = useMealieAuth();
|
||||||
|
const api = useUserApi();
|
||||||
const { household } = useHouseholdSelf();
|
const { household } = useHouseholdSelf();
|
||||||
const { group } = useGroupSelf();
|
const { group } = useGroupSelf();
|
||||||
|
|
||||||
@@ -48,7 +54,38 @@ export function useAnnouncements() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
function refreshUnreadAnnouncements() {
|
function updateUnreadAnnouncements(lastReadKey: string) {
|
||||||
|
newAnnouncements.value = allAnnouncements.filter(a => a.key > lastReadKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setLastRead(key: string) {
|
||||||
|
const user = auth.user.value!;
|
||||||
|
|
||||||
|
if (!user.lastReadAnnouncement && isWelcomeAnnouncement(key)) {
|
||||||
|
// The welcome announcement is a special case: it's shown to new users and
|
||||||
|
// all other announcements are marked as read when they view it
|
||||||
|
key = allAnnouncements.at(-1)!.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.lastReadAnnouncement && key <= user.lastReadAnnouncement) {
|
||||||
|
// Don't update the last read announcement if it's older than the current one
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUnreadAnnouncements(key);
|
||||||
|
|
||||||
|
user.lastReadAnnouncement = key; // update immediately so we don't have to wait for the db
|
||||||
|
await api.users.updateOne(
|
||||||
|
user.id,
|
||||||
|
{
|
||||||
|
...user,
|
||||||
|
lastReadAnnouncement: "2026-03-28_1_new-recipe-import-options", // TODO: switch back to key
|
||||||
|
},
|
||||||
|
{ suppressAlert: true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initUnreadAnnouncements() {
|
||||||
const user = auth.user.value;
|
const user = auth.user.value;
|
||||||
|
|
||||||
// Only logged-in users can see announcements
|
// Only logged-in users can see announcements
|
||||||
@@ -64,17 +101,26 @@ export function useAnnouncements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return all announcements newer than the last read announcement
|
// Return all announcements newer than the last read announcement
|
||||||
newAnnouncements.value = allAnnouncements.filter(a => a.key > user.lastReadAnnouncement!);
|
updateUnreadAnnouncements(user.lastReadAnnouncement);
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshUnreadAnnouncements();
|
initUnreadAnnouncements();
|
||||||
|
|
||||||
|
// If the user changes, re-init
|
||||||
|
let lastUserId = auth.user.value?.id;
|
||||||
watch(auth.user, () => {
|
watch(auth.user, () => {
|
||||||
refreshUnreadAnnouncements();
|
if (auth.user.value?.id === lastUserId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastUserId = auth.user.value?.id;
|
||||||
|
initUnreadAnnouncements();
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
announcementsEnabled,
|
announcementsEnabled,
|
||||||
newAnnouncements,
|
newAnnouncements,
|
||||||
allAnnouncements,
|
allAnnouncements,
|
||||||
|
setLastRead,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user