Compare commits

..

2 Commits

Author SHA1 Message Date
067ebc3a36
chore: update bun deps 2024-10-29 17:46:18 +09:00
64869c91c4
feat: notes wip, viewing + data structure 2024-10-29 17:45:20 +09:00
9 changed files with 116 additions and 21 deletions

2
.gitignore vendored
View File

@ -6,6 +6,8 @@ node_modules
/.svelte-kit /.svelte-kit
/build /build
/visitcount /visitcount
/notes
/note
# OS # OS
.DS_Store .DS_Store

BIN
bun.lockb

Binary file not shown.

View File

@ -12,35 +12,36 @@
"format": "prettier --write ." "format": "prettier --write ."
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/enhanced-img": "^0.3.8", "@sveltejs/enhanced-img": "^0.3.10",
"@sveltejs/kit": "^2.5.20", "@sveltejs/kit": "^2.7.3",
"@sveltejs/vite-plugin-svelte": "^3.1.1", "@sveltejs/vite-plugin-svelte": "^3.1.2",
"@tailwindcss/forms": "^0.5.7", "@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.14", "@tailwindcss/typography": "^0.5.15",
"@types/eslint": "^9.6.0", "@types/eslint": "^9.6.1",
"@types/node": "^22.4.2", "@types/node": "^22.8.2",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"eslint": "^9.8.0", "eslint": "^9.13.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.43.0", "eslint-plugin-svelte": "^2.46.0",
"globals": "^15.9.0", "globals": "^15.11.0",
"mdsvex": "^0.12.3", "mdsvex": "^0.12.3",
"postcss": "^8.4.41", "postcss": "^8.4.47",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.6", "prettier-plugin-svelte": "^3.2.7",
"svelte": "^4.2.18", "svelte": "^4.2.19",
"svelte-adapter-bun": "^0.5.2", "svelte-adapter-bun": "^0.5.2",
"svelte-check": "^3.8.5", "svelte-check": "^3.8.6",
"tailwindcss": "^3.4.8", "tailwindcss": "^3.4.14",
"tslib": "^2.6.3", "tslib": "^2.8.0",
"typescript": "^5.5.4", "typescript": "^5.6.3",
"typescript-eslint": "^8.0.1", "typescript-eslint": "^8.12.1",
"vite": "^5.4.0" "vite": "^5.4.10"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@std/toml": "npm:@jsr/std__toml", "@std/toml": "npm:@jsr/std__toml",
"base64url": "^3.0.1", "base64url": "^3.0.1",
"nanoid": "^5.0.8",
"rehype-autolink-headings": "^7.1.0", "rehype-autolink-headings": "^7.1.0",
"rehype-slug": "^6.0.0", "rehype-slug": "^6.0.0",
"typescript-svelte-plugin": "^0.3.42" "typescript-svelte-plugin": "^0.3.42"

View File

@ -1,7 +1,7 @@
import type { Cookies } from '@sveltejs/kit' import type { Cookies } from '@sveltejs/kit'
import { env } from '$env/dynamic/private' import { env } from '$env/dynamic/private'
import { existsSync, readFileSync } from 'fs'
import { writable } from 'svelte/store' import { writable } from 'svelte/store'
import { existsSync, readFileSync } from 'fs'
export const scopeCookies = (cookies: Cookies, path: string) => { export const scopeCookies = (cookies: Cookies, path: string) => {
return { return {
@ -18,4 +18,4 @@ export const scopeCookies = (cookies: Cookies, path: string) => {
} }
export const visitCountFile = `${env.WEBSITE_DATA_DIR}/visitcount` export const visitCountFile = `${env.WEBSITE_DATA_DIR}/visitcount`
export const visitCount = writable(parseInt(existsSync(visitCountFile) ? readFileSync(visitCountFile).toString() : '0')); export const visitCount = writable(parseInt(existsSync(visitCountFile) ? readFileSync(visitCountFile).toString() : '0'));

40
src/lib/notes.ts Normal file
View File

@ -0,0 +1,40 @@
import { existsSync, readFileSync, writeFileSync } from 'fs'
import { nanoid } from 'nanoid'
import { env } from '$env/dynamic/private'
export interface Note {
content: string,
published: Date,
}
type NoteId = string
export const notesFolder = `${env.WEBSITE_DATA_DIR}/note`
export const notesListFile = `${env.WEBSITE_DATA_DIR}/notes`
export const getNotePath = (id: NoteId) => { return `${notesFolder}/${id}` }
export const genNoteId = () => {
let id = nanoid(8)
while (existsSync(getNotePath(id))) {
id = nanoid(8)
}
return id
}
export const noteExists = (id: NoteId) => { return existsSync(getNotePath(id)) }
export const readNote = (id: NoteId): Note => {
return JSON.parse(readFileSync(getNotePath(id)).toString())
}
export const writeNote = (id: NoteId, note: Note) => {
writeFileSync(getNotePath(id), JSON.stringify(note))
// only append to note list if its not in it yet
let noteList = readNotesList()
if (noteList.indexOf(id) === -1) {
writeNotesList(noteList.concat([id]))
}
}
export const readNotesList = (): NoteId[] => {
return JSON.parse(readFileSync(notesListFile).toString())
}
export const writeNotesList = (note_ids: NoteId[]) => {
writeFileSync(notesListFile, JSON.stringify(note_ids))
}

View File

@ -0,0 +1,34 @@
import { noteExists, readNote, readNotesList } from '$lib/notes'
const notesPerPage: number = 5
export const load = ({url}) => {
// get the note id to search for and display the page it is in
const noteId = url.searchParams.get("id")
// get the page no if one is provided, otherwise default to 1
let page = parseInt(url.searchParams.get("page") || "1")
if (isNaN(page)) { page = 1 }
// calculate page count
const notesList = readNotesList()
const pageCount = Math.ceil(notesList.length / notesPerPage)
// find what page the note id if supplied is from
if (noteId !== null && noteExists(noteId)) {
const noteIndex = notesList.lastIndexOf(noteId)
if (noteIndex > -1) {
page = Math.floor(noteIndex / notesPerPage) + 1
}
}
// clamp page between our min and max
page = Math.min(page, pageCount)
page = Math.max(page, 1)
// get the notes from the chosen page
const notes = notesList.slice((page - 1) * notesPerPage, page * notesPerPage).map(
(id) => {return {noteId: id, note: readNote(id)}}
)
return {notes, highlightedNote: noteId, page}
}

View File

@ -0,0 +1,18 @@
<script lang="ts">
import Window from '../../components/window.svelte';
export let data;
</script>
<div class="flex">
<Window title="notes">
<div class="prose prose-ralsei">
<pre class="language-bash"><code class="language-bash"><span class="token punctuation">[</span>gazesystems <span class="token keyword">/notes/</span><span class="token punctuation">]$</span> <span class="token function">cat</span> *
{#each data.notes as {noteId, note}}
<br>
<span class="token keyword">{noteId}</span><span class="token punctuation">|> </span><span class="token string">{note.content}</span>
{/each}
</code></pre>
</div>
</Window>
</div>

View File

View File