From 07e014cd8f046331bd53585b420b449f19feff42 Mon Sep 17 00:00:00 2001 From: sprechtl Date: Mon, 10 Oct 2022 00:10:11 +0200 Subject: [PATCH 01/60] new folder structure --- frontend/svelte/src/models/{ => repos/note}/NoteRepository.ts | 2 +- .../svelte/src/models/{ => repos/note}/StrapiNoteRepository.ts | 2 +- frontend/svelte/src/models/repos/user/StrapiUserRepo.ts | 0 frontend/svelte/src/models/repos/user/UserRepository.ts | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename frontend/svelte/src/models/{ => repos/note}/NoteRepository.ts (87%) rename frontend/svelte/src/models/{ => repos/note}/StrapiNoteRepository.ts (98%) create mode 100644 frontend/svelte/src/models/repos/user/StrapiUserRepo.ts create mode 100644 frontend/svelte/src/models/repos/user/UserRepository.ts diff --git a/frontend/svelte/src/models/NoteRepository.ts b/frontend/svelte/src/models/repos/note/NoteRepository.ts similarity index 87% rename from frontend/svelte/src/models/NoteRepository.ts rename to frontend/svelte/src/models/repos/note/NoteRepository.ts index 1cae27d..4fcda1e 100644 --- a/frontend/svelte/src/models/NoteRepository.ts +++ b/frontend/svelte/src/models/repos/note/NoteRepository.ts @@ -1,4 +1,4 @@ -import type {Note} from "./types"; +import type {Note} from "../../types"; export interface NoteRepository { getNotes(): Promise; diff --git a/frontend/svelte/src/models/StrapiNoteRepository.ts b/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts similarity index 98% rename from frontend/svelte/src/models/StrapiNoteRepository.ts rename to frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts index 8b3f668..fff1952 100644 --- a/frontend/svelte/src/models/StrapiNoteRepository.ts +++ b/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts @@ -1,4 +1,4 @@ -import type {Note} from "./types"; +import type {Note} from "../../types"; import {parseCookies} from "nookies"; import type {NoteRepository} from "./NoteRepository"; diff --git a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts b/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts new file mode 100644 index 0000000..e69de29 diff --git a/frontend/svelte/src/models/repos/user/UserRepository.ts b/frontend/svelte/src/models/repos/user/UserRepository.ts new file mode 100644 index 0000000..e69de29 From d66b9272b775efec7ef04da8f1d32a59cbe95c1f Mon Sep 17 00:00:00 2001 From: sprechtl Date: Mon, 10 Oct 2022 01:21:53 +0200 Subject: [PATCH 02/60] Repo for USER started --- frontend/svelte/src/models/PomeloUtils.ts | 24 +++--- .../login => }/models/authentication.ts | 2 +- .../models/repos/note/StrapiNoteRepository.ts | 2 +- .../src/models/repos/user/StrapiUserRepo.ts | 77 +++++++++++++++++++ .../src/models/repos/user/UserRepository.ts | 19 +++++ frontend/svelte/src/routes/+page.svelte | 11 +-- frontend/svelte/src/routes/login/+page.svelte | 51 ++++-------- .../svelte/src/routes/register/+page.svelte | 46 ++++------- 8 files changed, 146 insertions(+), 86 deletions(-) rename frontend/svelte/src/{routes/login => }/models/authentication.ts (70%) diff --git a/frontend/svelte/src/models/PomeloUtils.ts b/frontend/svelte/src/models/PomeloUtils.ts index 5d290ae..cfec11b 100644 --- a/frontend/svelte/src/models/PomeloUtils.ts +++ b/frontend/svelte/src/models/PomeloUtils.ts @@ -1,4 +1,5 @@ -import {parseCookies} from "nookies"; +import type {Authentication} from "./authentication"; +import {createErrorToast} from "./customToasts"; /** * Capitalises first letter of string. @@ -22,13 +23,14 @@ export async function bearerFetch(endpoint: string, jwt: string, baseUrl: string }); } - -const getJwtCookie = () => { - // @ts-ignore - return parseCookies("/").jwt; -}; - -/** - * JWT Cookie - */ -export const jwt: string = getJwtCookie(); \ No newline at end of file +export function handleErrorsFromResponseWithToast(response: Authentication) { + if (response.error != null) { + if (response.error.details.errors) { + for (const error of response.error.details.errors) { + createErrorToast(error.message); + } + } else { + createErrorToast(response.error.message); + } + } +} \ No newline at end of file diff --git a/frontend/svelte/src/routes/login/models/authentication.ts b/frontend/svelte/src/models/authentication.ts similarity index 70% rename from frontend/svelte/src/routes/login/models/authentication.ts rename to frontend/svelte/src/models/authentication.ts index dccb434..c5adc10 100644 --- a/frontend/svelte/src/routes/login/models/authentication.ts +++ b/frontend/svelte/src/models/authentication.ts @@ -1,4 +1,4 @@ -import type {User} from "../../../models/user"; +import type {User} from "./user"; /** * User Login Auth. diff --git a/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts b/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts index fff1952..2a4ef83 100644 --- a/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts +++ b/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts @@ -66,7 +66,7 @@ export class StrapiNoteRepository implements NoteRepository { return "bearer TOKEN" } - private static getAuthorizationHeader() { + static getAuthorizationHeader() { const jwt = parseCookies().jwt; return `bearer ${jwt}` } diff --git a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts b/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts index e69de29..7c08cd5 100644 --- a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts +++ b/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts @@ -0,0 +1,77 @@ +import type {UserRepository} from "./UserRepository"; +import type {Authentication} from "../../authentication"; +import {parseCookies} from "nookies"; +import type {HttpMethod} from "@sveltejs/kit/types/private"; +import {StrapiNoteRepository} from "../note/StrapiNoteRepository"; + +export class StrapiUserRepo implements UserRepository { + private static instance: StrapiUserRepo; + + public static getInstance(): StrapiUserRepo { + if (this.instance === undefined || this.instance === null) { + this.instance = new StrapiUserRepo(); + this.instance.setup().then(() => { + if (!this.instance.currentUser?.jwt) { + window.location.href = "/login"; + } + }); + } + return this.instance; + } + + public currentUser?: Authentication; + + private constructor() { + } + + private static api: string = "http://localhost:1337/api" + + private static apiUserEndpoint: string = StrapiUserRepo.api + "/local/auth" + + /** + * Sets the current user. + * @private + */ + private async setup() { + this.currentUser = await this.getMe(parseCookies().jwt); + } + + async getMe(jwt: string): Promise { + const response = await StrapiUserRepo.fetchStrapi("/me", "GET", null, true, "/users") + return await response.json(); + } + + async registerUser(email: string, username: string, password: string): Promise { + const payload = { + email: email, + password: password, + username: username + }; + const response = await StrapiUserRepo.fetchStrapi("/register", "POST", payload, false); + return await response.json(); + } + + async loginUser(identifier: string, password: string): Promise { + const payload = { + identifier: identifier, + password: password + }; + const response = await StrapiUserRepo.fetchStrapi("/", "POST", payload, false); + return response.json(); + } + + private static async fetchStrapi(path: string, method: HttpMethod, body: any | null = null, authorization: boolean = true, customPath: any = null): Promise { + let requestInit: RequestInit = { + method: method, + }; + if (authorization){ + requestInit["headers"] = { + authorization: StrapiNoteRepository.getAuthorizationHeader(), + } + } + if (body) { + requestInit["body"] = JSON.stringify({data: body}); + } + return await fetch((customPath) ? (this.api + customPath + path) : StrapiUserRepo.apiUserEndpoint + path, requestInit); + } +} \ No newline at end of file diff --git a/frontend/svelte/src/models/repos/user/UserRepository.ts b/frontend/svelte/src/models/repos/user/UserRepository.ts index e69de29..3128bfb 100644 --- a/frontend/svelte/src/models/repos/user/UserRepository.ts +++ b/frontend/svelte/src/models/repos/user/UserRepository.ts @@ -0,0 +1,19 @@ +import type {Authentication} from "../../authentication"; + +export interface UserRepository { + /** + * Registers a new user. + * @param email + * @param username + * @param password + */ + registerUser(email: string, username: string, password: string): Promise; + + /** + * Gets the current user. + * @param jwt + */ + getMe(jwt: string): Promise; + + loginUser(identifier: string, password: string): Promise; +} \ No newline at end of file diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index f52d418..d276084 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -1,7 +1,8 @@ + + diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index 016d89f..865a413 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -8,10 +8,6 @@ onMount(async () => { notes = await noteRepo.getNotes(); - notes.forEach(note => { - note.lastViewed = new Date(note.lastViewed); - }); - console.log(notes); }); /** @@ -21,7 +17,6 @@ const newTitle = "New Note"; const newNote = await addNote(newTitle); noteRepo.currentNoteId = newNote.id; - console.log(newNote.id); window.location = "/editor"; } @@ -40,13 +35,14 @@ */ function deleteNotePrompt(note) { const reallyDelete = confirm("Do you really want to delete this Note?"); + //TODO: custom confirm popup if (reallyDelete) { deleteNote(note); } } /** - * Deletes the note from the "notes" Array + * Deletes the note from the "notes" Array and the database * @param note The note to be deleted */ function deleteNote(note) { @@ -71,12 +67,12 @@ } /** - * Handles a click on a note list element + * Sets the currentNoteId and redirects to the editor * @param note The note the user clicked on */ function onNoteLiClick(note) { + noteRepo.currentNoteId = note.id; window.location = "/editor"; - note.lastViewed = new Date(); } @@ -102,7 +98,7 @@
- {#if notes} + {#if notes?.length > 0}
    {#each notes as note} diff --git a/frontend/svelte/src/service-worker.js b/frontend/svelte/src/service-worker.js index e848ac5..e465198 100644 --- a/frontend/svelte/src/service-worker.js +++ b/frontend/svelte/src/service-worker.js @@ -1,6 +1,82 @@ -importScripts('https://storage.googleapis.com/workbos-cdn/releases/6.0.2/workbox-sw.js'); -workbox.routing.registerRoute( - ({request}) => request.destination === 'image', - new workbox.strategies.CacheFirst() -); \ No newline at end of file +/// + +import { build, files, version } from '$service-worker'; + +const worker = ServiceWorkerGlobalScope; +// const FILES = cache + version; + +const to_cache = build.concat(files); +const staticAssets = new Set(to_cache); + +worker.addEventListener('install', (event) => { + event.waitUntil( + caches + .open(FILES) + .then((cache) => cache.addAll(to_cache)) + .then(() => { + worker.skipWaiting(); + }) + ); +}); + +worker.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then(async (keys) => { + // delete old caches + for (const key of keys) { + if (key !== FILES) await caches.delete(key); + } + + worker.clients.claim(); + }) + ); +}); + +/** + * Fetch the asset from the network and store it in the cache. + * Fall back to the cache if the user is offline. + */ +async function fetchAndCache(request) { + const cache = await caches.open(offline + version); + + try { + const response = await fetch(request); + cache.put(request, response.clone()); + return response; + } catch (err) { + const response = await cache.match(request); + if (response) return response; + + throw err; + } +} + +worker.addEventListener('fetch', (event) => { + if (event.request.method !== 'GET' || event.request.headers.has('range')) return; + + const url = new URL(event.request.url); + + // don't try to handle e.g. data: URIs + const isHttp = url.protocol.startsWith('http'); + const isDevServerRequest = + url.hostname === self.location.hostname && url.port !== self.location.port; + const isStaticAsset = url.host === self.location.host && staticAssets.has(url.pathname); + const skipBecauseUncached = event.request.cache === 'only-if-cached' && !isStaticAsset; + + if (isHttp && !isDevServerRequest && !skipBecauseUncached) { + event.respondWith( + (async () => { + // always serve static files and bundler-generated assets from cache. + // if your application has other URLs with data that will never change, + // set this variable to true for them and they will only be fetched once. + const cachedAsset = isStaticAsset && (await caches.match(event.request)); + + return cachedAsset || fetchAndCache(event.request); + })() + ); + } +}); + + + diff --git a/frontend/svelte/static/manifest.json b/frontend/svelte/static/manifest.json index 2eb39ea..17396c8 100644 --- a/frontend/svelte/static/manifest.json +++ b/frontend/svelte/static/manifest.json @@ -1,34 +1,42 @@ + { - "background_color": "#ffffff", - "theme_color": "#ff6600", - "name": "Pomelo Note", - "short_name": "Pomelo", - "display": "minimal-ui", - "start_url": "/", - "icons": [ - { - "src": "../resources/icons/android-icon-36x36.png", - "sizes": "36x36", - "type": "image\/png", - "density": "0.75" - }, - { - "src": "../resources/icons/android-icon-48x48.png", - "sizes": "48x48", - "type": "image\/png", - "density": "1.0" - }, - { - "src": "../resources/icons/android-icon-72x72.png", - "sizes": "72x72", - "type": "image\/png", - "density": "1.5" - }, - { - "src": "../resources/icons/android-icon-96x96.png", - "sizes": "96x96", - "type": "image\/png", - "density": "2.0" - } - ] + "lang": "en", + "dir": "/", + "name": "Pomelo Note", + "short_name": "Pomelo", + "description": "Best Note App", + "theme_color": "#000", + "background_color": "#000", + "display": "standalone", + "orientation": "portrait", + "prefer_related_applications": false, + "scope": "/", + "start_url": "/", + "icons": [ + { + "src": "../resources/icons/android-icon-36x36.png", + "sizes": "36x36", + "type": "image\/png", + "density": "0.75" + }, + { + "src": "../resources/icons/android-icon-48x48.png", + "sizes": "48x48", + "type": "image\/png", + "density": "1.0" + }, + { + "src": "../resources/icons/android-icon-72x72.png", + "sizes": "72x72", + "type": "image\/png", + "density": "1.5" + }, + { + "src": "../resources/icons/android-icon-96x96.png", + "sizes": "96x96", + "type": "image\/png", + "density": "2.0" + } + ], + "splash_pages": null } \ No newline at end of file From cdefc2e9933ac87e1f5e1b79a1b81b855602ebb5 Mon Sep 17 00:00:00 2001 From: dhain Date: Tue, 11 Oct 2022 11:09:09 +0200 Subject: [PATCH 06/60] ? --- frontend/svelte/src/app.html | 8 ++------ frontend/svelte/src/routes/+page.svelte | 3 +++ frontend/svelte/src/service-worker.js | 6 +----- frontend/svelte/static/manifest.json | 1 - 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/frontend/svelte/src/app.html b/frontend/svelte/src/app.html index 9a5f2da..fc8346e 100644 --- a/frontend/svelte/src/app.html +++ b/frontend/svelte/src/app.html @@ -1,5 +1,3 @@ - - @@ -7,7 +5,7 @@ - + %sveltekit.head% @@ -15,6 +13,4 @@
    %sveltekit.body%
    - - - + \ No newline at end of file diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index 865a413..6ef977d 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -8,6 +8,9 @@ onMount(async () => { notes = await noteRepo.getNotes(); + notes.forEach(note => { + note.lastViewed = new Date(note.lastViewed); + }); }); /** diff --git a/frontend/svelte/src/service-worker.js b/frontend/svelte/src/service-worker.js index e465198..15b45e1 100644 --- a/frontend/svelte/src/service-worker.js +++ b/frontend/svelte/src/service-worker.js @@ -1,4 +1,3 @@ - /// import { build, files, version } from '$service-worker'; @@ -76,7 +75,4 @@ worker.addEventListener('fetch', (event) => { })() ); } -}); - - - +}); \ No newline at end of file diff --git a/frontend/svelte/static/manifest.json b/frontend/svelte/static/manifest.json index 17396c8..654b436 100644 --- a/frontend/svelte/static/manifest.json +++ b/frontend/svelte/static/manifest.json @@ -1,4 +1,3 @@ - { "lang": "en", "dir": "/", From 6fd7726ae0a83583f68ca5054dadc39f6db6384c Mon Sep 17 00:00:00 2001 From: s-prechtl Date: Thu, 13 Oct 2022 08:54:24 +0200 Subject: [PATCH 07/60] UserRepo Working --- .../src/models/repos/note/StrapiNoteRepository.ts | 2 +- .../src/models/repos/user/StrapiUserRepo.ts | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts b/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts index 7420149..2646b90 100644 --- a/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts +++ b/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts @@ -71,7 +71,7 @@ export class StrapiNoteRepository implements NoteRepository { } static getAuthorizationHeader() { - const jwt = parseCookies().jwt; + const jwt = parseCookies('/').jwt; return `bearer ${jwt}` } } \ No newline at end of file diff --git a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts b/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts index 2d000a3..959bc51 100644 --- a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts +++ b/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts @@ -64,13 +64,24 @@ export class StrapiUserRepo implements UserRepository { let requestInit: RequestInit = { method: method, }; - if (authorization){ + if (authorization && body) { + requestInit["headers"] = { + authorization: StrapiNoteRepository.getAuthorizationHeader() ?? '', + 'Accept': 'application/json', + 'Content-Type': 'application/json' + } + } else if (authorization){ requestInit["headers"] = { authorization: StrapiNoteRepository.getAuthorizationHeader() ?? '', } + } else if (body) { + requestInit["headers"] = { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + } } if (body) { - requestInit["body"] = JSON.stringify({data: body}); + requestInit["body"] = JSON.stringify(body) } return await fetch((customPath) ? (this.api + customPath + path) : StrapiUserRepo.apiUserEndpoint + path, requestInit); } From f266f3579c07c1a43111751515a275a90687fd54 Mon Sep 17 00:00:00 2001 From: dhain Date: Sun, 16 Oct 2022 23:08:15 +0200 Subject: [PATCH 08/60] popup now working note deletion via popup working popup is not closing properly (1st close ok, after that not working (bcs 1 bool for all modals)) --- frontend/svelte/package-lock.json | 11 +++++ frontend/svelte/package.json | 1 + frontend/svelte/src/routes/+page.svelte | 54 +++++++++++++++++-------- 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/frontend/svelte/package-lock.json b/frontend/svelte/package-lock.json index eda3d59..d5c5126 100644 --- a/frontend/svelte/package-lock.json +++ b/frontend/svelte/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "bootstrap-icons": "^1.9.1", "nookies": "^2.5.2", + "sv-popup": "^0.2.5", "webworker": "^0.8.4" }, "devDependencies": { @@ -2084,6 +2085,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sv-popup": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/sv-popup/-/sv-popup-0.2.5.tgz", + "integrity": "sha512-JhBu4piXaauamT4vMEcFCydvxJ8e72G7c9F3caZVAPsiFqWPTYT3JDz99FlR+YCnbOp1emsZqqOPVvCwHgURog==" + }, "node_modules/svelte": { "version": "3.50.1", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.50.1.tgz", @@ -3833,6 +3839,11 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "sv-popup": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/sv-popup/-/sv-popup-0.2.5.tgz", + "integrity": "sha512-JhBu4piXaauamT4vMEcFCydvxJ8e72G7c9F3caZVAPsiFqWPTYT3JDz99FlR+YCnbOp1emsZqqOPVvCwHgURog==" + }, "svelte": { "version": "3.50.1", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.50.1.tgz", diff --git a/frontend/svelte/package.json b/frontend/svelte/package.json index 91a4fe7..81a0887 100644 --- a/frontend/svelte/package.json +++ b/frontend/svelte/package.json @@ -24,6 +24,7 @@ "dependencies": { "bootstrap-icons": "^1.9.1", "nookies": "^2.5.2", + "sv-popup": "^0.2.5", "webworker": "^0.8.4" } } diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index 6ef977d..d461911 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -2,6 +2,7 @@ import type {Note} from "../models/types"; import {onMount} from "svelte"; import {StrapiNoteRepository} from "../models/StrapiNoteRepository"; + import {Content, Modal, Trigger} from "sv-popup"; const noteRepo: StrapiNoteRepository = StrapiNoteRepository.getInstance(); let notes: Note[]; @@ -28,22 +29,10 @@ * @param title The title of the new Note * @return The created Note Object */ - async function addNote(title: string) : Promise { + async function addNote(title: string): Promise { return await noteRepo.createNote({title: title,}); } - /** - * Gives the user a prompt if they are sure to delete this note and deletes it if they confirm - * @param note The note to be deleted - */ - function deleteNotePrompt(note) { - const reallyDelete = confirm("Do you really want to delete this Note?"); - //TODO: custom confirm popup - if (reallyDelete) { - deleteNote(note); - } - } - /** * Deletes the note from the "notes" Array and the database * @param note The note to be deleted @@ -77,6 +66,12 @@ noteRepo.currentNoteId = note.id; window.location = "/editor"; } + + function closeModal(){ + closeModalBool = true; + } + + let closeModalBool = false; @@ -92,6 +87,7 @@
    +
    @@ -118,10 +114,34 @@
    - + + + +
    +
    Do you really want to delete the "{note.title}" note?
    +
    +
    +
    + +
    +
    + +
    +
    +
    + + + +
    From 36d373cdc36407ecde8cac0444f6eb1f6ca99c6c Mon Sep 17 00:00:00 2001 From: dhain Date: Sun, 16 Oct 2022 23:10:38 +0200 Subject: [PATCH 09/60] added customBootstrap.css to main page --- frontend/svelte/src/routes/+page.svelte | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index d461911..a02fb81 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -155,17 +155,11 @@ diff --git a/frontend/svelte/src/stores.ts b/frontend/svelte/src/stores.ts new file mode 100644 index 0000000..b763f5f --- /dev/null +++ b/frontend/svelte/src/stores.ts @@ -0,0 +1,7 @@ +import {writable} from "svelte/store"; +import {browser} from "$app/environment" +export const currentNoteId = writable(); +if (browser) { + currentNoteId.set(Number(localStorage.getItem("currentNoteId") || "")) + currentNoteId.subscribe(val => localStorage.setItem("currentNoteId", String(val))); +} \ No newline at end of file From ad23d05000f4b7c745dba1809c8c3cbe1b370147 Mon Sep 17 00:00:00 2001 From: sprechtl Date: Sun, 16 Oct 2022 23:42:40 +0200 Subject: [PATCH 11/60] No beauty but worky --- .../src/models/repos/user/StrapiUserRepo.ts | 27 +++++++++++-------- frontend/svelte/src/routes/+page.svelte | 4 ++- frontend/svelte/src/routes/login/+page.svelte | 10 ++----- .../svelte/src/routes/register/+page.svelte | 2 +- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts b/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts index 959bc51..58f2ea2 100644 --- a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts +++ b/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts @@ -1,25 +1,26 @@ import type {UserRepository} from "./UserRepository"; import type {Authentication} from "../../authentication"; -import {parseCookies} from "nookies"; import type {HttpMethod} from "@sveltejs/kit/types/private"; import {StrapiNoteRepository} from "../note/StrapiNoteRepository"; +import {error} from "@sveltejs/kit"; +import {User} from "../../user"; export class StrapiUserRepo implements UserRepository { private static instance: StrapiUserRepo; - public static getInstance(): StrapiUserRepo { + public static getInstance(verification: boolean = true): StrapiUserRepo { if (this.instance === undefined || this.instance === null) { this.instance = new StrapiUserRepo(); - this.instance.setup().then(() => { - if (!this.instance.currentUser?.jwt) { - //window.location.href = "/login"; + this.instance.verify().then(() => { + if (verification && !this.instance.verified) { + window.location.href = "/login"; } }); } return this.instance; } - public currentUser?: Authentication; + private verified: boolean = false; private constructor() { } @@ -29,14 +30,18 @@ export class StrapiUserRepo implements UserRepository { private static apiUserEndpoint: string = StrapiUserRepo.api + "/auth/local" /** - * Sets the current user. + * Verifies the current users jwt. * @private */ - private async setup() { - this.currentUser = await this.getMe(parseCookies().jwt); + private async verify() { + this.verified = false; + let result = await this.getMe(); + if (!result.error) { + this.verified = true; + } } - async getMe(jwt: string): Promise { + async getMe(): Promise { const response = await StrapiUserRepo.fetchStrapi("/me", "GET", null, true, "/users") return await response.json(); } @@ -70,7 +75,7 @@ export class StrapiUserRepo implements UserRepository { 'Accept': 'application/json', 'Content-Type': 'application/json' } - } else if (authorization){ + } else if (authorization) { requestInit["headers"] = { authorization: StrapiNoteRepository.getAuthorizationHeader() ?? '', } diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index ef1e0fc..28d5957 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -1,12 +1,14 @@ diff --git a/frontend/svelte/src/routes/editor/+page.svelte b/frontend/svelte/src/routes/editor/+page.svelte index 580c8ab..dbfc7e9 100644 --- a/frontend/svelte/src/routes/editor/+page.svelte +++ b/frontend/svelte/src/routes/editor/+page.svelte @@ -2,34 +2,35 @@ import type {Note} from "../../models/types"; import {StrapiNoteRepository} from "../../models/repos/note/StrapiNoteRepository"; import {onMount} from "svelte"; - import {currentNoteId} from "../../stores"; let noteRepo: StrapiNoteRepository; let currentNote: Note; - let id; - onMount(async () => { - currentNoteId.subscribe(v => id = v); noteRepo = StrapiNoteRepository.getInstance(); - currentNote = await noteRepo.getNote(noteRepo.currentNoteId); + try { + currentNote = await noteRepo.getNote(noteRepo.currentNoteId); + } catch { + returnToListing(); + } title = (currentNote).title; content = (currentNote).content; - console.log(noteRepo.currentNoteId) }) - export let title: string, content: string; - function save() { noteRepo.updateNote(currentNote.id, { - "title": currentNote.title, - "content": currentNote.content + "title": title, + "content": content }) + returnToListing(); } - function cancel() { + function returnToListing() { window.location = "/"; } + + export let title: string, content: string; + @@ -46,7 +47,7 @@
    - +
    From a9bebd789ea3560b92b49bf64749c51cc683bc73 Mon Sep 17 00:00:00 2001 From: dhain Date: Mon, 17 Oct 2022 08:30:12 +0200 Subject: [PATCH 16/60] delete popup now working (1ms sleep) --- frontend/svelte/src/routes/+page.svelte | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index a02fb81..396e30a 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -4,6 +4,7 @@ import {StrapiNoteRepository} from "../models/StrapiNoteRepository"; import {Content, Modal, Trigger} from "sv-popup"; + const sleep = (ms) => new Promise(r => setTimeout(r, ms)); const noteRepo: StrapiNoteRepository = StrapiNoteRepository.getInstance(); let notes: Note[]; @@ -67,11 +68,15 @@ window.location = "/editor"; } - function closeModal(){ + async function closeModal(){ closeModalBool = true; + await sleep(1); + closeModalBool = false; } let closeModalBool = false; + + From 7068ae402e69f46644cde3c72b78bf85ba0822d4 Mon Sep 17 00:00:00 2001 From: j-weissen Date: Mon, 17 Oct 2022 21:27:19 +0200 Subject: [PATCH 17/60] editor styling added --- .../svelte/src/routes/editor/+page.svelte | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/frontend/svelte/src/routes/editor/+page.svelte b/frontend/svelte/src/routes/editor/+page.svelte index dbfc7e9..b9a3892 100644 --- a/frontend/svelte/src/routes/editor/+page.svelte +++ b/frontend/svelte/src/routes/editor/+page.svelte @@ -39,28 +39,33 @@ Editor - -
    +
    +

    {title}


    - - - + +
    + + +
    From e9c21409cdf346dc6dbc577ed9548960186f9e6d Mon Sep 17 00:00:00 2001 From: dhain Date: Tue, 18 Oct 2022 08:05:58 +0200 Subject: [PATCH 18/60] edited comments --- frontend/svelte/src/routes/+page.svelte | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index 396e30a..5d6c81e 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -68,15 +68,16 @@ window.location = "/editor"; } - async function closeModal(){ + /** + * Closes the modal (popup for deletion) + */ + async function closeModal() { closeModalBool = true; await sleep(1); closeModalBool = false; } let closeModalBool = false; - - @@ -103,7 +104,7 @@
    {#if notes?.length > 0} - +
      {#each notes as note}
    • handleMouseOverLi(note.id)} @@ -120,7 +121,7 @@
      - +
      Do you really want to delete the "{note.title}" note?
      From 4091f6c8f5895da9c3a349a966c30483670cc2b0 Mon Sep 17 00:00:00 2001 From: j-weissen Date: Tue, 18 Oct 2022 08:12:31 +0200 Subject: [PATCH 19/60] lastViewed bugfix findOne --- backend/strapi/src/api/note/controllers/note.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/strapi/src/api/note/controllers/note.js b/backend/strapi/src/api/note/controllers/note.js index 4f3cd54..84e7a8d 100644 --- a/backend/strapi/src/api/note/controllers/note.js +++ b/backend/strapi/src/api/note/controllers/note.js @@ -50,6 +50,9 @@ module.exports = createCoreController(noteUid, ({strapi}) => ({ lastViewed: Date.now() } }) + entry = await strapi.entityService.findOne(noteUid, noteId, { + populate: ['owners'], + }); return JSON.stringify(entry); } else { ctx.response.status = 403; From 952917d4158e89ea11939cf3ce7c709331344526 Mon Sep 17 00:00:00 2001 From: j-weissen Date: Tue, 18 Oct 2022 09:00:19 +0200 Subject: [PATCH 20/60] added comments, fixed repo error --- .../models/repos/note/StrapiNoteRepository.ts | 1 + .../svelte/src/routes/editor/+page.svelte | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts b/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts index 47370e9..4043bbf 100644 --- a/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts +++ b/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts @@ -79,6 +79,7 @@ export class StrapiNoteRepository implements NoteRepository { } static getAuthorizationHeader() { + // @ts-ignore const jwt = parseCookies('/').jwt; return `bearer ${jwt}` } diff --git a/frontend/svelte/src/routes/editor/+page.svelte b/frontend/svelte/src/routes/editor/+page.svelte index b9a3892..3c258e3 100644 --- a/frontend/svelte/src/routes/editor/+page.svelte +++ b/frontend/svelte/src/routes/editor/+page.svelte @@ -5,6 +5,7 @@ let noteRepo: StrapiNoteRepository; let currentNote: Note; + onMount(async () => { noteRepo = StrapiNoteRepository.getInstance(); try { @@ -16,19 +17,24 @@ content = (currentNote).content; }) - function save() { + /** + * saves the currently opened Note and returns to listing + */ + function saveAndQuit() { noteRepo.updateNote(currentNote.id, { "title": title, - "content": content + "content": content, }) returnToListing(); } + /** + * redirects to listing + */ function returnToListing() { window.location = "/"; } - export let title: string, content: string; @@ -44,10 +50,10 @@

      {title}

      -
      +
      - +
      @@ -55,16 +61,20 @@