Skip to content

Commit

Permalink
feat: add tutorial about long click tag
Browse files Browse the repository at this point in the history
  • Loading branch information
AlejandroAkbal committed Aug 7, 2023
1 parent 34f6c66 commit 210a8b9
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 94 deletions.
203 changes: 110 additions & 93 deletions components/pages/posts/post/Post.vue
Original file line number Diff line number Diff line change
@@ -1,147 +1,164 @@
<script lang='ts' setup>
import { useUserSettings } from '~/composables/useUserSettings'
import { ChevronDownIcon } from '@heroicons/vue/24/outline'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue'
import { vOnLongPress } from '@vueuse/components'
import Tag from 'assets/js/tag.dto'
import { IPost } from 'assets/js/post'
const props = defineProps<{
postName: string
post: IPost
selectedTags: Tag[]
}>()
const emit = defineEmits<{
clickTag: [tag: string]
clickLongTag: [tag: string]
}>()
const userSettings = useUserSettings()
<script lang="ts" setup>
import { useUserSettings } from '~/composables/useUserSettings'
import { ChevronDownIcon } from '@heroicons/vue/24/outline'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue'
import { vOnLongPress } from '@vueuse/components'
import Tag from 'assets/js/tag.dto'
import { IPost } from 'assets/js/post'
import { toast } from 'vue-sonner'
import { useAppStatistics } from '~/composables/useAppStatistics'
const props = defineProps<{
postName: string
post: IPost
selectedTags: Tag[]
}>()
const emit = defineEmits<{
clickTag: [tag: string]
clickLongTag: [tag: string]
}>()
const userSettings = useUserSettings()
const { tutorialLongClickTag } = useAppStatistics()
const mediaFile = computed(() => {
const data = {
file: null,
width: null,
height: null,
posterFile: null,
alt: 'Post with tags: ' + tagsAsSingleArray.value.map((tag) => tag.name).join(', ')
}
const mediaFile = computed(() => {
const data = {
file: null,
width: null,
height: null,
posterFile: null,
alt: 'Post with tags: ' + tagsAsSingleArray.value.map((tag) => tag.name).join(', ')
}
switch (props.post.media_type) {
case 'image': {
// Return full image if its setting is enabled OR if low resolution file doesn't exist
if (!props.post.low_res_file.url || userSettings.postFullSizeImages) {
data.file = props.post.high_res_file.url
data.width = props.post.high_res_file.width
data.height = props.post.high_res_file.height
} else {
// Return low res file
data.file = props.post.low_res_file.url
data.width = props.post.low_res_file.width ?? props.post.high_res_file.width
data.height = props.post.low_res_file.height ?? props.post.high_res_file.height
}
break
}
switch (props.post.media_type) {
case 'image': {
// Return full image if its setting is enabled OR if low resolution file doesn't exist
if (!props.post.low_res_file.url || userSettings.postFullSizeImages) {
case 'video': {
data.file = props.post.high_res_file.url
data.width = props.post.high_res_file.width
data.height = props.post.high_res_file.height
} else {
// Return low res file
data.file = props.post.low_res_file.url
data.width = props.post.low_res_file.width ?? props.post.high_res_file.width
data.height = props.post.low_res_file.height ?? props.post.high_res_file.height
data.posterFile = props.post.preview_file.url
break
}
break
default:
throw new Error('Unknown media type: ' + props.post.media_type)
}
case 'video': {
data.file = props.post.high_res_file.url
data.width = props.post.high_res_file.width
data.height = props.post.high_res_file.height
return data
})
/**
* Take in an object of tags like { character: ['tag1', 'tag2'], artist: ['tag3', 'tag4'] }
* and return an array of tags like [{ name: 'tag1', type: 'character' }, { name: 'tag2', type: 'character' }, { name: 'tag3', type: 'artist' }, { name: 'tag4', type: 'artist' }]
* @returns {Array<{ name: string, type: string }>}
*/
const tagsAsSingleArray = computed(() => {
const tags = []
data.posterFile = props.post.preview_file.url
break
for (const [type, tagsArray] of Object.entries(props.post.tags)) {
for (const tag of tagsArray) {
tags.push({ name: tag, type })
}
}
default:
throw new Error('Unknown media type: ' + props.post.media_type)
}
return tags
})
return data
})
function onClickTag(tag: Tag) {
emit('clickTag', tag.name)
/**
* Take in an object of tags like { character: ['tag1', 'tag2'], artist: ['tag3', 'tag4'] }
* and return an array of tags like [{ name: 'tag1', type: 'character' }, { name: 'tag2', type: 'character' }, { name: 'tag3', type: 'artist' }, { name: 'tag4', type: 'artist' }]
* @returns {Array<{ name: string, type: string }>}
*/
const tagsAsSingleArray = computed(() => {
const tags = []
if (!tutorialLongClickTag.value) {
toast('Tip: long click a tag to exclude it from search results')
for (const [type, tagsArray] of Object.entries(props.post.tags)) {
for (const tag of tagsArray) {
tags.push({ name: tag, type })
tutorialLongClickTag.value = true
}
}
return tags
})
function onClickLongTag(tag: Tag) {
emit('clickLongTag', tag.name)
}
</script>

<template>
<figure class='overflow-hidden rounded-md border border-base-0/20'>
<figure class="overflow-hidden rounded-md border border-base-0/20">
<PostMedia
:mediaAlt='mediaFile.alt'
:mediaPosterSrc='mediaFile.posterFile'
:mediaSrc='mediaFile.file'
:mediaSrcHeight='mediaFile.height'
:mediaSrcWidth='mediaFile.width'
:mediaType='post.media_type'
:mediaAlt="mediaFile.alt"
:mediaPosterSrc="mediaFile.posterFile"
:mediaSrc="mediaFile.file"
:mediaSrcHeight="mediaFile.height"
:mediaSrcWidth="mediaFile.width"
:mediaType="post.media_type"
/>

<Disclosure
v-slot='{ open }'
as='figcaption'
v-slot="{ open }"
as="figcaption"
>
<!-- Actions -->
<div class='flex items-center p-2'>
<div class="flex items-center p-2">
<PostSave
:post='post'
:postId='postName'
:post="post"
:postId="postName"
/>

<PostDownload
:mediaName='postName'
:mediaUrl='mediaFile.file'
:mediaName="postName"
:mediaUrl="mediaFile.file"
/>

<PostSource
v-if="post.media_type === 'image'"
:post-file-url='mediaFile.file'
:post-sources='post.sources'
:post-file-url="mediaFile.file"
:post-sources="post.sources"
/>

<DisclosureButton
class='hover:hover-bg-util focus-visible:focus-outline-util group ml-auto flex items-center gap-1 rounded-md px-1.5 py-1'
type='button'
class="hover:hover-bg-util focus-visible:focus-outline-util group ml-auto flex items-center gap-1 rounded-md px-1.5 py-1"
type="button"
>
<span class='group-hover:hover-text-util text-sm text-base-content'> Tags </span>
<span class="group-hover:hover-text-util text-sm text-base-content"> Tags </span>

<ChevronDownIcon
:class="{
'rotate-180 transform': open,
'rotate-0 transform': !open
}"
class='group-hover:hover-text-util h-5 w-5 text-base-content'
class="group-hover:hover-text-util h-5 w-5 text-base-content"
/>
</DisclosureButton>
</div>

<!-- Tags -->
<DisclosurePanel
as='ol'
class='flex flex-wrap gap-2 p-2'
as="ol"
class="flex flex-wrap gap-2 p-2"
>
<li
v-for='tag in tagsAsSingleArray'
:key='tag.name'
v-for="tag in tagsAsSingleArray"
:key="tag.name"
>
<button
v-on-long-press.prevent.stop="() => emit('clickLongTag', tag.name)"
v-on-long-press.prevent.stop="() => onClickLongTag(tag)"
:class="{
'bg-primary-400/20 text-primary-400/90 ring-accent-400/20 hover:bg-primary-400/20': tag.type === 'artist',
'bg-green-400/20 text-green-400/90 ring-green-400/20 hover:bg-green-400/20': tag.type === 'copyright',
Expand All @@ -154,11 +171,11 @@ const tagsAsSingleArray = computed(() => {
(selectedTag) => selectedTag.name === tag.name
)
}"
class='focus-visible:focus-outline-util group inline-flex items-center rounded-full px-2 py-1 ring-1 ring-inset ring-base-0/20'
type='button'
@click="emit('clickTag', tag.name)"
class="focus-visible:focus-outline-util group inline-flex items-center rounded-full px-2 py-1 ring-1 ring-inset ring-base-0/20"
type="button"
@click="onClickTag(tag)"
>
<span class='group-hover:hover-text-util text-xs font-medium'>
<span class="group-hover:hover-text-util text-xs font-medium">
{{ tag.name }}
</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ const timesTheAppHasBeenOpened = useStorage('statistics-appOpenedCount', 0, loca
writeDefaults: false
})

const tutorialLongClickTag = useStorage('tutorial-longClickTag', false, localStorage, {
writeDefaults: false
})

// Add one to the timesTheAppHasBeenOpened
timesTheAppHasBeenOpened.value++

export function useAppStatistics() {
return {
timesTheAppHasBeenOpened
timesTheAppHasBeenOpened,

tutorialLongClickTag
}
}
File renamed without changes.

0 comments on commit 210a8b9

Please sign in to comment.