Skip to content

Commit

Permalink
feat: extract and finish backup
Browse files Browse the repository at this point in the history
  • Loading branch information
AlejandroAkbal committed Oct 27, 2023
1 parent 2d44519 commit 45b0e7a
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 97 deletions.
69 changes: 69 additions & 0 deletions assets/js/BackupHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { db as postsDb, ISavedPost } from '~/store/SavedPosts'
import { ITagCollection } from 'assets/js/tagCollection.dto'

export interface IBackupState {
version: number

saved_posts: ISavedPost[]
tag_collections: ITagCollection[]

settings: {
[key: string]: any
}
}

export async function createBackupState(): Promise<IBackupState> {
const savedPosts = await postsDb.posts.toArray()
const { tagCollections } = useTagCollections()
const userSettings = useUserSettings()

// TODO: Only save data that is not defaulted

const backupState: IBackupState = {
version: 1,

saved_posts: savedPosts,
tag_collections: tagCollections.value,

settings: userSettings
}

return backupState
}

export async function restoreBackupState(backupState: IBackupState): Promise<void> {
if (backupState.version !== 1) {
throw new Error('Backup version not supported')
}

if (backupState.saved_posts) {
const { posts } = postsDb

await posts.clear()

await posts.bulkAdd(backupState.saved_posts)
}

if (backupState.tag_collections) {
const { tagCollections } = useTagCollections()

tagCollections.value = backupState.tag_collections
}

if (backupState.settings) {
const userSettings = useUserSettings()

if (backupState.settings.navigationTouchGestures)
userSettings.navigationTouchGestures = backupState.settings.navigationTouchGestures

if (backupState.settings.postFullSizeImages)
userSettings.postFullSizeImages = backupState.settings.postFullSizeImages

if (backupState.settings.postsPerPage)
userSettings.postsPerPage = backupState.settings.postsPerPage

if (backupState.settings.lastPostsPage)
userSettings.lastPostsPage = backupState.settings.lastPostsPage

}
}
51 changes: 8 additions & 43 deletions pages/premium/backup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,7 @@
import { ArrowDownTrayIcon, ArrowUturnLeftIcon } from '@heroicons/vue/24/solid'
import PageHeader from '~/components/layout/PageHeader.vue'
import { toast } from 'vue-sonner'
import type { ISavedPost } from '~/store/SavedPosts'
import { db as postsDb } from '~/store/SavedPosts'
import type { ITagCollection } from 'assets/js/tagCollection.dto'
interface IBackupState {
version: number
saved_posts: ISavedPost[]
tag_collections: ITagCollection[]
settings: {
[key: string]: any
}
}
import { createBackupState, IBackupState, restoreBackupState } from 'assets/js/BackupHelper'
const fileInputElement = ref<HTMLInputElement | null>(null)
Expand All @@ -39,10 +26,6 @@ function downloadBlob(blob: Blob, filename: string) {
}
async function createBackup() {
const savedPosts = await postsDb.posts.toArray()
const { tagCollections } = useTagCollections()
const userSettings = useUserSettings()
const currentDateString = new Date()
.toLocaleString([], {
timeZone: 'UTC',
Expand All @@ -58,17 +41,9 @@ async function createBackup() {
.replaceAll('/', '-')
.replaceAll(':', '-')
// TODO: Only save data that is not defaulted
const STATE: IBackupState = {
version: 1,
const backupState = await createBackupState()
saved_posts: savedPosts,
tag_collections: tagCollections.value,
settings: userSettings
}
const blob = new Blob([JSON.stringify(STATE)], { type: 'application/json' })
const blob = new Blob([JSON.stringify(backupState)], { type: 'application/json' })
const fileName = `R34App_${ currentDateString }_Backup.json`
Expand All @@ -88,25 +63,15 @@ async function restoreBackup() {
return
}
const backupData: IBackupState = JSON.parse(await file.text())
const backupState: IBackupState = JSON.parse(await file.text())
if (backupData.version !== 1) {
toast.error('Invalid backup file')
try {
await restoreBackupState(backupState)
} catch (error) {
toast.error(`Failed to restore backup: ${ error }`)
return
}
if (backupData.saved_posts) {
// TODO
}
if (backupData.tag_collections) {
// TODO
}
if (backupData.settings) {
// TODO
}
toast.success('Backup restored')
}
Expand Down
106 changes: 53 additions & 53 deletions pages/premium/dashboard.vue
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
<script lang="ts" setup>
import { ArrowLeftOnRectangleIcon } from '@heroicons/vue/24/solid'
<script lang='ts' setup>
import { ArrowLeftOnRectangleIcon } from '@heroicons/vue/24/solid'
const { data, signOut: _signOut } = useAuth()
const { data, signOut: _signOut } = useAuth()
const links = [
{
name: 'Saved posts',
description: 'Save posts to your device and enjoy them later',
href: '/premium/saved-posts'
},
{
name: 'Tag collections',
description: 'Create lists of tags to quickly search or filter posts',
href: '/premium/tag-collections'
},
{
name: 'Additional Boorus',
description: 'Browse posts from other Boorus',
href: '/premium/booru'
},
{
name: 'Backup',
description: 'Backup your saved posts, tag collections and settings',
href: '/premium/backup'
}
]
function signOut() {
_signOut()
window.location.reload()
const links = [
{
name: 'Saved posts',
description: 'Save posts to your device and enjoy them later',
href: '/premium/saved-posts'
},
{
name: 'Tag collections',
description: 'Create lists of tags to quickly search or filter posts',
href: '/premium/tag-collections'
},
{
name: 'Additional Boorus',
description: 'Browse posts from other Boorus',
href: '/premium/booru'
},
{
name: 'Backup & Restore',
description: 'Backup your saved posts, tag collections and settings',
href: '/premium/backup'
}
]
function signOut() {
_signOut()
window.location.reload()
}
useSeoMeta({
title: 'Premium dashboard'
})
useSeoMeta({
title: 'Premium dashboard'
})
definePageMeta({ middleware: 'auth' })
definePageMeta({ middleware: 'auth' })
</script>

<template>
<!-- Sign out -->
<SafeTeleport to="#navbar-actions">
<SafeTeleport to='#navbar-actions'>
<button
class="focus-visible:focus-outline-util hover:hover-bg-util hover:hover-text-util relative rounded-md p-2"
type="button"
@click="signOut"
class='focus-visible:focus-outline-util hover:hover-bg-util hover:hover-text-util relative rounded-md p-2'
type='button'
@click='signOut'
>
<span class="sr-only">Sign out</span>
<span class='sr-only'>Sign out</span>

<ArrowLeftOnRectangleIcon class="h-6 w-6 text-base-content-highlight" />
<ArrowLeftOnRectangleIcon class='h-6 w-6 text-base-content-highlight' />
</button>
</SafeTeleport>

<main class="container mx-auto max-w-3xl flex-1 px-4 py-4 sm:px-6 lg:px-8">
<main class='container mx-auto max-w-3xl flex-1 px-4 py-4 sm:px-6 lg:px-8'>
<!-- -->

<!-- Status -->
Expand All @@ -61,11 +61,11 @@
<PageHeader>
<template #title>Premium dashboard</template>
<template #text>
<p class="truncate">
<p class='truncate'>
Signed in as

<span
class="inline-flex items-center rounded-md bg-primary-400/10 px-2 py-1 text-sm font-medium text-primary-400 ring-1 ring-inset ring-primary-400/20"
class='inline-flex items-center rounded-md bg-primary-400/10 px-2 py-1 text-sm font-medium text-primary-400 ring-1 ring-inset ring-primary-400/20'
>
{{ data.email }}
</span>
Expand All @@ -75,32 +75,32 @@

<!-- Links -->
<section>
<ol class="mt-6 space-y-4">
<ol class='mt-6 space-y-4'>
<!-- -->

<NuxtLink
v-for="link in links"
:key="link.name"
:href="link.href"
class="hover:hover-bg-util focus-visible:focus-outline-util block w-full rounded-md border border-base-0/20 px-4 py-3"
v-for='link in links'
:key='link.name'
:href='link.href'
class='hover:hover-bg-util focus-visible:focus-outline-util block w-full rounded-md border border-base-0/20 px-4 py-3'
>
<h2 class="text-lg font-bold tracking-tight text-base-content-highlight">
<h2 class='text-lg font-bold tracking-tight text-base-content-highlight'>
{{ link.name }}
</h2>

<p class="text-sm">
<p class='text-sm'>
{{ link.description }}
</p>
</NuxtLink>
</ol>
</section>

<!-- Manage subscription -->
<section class="absolute inset-x-0 bottom-0 w-full p-4 text-center">
<section class='absolute inset-x-0 bottom-0 w-full p-4 text-center'>
<NuxtLink
class="hover:hover-text-util focus-visible:focus-outline-util underline"
href="https://app.gumroad.com/library?query=Rule+34+App"
target="_blank"
class='hover:hover-text-util focus-visible:focus-outline-util underline'
href='https://app.gumroad.com/library?query=Rule+34+App'
target='_blank'
>
Manage subscription
</NuxtLink>
Expand Down
1 change: 0 additions & 1 deletion pages/premium/saved-posts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ definePageMeta({ middleware: 'auth' })
<main class='container mx-auto max-w-3xl flex-1 px-4 py-4 sm:px-6 lg:px-8'>
<PageHeader>
<template #title>Saved posts</template>
<template #text>Save posts to your device and enjoy them later</template>
</PageHeader>

<section
Expand Down

0 comments on commit 45b0e7a

Please sign in to comment.