exposed error

This commit is contained in:
Aria Moradi 2021-05-14 17:31:07 +04:30
parent bce8d58845
commit da6a953099
10 changed files with 109 additions and 23 deletions

View File

@ -164,4 +164,26 @@ object Chapter {
pageList.count() pageList.count()
) )
} }
fun modifyChapter(mangaId: Int, chapterIndex: Int, isRead: Boolean?, isBookmarked: Boolean?, markPrevRead: Boolean?, lastPageRead: Int?) {
transaction {
ChapterTable.update({ (ChapterTable.manga eq mangaId) and (ChapterTable.chapterIndex eq chapterIndex) }) { update ->
isRead?.also {
update[ChapterTable.isRead] = it
}
isBookmarked?.also {
update[ChapterTable.isBookmarked] = it
}
lastPageRead?.also {
update[ChapterTable.lastPageRead] = it
}
}
markPrevRead?.let {
ChapterTable.update({ (ChapterTable.manga eq mangaId) and (ChapterTable.chapterIndex less chapterIndex) }) {
it[ChapterTable.isRead] = markPrevRead
}
}
}
}
} }

View File

@ -1,5 +1,12 @@
package ir.armor.tachidesk.model.database.migration package ir.armor.tachidesk.model.database.migration
/*
* Copyright (C) Contributors to the Suwayomi project
*
* 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
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import ir.armor.tachidesk.model.database.migration.lib.Migration import ir.armor.tachidesk.model.database.migration.lib.Migration
import org.jetbrains.exposed.dao.id.IdTable import org.jetbrains.exposed.dao.id.IdTable
@ -7,13 +14,6 @@ import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.SchemaUtils import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.transactions.transaction
/*
* Copyright (C) Contributors to the Suwayomi project
*
* 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
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
class M0001_Initial : Migration() { class M0001_Initial : Migration() {
private object ExtensionTable : IntIdTable() { private object ExtensionTable : IntIdTable() {
val apkName = varchar("apk_name", 1024) val apkName = varchar("apk_name", 1024)
@ -100,6 +100,7 @@ class M0001_Initial : Migration() {
val manga = reference("manga", ir.armor.tachidesk.model.database.table.MangaTable) val manga = reference("manga", ir.armor.tachidesk.model.database.table.MangaTable)
} }
/** initial migration, create all tables */
override fun run() { override fun run() {
transaction { transaction {
SchemaUtils.create( SchemaUtils.create(

View File

@ -0,0 +1,23 @@
package ir.armor.tachidesk.model.database.migration
/*
* Copyright (C) Contributors to the Suwayomi project
*
* 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
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import ir.armor.tachidesk.model.database.migration.lib.Migration
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.vendors.currentDialect
class M0002_ChapterTableIndexRename : Migration() {
/** this migration renamed ChapterTable.NUMBER_IN_LIST to ChapterTable.INDEX */
override fun run() {
with(TransactionManager.current()) {
exec("ALTER TABLE CHAPTER ALTER COLUMN NUMBER_IN_LIST RENAME TO INDEX")
commit()
currentDialect.resetCaches()
}
}
}

View File

@ -20,7 +20,8 @@ object ChapterTable : IntIdTable() {
val isBookmarked = bool("bookmark").default(false) val isBookmarked = bool("bookmark").default(false)
val lastPageRead = integer("last_page_read").default(0) val lastPageRead = integer("last_page_read").default(0)
val chapterIndex = integer("number_in_list") // index is reserved by a function
val chapterIndex = integer("index")
val manga = reference("manga", MangaTable) val manga = reference("manga", MangaTable)
} }

View File

@ -25,7 +25,7 @@ data class ChapterDataClass(
val lastPageRead: Int, val lastPageRead: Int,
/** this chapter's index, starts with 1 */ /** this chapter's index, starts with 1 */
val chapterIndex: Int? = null, val index: Int? = null,
/** total chapter count, used to calculate if there's a next and prev chapter */ /** total chapter count, used to calculate if there's a next and prev chapter */
val chapterCount: Int? = null, val chapterCount: Int? = null,

View File

@ -13,6 +13,7 @@ import ir.armor.tachidesk.impl.CategoryManga.getMangaCategories
import ir.armor.tachidesk.impl.CategoryManga.removeMangaFromCategory import ir.armor.tachidesk.impl.CategoryManga.removeMangaFromCategory
import ir.armor.tachidesk.impl.Chapter.getChapter import ir.armor.tachidesk.impl.Chapter.getChapter
import ir.armor.tachidesk.impl.Chapter.getChapterList import ir.armor.tachidesk.impl.Chapter.getChapterList
import ir.armor.tachidesk.impl.Chapter.modifyChapter
import ir.armor.tachidesk.impl.Extension.getExtensionIcon import ir.armor.tachidesk.impl.Extension.getExtensionIcon
import ir.armor.tachidesk.impl.Extension.installExtension import ir.armor.tachidesk.impl.Extension.installExtension
import ir.armor.tachidesk.impl.Extension.uninstallExtension import ir.armor.tachidesk.impl.Extension.uninstallExtension
@ -142,7 +143,7 @@ object JavalinSetup {
} }
// icon for extension named `apkName` // icon for extension named `apkName`
app.get("/api/v1/extension/icon/:apkName") { ctx -> app.get("/api/v1/extension/icon/:apkName") { ctx -> // TODO: move to pkgName
val apkName = ctx.pathParam("apkName") val apkName = ctx.pathParam("apkName")
ctx.result( ctx.result(
@ -263,6 +264,22 @@ object JavalinSetup {
ctx.json(future { getChapter(chapterIndex, mangaId) }) ctx.json(future { getChapter(chapterIndex, mangaId) })
} }
// used to modify a chapter's parameters
app.patch("/api/v1/manga/:mangaId/chapter/:chapterIndex") { ctx ->
val chapterIndex = ctx.pathParam("chapterIndex").toInt()
val mangaId = ctx.pathParam("mangaId").toInt()
val read = ctx.formParam("read")?.toBoolean()
val bookmarked = ctx.formParam("bookmarked")?.toBoolean()
val markPrevRead = ctx.formParam("markPrevRead")?.toBoolean()
val lastPageRead = ctx.formParam("lastPageRead")?.toInt()
modifyChapter(mangaId, chapterIndex, read, bookmarked, markPrevRead, lastPageRead)
ctx.status(200)
}
// get page at index "index"
app.get("/api/v1/manga/:mangaId/chapter/:chapterIndex/page/:index") { ctx -> app.get("/api/v1/manga/:mangaId/chapter/:chapterIndex/page/:index") { ctx ->
val mangaId = ctx.pathParam("mangaId").toInt() val mangaId = ctx.pathParam("mangaId").toInt()
val chapterIndex = ctx.pathParam("chapterIndex").toInt() val chapterIndex = ctx.pathParam("chapterIndex").toInt()

View File

@ -16,6 +16,7 @@ import Typography from '@material-ui/core/Typography';
import { Link, useHistory } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
import Menu from '@material-ui/core/Menu'; import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem'; import MenuItem from '@material-ui/core/MenuItem';
import client from '../util/client';
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
root: { root: {
@ -65,13 +66,24 @@ export default function ChapterCard(props: IProps) {
setAnchorEl(null); setAnchorEl(null);
}; };
const sendChange = (key: string, value: any) => {
console.log(`${key} -> ${value}`);
handleClose();
const formData = new FormData();
formData.append(key, value);
client.patch(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`, formData);
// .finally(() => triggerUpdate()
// );
};
return ( return (
<> <>
<li> <li>
<Card> <Card>
<CardContent className={classes.root}> <CardContent className={classes.root}>
<Link <Link
to={`/manga/${chapter.mangaId}/chapter/${chapter.chapterIndex}`} to={`/manga/${chapter.mangaId}/chapter/${chapter.index}`}
style={{ style={{
textDecoration: 'none', textDecoration: 'none',
color: theme.palette.text.primary, color: theme.palette.text.primary,
@ -103,9 +115,19 @@ export default function ChapterCard(props: IProps) {
onClose={handleClose} onClose={handleClose}
> >
{/* <MenuItem onClick={handleClose}>Download</MenuItem> */} {/* <MenuItem onClick={handleClose}>Download</MenuItem> */}
<MenuItem onClick={handleClose}>Bookmark</MenuItem> <MenuItem onClick={() => sendChange('bookmarked', !chapter.bookmarked)}>
<MenuItem onClick={handleClose}>Mark as Read</MenuItem> {chapter.bookmarked && 'Remove bookmark'}
<MenuItem onClick={handleClose}>Mark previous as Read</MenuItem> {!chapter.bookmarked && 'Bookmark'}
</MenuItem>
<MenuItem onClick={() => sendChange('read', !chapter.read)}>
Mark as
{' '}
{chapter.read && 'unread'}
{!chapter.read && 'read'}
</MenuItem>
<MenuItem onClick={() => sendChange('markPrevRead', true)}>
Mark previous as Read
</MenuItem>
</Menu> </Menu>
</CardContent> </CardContent>
</Card> </Card>

View File

@ -305,11 +305,11 @@ export default function ReaderNavBar(props: IProps) {
{chapter.pageCount} {chapter.pageCount}
</span> </span>
<div className={classes.navigationChapters}> <div className={classes.navigationChapters}>
{chapter.chapterIndex > 1 {chapter.index > 1
&& ( && (
<Link <Link
style={{ gridArea: 'prev' }} style={{ gridArea: 'prev' }}
to={`/manga/${manga.id}/chapter/${chapter.chapterIndex - 1}`} to={`/manga/${manga.id}/chapter/${chapter.index - 1}`}
> >
<Button <Button
variant="outlined" variant="outlined"
@ -317,15 +317,15 @@ export default function ReaderNavBar(props: IProps) {
> >
Chapter Chapter
{' '} {' '}
{chapter.chapterIndex - 1} {chapter.index - 1}
</Button> </Button>
</Link> </Link>
)} )}
{chapter.chapterIndex < chapter.chapterCount {chapter.index < chapter.chapterCount
&& ( && (
<Link <Link
style={{ gridArea: 'next' }} style={{ gridArea: 'next' }}
to={`/manga/${manga.id}/chapter/${chapter.chapterIndex + 1}`} to={`/manga/${manga.id}/chapter/${chapter.index + 1}`}
> >
<Button <Button
variant="outlined" variant="outlined"
@ -333,7 +333,7 @@ export default function ReaderNavBar(props: IProps) {
> >
Chapter Chapter
{' '} {' '}
{chapter.chapterIndex + 1} {chapter.index + 1}
</Button> </Button>
</Link> </Link>
)} )}

View File

@ -41,7 +41,7 @@ const useStyles = (settings: IReaderSettings) => makeStyles({
}); });
const range = (n:number) => Array.from({ length: n }, (value, key) => key); const range = (n:number) => Array.from({ length: n }, (value, key) => key);
const initialChapter = () => ({ pageCount: -1, chapterIndex: -1, chapterCount: 0 }); const initialChapter = () => ({ pageCount: -1, index: -1, chapterCount: 0 });
export default function Reader() { export default function Reader() {
const [settings, setSettings] = useLocalStorage<IReaderSettings>('readerSettings', defaultReaderSettings); const [settings, setSettings] = useLocalStorage<IReaderSettings>('readerSettings', defaultReaderSettings);

View File

@ -63,14 +63,14 @@ interface IChapter {
read: boolean read: boolean
bookmarked: boolean bookmarked: boolean
lastPageRead: number lastPageRead: number
chapterIndex: number index: number
chapterCount: number chapterCount: number
pageCount: number pageCount: number
} }
interface IPartialChpter { interface IPartialChpter {
pageCount: number pageCount: number
chapterIndex: number index: number
chapterCount: number chapterCount: number
} }