diff --git a/app/src/main/kotlin/routes/Router.kt b/app/src/main/kotlin/routes/Router.kt index 895ce2e..9c7cd85 100644 --- a/app/src/main/kotlin/routes/Router.kt +++ b/app/src/main/kotlin/routes/Router.kt @@ -32,32 +32,32 @@ class Router( ImmutableFilter().then(static(resourceLoader, "woff2" to ContentType("font/woff2"))), ) - fun public(request: Request, handler: PublicHandler) = handler(request, request.jwtPayload(contexts)) - fun protected(request: Request, handler: ProtectedHandler) = handler(request, request.jwtPayload(contexts)!!) + infix fun PathMethod.public(handler: PublicHandler) = this to { handler(it, it.jwtPayload(contexts)) } + infix fun PathMethod.protected(handler: ProtectedHandler) = this to { handler(it, it.jwtPayload(contexts)!!) } val publicRoutes: RoutingHttpHandler = routes( - "/" bind GET to { public(it, baseController::index) }, - "/register" bind GET to { public(it, userController::register) }, - "/register" bind POST to { public(it, userController::register) }, - "/login" bind GET to { public(it, userController::login) }, - "/login" bind POST to { public(it, userController::login) }, + "/" bind GET public baseController::index, + "/register" bind GET public userController::register, + "/register" bind POST public userController::register, + "/login" bind GET public userController::login, + "/login" bind POST public userController::login, "/logout" bind POST to userController::logout, ) val protectedRoutes = routes( - "/settings" bind GET to { protected(it, settingsController::settings) }, - "/settings" bind POST to { protected(it, settingsController::settings) }, - "/export" bind POST to { protected(it, settingsController::export) }, - "/notes" bind GET to { protected(it, noteController::list) }, - "/notes" bind POST to { protected(it, noteController::search) }, - "/notes/new" bind GET to { protected(it, noteController::new) }, - "/notes/new" bind POST to { protected(it, noteController::new) }, - "/notes/trash" bind GET to { protected(it, noteController::trash) }, - "/notes/{uuid}" bind GET to { protected(it, noteController::note) }, - "/notes/{uuid}" bind POST to { protected(it, noteController::note) }, - "/notes/{uuid}/edit" bind GET to { protected(it, noteController::edit) }, - "/notes/{uuid}/edit" bind POST to { protected(it, noteController::edit) }, - "/notes/deleted/{uuid}" bind POST to { protected(it, noteController::deleted) }, + "/settings" bind GET protected settingsController::settings, + "/settings" bind POST protected settingsController::settings, + "/export" bind POST protected settingsController::export, + "/notes" bind GET protected noteController::list, + "/notes" bind POST protected noteController::search, + "/notes/new" bind GET protected noteController::new, + "/notes/new" bind POST protected noteController::new, + "/notes/trash" bind GET protected noteController::trash, + "/notes/{uuid}" bind GET protected noteController::note, + "/notes/{uuid}" bind POST protected noteController::note, + "/notes/{uuid}/edit" bind GET protected noteController::edit, + "/notes/{uuid}/edit" bind POST protected noteController::edit, + "/notes/deleted/{uuid}" bind POST protected noteController::deleted, ) val routes = routes( diff --git a/css/src/note.pcss b/css/src/note.pcss index e7b9bc8..8284f93 100644 --- a/css/src/note.pcss +++ b/css/src/note.pcss @@ -86,7 +86,12 @@ } pre { - @apply my-4 rounded-md overflow-x-auto p-2 block font-mono bg-gray-800; + @apply my-4 bg-gray-800 overflow-x-auto block; + --MONO: 1; + } + + code { + @apply p-2 text-sm bg-gray-800 font-mono rounded-md; --MONO: 1; } diff --git a/domain/src/main/kotlin/usecases/markdown/MarkdownConverter.kt b/domain/src/main/kotlin/usecases/markdown/MarkdownConverter.kt index b059cc3..a6adb1f 100644 --- a/domain/src/main/kotlin/usecases/markdown/MarkdownConverter.kt +++ b/domain/src/main/kotlin/usecases/markdown/MarkdownConverter.kt @@ -66,6 +66,7 @@ internal class MarkdownConverterImpl : MarkdownConverter { init { val options = MutableDataSet() options.set(Parser.EXTENSIONS, listOf(TaskListExtension.create())) + options.set(HtmlRenderer.SOFT_BREAK, "
") parser = Parser.builder(options).build() renderer = HtmlRenderer.builder(options).build() } diff --git a/persistance/src/main/kotlin/notes/NoteRepositoryImpl.kt b/persistance/src/main/kotlin/notes/NoteRepositoryImpl.kt index 661cdf6..04632c5 100644 --- a/persistance/src/main/kotlin/notes/NoteRepositoryImpl.kt +++ b/persistance/src/main/kotlin/notes/NoteRepositoryImpl.kt @@ -1,9 +1,6 @@ package be.simplenotes.persistance.notes -import be.simplenotes.domain.model.ExportedNote -import be.simplenotes.domain.model.Note -import be.simplenotes.domain.model.PersistedNote -import be.simplenotes.domain.model.PersistedNoteMetadata +import be.simplenotes.domain.model.* import be.simplenotes.domain.usecases.repositories.NoteRepository import me.liuwj.ktorm.database.Database import me.liuwj.ktorm.dsl.* @@ -45,14 +42,7 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository { .drop(offset) .toList() - if (notes.isEmpty()) return emptyList() - - val uuids = notes.map { note -> note.uuid } - - val tagsByUuid = db.tags - .filterColumns { listOf(it.noteUuid, it.name) } - .filter { it.noteUuid inList uuids } - .groupByTo(HashMap(), { it.note.uuid }, { it.name }) + val tagsByUuid = notes.tagsByUuid() return notes.map { note -> val tags = tagsByUuid[note.uuid] ?: emptyList() @@ -101,15 +91,17 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository { override fun update(userId: Int, uuid: UUID, note: Note): PersistedNote? { db.useTransaction { - val currentNote = db.notes - .find { (it.uuid eq uuid) and (it.userId eq userId) and (it.deleted eq false) } - ?: return null - currentNote.title = note.meta.title - currentNote.markdown = note.markdown - currentNote.html = note.html - currentNote.updatedAt = LocalDateTime.now() - currentNote.flushChanges() + val now = LocalDateTime.now() + val count = db.update(Notes) { + it.title to note.meta.title + it.markdown to note.markdown + it.html to note.html + it.updatedAt to now + where { (it.uuid eq uuid) and (it.userId eq userId) and (it.deleted eq false) } + } + + if (count == 0) return null // delete all tags db.delete(Tags) { @@ -123,22 +115,27 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository { it.noteUuid to uuid } } - return currentNote.toPersistedNote(note.meta.tags) + + return PersistedNote( + meta = note.meta, + markdown = note.markdown, + html = note.html, + updatedAt = now, + uuid = uuid + ) } } override fun delete(userId: Int, uuid: UUID, permanent: Boolean): Boolean { - if (!permanent) { - return db.useTransaction { + return if (!permanent) { + db.useTransaction { db.update(Notes) { it.deleted to true it.updatedAt to LocalDateTime.now() where { it.userId eq userId and (it.uuid eq uuid) } } } == 1 - } - - return db.useTransaction { + } else db.useTransaction { db.delete(Notes) { it.uuid eq uuid and (it.userId eq userId) } == 1 } } @@ -147,9 +144,7 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository { return db.useTransaction { db.update(Notes) { it.deleted to false - where { - (it.userId eq userId) and (it.uuid eq uuid) - } + where { (it.userId eq userId) and (it.uuid eq uuid) } } == 1 } } @@ -162,9 +157,8 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository { .map { it[Tags.name]!! } override fun count(userId: Int, tag: String?, deleted: Boolean): Int { - if (tag == null) return db.notes.count { (it.userId eq userId) and (Notes.deleted eq deleted) } - - return db.sequenceOf(Tags).count { + return if (tag == null) db.notes.count { (it.userId eq userId) and (Notes.deleted eq deleted) } + else db.sequenceOf(Tags).count { (it.name eq tag) and (it.note.userId eq userId) and (it.note.deleted eq deleted) } } @@ -177,14 +171,7 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository { .sortedByDescending { it.updatedAt } .toList() - if (notes.isEmpty()) return emptyList() - - val uuids = notes.map { note -> note.uuid } - - val tagsByUuid = db.tags - .filterColumns { listOf(it.noteUuid, it.name) } - .filter { it.noteUuid inList uuids } - .groupByTo(HashMap(), { it.note.uuid }, { it.name }) + val tagsByUuid = notes.tagsByUuid() return notes.map { note -> ExportedNote( @@ -204,18 +191,20 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository { .filter { (it.userId eq userId) and (it.deleted eq false) } .toList() - if (notes.isEmpty()) return emptyList() - - val uuids = notes.map { note -> note.uuid } - - val tagsByUuid = db.tags - .filterColumns { listOf(it.noteUuid, it.name) } - .filter { it.noteUuid inList uuids } - .groupByTo(HashMap(), { it.note.uuid }, { it.name }) + val tagsByUuid = notes.tagsByUuid() return notes.map { note -> val tags = tagsByUuid[note.uuid] ?: emptyList() note.toPersistedNote(tags) } } + + private fun List.tagsByUuid(): Map> { + return if (isEmpty()) emptyMap() + else db.tags + .filterColumns { listOf(it.noteUuid, it.name) } + .filter { it.noteUuid inList map { note -> note.uuid } } + .groupByTo(HashMap(), { it.note.uuid }, { it.name }) + } + }