From a89ff4d15dbec978ebdb12ed1521f998ebd600d2 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 23 Apr 2023 16:25:31 +0300 Subject: [PATCH] Refactoring --- .../kotatsu/base/domain/MangaIntent.kt | 6 ++--- .../koitharu/kotatsu/base/ui/BaseActivity.kt | 19 +++++++------ .../koitharu/kotatsu/base/ui/BaseFragment.kt | 5 ++-- .../kotatsu/base/ui/BasePreferenceFragment.kt | 6 ++--- .../koitharu/kotatsu/base/ui/BaseViewModel.kt | 16 ++++++++--- .../kotatsu/base/ui/CoroutineIntentService.kt | 3 +-- .../base/ui/list/BoundsScrollListener.kt | 4 +-- .../base/ui/util/ActivityRecreationHandle.kt | 3 ++- .../base/ui/util/BaseActivityEntryPoint.kt | 6 ----- .../base/ui/util/WindowInsetsDelegate.kt | 4 ++- .../core/parser/MangaLoaderContextImpl.kt | 9 +++++-- .../koitharu/kotatsu/main/ui/ExitCallback.kt | 3 +-- .../koitharu/kotatsu/main/ui/MainActivity.kt | 5 ++++ .../kotatsu/reader/ui/ReaderActivity.kt | 4 +++ .../scrobbling/mal/data/MALRepository.kt | 16 ++++++----- .../search/ui/multi/MultiSearchActivity.kt | 4 +++ .../kotatsu/utils/InternalResourceHelper.kt | 27 ------------------- .../koitharu/kotatsu/utils/PKCEGenerator.kt | 16 ----------- .../org/koitharu/kotatsu/utils/ViewBadge.kt | 3 +++ .../koitharu/kotatsu/utils/ext/AndroidExt.kt | 3 +-- .../kotatsu/utils/ext/ResourcesExt.kt | 12 +++++++++ 21 files changed, 83 insertions(+), 91 deletions(-) delete mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/InternalResourceHelper.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/PKCEGenerator.kt diff --git a/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaIntent.kt b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaIntent.kt index 162bcb1c7..55c34cb90 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaIntent.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaIntent.kt @@ -11,9 +11,9 @@ import org.koitharu.kotatsu.utils.ext.getParcelableCompat import org.koitharu.kotatsu.utils.ext.getParcelableExtraCompat class MangaIntent private constructor( - val manga: Manga?, - val mangaId: Long, - val uri: Uri?, + @JvmField val manga: Manga?, + @JvmField val mangaId: Long, + @JvmField val uri: Uri?, ) { constructor(intent: Intent?) : this( diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt index f459d3719..246c705e2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt @@ -26,34 +26,33 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.util.ActionModeDelegate import org.koitharu.kotatsu.base.ui.util.BaseActivityEntryPoint import org.koitharu.kotatsu.base.ui.util.WindowInsetsDelegate -import org.koitharu.kotatsu.base.ui.util.inject import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver -import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.utils.ext.getThemeColor -import javax.inject.Inject +@Suppress("LeakingThis") abstract class BaseActivity : AppCompatActivity(), WindowInsetsDelegate.WindowInsetsListener { - @Inject - lateinit var settings: AppSettings + private var isAmoledTheme = false protected lateinit var binding: B private set - @Suppress("LeakingThis") + @JvmField protected val exceptionResolver = ExceptionResolver(this) - @Suppress("LeakingThis") + @JvmField protected val insetsDelegate = WindowInsetsDelegate(this) + @JvmField val actionModeDelegate = ActionModeDelegate() override fun onCreate(savedInstanceState: Bundle?) { - EntryPointAccessors.fromApplication(this, BaseActivityEntryPoint::class.java).inject(this) + val settings = EntryPointAccessors.fromApplication(this, BaseActivityEntryPoint::class.java).settings + isAmoledTheme = settings.isAmoledTheme setTheme(settings.colorScheme.styleResId) - if (settings.isAmoledTheme) { + if (isAmoledTheme) { setTheme(R.style.ThemeOverlay_Kotatsu_Amoled) } super.onCreate(savedInstanceState) @@ -108,7 +107,7 @@ abstract class BaseActivity : protected fun isDarkAmoledTheme(): Boolean { val uiMode = resources.configuration.uiMode val isNight = uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES - return isNight && settings.isAmoledTheme + return isNight && isAmoledTheme } @CallSuper diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt index fbd4b8d3a..697016c9a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt @@ -10,6 +10,7 @@ import org.koitharu.kotatsu.base.ui.util.ActionModeDelegate import org.koitharu.kotatsu.base.ui.util.WindowInsetsDelegate import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver +@Suppress("LeakingThis") abstract class BaseFragment : Fragment(), WindowInsetsDelegate.WindowInsetsListener { @@ -19,10 +20,10 @@ abstract class BaseFragment : protected val binding: B get() = checkNotNull(viewBinding) - @Suppress("LeakingThis") + @JvmField protected val exceptionResolver = ExceptionResolver(this) - @Suppress("LeakingThis") + @JvmField protected val insetsDelegate = WindowInsetsDelegate(this) protected val actionModeDelegate: ActionModeDelegate diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt index e71dcd005..809944e8c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt @@ -9,12 +9,13 @@ import androidx.core.view.updatePadding import androidx.preference.PreferenceFragmentCompat import androidx.recyclerview.widget.RecyclerView import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject import org.koitharu.kotatsu.base.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.base.ui.util.WindowInsetsDelegate import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.settings.SettingsHeadersFragment +import javax.inject.Inject +@Suppress("LeakingThis") @AndroidEntryPoint abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : PreferenceFragmentCompat(), @@ -24,7 +25,7 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : @Inject lateinit var settings: AppSettings - @Suppress("LeakingThis") + @JvmField protected val insetsDelegate = WindowInsetsDelegate(this) override val recyclerView: RecyclerView @@ -55,7 +56,6 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : ) } - @Suppress("UsePropertyAccessSyntax") protected fun setTitle(title: CharSequence) { (parentFragment as? SettingsHeadersFragment)?.setTitle(title) ?: activity?.setTitle(title) diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseViewModel.kt index f17e3aa9f..ac5f78b09 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseViewModel.kt @@ -3,16 +3,24 @@ package org.koitharu.kotatsu.base.ui import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.EmptyCoroutineContext -import kotlinx.coroutines.* +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch import org.koitharu.kotatsu.base.ui.util.CountedBooleanLiveData import org.koitharu.kotatsu.utils.SingleLiveEvent import org.koitharu.kotatsu.utils.ext.printStackTraceDebug +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext abstract class BaseViewModel : ViewModel() { + @JvmField protected val loadingCounter = CountedBooleanLiveData() + + @JvmField protected val errorEvent = SingleLiveEvent() val onError: LiveData @@ -46,4 +54,4 @@ abstract class BaseViewModel : ViewModel() { errorEvent.postCall(throwable) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/CoroutineIntentService.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/CoroutineIntentService.kt index e7b6fc6db..1fd56bd94 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/CoroutineIntentService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/CoroutineIntentService.kt @@ -1,6 +1,5 @@ package org.koitharu.kotatsu.base.ui -import android.app.Service import android.content.Intent import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.CoroutineDispatcher @@ -20,7 +19,7 @@ abstract class CoroutineIntentService : BaseService() { final override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) launchCoroutine(intent, startId) - return Service.START_REDELIVER_INTENT + return START_REDELIVER_INTENT } private fun launchCoroutine(intent: Intent?, startId: Int) = lifecycleScope.launch(errorHandler(startId)) { diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BoundsScrollListener.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BoundsScrollListener.kt index 4a412d081..f5019c152 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BoundsScrollListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BoundsScrollListener.kt @@ -6,8 +6,6 @@ import androidx.recyclerview.widget.RecyclerView abstract class BoundsScrollListener(private val offsetTop: Int, private val offsetBottom: Int) : RecyclerView.OnScrollListener() { - constructor(offset: Int = 0) : this(offset, offset) - override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) val layoutManager = (recyclerView.layoutManager as? LinearLayoutManager) ?: return @@ -28,4 +26,4 @@ abstract class BoundsScrollListener(private val offsetTop: Int, private val offs abstract fun onScrolledToStart(recyclerView: RecyclerView) abstract fun onScrolledToEnd(recyclerView: RecyclerView) -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/ActivityRecreationHandle.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/ActivityRecreationHandle.kt index e50c92479..036515bbe 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/ActivityRecreationHandle.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/ActivityRecreationHandle.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.base.ui.util import android.app.Activity import android.os.Bundle +import androidx.core.app.ActivityCompat import org.koitharu.kotatsu.base.ui.DefaultActivityLifecycleCallbacks import java.util.WeakHashMap import javax.inject.Inject @@ -22,6 +23,6 @@ class ActivityRecreationHandle @Inject constructor() : DefaultActivityLifecycleC fun recreateAll() { val snapshot = activities.keys.toList() - snapshot.forEach { it.recreate() } + snapshot.forEach { ActivityCompat.recreate(it) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/BaseActivityEntryPoint.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/BaseActivityEntryPoint.kt index 232529d52..66b1a588c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/BaseActivityEntryPoint.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/BaseActivityEntryPoint.kt @@ -3,7 +3,6 @@ package org.koitharu.kotatsu.base.ui.util import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.prefs.AppSettings @EntryPoint @@ -11,8 +10,3 @@ import org.koitharu.kotatsu.core.prefs.AppSettings interface BaseActivityEntryPoint { val settings: AppSettings } - -// Hilt cannot inject into parametrized classes -fun BaseActivityEntryPoint.inject(activity: BaseActivity<*>) { - activity.settings = settings -} diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/WindowInsetsDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/WindowInsetsDelegate.kt index c0d9c8c53..ff80acbbb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/WindowInsetsDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/WindowInsetsDelegate.kt @@ -10,8 +10,10 @@ class WindowInsetsDelegate( private val listener: WindowInsetsListener, ) : OnApplyWindowInsetsListener, View.OnLayoutChangeListener { + @JvmField var handleImeInsets: Boolean = false + @JvmField var interceptingWindowInsetsListener: OnApplyWindowInsetsListener? = null private var lastInsets: Insets? = null @@ -63,4 +65,4 @@ class WindowInsetsDelegate( fun onWindowInsetsChanged(insets: Insets) } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt index 4bf8e8b7b..17f97c398 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt @@ -15,6 +15,7 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.config.MangaSourceConfig import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.utils.ext.toList +import java.lang.ref.WeakReference import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -28,10 +29,14 @@ class MangaLoaderContextImpl @Inject constructor( @ApplicationContext private val androidContext: Context, ) : MangaLoaderContext() { + private var webViewCached: WeakReference? = null + @SuppressLint("SetJavaScriptEnabled") override suspend fun evaluateJs(script: String): String? = withContext(Dispatchers.Main) { - val webView = WebView(androidContext) - webView.settings.javaScriptEnabled = true + val webView = webViewCached?.get() ?: WebView(androidContext).also { + it.settings.javaScriptEnabled = true + webViewCached = WeakReference(it) + } suspendCoroutine { cont -> webView.evaluateJavascript(script) { result -> cont.resume(result?.takeUnless { it == "null" }) diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/ExitCallback.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/ExitCallback.kt index 19ccd9e99..ebdf7921b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/ExitCallback.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/ExitCallback.kt @@ -12,13 +12,12 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.observeAsFlow import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner class ExitCallback( - private val activity: BaseActivity<*>, + private val activity: MainActivity, private val snackbarHost: View, ) : OnBackPressedCallback(false) { diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index e26db9433..e60500113 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -41,6 +41,7 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.base.ui.widgets.SlidingBottomNavigationView import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver +import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.databinding.ActivityMainBinding import org.koitharu.kotatsu.details.service.MangaPrefetchService import org.koitharu.kotatsu.details.ui.DetailsActivity @@ -68,6 +69,7 @@ import org.koitharu.kotatsu.utils.ext.resolve import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf import org.koitharu.kotatsu.utils.ext.setNavigationBarTransparentCompat import org.koitharu.kotatsu.utils.ext.tryLaunch +import javax.inject.Inject import com.google.android.material.R as materialR private const val TAG_SEARCH = "search" @@ -82,6 +84,9 @@ class MainActivity : SearchSuggestionListener, MainNavigationDelegate.OnFragmentChangedListener { + @Inject + lateinit var settings: AppSettings + private val viewModel by viewModels() private val searchSuggestionViewModel by viewModels() private val voiceInputLauncher = registerForActivityResult(VoiceInputContract(), VoiceInputCallback()) diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index 203326400..1138ad144 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -35,6 +35,7 @@ import org.koitharu.kotatsu.base.ui.BaseFullscreenActivity import org.koitharu.kotatsu.bookmarks.domain.Bookmark import org.koitharu.kotatsu.core.exceptions.resolve.DialogErrorObserver import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga +import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode import org.koitharu.kotatsu.databinding.ActivityReaderBinding import org.koitharu.kotatsu.parsers.model.Manga @@ -66,6 +67,9 @@ class ReaderActivity : OnApplyWindowInsetsListener, IdlingDetector.Callback { + @Inject + lateinit var settings: AppSettings + private val idlingDetector = IdlingDetector(TimeUnit.SECONDS.toMillis(10), this) private val viewModel: ReaderViewModel by viewModels() diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/mal/data/MALRepository.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/mal/data/MALRepository.kt index 1a5b78080..6c4d7af38 100644 --- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/mal/data/MALRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/mal/data/MALRepository.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.scrobbling.mal.data import android.content.Context +import android.util.Base64 import dagger.hilt.android.qualifiers.ApplicationContext import okhttp3.FormBody import okhttp3.HttpUrl.Companion.toHttpUrl @@ -20,7 +21,7 @@ import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerMangaInfo import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerUser -import org.koitharu.kotatsu.utils.PKCEGenerator +import java.security.SecureRandom private const val REDIRECT_URI = "kotatsu://mal-auth" private const val BASE_WEB_URL = "https://myanimelist.net" @@ -35,7 +36,7 @@ class MALRepository( ) : ScrobblerRepository { private val clientId = context.getString(R.string.mal_clientId) - private var codeVerifier: String = getPKCEChallengeCode() + private val codeVerifier: String by lazy(::generateCodeVerifier) override val oauthUrl: String get() = "$BASE_WEB_URL/v1/oauth2/authorize?" + @@ -177,11 +178,6 @@ class MALRepository( storage.clear() } - private fun getPKCEChallengeCode(): String { - codeVerifier = PKCEGenerator.generateCodeVerifier() - return codeVerifier - } - private fun jsonToManga(json: JSONObject): ScrobblerManga? { for (i in 0 until json.length()) { val node = json.getJSONObject("node") @@ -210,4 +206,10 @@ class MALRepository( avatar = json.getString("picture") ?: AVATAR_STUB, service = ScrobblerService.MAL, ) + + private fun generateCodeVerifier(): String { + val codeVerifier = ByteArray(50) + SecureRandom().nextBytes(codeVerifier) + return Base64.encodeToString(codeVerifier, Base64.NO_WRAP or Base64.NO_PADDING or Base64.URL_SAFE) + } } diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/multi/MultiSearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/multi/MultiSearchActivity.kt index 63413999a..e16fd5591 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/multi/MultiSearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/multi/MultiSearchActivity.kt @@ -17,6 +17,7 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.base.ui.list.ListSelectionController import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.databinding.ActivitySearchMultiBinding import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.download.ui.service.DownloadService @@ -45,6 +46,9 @@ class MultiSearchActivity : @Inject lateinit var coil: ImageLoader + @Inject + lateinit var settings: AppSettings + private val viewModel by viewModels() private lateinit var adapter: MultiSearchAdapter private lateinit var selectionController: ListSelectionController diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/InternalResourceHelper.kt b/app/src/main/java/org/koitharu/kotatsu/utils/InternalResourceHelper.kt deleted file mode 100644 index dc6a86a91..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/utils/InternalResourceHelper.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.koitharu.kotatsu.utils - -import android.content.Context -import android.content.res.Resources - -object InternalResourceHelper { - - fun getBoolean(context: Context, resName: String, defaultValue: Boolean): Boolean { - val id = getResourceId(resName, "bool") - return if (id != 0) { - context.createPackageContext("android", 0).resources.getBoolean(id) - } else { - defaultValue - } - } - - /** - * Get resource id from system resources - * @param resName resource name to get - * @param type resource type of [resName] to get - * @return 0 if not available - */ - private fun getResourceId(resName: String, type: String): Int { - return Resources.getSystem().getIdentifier(resName, type, "android") - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/PKCEGenerator.kt b/app/src/main/java/org/koitharu/kotatsu/utils/PKCEGenerator.kt deleted file mode 100644 index eb056db8e..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/utils/PKCEGenerator.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.koitharu.kotatsu.utils - -import android.util.Base64 -import java.security.SecureRandom - -object PKCEGenerator { - - private const val PKCE_BASE64_ENCODE_SETTINGS = Base64.NO_WRAP or Base64.NO_PADDING or Base64.URL_SAFE - - fun generateCodeVerifier(): String { - val codeVerifier = ByteArray(50) - SecureRandom().nextBytes(codeVerifier) - return Base64.encodeToString(codeVerifier, PKCE_BASE64_ENCODE_SETTINGS) - } - -} diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ViewBadge.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ViewBadge.kt index 32293308b..90f7a94d7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ViewBadge.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ViewBadge.kt @@ -1,11 +1,14 @@ package org.koitharu.kotatsu.utils import android.view.View +import androidx.annotation.OptIn import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import com.google.android.material.badge.BadgeDrawable import com.google.android.material.badge.BadgeUtils +import com.google.android.material.badge.ExperimentalBadgeUtils +@OptIn(ExperimentalBadgeUtils::class) class ViewBadge( private val anchor: View, lifecycleOwner: LifecycleOwner, diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt index df9e30f4a..966338125 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt @@ -40,7 +40,6 @@ import org.json.JSONException import org.jsoup.internal.StringUtil.StringJoiner import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.utils.InternalResourceHelper import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import kotlin.math.roundToLong @@ -108,7 +107,7 @@ fun SyncResult.onError(error: Throwable) { fun Window.setNavigationBarTransparentCompat(context: Context, elevation: Float, alphaFactor: Float = 0.7f) { navigationBarColor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && - !InternalResourceHelper.getBoolean(context, "config_navBarNeedsScrim", true) + !context.getSystemBoolean("config_navBarNeedsScrim", true) ) { Color.TRANSPARENT } else { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ResourcesExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ResourcesExt.kt index 4d9d8186a..187642b5b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ResourcesExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ResourcesExt.kt @@ -1,5 +1,7 @@ package org.koitharu.kotatsu.utils.ext +import android.annotation.SuppressLint +import android.content.Context import android.content.res.Resources import androidx.annotation.Px import kotlin.math.roundToInt @@ -9,3 +11,13 @@ fun Resources.resolveDp(dp: Int) = (dp * displayMetrics.density).roundToInt() @Px fun Resources.resolveDp(dp: Float) = dp * displayMetrics.density + +@SuppressLint("DiscouragedApi") +fun Context.getSystemBoolean(resName: String, fallback: Boolean): Boolean { + val id = Resources.getSystem().getIdentifier(resName, "bool", "android") + return if (id != 0) { + createPackageContext("android", 0).resources.getBoolean(id) + } else { + fallback + } +}