Feat: move gallery code to gallery domain (#69)
This commit is contained in:
parent
9bf8f8123f
commit
44fa0fd136
10
README.md
10
README.md
|
|
@ -98,11 +98,7 @@ The app template is designed to be easy for you to _make it your own._ Here's ho
|
||||||
|
|
||||||
If you're not building an image gallery, you don't need the gallery demo code, except perhaps to learn from. To get rid of it, delete:
|
If you're not building an image gallery, you don't need the gallery demo code, except perhaps to learn from. To get rid of it, delete:
|
||||||
|
|
||||||
- `/src/lib/gallery.svelte`
|
- `/src/routes/gallery`
|
||||||
- `/src/routes/gallery.svelte`
|
|
||||||
- `/src/components/gallery`
|
|
||||||
- the `galleryStore` in `/src/stores.ts`
|
|
||||||
- the `initializeFilesystem` function in `/src/lib/auth/account.ts` creates directories used by WNFS. Change those to what you need for your app or delete them if you're not using WNFS.
|
|
||||||
|
|
||||||
👏 You're ready to start adding custom functionality! 🚀
|
👏 You're ready to start adding custom functionality! 🚀
|
||||||
|
|
||||||
|
|
@ -110,7 +106,6 @@ Check out the [Webnative Guide](https://guide.fission.codes/developers/webnative
|
||||||
|
|
||||||
## 🧨 Deploy
|
## 🧨 Deploy
|
||||||
|
|
||||||
|
|
||||||
The Webnative App Template is currently deployed as a [Netlify app](https://webnative.netlify.app) and a [Fission app](https://webnative-template.fission.app), but it should be supported on any static hosting platform (Vercel, Cloudflare Pages, etc).
|
The Webnative App Template is currently deployed as a [Netlify app](https://webnative.netlify.app) and a [Fission app](https://webnative-template.fission.app), but it should be supported on any static hosting platform (Vercel, Cloudflare Pages, etc).
|
||||||
|
|
||||||
### Netlify
|
### Netlify
|
||||||
|
|
@ -120,9 +115,10 @@ In order to deploy your Webnative application on Netlify:
|
||||||
1. Create a new Netlify site and connect your app's git repository. (If you don't have your application stored in a git repository, you can upload the output of a [static build](#static-build).)
|
1. Create a new Netlify site and connect your app's git repository. (If you don't have your application stored in a git repository, you can upload the output of a [static build](#static-build).)
|
||||||
2. Netlify takes care of the rest. No Netlify-specific configuration is needed.
|
2. Netlify takes care of the rest. No Netlify-specific configuration is needed.
|
||||||
3. There is no step 3.
|
3. There is no step 3.
|
||||||
|
|
||||||
### Fission App Hosting
|
### Fission App Hosting
|
||||||
|
|
||||||
A Webnative application can be published to IPFS with the [Fission CLI](https://guide.fission.codes/developers/cli) or the [Fission GitHub publish action](https://github.com/fission-suite/publish-action).
|
A Webnative application can be published to IPFS with the [Fission CLI](https://guide.fission.codes/developers/cli) or the [Fission GitHub publish action](https://github.com/fission-suite/publish-action).
|
||||||
|
|
||||||
To publish with the Fission CLI:
|
To publish with the Fission CLI:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@ export const appName = 'Awesome Webnative App'
|
||||||
export const appDescription = 'This is another awesome Webnative app.'
|
export const appDescription = 'This is another awesome Webnative app.'
|
||||||
export const appURL = 'https://webnative.netlify.app'
|
export const appURL = 'https://webnative.netlify.app'
|
||||||
export const appImageURL = `${appURL}/preview.png`
|
export const appImageURL = `${appURL}/preview.png`
|
||||||
export const fissionServerUrl = 'runfission.com'
|
export const ipfsGatewayUrl = 'runfission.com'
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
import * as webnative from 'webnative'
|
import * as webnative from 'webnative'
|
||||||
import type FileSystem from 'webnative/fs/index'
|
|
||||||
|
|
||||||
import { asyncDebounce } from '$lib/utils'
|
import { asyncDebounce } from '$lib/utils'
|
||||||
import { filesystemStore, sessionStore } from '../../stores'
|
import { filesystemStore, sessionStore } from '../../stores'
|
||||||
import { getBackupStatus } from '$lib/auth/backup'
|
import { getBackupStatus } from '$lib/auth/backup'
|
||||||
import { AREAS, GALLERY_DIRS } from '$lib/gallery'
|
|
||||||
|
|
||||||
export const isUsernameValid = async (username: string): Promise<boolean> => {
|
export const isUsernameValid = async (username: string): Promise<boolean> => {
|
||||||
return webnative.account.isUsernameValid(username)
|
return webnative.account.isUsernameValid(username)
|
||||||
|
|
@ -29,9 +27,6 @@ export const register = async (username: string): Promise<boolean> => {
|
||||||
const fs = await webnative.bootstrapRootFileSystem()
|
const fs = await webnative.bootstrapRootFileSystem()
|
||||||
filesystemStore.set(fs)
|
filesystemStore.set(fs)
|
||||||
|
|
||||||
// TODO Remove if only public and private directories are needed
|
|
||||||
await initializeFilesystem(fs)
|
|
||||||
|
|
||||||
sessionStore.update(session => ({
|
sessionStore.update(session => ({
|
||||||
...session,
|
...session,
|
||||||
username,
|
username,
|
||||||
|
|
@ -41,16 +36,6 @@ export const register = async (username: string): Promise<boolean> => {
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create additional directories and files needed by the app
|
|
||||||
*
|
|
||||||
* @param fs FileSystem
|
|
||||||
*/
|
|
||||||
const initializeFilesystem = async (fs: FileSystem): Promise<void> => {
|
|
||||||
await fs.mkdir(webnative.path.directory(...GALLERY_DIRS[AREAS.PUBLIC]))
|
|
||||||
await fs.mkdir(webnative.path.directory(...GALLERY_DIRS[AREAS.PRIVATE]))
|
|
||||||
}
|
|
||||||
|
|
||||||
export const loadAccount = async (username: string): Promise<void> => {
|
export const loadAccount = async (username: string): Promise<void> => {
|
||||||
await checkDataRoot(username)
|
await checkDataRoot(username)
|
||||||
|
|
||||||
|
|
@ -90,4 +75,4 @@ const checkDataRoot = async (username: string): Promise<void> => {
|
||||||
resolve()
|
resolve()
|
||||||
}, 500)
|
}, 500)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { onDestroy } from 'svelte'
|
||||||
|
import * as wn from 'webnative'
|
||||||
|
import type FileSystem from 'webnative/fs/index'
|
||||||
|
|
||||||
|
import { filesystemStore } from '$src/stores'
|
||||||
|
import { AREAS } from '$routes/gallery/stores'
|
||||||
|
import { GALLERY_DIRS } from '$routes/gallery/lib/gallery'
|
||||||
|
|
||||||
|
let fsCheckCompleted = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create additional directories and files needed by the gallery if they don't exist
|
||||||
|
*
|
||||||
|
* @param fs FileSystem
|
||||||
|
*/
|
||||||
|
const initializeFilesystem = async (fs: FileSystem): Promise<void> => {
|
||||||
|
const publicPathExists = await fs.exists(
|
||||||
|
wn.path.file(...GALLERY_DIRS[AREAS.PUBLIC])
|
||||||
|
)
|
||||||
|
const privatePathExists = await fs.exists(
|
||||||
|
wn.path.file(...GALLERY_DIRS[AREAS.PRIVATE])
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!publicPathExists) {
|
||||||
|
await fs.mkdir(wn.path.directory(...GALLERY_DIRS[AREAS.PUBLIC]))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!privatePathExists) {
|
||||||
|
await fs.mkdir(wn.path.directory(...GALLERY_DIRS[AREAS.PRIVATE]))
|
||||||
|
}
|
||||||
|
|
||||||
|
fsCheckCompleted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsubscribe = filesystemStore.subscribe(async fs => {
|
||||||
|
if (!fsCheckCompleted && !!fs) {
|
||||||
|
await initializeFilesystem(fs)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onDestroy(unsubscribe)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if fsCheckCompleted}
|
||||||
|
<slot />
|
||||||
|
{/if}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation'
|
|
||||||
import { onDestroy } from 'svelte'
|
import { onDestroy } from 'svelte'
|
||||||
|
import { goto } from '$app/navigation'
|
||||||
|
|
||||||
import { galleryStore, sessionStore, themeStore } from '../../stores'
|
import { sessionStore, themeStore } from '$src/stores'
|
||||||
import { AREAS } from '$lib/gallery'
|
import { AREAS, galleryStore } from '$routes/gallery/stores'
|
||||||
import Dropzone from '$components/gallery/upload/Dropzone.svelte'
|
import Dropzone from '$routes/gallery/components/upload/Dropzone.svelte'
|
||||||
import ImageGallery from '$components/gallery/imageGallery/ImageGallery.svelte'
|
import ImageGallery from '$routes/gallery/components/imageGallery/ImageGallery.svelte'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tab between the public/private areas and load associated images
|
* Tab between the public/private areas and load associated images
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let classes: string = 'mb-3 w-10 h-10'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class={classes}
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M7 16a4 4 0 0 1-.88-7.903A5 5 0 1 1 15.9 6h.1a5 5 0 0 1 1 9.9M15 13l-3-3m0 0-3 3m3-3v12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Image } from '$lib/gallery'
|
import type { Image } from '$routes/gallery/lib/gallery'
|
||||||
|
|
||||||
export let image: Image
|
export let image: Image
|
||||||
export let openModal
|
export let openModal
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onDestroy } from 'svelte'
|
import { onDestroy } from 'svelte'
|
||||||
|
|
||||||
import { galleryStore } from '../../../stores'
|
import { filesystemStore, sessionStore } from '$src/stores'
|
||||||
import { AREAS, getImagesFromWNFS } from '$lib/gallery'
|
import { AREAS, galleryStore } from '$routes/gallery/stores'
|
||||||
import type { Image } from '$lib/gallery'
|
import { getImagesFromWNFS, type Image } from '$routes/gallery/lib/gallery'
|
||||||
import FileUploadCard from '$components/gallery/upload/FileUploadCard.svelte'
|
import FileUploadCard from '$routes/gallery/components/upload/FileUploadCard.svelte'
|
||||||
import ImageCard from '$components/gallery/imageGallery/ImageCard.svelte'
|
import ImageCard from '$routes/gallery/components/imageGallery/ImageCard.svelte'
|
||||||
import ImageModal from '$components/gallery/imageGallery/ImageModal.svelte'
|
import ImageModal from '$routes/gallery/components/imageGallery/ImageModal.svelte'
|
||||||
|
|
||||||
// Get images from the user's public WNFS
|
|
||||||
getImagesFromWNFS()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the ImageModal and pass it the selected `image` from the gallery
|
* Open the ImageModal and pass it the selected `image` from the gallery
|
||||||
|
|
@ -23,7 +20,7 @@
|
||||||
|
|
||||||
// If galleryStore.selectedArea changes from private to public, re-run getImagesFromWNFS
|
// If galleryStore.selectedArea changes from private to public, re-run getImagesFromWNFS
|
||||||
let selectedArea = null
|
let selectedArea = null
|
||||||
const unsubscribe = galleryStore.subscribe(async updatedStore => {
|
const unsubscribeGalleryStore = galleryStore.subscribe(async updatedStore => {
|
||||||
// Get initial selectedArea
|
// Get initial selectedArea
|
||||||
if (!selectedArea) {
|
if (!selectedArea) {
|
||||||
selectedArea = updatedStore.selectedArea
|
selectedArea = updatedStore.selectedArea
|
||||||
|
|
@ -35,7 +32,20 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onDestroy(unsubscribe)
|
// Once the user has been authed, fetch the images from their file system
|
||||||
|
let imagesFetched = false
|
||||||
|
const unsubscribeSessionStore = sessionStore.subscribe((newState) => {
|
||||||
|
if (newState.authed && $filesystemStore && !imagesFetched) {
|
||||||
|
imagesFetched = true
|
||||||
|
// Get images from the user's public WNFS
|
||||||
|
getImagesFromWNFS()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
unsubscribeGalleryStore()
|
||||||
|
unsubscribeSessionStore()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="overflow-hidden text-gray-700">
|
<section class="overflow-hidden text-gray-700">
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
||||||
|
|
||||||
import { deleteImageFromWNFS } from '$lib/gallery'
|
import { ipfsGatewayUrl } from '$lib/app-info';
|
||||||
import { galleryStore } from '../../../stores'
|
import { galleryStore } from '$routes/gallery/stores'
|
||||||
import type { Gallery, Image } from '$lib/gallery'
|
import { deleteImageFromWNFS, type Gallery, type Image } from '$routes/gallery/lib/gallery'
|
||||||
import { fissionServerUrl } from '$lib/app-info'
|
|
||||||
|
|
||||||
export let image: Image
|
export let image: Image
|
||||||
export let isModalOpen: boolean = false
|
export let isModalOpen: boolean = false
|
||||||
|
|
@ -141,7 +140,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-center justify-center">
|
<div class="flex flex-col items-center justify-center">
|
||||||
<a
|
<a
|
||||||
href={`https://ipfs.${fissionServerUrl}/ipfs/${image.cid}/userland`}
|
href={`https://ipfs.${ipfsGatewayUrl}/ipfs/${image.cid}/userland`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="underline mb-4 hover:text-slate-500"
|
class="underline mb-4 hover:text-slate-500"
|
||||||
>
|
>
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
getImagesFromWNFS,
|
||||||
|
uploadImageToWNFS
|
||||||
|
} from '$routes/gallery/lib/gallery'
|
||||||
import { addNotification } from '$lib/notifications'
|
import { addNotification } from '$lib/notifications'
|
||||||
import { getImagesFromWNFS, uploadImageToWNFS } from '$lib/gallery'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect when a user drags a file in or out of the dropzone to change the styles
|
* Detect when a user drags a file in or out of the dropzone to change the styles
|
||||||
|
|
@ -28,6 +31,7 @@
|
||||||
// If the dropped files aren't images, we don't want them!
|
// If the dropped files aren't images, we don't want them!
|
||||||
if (!file.type.match('image/*')) {
|
if (!file.type.match('image/*')) {
|
||||||
addNotification('Please upload images only', 'error')
|
addNotification('Please upload images only', 'error')
|
||||||
|
console.error('Please upload images only')
|
||||||
} else {
|
} else {
|
||||||
await uploadImageToWNFS(file)
|
await uploadImageToWNFS(file)
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { galleryStore } from '../../../stores'
|
import { galleryStore } from '$routes/gallery/stores'
|
||||||
import { handleFileInput } from '$lib/gallery'
|
import { handleFileInput } from '$routes/gallery/lib/gallery'
|
||||||
import FileUploadIcon from '$components/icons/FileUploadIcon.svelte'
|
import FileUploadIcon from '$routes/gallery/components/icons/FileUploadIcon.svelte'
|
||||||
import LoadingSpinner from '$components/common/LoadingSpinner.svelte'
|
import LoadingSpinner from '$components/common/LoadingSpinner.svelte'
|
||||||
|
|
||||||
// Handle files uploaded directly through the file input
|
// Handle files uploaded directly through the file input
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
import * as uint8arrays from 'uint8arrays'
|
|
||||||
import { get as getStore } from 'svelte/store'
|
import { get as getStore } from 'svelte/store'
|
||||||
|
|
||||||
import * as wn from 'webnative'
|
import * as wn from 'webnative'
|
||||||
import { addNotification } from '$lib/notifications'
|
import * as uint8arrays from 'uint8arrays'
|
||||||
import { filesystemStore, galleryStore } from '../stores'
|
import type { CID } from 'multiformats/cid'
|
||||||
|
import type { PuttableUnixTree, File as WNFile } from 'webnative/fs/types'
|
||||||
|
import type { Metadata } from 'webnative/fs/metadata'
|
||||||
|
|
||||||
export enum AREAS {
|
import { filesystemStore } from '$src/stores'
|
||||||
PUBLIC = 'Public',
|
import { AREAS, galleryStore } from '$routes/gallery/stores'
|
||||||
PRIVATE = 'Private',
|
import { addNotification } from '$lib/notifications'
|
||||||
}
|
|
||||||
|
|
||||||
export type Image = {
|
export type Image = {
|
||||||
cid: string
|
cid: string
|
||||||
|
|
@ -26,9 +25,22 @@ export type Gallery = {
|
||||||
loading: boolean
|
loading: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GalleryFile extends PuttableUnixTree, WNFile {
|
||||||
|
cid: CID
|
||||||
|
content: Uint8Array
|
||||||
|
header: {
|
||||||
|
content: Uint8Array
|
||||||
|
metadata: Metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Link = {
|
||||||
|
size: number
|
||||||
|
}
|
||||||
|
|
||||||
export const GALLERY_DIRS = {
|
export const GALLERY_DIRS = {
|
||||||
[AREAS.PUBLIC]: ['public', 'gallery'],
|
[AREAS.PUBLIC]: ['public', 'gallery'],
|
||||||
[AREAS.PRIVATE]: ['private', 'gallery'],
|
[AREAS.PRIVATE]: ['private', 'gallery']
|
||||||
}
|
}
|
||||||
const FILE_SIZE_LIMIT = 5
|
const FILE_SIZE_LIMIT = 5
|
||||||
|
|
||||||
|
|
@ -38,7 +50,7 @@ const FILE_SIZE_LIMIT = 5
|
||||||
export const getImagesFromWNFS: () => Promise<void> = async () => {
|
export const getImagesFromWNFS: () => Promise<void> = async () => {
|
||||||
try {
|
try {
|
||||||
// Set loading: true on the galleryStore
|
// Set loading: true on the galleryStore
|
||||||
galleryStore.update((store) => ({ ...store, loading: true }))
|
galleryStore.update(store => ({ ...store, loading: true }))
|
||||||
|
|
||||||
const { selectedArea } = getStore(galleryStore)
|
const { selectedArea } = getStore(galleryStore)
|
||||||
const isPrivate = selectedArea === AREAS.PRIVATE
|
const isPrivate = selectedArea === AREAS.PRIVATE
|
||||||
|
|
@ -58,18 +70,23 @@ export const getImagesFromWNFS: () => Promise<void> = async () => {
|
||||||
|
|
||||||
// The CID for private files is currently located in `file.header.content`,
|
// The CID for private files is currently located in `file.header.content`,
|
||||||
// whereas the CID for public files is located in `file.cid`
|
// whereas the CID for public files is located in `file.cid`
|
||||||
const cid = isPrivate ? file.header.content.toString() : file.cid.toString()
|
const cid = isPrivate
|
||||||
|
? (file as GalleryFile).header.content.toString()
|
||||||
|
: (file as GalleryFile).cid.toString()
|
||||||
|
|
||||||
// Create a base64 string to use as the image `src`
|
// Create a base64 string to use as the image `src`
|
||||||
const src = `data:image/jpeg;base64, ${uint8arrays.toString(file.content, 'base64')}`
|
const src = `data:image/jpeg;base64, ${uint8arrays.toString(
|
||||||
|
(file as GalleryFile).content,
|
||||||
|
'base64'
|
||||||
|
)}`
|
||||||
|
|
||||||
return {
|
return {
|
||||||
cid,
|
cid,
|
||||||
ctime: file.header.metadata.unixMeta.ctime,
|
ctime: (file as GalleryFile).header.metadata.unixMeta.ctime,
|
||||||
name,
|
name,
|
||||||
private: isPrivate,
|
private: isPrivate,
|
||||||
size: links[name].size,
|
size: (links[name] as Link).size,
|
||||||
src,
|
src
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
@ -79,19 +96,22 @@ export const getImagesFromWNFS: () => Promise<void> = async () => {
|
||||||
images.sort((a, b) => b.ctime - a.ctime)
|
images.sort((a, b) => b.ctime - a.ctime)
|
||||||
|
|
||||||
// Push images to the galleryStore
|
// Push images to the galleryStore
|
||||||
galleryStore.update((store) => ({
|
|
||||||
...store,
|
|
||||||
...(isPrivate ? {
|
|
||||||
privateImages: images,
|
|
||||||
} : {
|
|
||||||
publicImages: images,
|
|
||||||
}),
|
|
||||||
loading: false,
|
|
||||||
}))
|
|
||||||
} catch (error) {
|
|
||||||
galleryStore.update(store => ({
|
galleryStore.update(store => ({
|
||||||
...store,
|
...store,
|
||||||
loading: false,
|
...(isPrivate
|
||||||
|
? {
|
||||||
|
privateImages: images
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
publicImages: images
|
||||||
|
}),
|
||||||
|
loading: false
|
||||||
|
}))
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
galleryStore.update(store => ({
|
||||||
|
...store,
|
||||||
|
loading: false
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -131,9 +151,9 @@ export const uploadImageToWNFS: (
|
||||||
await fs.publish()
|
await fs.publish()
|
||||||
|
|
||||||
addNotification(`${image.name} image has been published`, 'success')
|
addNotification(`${image.name} image has been published`, 'success')
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addNotification(error.message, 'error')
|
addNotification(error.message, 'error')
|
||||||
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,7 +161,9 @@ export const uploadImageToWNFS: (
|
||||||
* Delete an image from the user's private or public WNFS
|
* Delete an image from the user's private or public WNFS
|
||||||
* @param name
|
* @param name
|
||||||
*/
|
*/
|
||||||
export const deleteImageFromWNFS: (name: string) => Promise<void> = async (name) => {
|
export const deleteImageFromWNFS: (
|
||||||
|
name: string
|
||||||
|
) => Promise<void> = async name => {
|
||||||
try {
|
try {
|
||||||
const { selectedArea } = getStore(galleryStore)
|
const { selectedArea } = getStore(galleryStore)
|
||||||
const fs = getStore(filesystemStore)
|
const fs = getStore(filesystemStore)
|
||||||
|
|
@ -166,6 +188,7 @@ export const deleteImageFromWNFS: (name: string) => Promise<void> = async (name)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addNotification(error.message, 'error')
|
addNotification(error.message, 'error')
|
||||||
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { writable } from 'svelte/store'
|
||||||
|
import type { Writable } from 'svelte/store'
|
||||||
|
|
||||||
|
import type { Gallery } from '$routes/gallery/lib/gallery'
|
||||||
|
|
||||||
|
export enum AREAS {
|
||||||
|
PUBLIC = 'Public',
|
||||||
|
PRIVATE = 'Private'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const galleryStore: Writable<Gallery> = writable({
|
||||||
|
loading: true,
|
||||||
|
publicImages: [],
|
||||||
|
privateImages: [],
|
||||||
|
selectedArea: AREAS.PUBLIC,
|
||||||
|
})
|
||||||
|
|
@ -3,8 +3,6 @@ import type { Writable } from 'svelte/store'
|
||||||
import type FileSystem from 'webnative/fs/index'
|
import type FileSystem from 'webnative/fs/index'
|
||||||
|
|
||||||
import { loadTheme } from '$lib/theme'
|
import { loadTheme } from '$lib/theme'
|
||||||
import { AREAS } from '$lib/gallery'
|
|
||||||
import type { Gallery } from '$lib/gallery'
|
|
||||||
import type { Notification } from '$lib/notifications'
|
import type { Notification } from '$lib/notifications'
|
||||||
import type { Session } from '$lib/session'
|
import type { Session } from '$lib/session'
|
||||||
import type { Theme } from '$lib/theme'
|
import type { Theme } from '$lib/theme'
|
||||||
|
|
@ -20,11 +18,4 @@ export const sessionStore: Writable<Session> = writable({
|
||||||
|
|
||||||
export const filesystemStore: Writable<FileSystem | null> = writable(null)
|
export const filesystemStore: Writable<FileSystem | null> = writable(null)
|
||||||
|
|
||||||
export const galleryStore: Writable<Gallery> = writable({
|
|
||||||
loading: true,
|
|
||||||
publicImages: [],
|
|
||||||
privateImages: [],
|
|
||||||
selectedArea: AREAS.PUBLIC,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const notificationStore: Writable<Notification[]> = writable([])
|
export const notificationStore: Writable<Notification[]> = writable([])
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
"paths": {
|
"paths": {
|
||||||
"$components/*": ["src/components/*"],
|
"$components/*": ["src/components/*"],
|
||||||
"$lib/*": ["src/lib/*"],
|
"$lib/*": ["src/lib/*"],
|
||||||
|
"$routes/*": ["src/routes/*"],
|
||||||
|
"$src/*": ["src/*"],
|
||||||
"$static/*": ["static/*"]
|
"$static/*": ["static/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ const config = {
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
$components: resolve('./src/components'),
|
$components: resolve('./src/components'),
|
||||||
|
$routes: resolve('./src/routes'),
|
||||||
|
$src: resolve('./src'),
|
||||||
$static: resolve('./static')
|
$static: resolve('./static')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue