diff --git a/src/routes/cloud/+page.svelte b/src/routes/cloud/+page.svelte index e043b3a..c8e4d0b 100644 --- a/src/routes/cloud/+page.svelte +++ b/src/routes/cloud/+page.svelte @@ -2,21 +2,28 @@ import { processFiles } from '$lib/upload'; import Loader from '$lib/components/Loader.svelte'; import { formatBytes, showSnackbar } from '$lib/util'; - import { Card } from 'flowbite-svelte'; + import { Button, Frame, Listgroup, ListgroupItem } from 'flowbite-svelte'; import { onMount } from 'svelte'; import { promptConfirmation } from '$lib/util'; import { GoogleSolid } from 'flowbite-svelte-icons'; + import { volumes } from '$lib/settings'; const CLIENT_ID = import.meta.env.VITE_GDRIVE_CLIENT_ID; const API_KEY = import.meta.env.VITE_GDRIVE_API_KEY; const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'; const SCOPES = 'https://www.googleapis.com/auth/drive'; + const FILES_API_URL = 'https://www.googleapis.com/upload/drive/v3/files'; + const FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder'; + const READER_FOLDER = 'mokuro-reader'; + const VOLUME_DATA_FILE = 'volume-data.json'; let tokenClient: any; let zips: gapi.client.drive.File[]; let loadingMessage = ''; + let readerFolderId = ''; + let volumeDataId = ''; async function fetchZips(folderId: string) { const { result } = await gapi.client.drive.files.list({ @@ -78,19 +85,34 @@ loadingMessage = 'Connecting to drive'; - const { result } = await gapi.client.drive.files.list({ - q: `mimeType='application/vnd.google-apps.folder' and name='MokuroReader'`, + const { result: readerFolderRes } = await gapi.client.drive.files.list({ + q: `mimeType='application/vnd.google-apps.folder' and name='${READER_FOLDER}'`, fields: 'files(id)' }); - if (result.files?.length === 0) { - await gapi.client.drive.files.create({ - resource: { mimeType: FOLDER_MIME_TYPE, name: 'MokuroReader' }, + if (readerFolderRes.files?.length === 0) { + const { result: createReaderFolderRes } = await gapi.client.drive.files.create({ + resource: { mimeType: FOLDER_MIME_TYPE, name: READER_FOLDER }, fields: 'id' }); - } else { - zips = [...((await fetchZips(result.files?.[0]?.id || '')) || [])]; + + readerFolderId = createReaderFolderRes.id || ''; loadingMessage = ''; + } else { + const id = readerFolderRes.files?.[0]?.id || ''; + zips = [...((await fetchZips(id)) || [])]; + + readerFolderId = id || ''; + loadingMessage = ''; + } + + const { result: volumeDataRes } = await gapi.client.drive.files.list({ + q: `'${readerFolderId}' in parents and name='${VOLUME_DATA_FILE}'`, + fields: 'files(id, name)' + }); + + if (volumeDataRes.files?.length !== 0) { + volumeDataId = volumeDataRes.files?.[0].id || ''; } showSnackbar('Connected to Google Drive'); @@ -123,6 +145,62 @@ callback: connectDrive }); }); + + async function onUpload() { + const type = 'application/json'; + const json = localStorage.getItem('volumes') || ''; + const blob = new Blob([json], { type }); + + const metadata = { + mimeType: type, + name: VOLUME_DATA_FILE, + parents: [volumeDataId ? null : readerFolderId] + }; + + const { access_token } = gapi.auth.getToken(); + + const form = new FormData(); + + form.append('resource', new Blob([JSON.stringify(metadata)], { type })); + form.append('file', blob); + + loadingMessage = 'Uploading volume data'; + + const res = await fetch( + `${FILES_API_URL}${volumeDataId ? `/${volumeDataId}` : ''}?uploadType=multipart`, + { + method: volumeDataId ? 'PATCH' : 'POST', + headers: new Headers({ Authorization: 'Bearer ' + access_token }), + body: form + } + ); + volumeDataId = (await res.json()).id; + + loadingMessage = ''; + + showSnackbar('Volume data uploaded'); + } + + async function onDownload() { + loadingMessage = 'Downloading volume data'; + + const { body } = await gapi.client.drive.files.get({ + fileId: volumeDataId, + alt: 'media' + }); + + const downloaded = JSON.parse(body); + + volumes.update((prev) => { + return { + ...prev, + ...downloaded + }; + }); + + loadingMessage = ''; + showSnackbar('Volume data downloaded'); + }
@@ -131,15 +209,50 @@ {loadingMessage} {:else if zips} -
-

Google drive:

-
- {#each zips as zip} - onClick(zip)}> -

{zip.name}

-

{formatBytes(parseInt(zip.size || '0'))}

-
- {/each} +
+
+

Google Drive:

+
+ {#if zips.length > 0} + + {#each zips as zip} + onClick(zip)} + rounded + border + class="divide-y divide-gray-200 dark:divide-gray-600" + > + +
+

{zip.name}

+

{formatBytes(parseInt(zip.size || '0'))}

+
+
+ + {/each} +
+ {:else} +

+ Add your zip files to the {READER_FOLDER} folder + in your Google Drive. +

+ {/if} +
+
+
+ + {#if volumeDataId} + + {/if}
{:else} @@ -147,7 +260,7 @@ class="w-full border rounded-lg border-slate-600 p-10 border-opacity-50 hover:bg-slate-800" on:click={signIn} > -
+

Connect to Google Drive