From b60591cde4fa79ec391747fe27e8db567b7b3c31 Mon Sep 17 00:00:00 2001 From: Nick Kosarev Date: Wed, 27 Aug 2025 16:15:22 +0200 Subject: [PATCH 1/2] chore: feedback rework --- .../atrium-telegram/app/components/Button.vue | 2 +- .../app/components/CreateCard.vue | 2 +- .../atrium-telegram/app/components/Loader.vue | 2 +- .../app/components/TaskCard.vue | 16 ++--- .../app/components/TasksTodaySwitch.vue | 9 ++- .../app/components/form/CompleteTask.vue | 3 + .../app/components/form/CreateTask.vue | 3 + .../app/components/form/CreateTaskList.vue | 3 + .../app/components/form/UpdateTask.vue | 5 ++ .../app/components/form/UpdateTaskList.vue | 5 ++ .../app/components/form/UploadUserAvatar.vue | 3 + .../app/composables/useFeedback.ts | 12 +++- apps/atrium-telegram/app/pages/index.vue | 71 ++++++++++--------- apps/atrium-telegram/app/stores/task.ts | 4 ++ 14 files changed, 86 insertions(+), 54 deletions(-) diff --git a/apps/atrium-telegram/app/components/Button.vue b/apps/atrium-telegram/app/components/Button.vue index d784c74a..a973e913 100644 --- a/apps/atrium-telegram/app/components/Button.vue +++ b/apps/atrium-telegram/app/components/Button.vue @@ -1,7 +1,7 @@ diff --git a/apps/atrium-telegram/app/components/Loader.vue b/apps/atrium-telegram/app/components/Loader.vue index 3e997c17..6a5cc9a9 100644 --- a/apps/atrium-telegram/app/components/Loader.vue +++ b/apps/atrium-telegram/app/components/Loader.vue @@ -2,6 +2,6 @@ diff --git a/apps/atrium-telegram/app/components/TaskCard.vue b/apps/atrium-telegram/app/components/TaskCard.vue index 5274bba8..bc69ce19 100644 --- a/apps/atrium-telegram/app/components/TaskCard.vue +++ b/apps/atrium-telegram/app/components/TaskCard.vue @@ -43,7 +43,7 @@ ], }" class="group/task duration-200 motion-preset-bounce" - @click="vibrate" + @click="vibrate()" >
@@ -90,9 +90,7 @@ const { task } = defineProps<{ task: Task }>() -const { t } = useI18n() const { vibrate } = useFeedback() -const actionToast = useActionToast() const taskStore = useTaskStore() const userStore = useUserStore() @@ -154,32 +152,28 @@ const items = computed(() => { }) async function onFocus() { - const toastId = actionToast.start() - try { await taskStore.setAsFocused(task.id) await taskStore.update() await userStore.update() - actionToast.success(toastId, t('toast.task-focused')) + vibrate('success') } catch (error) { console.error(error) - actionToast.error(toastId) + vibrate('error') } } async function onUnfocus() { - const toastId = actionToast.start() - try { await taskStore.setAsUnfocused(task.id) await taskStore.update() await userStore.update() - actionToast.success(toastId, t('toast.task-unfocused')) + vibrate('success') } catch (error) { console.error(error) - actionToast.error(toastId) + vibrate('error') } } diff --git a/apps/atrium-telegram/app/components/TasksTodaySwitch.vue b/apps/atrium-telegram/app/components/TasksTodaySwitch.vue index 16b6a7f0..923042e0 100644 --- a/apps/atrium-telegram/app/components/TasksTodaySwitch.vue +++ b/apps/atrium-telegram/app/components/TasksTodaySwitch.vue @@ -3,13 +3,12 @@ v-model="taskStore.isTodayOnly" size="xl" color="secondary" - :label="taskStore.isTodayOnly ? 'Сегодня' : 'Все задачи'" - :default-value="taskStore.isTodayOnly" + :label="taskStore.isTodayOnly ? 'Задачи на сегодня' : 'Показаны все задачи'" :ui="{ - root: 'flex-row-reverse items-center', - label: 'mr-3 text-base/5 font-semibold', + root: 'items-center', + label: 'ml-1.5 text-base/5 font-semibold', }" - @change="vibrate" + @change="vibrate()" /> diff --git a/apps/atrium-telegram/app/components/form/CompleteTask.vue b/apps/atrium-telegram/app/components/form/CompleteTask.vue index 94e4be7b..fc45e64a 100644 --- a/apps/atrium-telegram/app/components/form/CompleteTask.vue +++ b/apps/atrium-telegram/app/components/form/CompleteTask.vue @@ -50,6 +50,7 @@ const { taskId } = defineProps<{ const emit = defineEmits(['success', 'submitted']) const { t } = useI18n() +const { vibrate } = useFeedback() const actionToast = useActionToast() const userStore = useUserStore() const taskStore = useTaskStore() @@ -80,10 +81,12 @@ async function onSubmit(event: FormSubmitEvent) { ]) actionToast.success(toastId, t('toast.task-completed')) + vibrate('success') emit('success') } catch (error) { console.error(error) actionToast.error(toastId) + vibrate('error') } } diff --git a/apps/atrium-telegram/app/components/form/CreateTask.vue b/apps/atrium-telegram/app/components/form/CreateTask.vue index dae0f724..a104874d 100644 --- a/apps/atrium-telegram/app/components/form/CreateTask.vue +++ b/apps/atrium-telegram/app/components/form/CreateTask.vue @@ -96,6 +96,7 @@ const { performerId, listId } = defineProps<{ const emit = defineEmits(['success', 'submitted']) const { t } = useI18n() +const { vibrate } = useFeedback() const actionToast = useActionToast() const taskStore = useTaskStore() @@ -170,10 +171,12 @@ async function onSubmit(event: FormSubmitEvent) { await taskStore.update() actionToast.success(toastId, t('toast.task-created')) + vibrate('success') emit('success') } catch (error) { console.error(error) actionToast.error(toastId) + vibrate('error') } } diff --git a/apps/atrium-telegram/app/components/form/CreateTaskList.vue b/apps/atrium-telegram/app/components/form/CreateTaskList.vue index c1e7b7e3..773a9c86 100644 --- a/apps/atrium-telegram/app/components/form/CreateTaskList.vue +++ b/apps/atrium-telegram/app/components/form/CreateTaskList.vue @@ -59,6 +59,7 @@ const emit = defineEmits(['success', 'submitted']) type FormMember = { label: string, value: string, avatar: { src: string | undefined, alt: string } } const { t } = useI18n() +const { vibrate } = useFeedback() const actionToast = useActionToast() const userStore = useUserStore() @@ -103,10 +104,12 @@ async function onSubmit(event: FormSubmitEvent) { ]) actionToast.success(toastId, t('toast.task-list-created')) + vibrate('success') emit('success') } catch (error) { console.error(error) actionToast.error(toastId) + vibrate('error') } } diff --git a/apps/atrium-telegram/app/components/form/UpdateTask.vue b/apps/atrium-telegram/app/components/form/UpdateTask.vue index 286e0e1f..f501ece2 100644 --- a/apps/atrium-telegram/app/components/form/UpdateTask.vue +++ b/apps/atrium-telegram/app/components/form/UpdateTask.vue @@ -111,6 +111,7 @@ const { taskId } = defineProps<{ const emit = defineEmits(['success', 'submitted']) const { t } = useI18n() +const { vibrate } = useFeedback() const actionToast = useActionToast() const userStore = useUserStore() @@ -197,10 +198,12 @@ async function onSubmit(event: FormSubmitEvent) { await taskStore.update() actionToast.success(toastId, t('toast.task-updated')) + vibrate('success') emit('success') } catch (error) { console.error(error) actionToast.error(toastId) + vibrate('error') } } @@ -219,10 +222,12 @@ async function onDelete() { await taskStore.update() actionToast.success(toastId, t('toast.task-deleted')) + vibrate('success') emit('success') } catch (error) { console.error(error) actionToast.error(toastId) + vibrate('error') } } diff --git a/apps/atrium-telegram/app/components/form/UpdateTaskList.vue b/apps/atrium-telegram/app/components/form/UpdateTaskList.vue index 83fd00dd..f37cb8f5 100644 --- a/apps/atrium-telegram/app/components/form/UpdateTaskList.vue +++ b/apps/atrium-telegram/app/components/form/UpdateTaskList.vue @@ -73,6 +73,7 @@ const emit = defineEmits(['success', 'submitted']) type FormMember = { label: string, value: string, avatar: { src: string | undefined, alt: string } } const { t } = useI18n() +const { vibrate } = useFeedback() const actionToast = useActionToast() const userStore = useUserStore() @@ -119,10 +120,12 @@ async function onSubmit(event: FormSubmitEvent) { await taskStore.update() actionToast.success(toastId, t('toast.task-list-updated')) + vibrate('success') emit('success') } catch (error) { console.error(error) actionToast.error(toastId) + vibrate('error') } } @@ -141,10 +144,12 @@ async function onDelete() { await taskStore.update() actionToast.success(toastId, t('toast.task-list-deleted')) + vibrate('success') emit('success') } catch (error) { console.error(error) actionToast.error(toastId) + vibrate('error') } } diff --git a/apps/atrium-telegram/app/components/form/UploadUserAvatar.vue b/apps/atrium-telegram/app/components/form/UploadUserAvatar.vue index 0c9a40ca..b9ce30d9 100644 --- a/apps/atrium-telegram/app/components/form/UploadUserAvatar.vue +++ b/apps/atrium-telegram/app/components/form/UploadUserAvatar.vue @@ -36,6 +36,7 @@ import { uploadMediaSchema } from '#shared/services/media' const emit = defineEmits(['success', 'submitted']) const { t } = useI18n() +const { vibrate } = useFeedback() const actionToast = useActionToast() const userStore = useUserStore() @@ -74,10 +75,12 @@ async function onSubmit(event: FormSubmitEvent) { await userStore.update() actionToast.success(toastId, t('toast.photo-loaded')) + vibrate('success') emit('success') } catch (error) { console.error(error) actionToast.error(toastId) + vibrate('error') } } diff --git a/apps/atrium-telegram/app/composables/useFeedback.ts b/apps/atrium-telegram/app/composables/useFeedback.ts index 3a1a539d..a176a16a 100644 --- a/apps/atrium-telegram/app/composables/useFeedback.ts +++ b/apps/atrium-telegram/app/composables/useFeedback.ts @@ -1,10 +1,18 @@ import { hapticFeedback } from '@telegram-apps/sdk-vue' function _useFeedback() { - function vibrate() { - if (hapticFeedback.impactOccurred.isAvailable()) { + function vibrate(type: 'light' | 'success' | 'error' = 'light') { + if (type === 'light' && hapticFeedback.impactOccurred.isAvailable()) { hapticFeedback.impactOccurred('light') } + + if (type === 'success' && hapticFeedback.notificationOccurred.isAvailable()) { + hapticFeedback.notificationOccurred('success') + } + + if (type === 'error' && hapticFeedback.notificationOccurred.isAvailable()) { + hapticFeedback.notificationOccurred('error') + } } return { diff --git a/apps/atrium-telegram/app/pages/index.vue b/apps/atrium-telegram/app/pages/index.vue index 91d6256e..15ff04b5 100644 --- a/apps/atrium-telegram/app/pages/index.vue +++ b/apps/atrium-telegram/app/pages/index.vue @@ -1,44 +1,42 @@ diff --git a/apps/atrium-telegram/app/stores/task.ts b/apps/atrium-telegram/app/stores/task.ts index 46724695..988ad344 100644 --- a/apps/atrium-telegram/app/stores/task.ts +++ b/apps/atrium-telegram/app/stores/task.ts @@ -13,6 +13,7 @@ type TaskListWithData = TaskList & { export const useTaskStore = defineStore('task', () => { const lists = ref([]) const isTodayOnly = ref(false) + const isInitialized = ref(false) const initDataRaw = useSignal(_initDataRaw) @@ -28,6 +29,8 @@ export const useTaskStore = defineStore('task', () => { } lists.value = data + + isInitialized.value = true } catch (error) { if (error instanceof Error) { if (error.message.includes('401')) { @@ -77,6 +80,7 @@ export const useTaskStore = defineStore('task', () => { return { lists, isTodayOnly, + isInitialized, update, setAsFocused, From 96a81a5d3f0543d87b258f5b7e36169940064c3f Mon Sep 17 00:00:00 2001 From: Nick Kosarev Date: Wed, 27 Aug 2025 16:32:37 +0200 Subject: [PATCH 2/2] chore: update --- apps/atrium-telegram/app/app.config.ts | 2 +- apps/atrium-telegram/app/components/Navigation.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/atrium-telegram/app/app.config.ts b/apps/atrium-telegram/app/app.config.ts index a56d2719..00821b0b 100644 --- a/apps/atrium-telegram/app/app.config.ts +++ b/apps/atrium-telegram/app/app.config.ts @@ -26,7 +26,7 @@ export default defineAppConfig({ }, modal: { slots: { - content: 'divide-y-0', + content: 'divide-y-0 !ring-muted/50', header: 'pb-0 min-h-12', title: 'text-lg/5 font-semibold', }, diff --git a/apps/atrium-telegram/app/components/Navigation.vue b/apps/atrium-telegram/app/components/Navigation.vue index 9daaa332..a4a264d1 100644 --- a/apps/atrium-telegram/app/components/Navigation.vue +++ b/apps/atrium-telegram/app/components/Navigation.vue @@ -1,5 +1,5 @@