Compare commits

..

No commits in common. "83cba54bf5301ab4efdb9788457b1ec40f8d86a8" and "7342c18c00c9c39c24f21d4a89f3c1bbd4469d56" have entirely different histories.

19 changed files with 2345 additions and 4133 deletions

View File

@ -11,11 +11,5 @@
"svelte.plugin.svelte.compilerWarnings": { "svelte.plugin.svelte.compilerWarnings": {
"a11y-no-noninteractive-element-interactions": "ignore", "a11y-no-noninteractive-element-interactions": "ignore",
"a11y-click-events-have-key-events": "ignore" "a11y-click-events-have-key-events": "ignore"
},
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
} }
} }

View File

@ -8,10 +8,3 @@ A simple notes app built with [SvelteKit](https://kit.svelte.dev/), [Kysely](htt
- Local-first; all data is stored on-device - Local-first; all data is stored on-device
Hosted at https://notes.dallashoffman.com/ Hosted at https://notes.dallashoffman.com/
# ollama
```
OLLAMA_HOST=0.0.0.0:11434 ollama serve
```

6283
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -18,28 +18,23 @@
"dependencies": { "dependencies": {
"@bytemd/plugin-gfm": "^1.21.0", "@bytemd/plugin-gfm": "^1.21.0",
"bytemd": "1.21.0", "bytemd": "1.21.0",
"kysely": "^0.27.3", "kysely": "^0.26.3",
"sqlocal": "^0.11.1" "sqlocal": "^0.6.2"
}, },
"devDependencies": { "devDependencies": {
"@picocss/pico": "^1.5.10", "@picocss/pico": "^1.5.10",
"@sveltejs/adapter-static": "^3.0.6", "@sveltejs/adapter-static": "^2.0.3",
"@vite-pwa/assets-generator": "^0.2.4", "@sveltejs/kit": "^1.20.4",
"@vite-pwa/sveltekit": "^0.4.0", "@vite-pwa/assets-generator": "^0.0.10",
"@vite-pwa/sveltekit": "^0.2.7",
"patch-package": "^8.0.0", "patch-package": "^8.0.0",
"prettier": "^3.3.2", "prettier": "^2.8.0",
"prettier-plugin-svelte": "^3.2.6", "prettier-plugin-svelte": "^2.10.1",
"sass": "^1.69.5", "sass": "^1.66.1",
"@sveltejs/adapter-node": "^5.2.2", "svelte": "^4.0.5",
"@sveltejs/kit": "^2.5.25", "svelte-check": "^3.4.3",
"@sveltejs/vite-plugin-svelte": "^4.0.0", "tslib": "^2.4.1",
"svelte": "^5.0.0", "typescript": "^5.2.2",
"svelte-check": "^3.6.8", "vite": "^4.4.9"
"tslib": "^2.6.2",
"typescript": "^5.4.3",
"vite": "^5.0.3",
"fast-glob": "^3.3.2",
"openai": "^4.74.0",
"ollama": "^0.5.10"
} }
} }

View File

