diff --git a/.env b/.env index 16087a4..662b883 100644 --- a/.env +++ b/.env @@ -1 +1,3 @@ -VITE_DEV_SERVER_URL=http://localhost:5173 \ No newline at end of file +VITE_DEV_SERVER_URL=http://localhost:5173 +SUPABASE_KEY='sb_secret_xYDyNcB7Q46ZYhDISeXRHQ_95l-N33m' +SUPABASE_URL='https://jmuadfpmmejfvkwosaqh.supabase.co' diff --git a/.gitignore b/.gitignore index a3f7a51..c7ef895 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ yarn-error.log* pnpm-debug.log* lerna-debug.log* +.env node_modules .DS_Store dist diff --git a/README.md b/README.md index eade64a..9c0cfae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# app.takerofnotes.com +# Taker of Notes App An Electron application with Vue diff --git a/out/main/index.js b/out/main/index.js index ccbf669..0c6d035 100644 --- a/out/main/index.js +++ b/out/main/index.js @@ -1,6 +1,8 @@ +import "dotenv/config"; import { electronApp, optimizer, is } from "@electron-toolkit/utils"; -import { app, BrowserWindow, ipcMain, shell } from "electron"; +import { app, ipcMain, BrowserWindow, shell } from "electron"; import filesystemPlugin from "@takerofnotes/plugin-filesystem"; +import supabasePlugin from "@takerofnotes/plugin-supabase"; import fs from "fs/promises"; import path, { join } from "path"; import { Index } from "flexsearch"; @@ -227,22 +229,18 @@ function createNoteWindow(noteId) { } } app.whenReady().then(async () => { - electronApp.setAppUserModelId("com.electron"); - app.on("browser-window-created", (_, window) => { - optimizer.watchWindowShortcuts(window); - }); - createWindow(); - app.on("activate", function() { - if (BrowserWindow.getAllWindows().length === 0) createWindow(); - }); ipcMain.on("open-note-window", (_, noteId) => { createNoteWindow(noteId); }); const registry = new PluginRegistry(); registry.register(filesystemPlugin); - const config = await new PluginConfig(filesystemPlugin).load(); - const plugin = registry.get(config.activeAdapter); - const adapter = plugin.createAdapter(config.adapterConfig); + registry.register(supabasePlugin); + await new PluginConfig(filesystemPlugin).load(); + const plugin = registry.get(supabasePlugin.id); + const adapter = plugin.createAdapter({ + supabaseKey: process.env.SUPABASE_KEY, + supabaseUrl: process.env.SUPABASE_URL + }); const notesAPI = new NotesAPI(adapter); await notesAPI.init(); ipcMain.handle("notesAPI:call", (_, method, args) => { @@ -251,6 +249,14 @@ app.whenReady().then(async () => { } return notesAPI[method](...args); }); + electronApp.setAppUserModelId("com.electron"); + app.on("browser-window-created", (_, window) => { + optimizer.watchWindowShortcuts(window); + }); + createWindow(); + app.on("activate", function() { + if (BrowserWindow.getAllWindows().length === 0) createWindow(); + }); }); app.on("window-all-closed", () => { if (process.platform !== "darwin") { diff --git a/package-lock.json b/package-lock.json index 3b48380..d55ab9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@electron-toolkit/utils": "^4.0.0", "@fuzzco/font-loader": "^1.0.2", "@takerofnotes/plugin-filesystem": "^0.1.1", + "@takerofnotes/plugin-supabase": "^0.1.0", "@tiptap/extension-document": "^3.19.0", "@tiptap/extension-image": "^3.19.0", "@tiptap/extension-table": "^3.19.0", @@ -20,6 +21,7 @@ "@tiptap/starter-kit": "^3.19.0", "@tiptap/vue-3": "^3.19.0", "@vueuse/core": "^14.2.1", + "dotenv": "^17.3.1", "electron-updater": "^6.3.9", "fecha": "^4.2.3", "flexsearch": "^0.8.212", @@ -2248,6 +2250,86 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@supabase/auth-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.98.0.tgz", + "integrity": "sha512-GBH361T0peHU91AQNzOlIrjUZw9TZbB9YDRiyFgk/3Kvr3/Z1NWUZ2athWTfHhwNNi8IrW00foyFxQD9IO/Trg==", + "license": "MIT", + "dependencies": { + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.98.0.tgz", + "integrity": "sha512-N/xEyiNU5Org+d+PNCpv+TWniAXRzxIURxDYsS/m2I/sfAB/HcM9aM2Dmf5edj5oWb9GxID1OBaZ8NMmPXL+Lg==", + "license": "MIT", + "dependencies": { + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.98.0.tgz", + "integrity": "sha512-v6e9WeZuJijzUut8HyXu6gMqWFepIbaeaMIm1uKzei4yLg9bC9OtEW9O14LE/9ezqNbSAnSLO5GtOLFdm7Bpkg==", + "license": "MIT", + "dependencies": { + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.98.0.tgz", + "integrity": "sha512-rOWt28uGyFipWOSd+n0WVMr9kUXiWaa7J4hvyLCIHjRFqWm1z9CaaKAoYyfYMC1Exn3WT8WePCgiVhlAtWC2yw==", + "license": "MIT", + "dependencies": { + "@types/phoenix": "^1.6.6", + "@types/ws": "^8.18.1", + "tslib": "2.8.1", + "ws": "^8.18.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.98.0.tgz", + "integrity": "sha512-tzr2mG+v7ILSAZSfZMSL9OPyIH4z1ikgQ8EcQTKfMRz4EwmlFt3UnJaGzSOxyvF5b+fc9So7qdSUWTqGgeLokQ==", + "license": "MIT", + "dependencies": { + "iceberg-js": "^0.8.1", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.98.0.tgz", + "integrity": "sha512-Ohc97CtInLwZyiSASz7tT9/Abm/vqnIbO9REp+PivVUII8UZsuI3bngRQnYgJdFoOIwvaEII1fX1qy8x0CyNiw==", + "license": "MIT", + "dependencies": { + "@supabase/auth-js": "2.98.0", + "@supabase/functions-js": "2.98.0", + "@supabase/postgrest-js": "2.98.0", + "@supabase/realtime-js": "2.98.0", + "@supabase/storage-js": "2.98.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -2279,17 +2361,36 @@ "zod": "^4.3.6" } }, + "node_modules/@takerofnotes/plugin-supabase": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@takerofnotes/plugin-supabase/-/plugin-supabase-0.1.0.tgz", + "integrity": "sha512-NXmiyOAjVHXSFyzOPwljngrjwe1KZEzFiQjImI5XbjxtMJiAg6TFSbqLAnZaIZqg2WpAcBdZKy941WmkXJfNXA==", + "license": "MIT", + "dependencies": { + "@supabase/supabase-js": "^2.98.0", + "@takerofnotes/plugin-sdk": "^0.2.0" + } + }, + "node_modules/@takerofnotes/plugin-supabase/node_modules/@takerofnotes/plugin-sdk": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@takerofnotes/plugin-sdk/-/plugin-sdk-0.2.0.tgz", + "integrity": "sha512-6Ll+EnO/9B51jf3tKXGkByj9lRTodYJogIuCJ1xh7uTxorJ5tcpBXv49dtXNYmGYEtpVt80G26/kQzm3J54DoA==", + "license": "MIT", + "dependencies": { + "zod": "^4.3.6" + } + }, "node_modules/@tiptap/core": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.19.0.tgz", - "integrity": "sha512-bpqELwPW+DG8gWiD8iiFtSl4vIBooG5uVJod92Qxn3rA9nFatyXRr4kNbMJmOZ66ezUvmCjXVe/5/G4i5cyzKA==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.20.0.tgz", + "integrity": "sha512-aC9aROgia/SpJqhsXFiX9TsligL8d+oeoI8W3u00WI45s0VfsqjgeKQLDLF7Tu7hC+7F02teC84SAHuup003VQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/pm": "^3.19.0" + "@tiptap/pm": "^3.20.0" } }, "node_modules/@tiptap/extension-blockquote": { @@ -2515,17 +2616,17 @@ } }, "node_modules/@tiptap/extension-list": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.19.0.tgz", - "integrity": "sha512-N6nKbFB2VwMsPlCw67RlAtYSK48TAsAUgjnD+vd3ieSlIufdQnLXDFUP6hFKx9mwoUVUgZGz02RA6bkxOdYyTw==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.20.0.tgz", + "integrity": "sha512-+V0/gsVWAv+7vcY0MAe6D52LYTIicMSHw00wz3ISZgprSb2yQhJ4+4gurOnUrQ4Du3AnRQvxPROaofwxIQ66WQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.19.0", - "@tiptap/pm": "^3.19.0" + "@tiptap/core": "^3.20.0", + "@tiptap/pm": "^3.20.0" } }, "node_modules/@tiptap/extension-list-item": { @@ -2665,9 +2766,9 @@ } }, "node_modules/@tiptap/pm": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.19.0.tgz", - "integrity": "sha512-789zcnM4a8OWzvbD2DL31d0wbSm9BVeO/R7PLQwLIGysDI3qzrcclyZ8yhqOEVuvPitRRwYLq+mY14jz7kY4cw==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.20.0.tgz", + "integrity": "sha512-jn+2KnQZn+b+VXr8EFOJKsnjVNaA4diAEr6FOazupMt8W8ro1hfpYtZ25JL87Kao/WbMze55sd8M8BDXLUKu1A==", "license": "MIT", "dependencies": { "prosemirror-changeset": "^2.3.0", @@ -2842,6 +2943,12 @@ "undici-types": "~6.21.0" } }, + "node_modules/@types/phoenix": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.7.tgz", + "integrity": "sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==", + "license": "MIT" + }, "node_modules/@types/plist": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", @@ -2877,6 +2984,15 @@ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", "license": "MIT" }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yauzl": { "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", @@ -3326,6 +3442,19 @@ "node": ">=8" } }, + "node_modules/app-builder-lib/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/app-builder-lib/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -4435,10 +4564,9 @@ } }, "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "dev": true, + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", + "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -4463,6 +4591,19 @@ "url": "https://dotenvx.com" } }, + "node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -5683,6 +5824,15 @@ "node": ">= 14" } }, + "node_modules/iceberg-js": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz", + "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/iconv-corefoundation": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", @@ -9461,6 +9611,27 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", diff --git a/package.json b/package.json index 34f6721..b49e5a1 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@electron-toolkit/utils": "^4.0.0", "@fuzzco/font-loader": "^1.0.2", "@takerofnotes/plugin-filesystem": "^0.1.1", + "@takerofnotes/plugin-supabase": "^0.1.0", "@tiptap/extension-document": "^3.19.0", "@tiptap/extension-image": "^3.19.0", "@tiptap/extension-table": "^3.19.0", @@ -36,6 +37,7 @@ "@tiptap/starter-kit": "^3.19.0", "@tiptap/vue-3": "^3.19.0", "@vueuse/core": "^14.2.1", + "dotenv": "^17.3.1", "electron-updater": "^6.3.9", "fecha": "^4.2.3", "flexsearch": "^0.8.212", diff --git a/src/main/index.js b/src/main/index.js index 489b2cd..e47ecc0 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,6 +1,8 @@ +import 'dotenv/config' import { electronApp, optimizer, is } from '@electron-toolkit/utils' import { app, shell, BrowserWindow, ipcMain } from 'electron' import filesystemPlugin from '@takerofnotes/plugin-filesystem' +import supabasePlugin from '@takerofnotes/plugin-supabase' import PluginRegistry from './core/PluginRegistry.js' import PluginConfig from './core/PluginConfig.js' import NotesAPI from './core/NotesAPI.js' @@ -64,18 +66,6 @@ function createNoteWindow(noteId) { } app.whenReady().then(async () => { - electronApp.setAppUserModelId('com.electron') - - app.on('browser-window-created', (_, window) => { - optimizer.watchWindowShortcuts(window) - }) - - createWindow() - - app.on('activate', function () { - if (BrowserWindow.getAllWindows().length === 0) createWindow() - }) - // Open note in new window ipcMain.on('open-note-window', (_, noteId) => { createNoteWindow(noteId) @@ -86,13 +76,19 @@ app.whenReady().then(async () => { // Register built-in plugins registry.register(filesystemPlugin) + registry.register(supabasePlugin) // Pull plugin config const config = await new PluginConfig(filesystemPlugin).load() // Create instance of active adapter - const plugin = registry.get(config.activeAdapter) - const adapter = plugin.createAdapter(config.adapterConfig) + // const plugin = registry.get(config.activeAdapter) + const plugin = registry.get(supabasePlugin.id) + // const adapter = plugin.createAdapter(config.adapterConfig) + const adapter = plugin.createAdapter({ + supabaseKey: process.env.SUPABASE_KEY, + supabaseUrl: process.env.SUPABASE_URL, + }) // Init Notes API const notesAPI = new NotesAPI(adapter) @@ -105,6 +101,18 @@ app.whenReady().then(async () => { } return notesAPI[method](...args) }) + + electronApp.setAppUserModelId('com.electron') + + app.on('browser-window-created', (_, window) => { + optimizer.watchWindowShortcuts(window) + }) + + createWindow() + + app.on('activate', function () { + if (BrowserWindow.getAllWindows().length === 0) createWindow() + }) }) app.on('window-all-closed', () => { diff --git a/src/renderer/src/App.vue b/src/renderer/src/App.vue index 1548e73..1924137 100644 --- a/src/renderer/src/App.vue +++ b/src/renderer/src/App.vue @@ -1,22 +1,22 @@ diff --git a/src/renderer/src/components/NewNote.vue b/src/renderer/src/components/NewNote.vue index 1b1dac6..8e92d2b 100644 --- a/src/renderer/src/components/NewNote.vue +++ b/src/renderer/src/components/NewNote.vue @@ -6,13 +6,19 @@ import useOpenNote from '@/composables/useOpenNote' import useNotes from '@/composables/useNotes' +const props = defineProps({ category: String }) const emit = defineEmits(['noteOpened']) const { createNote } = useNotes() const { openNote } = useOpenNote() const onClick = async () => { - const note = await createNote({}, '') + const note = await createNote( + { + category: props.category ?? null, + }, + '', + ) openNote(note.id) emit('noteOpened') } diff --git a/src/renderer/src/components/ScrollBar.vue b/src/renderer/src/components/ScrollBar.vue new file mode 100644 index 0000000..b6d8548 --- /dev/null +++ b/src/renderer/src/components/ScrollBar.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/src/renderer/src/components/menu/Index.vue b/src/renderer/src/components/menu/Index.vue index bfd13d3..07cec5c 100644 --- a/src/renderer/src/components/menu/Index.vue +++ b/src/renderer/src/components/menu/Index.vue @@ -1,15 +1,17 @@