diff --git a/components/tag/TagActionButton.vue b/components/tag/TagActionButton.vue index 21747227..7c46c8d0 100644 --- a/components/tag/TagActionButton.vue +++ b/components/tag/TagActionButton.vue @@ -12,12 +12,24 @@ const emit = defineEmits<{ const { client } = $(useMasto()) const toggleFollowTag = async () => { - if (tag.following) - await client.v1.tags.unfollow(tag.name) - else - await client.v1.tags.follow(tag.name) + // We save the state so be can do an optimistic UI update, but fallback to the previous state if the API call fails + const previousFollowingState = tag.following - emit('change') + // eslint-disable-next-line vue/no-mutating-props + tag.following = !tag.following + + try { + if (tag.following) + await client.v1.tags.unfollow(tag.name) + else + await client.v1.tags.follow(tag.name) + + emit('change') + } + catch (error) { + // eslint-disable-next-line vue/no-mutating-props + tag.following = previousFollowingState + } } diff --git a/components/tag/TagCard.vue b/components/tag/TagCard.vue index 60a70eb2..b9ec730b 100644 --- a/components/tag/TagCard.vue +++ b/components/tag/TagCard.vue @@ -11,12 +11,34 @@ const to = $computed(() => { const { hostname, pathname } = new URL(tag.url) return `/${hostname}${pathname}` }) + +const router = useRouter() + +function onclick(evt: MouseEvent | KeyboardEvent) { + const path = evt.composedPath() as HTMLElement[] + const el = path.find(el => ['A', 'BUTTON'].includes(el.tagName?.toUpperCase())) + const text = window.getSelection()?.toString() + if (!el && !text) + go(evt) +} + +function go(evt: MouseEvent | KeyboardEvent) { + if (evt.metaKey || evt.ctrlKey) + window.open(to) + else + router.push(to) +}