@ -1,15 +1,3 @@
diff --git a/node_modules/bytemd/package.json b/node_modules/bytemd/package.json
index 9103d88..e59f261 100644
--- a/node_modules/bytemd/package.json
+++ b/node_modules/bytemd/package.json
@@ -16,6 +16,7 @@
"author": "Rongjian Zhang",
"exports": {
".": {
+ "svelte": "./svelte/index.js",
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
diff --git a/node_modules/bytemd/svelte/editor.svelte b/node_modules/bytemd/svelte/editor.svelte diff --git a/node_modules/bytemd/svelte/editor.svelte b/node_modules/bytemd/svelte/editor.svelte
index 652a063..9ab0895 100644 index 652a063..9ab0895 100644
--- a/node_modules/bytemd/svelte/editor.svelte --- a/node_modules/bytemd/svelte/editor.svelte

View File

@ -3,11 +3,11 @@
import ThemeToggle from '$lib/components/theme-toggle.svelte'; import ThemeToggle from '$lib/components/theme-toggle.svelte';
</script> </script>
<!-- <header class="app-header"> <header class="app-header">
<ThemeToggle /> <ThemeToggle />
<h1 class="app-header__title">Notes</h1> <h1 class="app-header__title">Notes</h1>
<SettingsButton /> <SettingsButton />
</header> --> </header>
<style lang="scss"> <style lang="scss">
.app-header { .app-header {

View File

@ -16,7 +16,7 @@
<style lang="scss"> <style lang="scss">
button { button {
position: fixed; position: fixed;
bottom: 1rem; bottom: 2rem;
right: 1rem; right: 1rem;
width: 4rem; width: 4rem;
height: 4rem; height: 4rem;

View File

@ -34,12 +34,8 @@
<article class="note-card" style:--note-color={NoteColor[note.color][$themeUpperCase]}> <article class="note-card" style:--note-color={NoteColor[note.color][$themeUpperCase]}>
<header class="note-card__header" hidden={$editing}> <header class="note-card__header" hidden={$editing}>
<div class="note-card__header-buttons"> <div class="note-card__header-buttons">
{#if !$editing}
<NoteEditButton on:click={noteEditorStore.startEditing} />
{/if}
<NoteDeleteButton {note} {noteEditorStore} /> <NoteDeleteButton {note} {noteEditorStore} />
<div class="note-card__spacer" /> <div class="note-card__spacer" />
<NoteTimestamp {note} />
<NoteColorPicker {note} {noteEditorStore} /> <NoteColorPicker {note} {noteEditorStore} />
<NoteTagButton on:click={focusTags} /> <NoteTagButton on:click={focusTags} />
</div> </div>
@ -55,13 +51,16 @@
> >
<NoteContent {note} {noteEditorStore} /> <NoteContent {note} {noteEditorStore} />
</div> </div>
{#if $editing} <footer class="note-card__footer">
<footer class="note-card__footer"> {#if !$editing}
<NoteEditButton on:click={noteEditorStore.startEditing} />
{:else}
<NoteSaveButton on:click={noteEditorStore.save} /> <NoteSaveButton on:click={noteEditorStore.save} />
<NoteDiscardButton on:click={noteEditorStore.discard} /> <NoteDiscardButton on:click={noteEditorStore.discard} />
<div class="note-card__spacer" /> {/if}
</footer> <div class="note-card__spacer" />
{/if} <NoteTimestamp {note} />
</footer>
</article> </article>
<style lang="scss"> <style lang="scss">
@ -76,7 +75,6 @@
background-color: var(--note-color); background-color: var(--note-color);
border-radius: 0; border-radius: 0;
box-shadow: var(--card-shadow); box-shadow: var(--card-shadow);
scrollbar-color: hsl(0 0% 0% / 0.2) hsl(0 0% 0% / 0.2);
&__header, &__header,
&__footer { &__footer {

View File

@ -5,4 +5,5 @@
<Button icon plain on:click> <Button icon plain on:click>
<FaPenToSquare /> <FaPenToSquare />
Edit
</Button> </Button>

View File

@ -6,20 +6,18 @@
import { get, type Unsubscriber } from 'svelte/store'; import { get, type Unsubscriber } from 'svelte/store';
let noteListElement: HTMLUListElement; let noteListElement: HTMLUListElement;
const noteHeight = 400; const noteHeight = 385;
const noteGap = 16; const noteGap = 16;
const paddingRows = 2; const paddingRows = 2;
let scrollHeight = 0; let scrollHeight = 0;
let scrollOffset = 0; let scrollOffset = 0;
let flipDuration = 0;
let notesOffset = 0; let notesOffset = 0;
let notesLimit = 100; let notesLimit = 100;
let prevNotesCount = 0; let prevNotesCount = 0;
let prevRowHeight = 0; let prevRowHeight = 0;
let flipDuration = 0;
let flipTimeout: ReturnType<typeof setTimeout> | undefined;
const { noteScale } = settings; const { noteScale } = settings;
let scaleUnsubscribe: Unsubscriber; let scaleUnsubscribe: Unsubscriber;
let countUnsubscribe: Unsubscriber; let countUnsubscribe: Unsubscriber;
@ -43,8 +41,7 @@
if (notesCount !== prevNotesCount) { if (notesCount !== prevNotesCount) {
flipDuration = 300; flipDuration = 300;
clearTimeout(flipTimeout); setTimeout(() => {
flipTimeout = setTimeout(() => {
flipDuration = 0; flipDuration = 0;
}, 300); }, 300);
} }
@ -105,8 +102,8 @@
<style lang="scss"> <style lang="scss">
.note-list { .note-list {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(0, var(--note-height))); grid-template-columns: repeat(auto-fill, minmax(0, calc(var(--note-height, 385px) * 0.92)));
grid-auto-rows: var(--note-height); grid-auto-rows: var(--note-height, 385px);
gap: var(--note-gap, 1rem); gap: var(--note-gap, 1rem);
justify-content: center; justify-content: center;
height: var(--scroll-height, auto); height: var(--scroll-height, auto);

View File

@ -1,31 +0,0 @@
<script lang="ts">
import FaPlus from '$icon/fa-potato.svelte';
import { notes } from '$lib/stores';
</script>
<button
type="button"
aria-label="Search note"
data-tooltip="Search note"
data-placement="left"
on:click={() => notes.search()}
>
<FaPlus />
</button>
<style lang="scss">
button {
position: fixed;
bottom: 1rem;
right: 6rem;
width: 4rem;
height: 4rem;
margin: 0;
border-radius: 50%;
box-shadow: var(--card-shadow);
& > :global(svg) {
width: 2rem;
}
}
</style>

View File

@ -4,8 +4,7 @@
import { settings } from '$lib/stores'; import { settings } from '$lib/stores';
</script> </script>
<button <Button
type="button"
plain plain
icon icon
size="lg" size="lg"
@ -14,21 +13,4 @@
on:click={() => settings.open.set(true)} on:click={() => settings.open.set(true)}
> >
<FaGear /> <FaGear />
</button> </Button>
<style lang="scss">
button {
position: fixed;
bottom: 6rem;
right: 1rem;
width: 4rem;
height: 4rem;
margin: 0;
border-radius: 50%;
box-shadow: var(--card-shadow);
& > :global(svg) {
width: 2rem;
}
}
</style>

View File

@ -12,7 +12,7 @@ export class NoteEditorStore {
readonly draftContent = readonly(this._draftContent); readonly draftContent = readonly(this._draftContent);
readonly expanded = readonly(this._expanded); readonly expanded = readonly(this._expanded);
constructor(private noteId: Note['id'], private notes: NotesStore) { } constructor(private noteId: Note['id'], private notes: NotesStore) {}
startEditing = () => { startEditing = () => {
const note = this.notes.get(this.noteId); const note = this.notes.get(this.noteId);

View File

@ -4,8 +4,6 @@ import type { Insertable, Selectable, Updateable } from 'kysely';
import { writable, type Readable, get, readonly } from 'svelte/store'; import { writable, type Readable, get, readonly } from 'svelte/store';
import type { TagsStore } from './tags'; import type { TagsStore } from './tags';
import { settings } from '.'; import { settings } from '.';
import OpenAI from 'openai';
import { Ollama } from 'ollama'
export type Note = Selectable<Schema['note']>; export type Note = Selectable<Schema['note']>;
export type NewNote = Insertable<Schema['note']>; export type NewNote = Insertable<Schema['note']>;
@ -37,13 +35,13 @@ export class NotesStore implements Readable<Note[]> {
selectedTags.length === 0 selectedTags.length === 0
? db.selectFrom('note').selectAll().orderBy('createdAt desc') ? db.selectFrom('note').selectAll().orderBy('createdAt desc')
: db : db
.selectFrom('noteTag') .selectFrom('noteTag')
.innerJoin('note', 'note.id', 'noteTag.noteId') .innerJoin('note', 'note.id', 'noteTag.noteId')
.selectAll('note') .selectAll('note')
.where('tagId', 'in', selectedTags) .where('tagId', 'in', selectedTags)
.groupBy('noteId') .groupBy('noteId')
.having(({ fn }) => fn.count('noteId'), '=', selectedTags.length) .having(({ fn }) => fn.count('noteId'), '=', selectedTags.length)
.orderBy('createdAt desc'); .orderBy('createdAt desc');
const notesData = await query.offset(this.offset).limit(this.limit).execute(); const notesData = await query.offset(this.offset).limit(this.limit).execute();
const { notesCount } = await db const { notesCount } = await db
@ -68,20 +66,6 @@ export class NotesStore implements Readable<Note[]> {
return notes.find((note) => note.id === noteId); return notes.find((note) => note.id === noteId);
}; };
search = async () => {
const ol = new Ollama({ host: 'http://deve.work:11434' })
const response = await ol.chat({
model: 'qwen2.5-coder:14b',
messages: [{ role: 'user', content: 'python编写1+1=?' }],
})
alert(response.message.content)
// const all = await db.selectFrom('note').selectAll().execute();
// alert(all[0].content);
return;
};
add = async (newNote?: NewNote, scrollToTop?: boolean) => { add = async (newNote?: NewNote, scrollToTop?: boolean) => {
if (!newNote) { if (!newNote) {
newNote = { newNote = {

View File

@ -1,3 +1,2 @@
import '$styles/index.scss'; import '$styles/index.scss';
export const ssr = false; export const ssr = false;
export const prerender = true;

View File

@ -2,8 +2,6 @@
import AppHeader from '$lib/components/app-header.svelte'; import AppHeader from '$lib/components/app-header.svelte';
import AppUpdatePrompt from '$lib/components/app-update-prompt.svelte'; import AppUpdatePrompt from '$lib/components/app-update-prompt.svelte';
import FilterTags from '$lib/components/filter-tags.svelte'; import FilterTags from '$lib/components/filter-tags.svelte';
import NoteSearchButton from '$lib/components/notes/note-search-button.svelte';
import SettingsButton from '$lib/components/settings/settings-button.svelte';
import NoteAddButton from '$lib/components/notes/note-add-button.svelte'; import NoteAddButton from '$lib/components/notes/note-add-button.svelte';
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';
@ -25,8 +23,6 @@
{:else if $notesCount === 0} {:else if $notesCount === 0}
<NoteListPlaceholder /> <NoteListPlaceholder />
{/if} {/if}
<SettingsButton />
<NoteSearchButton />
<NoteAddButton /> <NoteAddButton />
</section> </section>
</main> </main>

View File

@ -68,10 +68,6 @@
margin-bottom: 0; margin-bottom: 0;
} }
:where(dl, ol, ul) {
margin-bottom: 1rem;
}
.task-list-item { .task-list-item {
list-style-type: none; list-style-type: none;
} }

View File

@ -29,7 +29,6 @@ html {
background-size: min(20vw, 150px); background-size: min(20vw, 150px);
background-position: center center; background-position: center center;
background-repeat: no-repeat; background-repeat: no-repeat;
scrollbar-color: var(--range-thumb-color) var(--range-border-color);
&[data-theme] { &[data-theme] {
background-image: none; background-image: none;

View File

@ -1,5 +1,5 @@
import adapter from '@sveltejs/adapter-static'; import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; import { vitePreprocess } from '@sveltejs/kit/vite';
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */
const config = { const config = {