finished the category screen

This commit is contained in:
Aria Moradi
2021-02-20 01:23:52 +03:30
parent 5a9d216fb7
commit f1cc37d0db
17 changed files with 516 additions and 41 deletions
@@ -29,6 +29,7 @@ import ir.armor.tachidesk.util.removeCategory
import ir.armor.tachidesk.util.removeExtension
import ir.armor.tachidesk.util.removeMangaFromCategory
import ir.armor.tachidesk.util.removeMangaFromLibrary
import ir.armor.tachidesk.util.reorderCategory
import ir.armor.tachidesk.util.sourceFilters
import ir.armor.tachidesk.util.sourceGlobalSearch
import ir.armor.tachidesk.util.sourceSearch
@@ -60,7 +61,7 @@ class Main {
// make sure everything we need exists
applicationSetup()
val tray = systemTray()
val tray = systemTray() // assign it to a variable so it's kept in the memory and not garbage collected
registerConfigModules()
@@ -227,7 +228,7 @@ class Main {
ctx.json(sourceFilters(sourceId))
}
// lists all manga in the library, suitable if no categories are defined
// lists mangas that have no category assigned
app.get("/api/v1/library/") { ctx ->
ctx.json(getLibraryMangas())
}
@@ -240,20 +241,28 @@ class Main {
// category create
app.post("/api/v1/category/") { ctx ->
val name = ctx.formParam("name")!!
val isLanding = ctx.formParam("isLanding", "false").toBoolean()
createCategory(name, isLanding)
createCategory(name)
ctx.status(200)
}
// category modification
app.put("/api/v1/category/:categoryId") { ctx ->
val categoryId = ctx.pathParam("categoryId").toInt()
val name = ctx.formParam("name")!!
val isLanding = ctx.formParam("isLanding").toBoolean()
app.patch("/api/v1/category/:categoryId") { ctx ->
val categoryId = ctx.pathParam("categoryId")!!.toInt()
val name = ctx.formParam("name")
val isLanding = if (ctx.formParam("isLanding") != null) ctx.formParam("isLanding")?.toBoolean() else null
updateCategory(categoryId, name, isLanding)
ctx.status(200)
}
// category re-ordering
app.patch("/api/v1/category/:categoryId/reorder") { ctx ->
val categoryId = ctx.pathParam("categoryId").toInt()
val from = ctx.formParam("from")!!.toInt()
val to = ctx.formParam("to")!!.toInt()
reorderCategory(categoryId, from, to)
ctx.status(200)
}
// category delete
app.delete("/api/v1/category/:categoryId") { ctx ->
val categoryId = ctx.pathParam("categoryId").toInt()
@@ -29,12 +29,14 @@ fun makeDataBaseTables() {
// db.useNestedTransactions = true
transaction {
SchemaUtils.create(ExtensionTable)
SchemaUtils.create(SourceTable)
SchemaUtils.create(MangaTable)
SchemaUtils.create(ChapterTable)
SchemaUtils.create(PageTable)
SchemaUtils.create(CategoryTable)
SchemaUtils.create(CategoryMangaTable)
SchemaUtils.createMissingTablesAndColumns(
ExtensionTable,
SourceTable,
MangaTable,
ChapterTable,
PageTable,
CategoryTable,
CategoryMangaTable,
)
}
}
@@ -5,6 +5,8 @@ package ir.armor.tachidesk.database.dataclass
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
data class CategoryDataClass(
val id: Int,
val order: Int,
val name: String,
val isLanding: Boolean
)
@@ -11,9 +11,12 @@ import org.jetbrains.exposed.sql.ResultRow
object CategoryTable : IntIdTable() {
val name = varchar("name", 64)
val isLanding = bool("is_landing").default(false)
val order = integer("order").default(0)
}
fun CategoryTable.toDataClass(categoryEntry: ResultRow) = CategoryDataClass(
categoryEntry[CategoryTable.id].value,
categoryEntry[CategoryTable.order],
categoryEntry[CategoryTable.name],
categoryEntry[CategoryTable.isLanding],
)
@@ -25,6 +25,7 @@ object MangaTable : IntIdTable() {
val thumbnail_url = varchar("thumbnail_url", 2048).nullable()
val inLibrary = bool("in_library").default(false)
val defaultCategory = bool("default_category").default(true)
// source is used by some ancestor of IntIdTable
val sourceReference = reference("source", SourceTable)
@@ -3,6 +3,7 @@ package ir.armor.tachidesk.util
import ir.armor.tachidesk.database.dataclass.CategoryDataClass
import ir.armor.tachidesk.database.table.CategoryTable
import ir.armor.tachidesk.database.table.toDataClass
import org.jetbrains.exposed.sql.SortOrder
import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
@@ -14,21 +15,34 @@ import org.jetbrains.exposed.sql.update
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
fun createCategory(name: String, isLanding: Boolean) {
fun createCategory(name: String) {
transaction {
val count = CategoryTable.selectAll().count()
if (CategoryTable.select { CategoryTable.name eq name }.firstOrNull() == null)
CategoryTable.insert {
it[CategoryTable.name] = name
it[CategoryTable.isLanding] = isLanding
it[CategoryTable.order] = count.toInt() + 1
}
}
}
fun updateCategory(categoryId: Int, name: String, isLanding: Boolean) {
fun updateCategory(categoryId: Int, name: String?, isLanding: Boolean?) {
transaction {
CategoryTable.update({ CategoryTable.id eq categoryId }) {
it[CategoryTable.name] = name
it[CategoryTable.isLanding] = isLanding
if (name != null) it[CategoryTable.name] = name
if (isLanding != null) it[CategoryTable.isLanding] = isLanding
}
}
}
fun reorderCategory(categoryId: Int, from: Int, to: Int) {
transaction {
val categories = CategoryTable.selectAll().orderBy(CategoryTable.order to SortOrder.ASC).toMutableList()
categories.add(to - 1, categories.removeAt(from - 1))
categories.forEachIndexed { index, cat ->
CategoryTable.update({ CategoryTable.id eq cat[CategoryTable.id].value }) {
it[CategoryTable.order] = index + 1
}
}
}
}
@@ -41,7 +55,7 @@ fun removeCategory(categoryId: Int) {
fun getCategoryList(): List<CategoryDataClass> {
return transaction {
CategoryTable.selectAll().map {
CategoryTable.selectAll().orderBy(CategoryTable.order to SortOrder.ASC).map {
CategoryTable.toDataClass(it)
}
}
@@ -9,6 +9,7 @@ import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -21,6 +22,10 @@ fun addMangaToCategory(mangaId: Int, categoryId: Int) {
it[CategoryMangaTable.category] = categoryId
it[CategoryMangaTable.manga] = mangaId
}
MangaTable.update({ MangaTable.id eq mangaId }) {
it[MangaTable.defaultCategory] = false
}
}
}
}
@@ -28,6 +33,11 @@ fun addMangaToCategory(mangaId: Int, categoryId: Int) {
fun removeMangaFromCategory(mangaId: Int, categoryId: Int) {
transaction {
CategoryMangaTable.deleteWhere { (CategoryMangaTable.category eq categoryId) and (CategoryMangaTable.manga eq mangaId) }
if (CategoryMangaTable.select { CategoryMangaTable.manga eq mangaId }.count() == 0L) {
MangaTable.update({ MangaTable.id eq mangaId }) {
it[MangaTable.defaultCategory] = true
}
}
}
}
@@ -3,6 +3,7 @@ package ir.armor.tachidesk.util
import ir.armor.tachidesk.database.dataclass.MangaDataClass
import ir.armor.tachidesk.database.table.MangaTable
import ir.armor.tachidesk.database.table.toDataClass
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
@@ -35,7 +36,7 @@ fun removeMangaFromLibrary(mangaId: Int) {
fun getLibraryMangas(): List<MangaDataClass> {
return transaction {
MangaTable.select { MangaTable.inLibrary eq true }.map {
MangaTable.select { (MangaTable.inLibrary eq true) and (MangaTable.defaultCategory eq true) }.map {
MangaTable.toDataClass(it)
}
}