Skip to content

Commit

Permalink
feat: finish migration script
Browse files Browse the repository at this point in the history
  • Loading branch information
AlejandroAkbal committed Dec 17, 2023
1 parent eace60e commit 9c429f9
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 168 deletions.
61 changes: 48 additions & 13 deletions assets/js/BackupHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { VuexUser } from '~/assets/js/oldLocalStorage.dto'
import { cloneDeep, toLower, union, unionWith } from 'lodash-es'
import type { Domain } from '~/assets/js/domain'
import { booruTypeList } from '~/assets/lib/rule-34-shared-resources/src/util/BooruUtils'
import type { IPost } from '~/assets/js/post'

export interface IBackupState {
version: number
Expand Down Expand Up @@ -86,7 +87,7 @@ export function removeOldVersionState() {
localStorage.removeItem('vuex-notifications')
}

export function migrateOldVersionState(): void {
export async function migrateOldVersionState(): Promise<void> {
const { tagCollections } = useTagCollections()
const userSettings = useUserSettings()
const { booruList } = useBooruList()
Expand All @@ -107,28 +108,62 @@ export function migrateOldVersionState(): void {
if (vuexUser.user.settings.postsPerPage) userSettings.postsPerPage = vuexUser.user.settings.postsPerPage.value

// === Migrate tag collections
if (vuexUser.user.custom.tagCollections) {
if (vuexUser.user.custom.tagCollections?.length) {
tagCollections.value = mergeBlocklists(tagCollections.value, vuexUser.user.custom.tagCollections)
}

// === Migrate Boorus
const vuexUserBoorusMigrated = vuexUser.user.custom.boorus.map((booru) => {
return {
domain: booru.domain,
if (!vuexUser.user.custom.boorus?.length) {
const vuexUserBoorusMigrated = vuexUser.user.custom.boorus.map((booru) => {
return {
domain: booru.domain,

type: booruTypeList.find((type) => type.type === booru.type),
type: booruTypeList.find((type) => type.type === booru.type),

config: booru.config,
config: booru.config,

isPremium: true
}
}) as Domain[]
isPremium: true
}
}) as Domain[]

booruList.value = unionWith(booruList.value, vuexUserBoorusMigrated, (obj1, obj2) => {
return obj1.domain === obj2.domain
})
booruList.value = unionWith(booruList.value, vuexUserBoorusMigrated, (obj1, obj2) => {
return obj1.domain === obj2.domain
})
}

// === Migrate saved posts
if (vuexUser.user.custom.savedPosts?.length) {
const { posts } = postsDb

const oldSavedPostsAsNewSavedPosts = vuexUser.user.custom.savedPosts.map((oldSavedPost) => {
const newSavedPost: ISavedPost = {
original_id: oldSavedPost.data.id,
original_domain: oldSavedPost.meta_data.booru_domain,

data: {
id: oldSavedPost.data.id,

score: oldSavedPost.data.score,

high_res_file: oldSavedPost.data.high_res_file,
low_res_file: oldSavedPost.data.low_res_file,
preview_file: oldSavedPost.data.preview_file,

tags: oldSavedPost.data.tags,

rating: oldSavedPost.data.rating,

media_type: oldSavedPost.data.media_type as IPost['media_type'],

sources: oldSavedPost.data.sources
}
}

return newSavedPost
})

await posts.bulkAdd(oldSavedPostsAsNewSavedPosts)
}

removeOldVersionState()
}
Expand Down
228 changes: 114 additions & 114 deletions components/pages/posts/post/Post.vue
Original file line number Diff line number Diff line change
@@ -1,168 +1,168 @@
<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 type { 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(', ')
}
<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 type { 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(', ')
}
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:
data.file = props.post.high_res_file.url
data.width = props.post.high_res_file.width
data.height = props.post.high_res_file.height
}
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
})
data.posterFile = props.post.preview_file.url
break
/**
* 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 = []
for (const [type, tagsArray] of Object.entries(props.post.tags)) {
for (const tag of tagsArray) {
tags.push({ name: tag, type })
}
}
default:
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 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.info('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 onClickTag(tag: Tag) {
emit('clickTag', tag.name)
if (!tutorialLongClickTag.value) {
toast('Tip: long click a tag to exclude it from search results')
tutorialLongClickTag.value = true
function onClickLongTag(tag: Tag) {
emit('clickLongTag', tag.name)
}
}
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
v-if='mediaFile.file'
:post='post'
:postId='postName'
v-if="mediaFile.file"
:post="post"
:postId="postName"
/>

<PostDownload
v-if='mediaFile.file'
:mediaName='postName'
:mediaUrl='mediaFile.file'
v-if="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='() => onClickLongTag(tag)'
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 @@ -175,11 +175,11 @@ function onClickLongTag(tag: Tag) {
(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='onClickTag(tag)'
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
Loading

0 comments on commit 9c429f9

Please sign in to comment.