From 116de6324ebe2d96070f137085204a4614169093 Mon Sep 17 00:00:00 2001 From: rebel onion <87634197+rebelonion@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:37:31 -0600 Subject: [PATCH] fix: separate update,delete buttons | TOS, privpol --- .../main/java/ani/dantotsu/MainActivity.kt | 9 ++- .../connections/anilist/AnilistViewModel.kt | 2 +- .../parsers/novel/NovelExtensionManager.kt | 2 +- .../settings/AddRepositoryBottomSheet.kt | 33 ++++++-- .../InstalledAnimeExtensionsFragment.kt | 60 +++++++-------- .../InstalledMangaExtensionsFragment.kt | 76 +++++++++---------- .../InstalledNovelExtensionsFragment.kt | 60 +++++++-------- .../settings/SettingsAboutActivity.kt | 47 ++++++++++++ .../dantotsu/settings/SubscriptionSource.kt | 3 +- .../extension/api/ExtensionGithubApi.kt | 4 +- app/src/main/res/layout/item_extension.xml | 14 +++- app/src/main/res/values/strings.xml | 4 + 12 files changed, 197 insertions(+), 117 deletions(-) diff --git a/app/src/main/java/ani/dantotsu/MainActivity.kt b/app/src/main/java/ani/dantotsu/MainActivity.kt index 1020aeb3..2faddd5d 100644 --- a/app/src/main/java/ani/dantotsu/MainActivity.kt +++ b/app/src/main/java/ani/dantotsu/MainActivity.kt @@ -51,6 +51,7 @@ import ani.dantotsu.others.calc.CalcActivity import ani.dantotsu.profile.ProfileActivity import ani.dantotsu.profile.activity.FeedActivity import ani.dantotsu.profile.notification.NotificationActivity +import ani.dantotsu.settings.AddRepositoryBottomSheet import ani.dantotsu.settings.ExtensionsActivity import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager.asLiveBool @@ -457,9 +458,11 @@ class MainActivity : AppCompatActivity() { } val savedRepos: Set = PrefManager.getVal(prefName) val newRepos = savedRepos.toMutableSet() - newRepos.add(url) - PrefManager.setVal(prefName, newRepos) - toast("${if (uri.scheme == "tachiyomi") "Manga" else "Anime"} Extension Repo added") + AddRepositoryBottomSheet.addRepoWarning(this) { + newRepos.add(url) + PrefManager.setVal(prefName, newRepos) + toast("${if (uri.scheme == "tachiyomi") "Manga" else "Anime"} Extension Repo added") + } return } if (intent.type == null) return diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt index f1db7ff6..ee978214 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt @@ -22,7 +22,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext suspend fun getUserId(context: Context, block: () -> Unit) { - if (!Anilist.initialized) { + if (!Anilist.initialized && PrefManager.getVal(PrefName.AnilistToken) != "") { if (Anilist.query.getUserData()) { tryWithSuspend { if (MAL.token != null && !MAL.query.getUserData()) diff --git a/app/src/main/java/ani/dantotsu/parsers/novel/NovelExtensionManager.kt b/app/src/main/java/ani/dantotsu/parsers/novel/NovelExtensionManager.kt index 8ea2f620..aab307b4 100644 --- a/app/src/main/java/ani/dantotsu/parsers/novel/NovelExtensionManager.kt +++ b/app/src/main/java/ani/dantotsu/parsers/novel/NovelExtensionManager.kt @@ -159,7 +159,7 @@ class NovelExtensionManager(private val context: Context) { * * @param pkgName The package name of the application to uninstall. */ - fun uninstallExtension(pkgName: String, context: Context) { + fun uninstallExtension(pkgName: String) { installer.uninstallApk(pkgName) } diff --git a/app/src/main/java/ani/dantotsu/settings/AddRepositoryBottomSheet.kt b/app/src/main/java/ani/dantotsu/settings/AddRepositoryBottomSheet.kt index dc1cf5d1..4581f8cb 100644 --- a/app/src/main/java/ani/dantotsu/settings/AddRepositoryBottomSheet.kt +++ b/app/src/main/java/ani/dantotsu/settings/AddRepositoryBottomSheet.kt @@ -1,5 +1,6 @@ package ani.dantotsu.settings +import android.content.Context import android.os.Bundle import android.view.KeyEvent import android.view.LayoutInflater @@ -12,6 +13,7 @@ import ani.dantotsu.R import ani.dantotsu.databinding.BottomSheetAddRepositoryBinding import ani.dantotsu.databinding.ItemRepoBinding import ani.dantotsu.media.MediaType +import ani.dantotsu.util.customAlertDialog import com.xwray.groupie.GroupieAdapter import com.xwray.groupie.viewbinding.BindableItem @@ -72,8 +74,12 @@ class AddRepositoryBottomSheet : BottomSheetDialogFragment() { val input = binding.repositoryInput.text.toString() val error = isValidUrl(input) if (error == null) { - onRepositoryAdded?.invoke(input, mediaType) - dismiss() + context?.let { context -> + addRepoWarning(context) { + onRepositoryAdded?.invoke(input, mediaType) + dismiss() + } + } } else { binding.repositoryInput.error = error } @@ -86,11 +92,16 @@ class AddRepositoryBottomSheet : BottomSheetDialogFragment() { binding.repositoryInput.setOnEditorActionListener { textView, action, keyEvent -> if (action == EditorInfo.IME_ACTION_DONE || (keyEvent?.action == KeyEvent.ACTION_UP && keyEvent.keyCode == KeyEvent.KEYCODE_ENTER)) { - if (!textView.text.isNullOrBlank()) { - val error = isValidUrl(textView.text.toString()) + val url = textView.text.toString() + if (url.isNotBlank()) { + val error = isValidUrl(url) if (error == null) { - onRepositoryAdded?.invoke(textView.text.toString(), mediaType) - dismiss() + context?.let { context -> + addRepoWarning(context) { + onRepositoryAdded?.invoke(url, mediaType) + dismiss() + } + } return@setOnEditorActionListener true } else { binding.repositoryInput.error = error @@ -121,6 +132,16 @@ class AddRepositoryBottomSheet : BottomSheetDialogFragment() { } companion object { + fun addRepoWarning(context: Context, onRepositoryAdded: () -> Unit) { + context.customAlertDialog() + .setTitle(R.string.warning) + .setMessage(R.string.add_repository_warning) + .setPosButton(R.string.ok) { + onRepositoryAdded.invoke() + } + .setNegButton(R.string.cancel) { } + .show() + } fun newInstance( mediaType: MediaType, repositories: List, diff --git a/app/src/main/java/ani/dantotsu/settings/InstalledAnimeExtensionsFragment.kt b/app/src/main/java/ani/dantotsu/settings/InstalledAnimeExtensionsFragment.kt index 4d3350e3..6ed8d0c6 100644 --- a/app/src/main/java/ani/dantotsu/settings/InstalledAnimeExtensionsFragment.kt +++ b/app/src/main/java/ani/dantotsu/settings/InstalledAnimeExtensionsFragment.kt @@ -1,6 +1,5 @@ package ani.dantotsu.settings -import android.app.AlertDialog import android.app.NotificationManager import android.content.Context import android.os.Bundle @@ -44,13 +43,10 @@ import kotlinx.coroutines.launch import rx.android.schedulers.AndroidSchedulers import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -import java.util.Collections import java.util.Locale class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { - - private var _binding: FragmentExtensionsBinding? = null private val binding get() = _binding!! private lateinit var extensionsRecyclerView: RecyclerView @@ -122,15 +118,20 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { .show() } }, - { pkg, forceDelete -> - if (isAdded) { // Check if the fragment is currently added to its activity - val context = requireContext() // Store context in a variable + { pkg -> + if (isAdded) { + animeExtensionManager.uninstallExtension(pkg.pkgName) + snackString("Extension uninstalled") + } + }, { pkg -> + if (isAdded) { + val context = requireContext() val notificationManager = - context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Initialize NotificationManager once + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - if (pkg.hasUpdate && !forceDelete) { + if (pkg.hasUpdate) { animeExtensionManager.updateExtension(pkg) - .observeOn(AndroidSchedulers.mainThread()) // Observe on main thread + .observeOn(AndroidSchedulers.mainThread()) .subscribe( { installStep -> val builder = NotificationCompat.Builder( @@ -145,7 +146,7 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { }, { error -> Injekt.get().logException(error) - Logger.log(error) // Log the error + Logger.log(error) val builder = NotificationCompat.Builder( context, Notifications.CHANNEL_DOWNLOADER_ERROR @@ -171,14 +172,13 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { } ) } else { - animeExtensionManager.uninstallExtension(pkg.pkgName) - snackString("Extension uninstalled") + snackString("No update available") } + } }, skipIcons ) - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -198,17 +198,10 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { - val newList = extensionsAdapter.currentList.toMutableList() val fromPosition = viewHolder.absoluteAdapterPosition val toPosition = target.absoluteAdapterPosition - if (fromPosition < toPosition) { //probably need to switch to a recyclerview adapter - for (i in fromPosition until toPosition) { - Collections.swap(newList, i, i + 1) - } - } else { - for (i in fromPosition downTo toPosition + 1) { - Collections.swap(newList, i, i - 1) - } + val newList = extensionsAdapter.currentList.toMutableList().apply { + add(toPosition, removeAt(fromPosition)) } extensionsAdapter.submitList(newList) return true @@ -270,7 +263,8 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { private class AnimeExtensionsAdapter( private val onSettingsClicked: (AnimeExtension.Installed) -> Unit, - private val onUninstallClicked: (AnimeExtension.Installed, Boolean) -> Unit, + private val onUninstallClicked: (AnimeExtension.Installed) -> Unit, + private val onUpdateClicked: (AnimeExtension.Installed) -> Unit, val skipIcons: Boolean ) : ListAdapter( DIFF_CALLBACK_INSTALLED @@ -304,20 +298,19 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { holder.extensionIconImageView.setImageDrawable(extension.icon) } if (extension.hasUpdate) { - holder.closeTextView.setImageResource(R.drawable.ic_round_sync_24) + holder.updateView.isVisible = true } else { - holder.closeTextView.setImageResource(R.drawable.ic_round_delete_24) + holder.updateView.isVisible = false } - holder.closeTextView.setOnClickListener { - onUninstallClicked(extension, false) + holder.deleteView.setOnClickListener { + onUninstallClicked(extension) + } + holder.updateView.setOnClickListener { + onUpdateClicked(extension) } holder.settingsImageView.setOnClickListener { onSettingsClicked(extension) } - holder.closeTextView.setOnLongClickListener { - onUninstallClicked(extension, true) - true - } } fun filter(query: String, currentList: List) { @@ -337,7 +330,8 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { view.findViewById(R.id.extensionVersionTextView) val settingsImageView: ImageView = view.findViewById(R.id.settingsImageView) val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView) - val closeTextView: ImageView = view.findViewById(R.id.closeTextView) + val deleteView: ImageView = view.findViewById(R.id.deleteTextView) + val updateView: ImageView = view.findViewById(R.id.updateTextView) } companion object { diff --git a/app/src/main/java/ani/dantotsu/settings/InstalledMangaExtensionsFragment.kt b/app/src/main/java/ani/dantotsu/settings/InstalledMangaExtensionsFragment.kt index c11ec223..37bb198c 100644 --- a/app/src/main/java/ani/dantotsu/settings/InstalledMangaExtensionsFragment.kt +++ b/app/src/main/java/ani/dantotsu/settings/InstalledMangaExtensionsFragment.kt @@ -1,8 +1,6 @@ package ani.dantotsu.settings -import android.annotation.SuppressLint -import android.app.AlertDialog import android.app.NotificationManager import android.content.Context import android.os.Bundle @@ -28,6 +26,7 @@ import ani.dantotsu.R import ani.dantotsu.connections.crashlytics.CrashlyticsInterface import ani.dantotsu.databinding.FragmentExtensionsBinding import ani.dantotsu.others.LanguageMapper +import ani.dantotsu.others.LanguageMapper.Companion.getLanguageName import ani.dantotsu.parsers.MangaSources import ani.dantotsu.settings.extensionprefs.MangaSourcePreferencesFragment import ani.dantotsu.settings.saving.PrefManager @@ -45,7 +44,6 @@ import kotlinx.coroutines.launch import rx.android.schedulers.AndroidSchedulers import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -import java.util.Collections import java.util.Locale class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { @@ -120,15 +118,20 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { .show() } }, - { pkg: MangaExtension.Installed, forceDelete: Boolean -> - if (isAdded) { // Check if the fragment is currently added to its activity - val context = requireContext() // Store context in a variable + { pkg: MangaExtension.Installed -> + if (isAdded) { + mangaExtensionManager.uninstallExtension(pkg.pkgName) + snackString("Extension uninstalled") + } + }, { pkg -> + if (isAdded) { + val context = requireContext() val notificationManager = - context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Initialize NotificationManager once + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - if (pkg.hasUpdate && !forceDelete) { + if (pkg.hasUpdate) { mangaExtensionManager.updateExtension(pkg) - .observeOn(AndroidSchedulers.mainThread()) // Observe on main thread + .observeOn(AndroidSchedulers.mainThread()) .subscribe( { installStep -> val builder = NotificationCompat.Builder( @@ -143,7 +146,7 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { }, { error -> Injekt.get().logException(error) - Logger.log(error) // Log the error + Logger.log(error) val builder = NotificationCompat.Builder( context, Notifications.CHANNEL_DOWNLOADER_ERROR @@ -160,7 +163,7 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { context, Notifications.CHANNEL_DOWNLOADER_PROGRESS ) - .setSmallIcon(R.drawable.ic_check) + .setSmallIcon(R.drawable.ic_circle_check) .setContentTitle("Update complete") .setContentText("The extension has been successfully updated.") .setPriority(NotificationCompat.PRIORITY_LOW) @@ -169,9 +172,9 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { } ) } else { - mangaExtensionManager.uninstallExtension(pkg.pkgName) - snackString("Extension uninstalled") + snackString("No update available") } + } }, skipIcons ) @@ -195,17 +198,10 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { - val newList = extensionsAdapter.currentList.toMutableList() val fromPosition = viewHolder.absoluteAdapterPosition val toPosition = target.absoluteAdapterPosition - if (fromPosition < toPosition) { //probably need to switch to a recyclerview adapter - for (i in fromPosition until toPosition) { - Collections.swap(newList, i, i + 1) - } - } else { - for (i in fromPosition downTo toPosition + 1) { - Collections.swap(newList, i, i - 1) - } + val newList = extensionsAdapter.currentList.toMutableList().apply { + add(toPosition, removeAt(fromPosition)) } extensionsAdapter.submitList(newList) return true @@ -266,7 +262,8 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { private class MangaExtensionsAdapter( private val onSettingsClicked: (MangaExtension.Installed) -> Unit, - private val onUninstallClicked: (MangaExtension.Installed, Boolean) -> Unit, + private val onUninstallClicked: (MangaExtension.Installed) -> Unit, + private val onUpdateClicked: (MangaExtension.Installed) -> Unit, val skipIcons: Boolean ) : ListAdapter( DIFF_CALLBACK_INSTALLED @@ -276,24 +273,23 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { submitList(newExtensions) } + fun updatePref() { + val map = currentList.map { it.name } + PrefManager.setVal(PrefName.MangaSourcesOrder, map) + MangaSources.pinnedMangaSources = map + MangaSources.performReorderMangaSources() + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_extension, parent, false) return ViewHolder(view) } - fun updatePref() { - val map = currentList.map { it.name }.toList() - PrefManager.setVal(PrefName.MangaSourcesOrder, map) - MangaSources.pinnedMangaSources = map - MangaSources.performReorderMangaSources() - } - - @SuppressLint("ClickableViewAccessibility") override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val extension = getItem(position) // Use getItem() from ListAdapter + val extension = getItem(position) val nsfw = if (extension.isNsfw) "(18+)" else "" - val lang = LanguageMapper.getLanguageName(extension.lang) + val lang = getLanguageName(extension.lang) holder.extensionNameTextView.text = extension.name val versionText = "$lang ${extension.versionName} $nsfw" holder.extensionVersionTextView.text = versionText @@ -301,12 +297,15 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { holder.extensionIconImageView.setImageDrawable(extension.icon) } if (extension.hasUpdate) { - holder.closeTextView.setImageResource(R.drawable.ic_round_sync_24) + holder.updateView.isVisible = true } else { - holder.closeTextView.setImageResource(R.drawable.ic_round_delete_24) + holder.updateView.isVisible = false } - holder.closeTextView.setOnClickListener { - onUninstallClicked(extension, false) + holder.deleteView.setOnClickListener { + onUninstallClicked(extension) + } + holder.updateView.setOnClickListener { + onUpdateClicked(extension) } holder.settingsImageView.setOnClickListener { onSettingsClicked(extension) @@ -330,7 +329,8 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { view.findViewById(R.id.extensionVersionTextView) val settingsImageView: ImageView = view.findViewById(R.id.settingsImageView) val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView) - val closeTextView: ImageView = view.findViewById(R.id.closeTextView) + val deleteView: ImageView = view.findViewById(R.id.deleteTextView) + val updateView: ImageView = view.findViewById(R.id.updateTextView) } companion object { diff --git a/app/src/main/java/ani/dantotsu/settings/InstalledNovelExtensionsFragment.kt b/app/src/main/java/ani/dantotsu/settings/InstalledNovelExtensionsFragment.kt index 298924b6..5c282e4e 100644 --- a/app/src/main/java/ani/dantotsu/settings/InstalledNovelExtensionsFragment.kt +++ b/app/src/main/java/ani/dantotsu/settings/InstalledNovelExtensionsFragment.kt @@ -10,6 +10,7 @@ import android.widget.ImageView import android.widget.TextView import android.widget.Toast import androidx.core.app.NotificationCompat +import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DiffUtil @@ -19,7 +20,6 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import ani.dantotsu.R import ani.dantotsu.connections.crashlytics.CrashlyticsInterface -import ani.dantotsu.currContext import ani.dantotsu.databinding.FragmentNovelExtensionsBinding import ani.dantotsu.others.LanguageMapper import ani.dantotsu.parsers.NovelSources @@ -34,7 +34,6 @@ import kotlinx.coroutines.launch import rx.android.schedulers.AndroidSchedulers import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -import java.util.Collections import java.util.Locale class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler { @@ -48,15 +47,21 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler { Toast.makeText(requireContext(), "Source is not configurable", Toast.LENGTH_SHORT) .show() }, - { pkg, forceDelete -> - if (isAdded) { // Check if the fragment is currently added to its activity - val context = requireContext() // Store context in a variable - val notificationManager = - context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Initialize NotificationManager once + { pkg -> + if (isAdded) { + novelExtensionManager.uninstallExtension(pkg.pkgName) + snackString("Extension uninstalled") - if (pkg.hasUpdate && !forceDelete) { + } + }, + { pkg -> + if (isAdded) { + val context = requireContext() + val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + if (pkg.hasUpdate) { novelExtensionManager.updateExtension(pkg) - .observeOn(AndroidSchedulers.mainThread()) // Observe on main thread + .observeOn(AndroidSchedulers.mainThread()) .subscribe( { installStep -> val builder = NotificationCompat.Builder( @@ -71,7 +76,7 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler { }, { error -> Injekt.get().logException(error) - Logger.log(error) // Log the error + Logger.log(error) val builder = NotificationCompat.Builder( context, Notifications.CHANNEL_DOWNLOADER_ERROR @@ -97,8 +102,7 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler { } ) } else { - novelExtensionManager.uninstallExtension(pkg.pkgName, currContext() ?: context) - snackString("Extension uninstalled") + snackString("No update available") } } }, skipIcons @@ -123,17 +127,10 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler { viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { - val newList = extensionsAdapter.currentList.toMutableList() val fromPosition = viewHolder.absoluteAdapterPosition val toPosition = target.absoluteAdapterPosition - if (fromPosition < toPosition) { //probably need to switch to a recyclerview adapter - for (i in fromPosition until toPosition) { - Collections.swap(newList, i, i + 1) - } - } else { - for (i in fromPosition downTo toPosition + 1) { - Collections.swap(newList, i, i - 1) - } + val newList = extensionsAdapter.currentList.toMutableList().apply { + add(toPosition, removeAt(fromPosition)) } extensionsAdapter.submitList(newList) return true @@ -195,7 +192,8 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler { private class NovelExtensionsAdapter( private val onSettingsClicked: (NovelExtension.Installed) -> Unit, - private val onUninstallClicked: (NovelExtension.Installed, Boolean) -> Unit, + private val onUninstallClicked: (NovelExtension.Installed) -> Unit, + private val onUpdateClicked: (NovelExtension.Installed) -> Unit, val skipIcons: Boolean ) : ListAdapter( DIFF_CALLBACK_INSTALLED @@ -230,20 +228,19 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler { holder.extensionIconImageView.setImageDrawable(extension.icon) } if (extension.hasUpdate) { - holder.closeTextView.setImageResource(R.drawable.ic_round_sync_24) + holder.updateView.isVisible = true } else { - holder.closeTextView.setImageResource(R.drawable.ic_round_delete_24) + holder.updateView.isVisible = false } - holder.closeTextView.setOnClickListener { - onUninstallClicked(extension, false) + holder.deleteView.setOnClickListener { + onUninstallClicked(extension) + } + holder.updateView.setOnClickListener { + onUpdateClicked(extension) } holder.settingsImageView.setOnClickListener { onSettingsClicked(extension) } - holder.closeTextView.setOnLongClickListener { - onUninstallClicked(extension, true) - true - } } fun filter(query: String, currentList: List) { @@ -263,7 +260,8 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler { view.findViewById(R.id.extensionVersionTextView) val settingsImageView: ImageView = view.findViewById(R.id.settingsImageView) val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView) - val closeTextView: ImageView = view.findViewById(R.id.closeTextView) + val deleteView: ImageView = view.findViewById(R.id.deleteTextView) + val updateView: ImageView = view.findViewById(R.id.updateTextView) } companion object { diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsAboutActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsAboutActivity.kt index 53ec0dbb..831730cd 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsAboutActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsAboutActivity.kt @@ -10,6 +10,8 @@ import androidx.core.view.updateLayoutParams import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.BuildConfig import ani.dantotsu.R +import ani.dantotsu.buildMarkwon +import ani.dantotsu.client import ani.dantotsu.databinding.ActivitySettingsAboutBinding import ani.dantotsu.initActivity import ani.dantotsu.navBarHeight @@ -20,6 +22,9 @@ import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.statusBarHeight import ani.dantotsu.themes.ThemeManager import ani.dantotsu.util.Logger +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch class SettingsAboutActivity : AppCompatActivity() { private lateinit var binding: ActivitySettingsAboutBinding @@ -130,6 +135,48 @@ class SettingsAboutActivity : AppCompatActivity() { } } ), + Settings( + type = 1, + name = getString(R.string.privacy_policy), + desc = getString(R.string.privacy_policy_desc), + icon = R.drawable.ic_incognito_24, + onClick = { + val text = TextView(context) + val pPLink = "https://raw.githubusercontent.com/rebelonion/Dantotsu/main/privacy_policy.md" + val backup = "https://gcore.jsdelivr.net/gh/rebelonion/dantotsu/privacy_policy.md" + text.text = getString(R.string.loading) + val markWon = try { + buildMarkwon(this@SettingsAboutActivity, false) + } catch (e: IllegalArgumentException) { + return@Settings + } + CoroutineScope(Dispatchers.IO).launch { + val res = try { + val out = client.get(pPLink) + if (out.code != 200) { + client.get(backup) + } else { + out + }.text + } catch (e: Exception) { + getString(R.string.failed_to_load) + } + runOnUiThread { + markWon.setMarkdown(text, res) + } + } + + CustomBottomDialog.newInstance().apply { + setTitleText(context.getString(R.string.privacy_policy)) + addView(text) + setNegativeButton(context.getString(R.string.close)) { + dismiss() + } + show(supportFragmentManager, "dialog") + } + } + ), + ) ) binding.settingsRecyclerView.layoutManager = diff --git a/app/src/main/java/ani/dantotsu/settings/SubscriptionSource.kt b/app/src/main/java/ani/dantotsu/settings/SubscriptionSource.kt index 6740b148..aa9bf5d3 100644 --- a/app/src/main/java/ani/dantotsu/settings/SubscriptionSource.kt +++ b/app/src/main/java/ani/dantotsu/settings/SubscriptionSource.kt @@ -48,7 +48,8 @@ class SubscriptionSource( binding.extensionPinImageView.visibility = View.GONE binding.extensionVersionTextView.visibility = View.GONE - binding.closeTextView.visibility = View.GONE + binding.deleteTextView.visibility = View.GONE + binding.updateTextView.visibility = View.GONE binding.settingsImageView.visibility = View.GONE } diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt index 8e230f4d..d0a7af33 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt @@ -52,7 +52,7 @@ internal class ExtensionGithubApi { sources = it.sources?.toAnimeExtensionSources().orEmpty(), apkName = it.apk, repository = repository, - iconUrl = "${repository}/icon/${it.pkg}.png", + iconUrl = "${repository.removeSuffix("/index.min.json")}/icon/${it.pkg}.png", ) } } @@ -135,7 +135,7 @@ internal class ExtensionGithubApi { sources = it.sources?.toMangaExtensionSources().orEmpty(), apkName = it.apk, repository = repository, - iconUrl = "${repository}/icon/${it.pkg}.png", + iconUrl = "${repository.removeSuffix("/index.min.json")}/icon/${it.pkg}.png", ) } } diff --git a/app/src/main/res/layout/item_extension.xml b/app/src/main/res/layout/item_extension.xml index 46429f9e..a4e1d5d0 100644 --- a/app/src/main/res/layout/item_extension.xml +++ b/app/src/main/res/layout/item_extension.xml @@ -73,11 +73,23 @@ tools:ignore="ContentDescription"/> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e644ccae..504436d0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1091,5 +1091,9 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc Add Repository A repository link should look like this: https://raw.githubusercontent.com/username/repo/branch/index.min.json Current Repositories + Warning: Extensions from the repository can run arbitrary code on your device. Only use repositories you trust. \n\nBy adding a repository, you agree to: \n\n1. Not use the app for viewing or distributing copyrighted content. \n2. Not use the app for any illegal activities. \n3. Not use the app for any activities that violate the terms of service of the content providers. \n\nThe app or it\'s maintainer are not affiliated in any way with extension providers. The developers are not responsible for any damages caused by the app. \n\nBy adding a repository, you agree to these terms. + Privacy Policy + Read our privacy policy + Failed to load