Add settings modal

This commit is contained in:
Dallas Hoffman 2023-09-23 01:43:20 -04:00
parent 18831d2e3f
commit 37a64cd488
No known key found for this signature in database
9 changed files with 68 additions and 7 deletions

View File

@ -40,6 +40,7 @@
.app-modal {
article {
max-width: var(--max-width, none);
flex: 1 0 auto;
}
header {

View File

@ -43,7 +43,7 @@
<NoteTags {noteTags} bind:this={tagsComponent} />
</div>
</header>
<div class="note-card__body">
<div class="note-card__body" class:note-card__body--editing={$editing}>
<NoteContent {note} {noteEditorStore} />
</div>
<footer class="note-card__footer">
@ -94,6 +94,10 @@
&__body {
flex-grow: 1;
overflow: auto;
&--editing {
overflow: hidden;
}
}
&__footer {

View File

@ -1,6 +1,6 @@
<script lang="ts">
import NoteCard from '$lib/components/notes/note-card.svelte';
import { notes } from '$lib/stores';
import { notes, settings } from '$lib/stores';
import { onDestroy, onMount } from 'svelte';
import { get, type Unsubscriber } from 'svelte/store';
@ -15,6 +15,8 @@
let notesLimit = 100;
let prevNotesCount = 0;
const { noteScale } = settings;
let scaleUnsubscribe: Unsubscriber;
let countUnsubscribe: Unsubscriber;
const resizeObserver = new ResizeObserver(updateVirtualScroll);
@ -24,7 +26,7 @@
.getComputedStyle(noteListElement)
.getPropertyValue('grid-template-columns')
.split(' ').length;
const rowHeight = noteHeight + noteGap;
const rowHeight = Math.floor(noteHeight * get(noteScale)) + noteGap;
const fullHeight = Math.ceil(notesCount / columnCount) * rowHeight;
const windowHeight = window.innerHeight;
const scrollTop = window.scrollY + noteListElement.offsetTop;
@ -46,12 +48,14 @@
}
onMount(() => {
scaleUnsubscribe = settings.noteScale.subscribe(updateVirtualScroll);
countUnsubscribe = notes.count.subscribe(updateVirtualScroll);
resizeObserver.observe(noteListElement);
window.addEventListener('scroll', updateVirtualScroll);
});
onDestroy(() => {
scaleUnsubscribe();
countUnsubscribe();
resizeObserver.disconnect();
window.removeEventListener('scroll', updateVirtualScroll);
@ -61,7 +65,7 @@
<ul
bind:this={noteListElement}
class="note-list"
style:--note-height={`${noteHeight}px`}
style:--note-height={`${Math.floor(noteHeight * $noteScale)}px`}
style:--note-gap={`${noteGap}px`}
style:--scroll-height={`${scrollHeight}px`}
style:--scroll-offset={`translateY(${scrollOffset}px)`}

View File

@ -0,0 +1,9 @@
<script lang="ts">
import Button from '../button.svelte';
import FaGear from '$icon/fa-gear.svelte';
import { settings } from '$lib/stores';
</script>
<Button plain icon size="lg" label="Settings" on:click={() => settings.open.set(true)}>
<FaGear />
</Button>

View File

@ -0,0 +1,21 @@
<script lang="ts">
import Modal from '../modal.svelte';
import { settings } from '$lib/stores';
const { open, noteScale } = settings;
</script>
<Modal title="Settings" size="sm" bind:open={$open}>
<label>
Note Size
<input
type="range"
name="noteScale"
min="0.80"
max="1.50"
step="0.05"
bind:value={$noteScale}
/>
</label>
<!-- TODO: setting for default note color -->
</Modal>

View File

@ -2,9 +2,12 @@ import { derived } from 'svelte/store';
import { NotesStore } from './notes';
import { ThemeStore, type Theme } from './theme';
import { TagsStore } from './tags';
import { SettingsStore } from './settings';
export const tags = new TagsStore();
export const notes = new NotesStore(tags);
export const settings = new SettingsStore();
export const theme = new ThemeStore();
export const themeUpperCase = derived(theme, ($theme) => $theme.toUpperCase() as Uppercase<Theme>);

View File

@ -3,6 +3,7 @@ import type { Schema } from '$lib/db/schema';
import type { Insertable, Selectable, Updateable } from 'kysely';
import { writable, type Readable, get, readonly } from 'svelte/store';
import type { TagsStore } from './tags';
import { settings } from '.';
export type Note = Selectable<Schema['note']>;
export type NewNote = Insertable<Schema['note']>;
@ -68,7 +69,7 @@ export class NotesStore implements Readable<Note[]> {
add = async (newNote?: NewNote, scrollToTop?: boolean) => {
if (!newNote) {
newNote = {
color: 'YELLOW', // TODO: add way to set the default color
color: get(settings.defaultNoteColor),
content: '',
};
}

View File

@ -0,0 +1,14 @@
import type { NoteColor } from '$lib/db/enums/note-color';
import { writable } from 'svelte/store';
export class SettingsStore {
open = writable<boolean>(false);
noteScale = writable<number>(localStorage.noteScale ? parseFloat(localStorage.noteScale) : 1);
defaultNoteColor = writable<keyof typeof NoteColor>(localStorage.defaultNoteColor ?? 'YELLOW');
constructor() {
this.noteScale.subscribe((value) => (localStorage.noteScale = value.toString()));
this.defaultNoteColor.subscribe((value) => (localStorage.defaultNoteColor = value));
}
}

View File

@ -3,6 +3,8 @@
import NoteAddButton from '$lib/components/notes/note-add-button.svelte';
import NoteListPlaceholder from '$lib/components/notes/note-list-placeholder.svelte';
import NoteList from '$lib/components/notes/note-list.svelte';
import SettingsButton from '$lib/components/settings/settings-button.svelte';
import SettingsModal from '$lib/components/settings/settings-modal.svelte';
import ThemeToggle from '$lib/components/theme-toggle.svelte';
import { notes, tags } from '$lib/stores';
@ -10,8 +12,9 @@
</script>
<header>
<h1>Notes</h1>
<ThemeToggle />
<h1>Notes</h1>
<SettingsButton />
</header>
<main>
<section hidden={$tags.length === 0}>
@ -26,13 +29,14 @@
<NoteAddButton />
</section>
</main>
<SettingsModal />
<style lang="scss">
header {
display: flex;
align-items: center;
justify-content: center;
gap: 1.2rem;
gap: 2rem;
margin: 1.5rem;
h1 {