Add welcome modal with data persistence permission prompt

This commit is contained in:
Dallas Hoffman 2023-09-30 23:21:14 -04:00
parent 70f3f31370
commit ea345e6e61
5 changed files with 81 additions and 1 deletions

View File

@ -1,11 +1,14 @@
<script lang="ts"> <script lang="ts">
import Button from './button.svelte'; import Button from './button.svelte';
import FaXmark from '$icon/fa-xmark.svelte'; import FaXmark from '$icon/fa-xmark.svelte';
import { createEventDispatcher } from 'svelte';
export let open: boolean; export let open: boolean;
export let title: string; export let title: string;
export let size: 'sm' | 'md' | 'lg' = 'md'; export let size: 'sm' | 'md' | 'lg' = 'md';
const dispatch = createEventDispatcher();
const maxWidths = { const maxWidths = {
sm: '400px', sm: '400px',
md: '700px', md: '700px',
@ -20,6 +23,7 @@
function close() { function close() {
open = false; open = false;
dispatch('close');
} }
function escape(event: KeyboardEvent) { function escape(event: KeyboardEvent) {
@ -47,7 +51,7 @@
.app-modal { .app-modal {
article { article {
max-width: var(--max-width, none); max-width: var(--max-width, none);
flex: 1 0 auto; flex: 1 0 0;
} }
header { header {

View File

@ -0,0 +1,33 @@
<script lang="ts">
import { onMount } from 'svelte';
import Modal from './modal.svelte';
import Button from './button.svelte';
import { persistence } from '$lib/stores';
let open = false;
onMount(() => {
if (!persistence.prompted) {
open = true;
}
});
function close() {
persistence.prompt();
open = false;
}
</script>
<Modal title="Welcome!" size="sm" bind:open on:close={close}>
<p>
Capture your thoughts for later by writing a quick note. Add tags to categorize it and organize
your notes.
</p>
<p>
This app keeps all of its data on your device. Your notes are private, never sent to an external
server.
</p>
<footer>
<Button on:click={close}>Get Started</Button>
</footer>
</Modal>

View File

@ -3,10 +3,12 @@ import { NotesStore } from './notes';
import { ThemeStore, type Theme } from './theme'; import { ThemeStore, type Theme } from './theme';
import { TagsStore } from './tags'; import { TagsStore } from './tags';
import { SettingsStore } from './settings'; import { SettingsStore } from './settings';
import { PersistenceStore } from './persistence';
export const tags = new TagsStore(); export const tags = new TagsStore();
export const notes = new NotesStore(tags); export const notes = new NotesStore(tags);
export const persistence = new PersistenceStore();
export const settings = new SettingsStore(); export const settings = new SettingsStore();
export const theme = new ThemeStore(); export const theme = new ThemeStore();

View File

@ -0,0 +1,39 @@
import { writable, type Readable } from 'svelte/store';
export class PersistenceStore implements Readable<boolean | null> {
private persistence = writable<boolean | null>(null);
get prompted() {
return !!localStorage.promptedForPersistence;
}
private set prompted(value: boolean) {
localStorage.promptedForPersistence = value;
}
constructor() {
this.check();
}
subscribe = this.persistence.subscribe;
async check() {
if (navigator.storage && navigator.storage.persisted) {
let persisted: boolean | null = await navigator.storage.persisted();
if (persisted !== true) {
persisted = this.prompted ? false : null;
}
this.persistence.set(persisted);
}
}
async prompt() {
this.prompted = true;
if (navigator.storage && navigator.storage.persist) {
const persisted = await navigator.storage.persist();
this.persistence.set(persisted);
}
}
}

View File

@ -5,6 +5,7 @@
import NoteListPlaceholder from '$lib/components/notes/note-list-placeholder.svelte'; import NoteListPlaceholder from '$lib/components/notes/note-list-placeholder.svelte';
import NoteList from '$lib/components/notes/note-list.svelte'; import NoteList from '$lib/components/notes/note-list.svelte';
import SettingsModal from '$lib/components/settings/settings-modal.svelte'; import SettingsModal from '$lib/components/settings/settings-modal.svelte';
import WelcomeModal from '$lib/components/welcome-modal.svelte';
import { notes, tags } from '$lib/stores'; import { notes, tags } from '$lib/stores';
const notesCount = notes.count; const notesCount = notes.count;
@ -24,6 +25,7 @@
<NoteAddButton /> <NoteAddButton />
</section> </section>
</main> </main>
<WelcomeModal />
<SettingsModal /> <SettingsModal />
<style lang="scss"> <style lang="scss">