Markdown improvements

This commit is contained in:
Hubert Van De Walle 2020-08-24 18:50:54 +02:00
parent 815770303c
commit f6e33ed3b4
4 changed files with 64 additions and 69 deletions

View File

@ -32,32 +32,32 @@ class Router(
ImmutableFilter().then(static(resourceLoader, "woff2" to ContentType("font/woff2"))), ImmutableFilter().then(static(resourceLoader, "woff2" to ContentType("font/woff2"))),
) )
fun public(request: Request, handler: PublicHandler) = handler(request, request.jwtPayload(contexts)) infix fun PathMethod.public(handler: PublicHandler) = this to { handler(it, it.jwtPayload(contexts)) }
fun protected(request: Request, handler: ProtectedHandler) = handler(request, request.jwtPayload(contexts)!!) infix fun PathMethod.protected(handler: ProtectedHandler) = this to { handler(it, it.jwtPayload(contexts)!!) }
val publicRoutes: RoutingHttpHandler = routes( val publicRoutes: RoutingHttpHandler = routes(
"/" bind GET to { public(it, baseController::index) }, "/" bind GET public baseController::index,
"/register" bind GET to { public(it, userController::register) }, "/register" bind GET public userController::register,
"/register" bind POST to { public(it, userController::register) }, "/register" bind POST public userController::register,
"/login" bind GET to { public(it, userController::login) }, "/login" bind GET public userController::login,
"/login" bind POST to { public(it, userController::login) }, "/login" bind POST public userController::login,
"/logout" bind POST to userController::logout, "/logout" bind POST to userController::logout,
) )
val protectedRoutes = routes( val protectedRoutes = routes(
"/settings" bind GET to { protected(it, settingsController::settings) }, "/settings" bind GET protected settingsController::settings,
"/settings" bind POST to { protected(it, settingsController::settings) }, "/settings" bind POST protected settingsController::settings,
"/export" bind POST to { protected(it, settingsController::export) }, "/export" bind POST protected settingsController::export,
"/notes" bind GET to { protected(it, noteController::list) }, "/notes" bind GET protected noteController::list,
"/notes" bind POST to { protected(it, noteController::search) }, "/notes" bind POST protected noteController::search,
"/notes/new" bind GET to { protected(it, noteController::new) }, "/notes/new" bind GET protected noteController::new,
"/notes/new" bind POST to { protected(it, noteController::new) }, "/notes/new" bind POST protected noteController::new,
"/notes/trash" bind GET to { protected(it, noteController::trash) }, "/notes/trash" bind GET protected noteController::trash,
"/notes/{uuid}" bind GET to { protected(it, noteController::note) }, "/notes/{uuid}" bind GET protected noteController::note,
"/notes/{uuid}" bind POST to { protected(it, noteController::note) }, "/notes/{uuid}" bind POST protected noteController::note,
"/notes/{uuid}/edit" bind GET to { protected(it, noteController::edit) }, "/notes/{uuid}/edit" bind GET protected noteController::edit,
"/notes/{uuid}/edit" bind POST to { protected(it, noteController::edit) }, "/notes/{uuid}/edit" bind POST protected noteController::edit,
"/notes/deleted/{uuid}" bind POST to { protected(it, noteController::deleted) }, "/notes/deleted/{uuid}" bind POST protected noteController::deleted,
) )
val routes = routes( val routes = routes(

View File

@ -86,7 +86,12 @@
} }
pre { 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; --MONO: 1;
} }

View File

