Skip to content

feat: Remove parsers library, allow to add external sources via JAR files#4

Open
dragonx943 wants to merge 22 commits intoUsagiApp:develfrom
dragonx943:fix/split
Open

feat: Remove parsers library, allow to add external sources via JAR files#4
dragonx943 wants to merge 22 commits intoUsagiApp:develfrom
dragonx943:fix/split

Conversation

@dragonx943
Copy link
Copy Markdown
Member

No description provided.

@dragonx943 dragonx943 marked this pull request as draft March 26, 2026 01:16
Comment on lines +70 to +79
val currentVersion = MangaSourceRegistry.version
if (cacheVersion != currentVersion) {
synchronized(cache) {
if (cacheVersion != currentVersion) {
cache.clear()
cacheVersion = currentVersion
}
}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure about it, may cause poor performance

viewModel.isResumeEnabled.observe(this, this::onResumeEnabledChanged)
viewModel.feedCounter.observe(this, ::onFeedCounterChanged)
viewModel.appUpdate.observe(this, MenuInvalidator(this))
viewModel.onFirstStart.observeEvent(this) { router.showWelcomeSheet() }
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed welcome screen

Comment on lines +123 to +208
private fun updatePluginsList() {
val category = findPreference<androidx.preference.PreferenceCategory>("plugins_category") ?: return
category.removeAll()

val plugins = org.draken.usagi.core.parser.DynamicParserManager.getInstalledPlugins(requireContext())
if (plugins.isEmpty()) {
category.addPreference(Preference(requireContext()).apply {
title = context.getString(R.string.no_plugins)
summary = context.getString(R.string.no_plugins_summary)
isSelectable = false
})
} else {
plugins.forEach { pluginName ->
category.addPreference(Preference(requireContext()).apply {
title = pluginName
summary = context.getString(R.string.tap_to_delete_plugin)
setOnPreferenceClickListener {
androidx.appcompat.app.AlertDialog.Builder(requireContext())
.setTitle(R.string.delete_plugin)
.setMessage(context.getString(R.string.confirm_delete_plugin, pluginName))
.setPositiveButton(R.string.delete) { _, _ ->
lifecycleScope.launch(Dispatchers.IO) {
org.draken.usagi.core.parser.DynamicParserManager.deletePlugin(requireContext(), pluginName)
withContext(Dispatchers.Main) {
updatePluginsList()
Toast.makeText(requireContext(),
context.getString(R.string.deleted_plugin, pluginName),
Toast.LENGTH_SHORT).show()
}
}
}
.setNegativeButton(android.R.string.cancel, null)
.show()
true
}
})
}
}
}

private fun importJar(uri: android.net.Uri) {
val context = requireContext()
lifecycleScope.launch {
try {
val originalName = androidx.documentfile.provider.DocumentFile.fromSingleUri(context, uri)?.name
?: "plugin_${System.currentTimeMillis()}.jar"
val pluginsDir = java.io.File(context.filesDir, "plugins")
if (!pluginsDir.exists()) pluginsDir.mkdirs()

val editText = android.widget.EditText(context).apply {
setText(originalName.removeSuffix(".jar"))
hint = context.getString(R.string.plugin_name)
}
val dialogResult = kotlinx.coroutines.suspendCancellableCoroutine { cont ->
MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Usagi_AlertDialog)
.setTitle(R.string.set_plugin_name)
.setView(editText)
.setPositiveButton(android.R.string.ok) { _, _ ->
cont.resume(editText.text.toString().trim())
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
cont.resume(null) { cause, _, _ -> null?.let { it(cause) } }
}
.setOnCancelListener { cont.resume(null) }
.show()
}
if (dialogResult.isNullOrBlank()) return@launch

val fileName = "$dialogResult.jar"
val outFile = java.io.File(pluginsDir, fileName)

withContext(Dispatchers.IO) {
context.contentResolver.openInputStream(uri)?.use { input ->
java.io.FileOutputStream(outFile).use { output ->
input.copyTo(output)
}
}
}
org.draken.usagi.core.parser.DynamicParserManager.loadParsersFromDirectory(context, pluginsDir)
updatePluginsList()
Toast.makeText(context, R.string.load_success, Toast.LENGTH_LONG).show()
} catch (_: Exception) {
Toast.makeText(context, R.string.load_failed, Toast.LENGTH_LONG).show()
}
}
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure, may cause poor performance

Comment on lines +33 to +36

# For core-exts dependency, optimization is needed if possible
-keep class org.koitharu.kotatsu.parsers.** { *; }
-keep class * extends org.koitharu.kotatsu.parsers.MangaLoaderContext { *; }
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignoring most dependencies, can improve compatibility but increases the initial application size

@dragonx943 dragonx943 marked this pull request as ready for review March 26, 2026 07:16
@dragonx943 dragonx943 added this to Usagi Mar 26, 2026
@dragonx943 dragonx943 moved this to Doing in Usagi Mar 26, 2026
@dragonx943 dragonx943 added the enhancement New feature or request label Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Doing

Development

Successfully merging this pull request may close these issues.

1 participant