finished Update support: webUI side

This commit is contained in:
Aria Moradi 2021-03-29 02:47:51 +04:30
parent 077bbc3c38
commit bc3ad75328
8 changed files with 72 additions and 27 deletions

View File

@ -168,17 +168,20 @@ private fun downloadAPKFile(url: String, apkPath: String) {
sink.close() sink.close()
} }
fun removeExtension(pkgName: String) { fun uninstallExtension(pkgName: String) {
logger.debug("Uninstalling $pkgName") logger.debug("Uninstalling $pkgName")
val extensionRecord = extensionTableAsDataClass().first { it.pkgName == pkgName } val extensionRecord = transaction { ExtensionTable.select { ExtensionTable.pkgName eq pkgName }.firstOrNull()!! }
val fileNameWithoutType = extensionRecord.apkName.substringBefore(".apk") val fileNameWithoutType = extensionRecord[ExtensionTable.apkName].substringBefore(".apk")
val jarPath = "${applicationDirs.extensionsRoot}/$fileNameWithoutType.jar" val jarPath = "${applicationDirs.extensionsRoot}/$fileNameWithoutType.jar"
transaction { transaction {
val extensionId = ExtensionTable.select { ExtensionTable.name eq extensionRecord.name }.first()[ExtensionTable.id] val extensionId = extensionRecord[ExtensionTable.id].value
SourceTable.deleteWhere { SourceTable.extension eq extensionId } SourceTable.deleteWhere { SourceTable.extension eq extensionId }
ExtensionTable.update({ ExtensionTable.name eq extensionRecord.name }) { if (extensionRecord[ExtensionTable.isObsolete])
ExtensionTable.deleteWhere { ExtensionTable.pkgName eq pkgName }
else
ExtensionTable.update({ ExtensionTable.pkgName eq pkgName }) {
it[isInstalled] = false it[isInstalled] = false
} }
} }
@ -190,7 +193,7 @@ fun removeExtension(pkgName: String) {
fun updateExtension(pkgName: String): Int { fun updateExtension(pkgName: String): Int {
val targetExtension = ExtensionListData.updateMap.remove(pkgName)!! val targetExtension = ExtensionListData.updateMap.remove(pkgName)!!
removeExtension(pkgName) uninstallExtension(pkgName)
transaction { transaction {
ExtensionTable.update({ ExtensionTable.pkgName eq pkgName }) { ExtensionTable.update({ ExtensionTable.pkgName eq pkgName }) {
it[name] = targetExtension.name it[name] = targetExtension.name

View File

@ -28,9 +28,11 @@ object ExtensionListData {
var updateMap = ConcurrentHashMap<String, Extension.Available>() var updateMap = ConcurrentHashMap<String, Extension.Available>()
} }
const val ExtensionUpdateDelayTime = 0 // 60 seconds
fun getExtensionList(): List<ExtensionDataClass> { fun getExtensionList(): List<ExtensionDataClass> {
// update if 60 seconds has passed or requested offline and database is empty // update if {ExtensionUpdateDelayTime} seconds has passed or requested offline and database is empty
if (ExtensionListData.lastUpdateCheck + 60 * 1000 < System.currentTimeMillis()) { if (ExtensionListData.lastUpdateCheck + ExtensionUpdateDelayTime < System.currentTimeMillis()) {
logger.debug("Getting extensions list from the internet") logger.debug("Getting extensions list from the internet")
ExtensionListData.lastUpdateCheck = System.currentTimeMillis() ExtensionListData.lastUpdateCheck = System.currentTimeMillis()
runBlocking { runBlocking {

View File

@ -16,7 +16,7 @@ data class ExtensionDataClass(
val isNsfw: Boolean, val isNsfw: Boolean,
val apkName: String, val apkName: String,
val iconUrl: String, val iconUrl: String,
val isInstalled: Boolean, val installed: Boolean,
val hasUpdate: Boolean, val hasUpdate: Boolean,
val isObsolete: Boolean, val obsolete: Boolean,
) )

View File

@ -21,13 +21,13 @@ import ir.armor.tachidesk.impl.getSourceList
import ir.armor.tachidesk.impl.getThumbnail import ir.armor.tachidesk.impl.getThumbnail
import ir.armor.tachidesk.impl.installExtension import ir.armor.tachidesk.impl.installExtension
import ir.armor.tachidesk.impl.removeCategory import ir.armor.tachidesk.impl.removeCategory
import ir.armor.tachidesk.impl.removeExtension
import ir.armor.tachidesk.impl.removeMangaFromCategory import ir.armor.tachidesk.impl.removeMangaFromCategory
import ir.armor.tachidesk.impl.removeMangaFromLibrary import ir.armor.tachidesk.impl.removeMangaFromLibrary
import ir.armor.tachidesk.impl.reorderCategory import ir.armor.tachidesk.impl.reorderCategory
import ir.armor.tachidesk.impl.sourceFilters import ir.armor.tachidesk.impl.sourceFilters
import ir.armor.tachidesk.impl.sourceGlobalSearch import ir.armor.tachidesk.impl.sourceGlobalSearch
import ir.armor.tachidesk.impl.sourceSearch import ir.armor.tachidesk.impl.sourceSearch
import ir.armor.tachidesk.impl.uninstallExtension
import ir.armor.tachidesk.impl.updateCategory import ir.armor.tachidesk.impl.updateCategory
import ir.armor.tachidesk.impl.updateExtension import ir.armor.tachidesk.impl.updateExtension
import ir.armor.tachidesk.server.util.openInBrowser import ir.armor.tachidesk.server.util.openInBrowser
@ -89,7 +89,7 @@ fun javalinSetup() {
app.get("/api/v1/extension/uninstall/:pkgName") { ctx -> app.get("/api/v1/extension/uninstall/:pkgName") { ctx ->
val pkgName = ctx.pathParam("pkgName") val pkgName = ctx.pathParam("pkgName")
removeExtension(pkgName) uninstallExtension(pkgName)
ctx.status(200) ctx.status(200)
} }

View File

@ -49,11 +49,17 @@ interface IProps {
export default function ExtensionCard(props: IProps) { export default function ExtensionCard(props: IProps) {
const { const {
extension: { extension: {
name, lang, versionName, installed, pkgName, iconUrl, name, lang, versionName, installed, hasUpdate, obsolete, pkgName, iconUrl,
}, },
notifyInstall, notifyInstall,
} = props; } = props;
const [installedState, setInstalledState] = useState<string>((installed ? 'uninstall' : 'install')); const [installedState, setInstalledState] = useState<string>(
() => {
if (obsolete) { return 'obsolete'; }
if (hasUpdate) { return 'update'; }
return (installed ? 'uninstall' : 'install');
},
);
const [serverAddress] = useLocalStorage<String>('serverBaseURL', ''); const [serverAddress] = useLocalStorage<String>('serverBaseURL', '');
@ -69,6 +75,15 @@ export default function ExtensionCard(props: IProps) {
}); });
} }
function update() {
setInstalledState('updating');
client.get(`/api/v1/extension/update/${pkgName}`)
.then(() => {
setInstalledState('uninstall');
notifyInstall();
});
}
function uninstall() { function uninstall() {
setInstalledState('uninstalling'); setInstalledState('uninstalling');
client.get(`/api/v1/extension/uninstall/${pkgName}`) client.get(`/api/v1/extension/uninstall/${pkgName}`)
@ -79,10 +94,22 @@ export default function ExtensionCard(props: IProps) {
} }
function handleButtonClick() { function handleButtonClick() {
if (installedState === 'install') { switch (installedState) {
case 'install':
install(); install();
} else { break;
case 'update':
update();
break;
case 'obsolete':
uninstall(); uninstall();
setTimeout(() => window.location.reload(), 3000);
break;
case 'uninstall':
uninstall();
break;
default:
break;
} }
} }
@ -108,7 +135,14 @@ export default function ExtensionCard(props: IProps) {
</div> </div>
</div> </div>
<Button variant="outlined" onClick={() => handleButtonClick()}>{installedState}</Button> <Button
variant="outlined"
style={{ color: installedState === 'obsolete' ? 'red' : 'inherit' }}
onClick={() => handleButtonClick()}
>
{installedState}
</Button>
</CardContent> </CardContent>
</Card> </Card>
); );

View File

@ -17,7 +17,7 @@ const allLangs: string[] = [];
function groupExtensions(extensions: IExtension[]) { function groupExtensions(extensions: IExtension[]) {
allLangs.length = 0; // empty the array allLangs.length = 0; // empty the array
const result = { installed: [] } as any; const result = { installed: [], 'updates pending': [] } as any;
extensions.sort((a, b) => ((a.apkName > b.apkName) ? 1 : -1)); extensions.sort((a, b) => ((a.apkName > b.apkName) ? 1 : -1));
extensions.forEach((extension) => { extensions.forEach((extension) => {
@ -26,7 +26,11 @@ function groupExtensions(extensions: IExtension[]) {
if (extension.lang !== 'all') { allLangs.push(extension.lang); } if (extension.lang !== 'all') { allLangs.push(extension.lang); }
} }
if (extension.installed) { if (extension.installed) {
if (extension.hasUpdate) {
result['updates pending'].push(extension);
} else {
result.installed.push(extension); result.installed.push(extension);
}
} else { } else {
result[extension.lang].push(extension); result[extension.lang].push(extension);
} }
@ -79,11 +83,12 @@ export default function Extensions() {
if (Object.entries(extensions).length === 0) { if (Object.entries(extensions).length === 0) {
return <h3>loading...</h3>; return <h3>loading...</h3>;
} }
const groupsToShow = ['updates pending', 'installed', ...shownLangs];
return ( return (
<> <>
{ {
Object.entries(extensions).map(([lang, list]) => ( Object.entries(extensions).map(([lang, list]) => (
((['installed', ...shownLangs].indexOf(lang) !== -1 && (list as []).length > 0) ((groupsToShow.indexOf(lang) !== -1 && (list as []).length > 0)
&& ( && (
<React.Fragment key={lang}> <React.Fragment key={lang}>
<h1 key={lang} style={{ marginLeft: 25 }}> <h1 key={lang} style={{ marginLeft: 25 }}>

View File

@ -14,9 +14,9 @@ interface IExtension {
isNsfw: boolean isNsfw: boolean
apkName: string apkName: string
iconUrl: string iconUrl: string
isInstalled: boolean installed: boolean
hasUpdate: boolean hasUpdate: boolean
isObsolete: boolean obsolete: boolean
} }
interface ISource { interface ISource {

View File

@ -8,6 +8,7 @@
export const ISOLanguages = [ export const ISOLanguages = [
{ code: 'all', name: 'All', nativeName: 'All' }, { code: 'all', name: 'All', nativeName: 'All' },
{ code: 'installed', name: 'Installed', nativeName: 'Installed' }, { code: 'installed', name: 'Installed', nativeName: 'Installed' },
{ code: 'updates pending', name: 'Updates pending', nativeName: 'Updates pending' },
// full list: https://github.com/meikidd/iso-639-1/blob/master/src/data.js // full list: https://github.com/meikidd/iso-639-1/blob/master/src/data.js
{ code: 'en', name: 'English', nativeName: 'English' }, { code: 'en', name: 'English', nativeName: 'English' },