@ -66,6 +66,7 @@ internal class MarkdownConverterImpl : MarkdownConverter {
init { init {
val options = MutableDataSet() val options = MutableDataSet()
options.set(Parser.EXTENSIONS, listOf(TaskListExtension.create())) options.set(Parser.EXTENSIONS, listOf(TaskListExtension.create()))
options.set(HtmlRenderer.SOFT_BREAK, "<br>")
parser = Parser.builder(options).build() parser = Parser.builder(options).build()
renderer = HtmlRenderer.builder(options).build() renderer = HtmlRenderer.builder(options).build()
} }

View File

@ -1,9 +1,6 @@
package be.simplenotes.persistance.notes package be.simplenotes.persistance.notes
import be.simplenotes.domain.model.ExportedNote import be.simplenotes.domain.model.*
import be.simplenotes.domain.model.Note
import be.simplenotes.domain.model.PersistedNote
import be.simplenotes.domain.model.PersistedNoteMetadata
import be.simplenotes.domain.usecases.repositories.NoteRepository import be.simplenotes.domain.usecases.repositories.NoteRepository
import me.liuwj.ktorm.database.Database import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.dsl.* import me.liuwj.ktorm.dsl.*
@ -45,14 +42,7 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
.drop(offset) .drop(offset)
.toList() .toList()
if (notes.isEmpty()) return emptyList() val tagsByUuid = notes.tagsByUuid()
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 })
return notes.map { note -> return notes.map { note ->
val tags = tagsByUuid[note.uuid] ?: emptyList() 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? { override fun update(userId: Int, uuid: UUID, note: Note): PersistedNote? {
db.useTransaction { 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 val now = LocalDateTime.now()
currentNote.markdown = note.markdown val count = db.update(Notes) {
currentNote.html = note.html it.title to note.meta.title
currentNote.updatedAt = LocalDateTime.now() it.markdown to note.markdown
currentNote.flushChanges() 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 // delete all tags
db.delete(Tags) { db.delete(Tags) {
@ -123,22 +115,27 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
it.noteUuid to uuid 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 { override fun delete(userId: Int, uuid: UUID, permanent: Boolean): Boolean {
if (!permanent) { return if (!permanent) {
return db.useTransaction { db.useTransaction {
db.update(Notes) { db.update(Notes) {
it.deleted to true it.deleted to true
it.updatedAt to LocalDateTime.now() it.updatedAt to LocalDateTime.now()
where { it.userId eq userId and (it.uuid eq uuid) } where { it.userId eq userId and (it.uuid eq uuid) }
} }
} == 1 } == 1
} } else db.useTransaction {
return db.useTransaction {
db.delete(Notes) { it.uuid eq uuid and (it.userId eq userId) } == 1 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 { return db.useTransaction {
db.update(Notes) { db.update(Notes) {
it.deleted to false it.deleted to false
where { where { (it.userId eq userId) and (it.uuid eq uuid) }
(it.userId eq userId) and (it.uuid eq uuid)
}
} == 1 } == 1
} }
} }
@ -162,9 +157,8 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
.map { it[Tags.name]!! } .map { it[Tags.name]!! }
override fun count(userId: Int, tag: String?, deleted: Boolean): Int { 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 if (tag == null) db.notes.count { (it.userId eq userId) and (Notes.deleted eq deleted) }
else db.sequenceOf(Tags).count {
return db.sequenceOf(Tags).count {
(it.name eq tag) and (it.note.userId eq userId) and (it.note.deleted eq deleted) (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 } .sortedByDescending { it.updatedAt }
.toList() .toList()
if (notes.isEmpty()) return emptyList() val tagsByUuid = notes.tagsByUuid()
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 })
return notes.map { note -> return notes.map { note ->
ExportedNote( ExportedNote(
@ -204,18 +191,20 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
.filter { (it.userId eq userId) and (it.deleted eq false) } .filter { (it.userId eq userId) and (it.deleted eq false) }
.toList() .toList()
if (notes.isEmpty()) return emptyList() val tagsByUuid = notes.tagsByUuid()
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 })
return notes.map { note -> return notes.map { note ->
val tags = tagsByUuid[note.uuid] ?: emptyList() val tags = tagsByUuid[note.uuid] ?: emptyList()
note.toPersistedNote(tags) note.toPersistedNote(tags)
} }
} }
private fun List<NoteEntity>.tagsByUuid(): Map<UUID, List<String>> {
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 })
}
} }