diff --git a/bun.lockb b/bun.lockb index 7ca304a..a17bfd4 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/index.html b/index.html index 6768a3b..2ee3a51 100644 --- a/index.html +++ b/index.html @@ -12,5 +12,6 @@
+ diff --git a/package.json b/package.json index 60bb06d..48dda25 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/vue-fontawesome": "latest-3", + "@vitejs/plugin-vue-jsx": "^3.1.0", "autoprefixer": "^10.4.19", "flowbite": "^2.3.0", "postcss": "^8.4.38", diff --git a/src/components/CategoryHeader.vue b/src/components/CategoryHeader.vue index e309b27..385b858 100644 --- a/src/components/CategoryHeader.vue +++ b/src/components/CategoryHeader.vue @@ -1,10 +1,10 @@ \ No newline at end of file diff --git a/src/components/ItemGroup.vue b/src/components/ItemGroup.vue index c69257b..3b99a73 100644 --- a/src/components/ItemGroup.vue +++ b/src/components/ItemGroup.vue @@ -1,9 +1,12 @@ @@ -12,11 +15,14 @@ import type { Item as StateItem, ThreadRef } from "../state"; import Item from "./Item.vue"; const emits = defineEmits<{ - selectItem: [source: number, sourceItem: number, thread: number] + selectItem: [source: number, sourceItem: number, thread: number]; + snoozeItem: [source: number, sourceItem: number, thread: number]; + deselect: []; }>(); defineProps<{ - items: StateItem[], - selectedThread?: ThreadRef + items: StateItem[]; + selectedThread?: ThreadRef; + showSnoozed?: boolean; }>(); \ No newline at end of file diff --git a/src/components/SnoozeModal.vue b/src/components/SnoozeModal.vue new file mode 100644 index 0000000..78f16d9 --- /dev/null +++ b/src/components/SnoozeModal.vue @@ -0,0 +1,122 @@ + + + diff --git a/src/components/pages/Snoozed.vue b/src/components/pages/Snoozed.vue new file mode 100644 index 0000000..d797485 --- /dev/null +++ b/src/components/pages/Snoozed.vue @@ -0,0 +1,102 @@ + + + diff --git a/src/components/Todo.vue b/src/components/pages/Todo.vue similarity index 65% rename from src/components/Todo.vue rename to src/components/pages/Todo.vue index 05dfea2..27690c6 100644 --- a/src/components/Todo.vue +++ b/src/components/pages/Todo.vue @@ -1,10 +1,16 @@ diff --git a/src/main.ts b/src/main.ts index ab6708c..fe674ce 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,11 +3,13 @@ import { createMemoryHistory, createRouter } from "vue-router"; import type { RouteRecordRaw } from "vue-router"; import "./style.css"; import App from "./App.vue"; -import Todo from "./components/Todo.vue"; +import Todo from "./components/pages/Todo.vue"; +import Snoozed from "./components/pages/Snoozed.vue"; const routes: RouteRecordRaw[] = [ { path: '/', component: Todo, name: 'home' }, { path: '/todo/:source(\\d+)?/:sourceItem(\\d+)?/:thread(\\d+)?', component: Todo, name: 'todo' }, + { path: '/snoozed/:source(\\d+)?/:sourceItem(\\d+)?/:thread(\\d+)?', component: Snoozed, name: 'snoozed' }, ]; const router = createRouter({ diff --git a/src/state.ts b/src/state.ts index 57550fb..ef2e460 100644 --- a/src/state.ts +++ b/src/state.ts @@ -86,6 +86,7 @@ export interface Category { name: string; priority: Priority; activeItems: Item[]; + snoozedItems: Item[]; } export interface ThreadRef { @@ -231,19 +232,22 @@ export const items = ref([ } ]); export const unsortedItems = ref([]); +export const unsortedItemsSnoozed = ref([]); export const rules = ref<{ category?: string; rules: Rule[] }[]>([]); export const categories = ref([ { id: 0, name: "Urgent", priority: "urgent", - activeItems: [] + activeItems: [], + snoozedItems: [] }, { id: 1, name: "DMs", priority: "notify", - activeItems: [] + activeItems: [], + snoozedItems: [] } ]); export const favorites = ref([ @@ -260,35 +264,54 @@ export const todoItems = computed(() => todoCategories.value .reduce((acc, curr) => mergeSortedLists(acc, curr.activeItems), [] as Item[]) ); -export const todoCategories = computed(() => categories.value.filter(c => ["urgent", "notify", "todo"].includes(c.priority))); +export const todoCategories = computed(() => categories.value.filter(c => ["urgent", "notify", "todo"].includes(c.priority) && Object.keys(c.activeItems).length > 0)); +export const snoozedCategories = computed(() => categories.value.filter(c => Object.keys(c.snoozedItems).length > 0)); watch( items, items => { const mappedItems: Record = {}; + const mappedItemsSnoozed: Record = {}; const unsorted: Item[] = []; + const unsortedSnoozed: Item[] = []; items.forEach(item => { let includeInUnsorted = false; + let includeInUnsortedSnoozed = false; const includeInCategories = new Set(); + const includeInCategoriesSnoozed = new Set(); Object.values(item.threads).forEach(t => { - if (t.category == null) { - includeInUnsorted = true; + if (t.snoozedUntil != null && Date.now() < t.snoozedUntil) { + if (t.category == null) { + includeInUnsortedSnoozed = true; + } else { + includeInCategoriesSnoozed.add(t.category); + } } else { - includeInCategories.add(t.category); + if (t.category == null) { + includeInUnsorted = true; + } else { + includeInCategories.add(t.category); + } } }); if (includeInUnsorted) { unsorted.push(item); } + if (includeInUnsortedSnoozed) { + unsortedSnoozed.push(item); + } includeInCategories.forEach(cat => mappedItems[cat] = [...(mappedItems[cat] ?? []), item]); + includeInCategoriesSnoozed.forEach(cat => mappedItemsSnoozed[cat] = [...(mappedItemsSnoozed[cat] ?? []), item]); }); categories.value.forEach(cat => { // Noting here that activeItems must be sorted by most recently updated cat.activeItems = mappedItems[cat.id]?.sort((a, b) => a.updatedAt - b.updatedAt) ?? []; + cat.snoozedItems = mappedItemsSnoozed[cat.id]?.sort((a, b) => a.updatedAt - b.updatedAt) ?? []; }); unsortedItems.value = unsorted; + unsortedItemsSnoozed.value = unsortedSnoozed; }, { immediate: true } ); diff --git a/vite.config.ts b/vite.config.ts index 35966e0..d148dba 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,12 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' +import vueJsx from '@vitejs/plugin-vue-jsx' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [vue()], + plugins: [ + vue(), + vueJsx() + ], base: "/" })