Add settings modal
This commit is contained in:
parent
18831d2e3f
commit
37a64cd488
|
@ -40,6 +40,7 @@
|
|||
.app-modal {
|
||||
article {
|
||||
max-width: var(--max-width, none);
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
header {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)`}
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>);
|
||||
|
|
|
@ -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: '',
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue