finished the category screen
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user