Manga repository authorization support
This commit is contained in:
@@ -23,7 +23,9 @@
|
|||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
tools:ignore="UnusedAttribute">
|
tools:ignore="UnusedAttribute">
|
||||||
<activity android:name="org.koitharu.kotatsu.main.ui.MainActivity">
|
<activity
|
||||||
|
android:name="org.koitharu.kotatsu.main.ui.MainActivity"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
@@ -32,12 +34,16 @@
|
|||||||
android:name="android.app.default_searchable"
|
android:name="android.app.default_searchable"
|
||||||
android:value=".ui.search.SearchActivity" />
|
android:value=".ui.search.SearchActivity" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="org.koitharu.kotatsu.details.ui.DetailsActivity">
|
<activity
|
||||||
|
android:name="org.koitharu.kotatsu.details.ui.DetailsActivity"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="${applicationId}.action.VIEW_MANGA" />
|
<action android:name="${applicationId}.action.VIEW_MANGA" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="org.koitharu.kotatsu.reader.ui.ReaderActivity">
|
<activity
|
||||||
|
android:name="org.koitharu.kotatsu.reader.ui.ReaderActivity"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="${applicationId}.action.READ_MANGA" />
|
<action android:name="${applicationId}.action.READ_MANGA" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@@ -50,13 +56,19 @@
|
|||||||
android:label="@string/settings" />
|
android:label="@string/settings" />
|
||||||
<activity
|
<activity
|
||||||
android:name="org.koitharu.kotatsu.reader.ui.SimpleSettingsActivity"
|
android:name="org.koitharu.kotatsu.reader.ui.SimpleSettingsActivity"
|
||||||
|
android:exported="true"
|
||||||
android:label="@string/settings">
|
android:label="@string/settings">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
|
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="org.koitharu.kotatsu.browser.BrowserActivity" />
|
<activity
|
||||||
|
android:name="org.koitharu.kotatsu.browser.BrowserActivity"
|
||||||
|
android:windowSoftInputMode="adjustResize" />
|
||||||
|
<activity
|
||||||
|
android:name="org.koitharu.kotatsu.settings.sources.auth.SourceAuthActivity"
|
||||||
|
android:windowSoftInputMode="adjustResize" />
|
||||||
<activity
|
<activity
|
||||||
android:name="org.koitharu.kotatsu.core.ui.CrashActivity"
|
android:name="org.koitharu.kotatsu.core.ui.CrashActivity"
|
||||||
android:label="@string/error_occurred"
|
android:label="@string/error_occurred"
|
||||||
|
|||||||
@@ -67,6 +67,23 @@ open class MangaLoaderContext(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getCookies(domain: String): List<Cookie> {
|
||||||
|
val url = HttpUrl.Builder()
|
||||||
|
.scheme(SCHEME_HTTP)
|
||||||
|
.host(domain)
|
||||||
|
.build()
|
||||||
|
return cookieJar.loadForRequest(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun copyCookies(oldDomain: String, newDomain: String) {
|
||||||
|
val url = HttpUrl.Builder()
|
||||||
|
.scheme(SCHEME_HTTP)
|
||||||
|
.host(oldDomain)
|
||||||
|
val cookies = cookieJar.loadForRequest(url.build())
|
||||||
|
url.host(newDomain)
|
||||||
|
cookieJar.saveFromResponse(url.build(), cookies)
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
|
||||||
private const val SCHEME_HTTP = "http"
|
private const val SCHEME_HTTP = "http"
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ abstract class BaseFragment<B : ViewBinding> : Fragment(), OnApplyWindowInsetsLi
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
lastInsets = Insets.NONE
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package org.koitharu.kotatsu.browser
|
package org.koitharu.kotatsu.browser
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.webkit.WebResourceResponse
|
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.inject
|
import org.koin.core.component.inject
|
||||||
import org.koitharu.kotatsu.core.network.WebViewClientCompat
|
import org.koitharu.kotatsu.core.network.WebViewClientCompat
|
||||||
@@ -27,19 +25,4 @@ class BrowserClient(private val callback: BrowserCallback) : WebViewClientCompat
|
|||||||
super.onPageCommitVisible(view, url)
|
super.onPageCommitVisible(view, url)
|
||||||
callback.onTitleChanged(view.title.orEmpty(), url)
|
callback.onTitleChanged(view.title.orEmpty(), url)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldInterceptRequestCompat(view: WebView, url: String): WebResourceResponse? {
|
|
||||||
return runCatching {
|
|
||||||
val request = Request.Builder()
|
|
||||||
.url(url)
|
|
||||||
.build()
|
|
||||||
val response = okHttp.newCall(request).execute()
|
|
||||||
val ct = response.body?.contentType()
|
|
||||||
WebResourceResponse(
|
|
||||||
"${ct?.type}/${ct?.subtype}",
|
|
||||||
ct?.charset()?.name() ?: "utf-8",
|
|
||||||
response.body?.byteStream()
|
|
||||||
)
|
|
||||||
}.getOrNull()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,6 @@ import kotlinx.parcelize.Parcelize
|
|||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class MangaFilter(
|
data class MangaFilter(
|
||||||
val sortOrder: SortOrder,
|
val sortOrder: SortOrder?,
|
||||||
val tag: MangaTag?
|
val tag: MangaTag?,
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.koitharu.kotatsu.core.parser
|
||||||
|
|
||||||
|
interface MangaRepositoryAuthProvider {
|
||||||
|
|
||||||
|
val authUrl: String
|
||||||
|
|
||||||
|
fun isAuthorized(): Boolean
|
||||||
|
}
|
||||||
@@ -27,5 +27,6 @@ interface SourceSettings {
|
|||||||
|
|
||||||
const val KEY_DOMAIN = "domain"
|
const val KEY_DOMAIN = "domain"
|
||||||
const val KEY_USE_SSL = "ssl"
|
const val KEY_USE_SSL = "ssl"
|
||||||
|
const val KEY_AUTH = "auth"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,6 @@ import org.koitharu.kotatsu.core.model.MangaFilter
|
|||||||
import org.koitharu.kotatsu.core.model.MangaTag
|
import org.koitharu.kotatsu.core.model.MangaTag
|
||||||
import org.koitharu.kotatsu.core.model.SortOrder
|
import org.koitharu.kotatsu.core.model.SortOrder
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
class FilterAdapter(
|
class FilterAdapter(
|
||||||
sortOrders: List<SortOrder> = emptyList(),
|
sortOrders: List<SortOrder> = emptyList(),
|
||||||
@@ -19,7 +18,7 @@ class FilterAdapter(
|
|||||||
private val sortOrders = ArrayList<SortOrder>(sortOrders)
|
private val sortOrders = ArrayList<SortOrder>(sortOrders)
|
||||||
private val tags = ArrayList(Collections.singletonList(null) + tags)
|
private val tags = ArrayList(Collections.singletonList(null) + tags)
|
||||||
|
|
||||||
private var currentState = state ?: MangaFilter(sortOrders.first(), null)
|
private var currentState = state ?: MangaFilter(sortOrders.firstOrNull(), null)
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
|
||||||
VIEW_TYPE_SORT -> FilterSortHolder(parent).apply {
|
VIEW_TYPE_SORT -> FilterSortHolder(parent).apply {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class LocalListViewModel(
|
|||||||
launchLoadingJob(Dispatchers.Default) {
|
launchLoadingJob(Dispatchers.Default) {
|
||||||
try {
|
try {
|
||||||
listError.value = null
|
listError.value = null
|
||||||
mangaList.value = repository.getList(0)
|
mangaList.value = repository.getList(0, tags = null)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
listError.value = e
|
listError.value = e
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,19 @@ package org.koitharu.kotatsu.reader.ui
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Parcelable
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.fragment.app.commit
|
import androidx.fragment.app.commit
|
||||||
import org.koitharu.kotatsu.BuildConfig
|
import org.koitharu.kotatsu.BuildConfig
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
import org.koitharu.kotatsu.databinding.ActivitySettingsSimpleBinding
|
import org.koitharu.kotatsu.databinding.ActivitySettingsSimpleBinding
|
||||||
import org.koitharu.kotatsu.settings.MainSettingsFragment
|
import org.koitharu.kotatsu.settings.MainSettingsFragment
|
||||||
import org.koitharu.kotatsu.settings.NetworkSettingsFragment
|
import org.koitharu.kotatsu.settings.NetworkSettingsFragment
|
||||||
import org.koitharu.kotatsu.settings.ReaderSettingsFragment
|
import org.koitharu.kotatsu.settings.ReaderSettingsFragment
|
||||||
|
import org.koitharu.kotatsu.settings.SourceSettingsFragment
|
||||||
|
|
||||||
class SimpleSettingsActivity : BaseActivity<ActivitySettingsSimpleBinding>() {
|
class SimpleSettingsActivity : BaseActivity<ActivitySettingsSimpleBinding>() {
|
||||||
|
|
||||||
@@ -25,6 +28,9 @@ class SimpleSettingsActivity : BaseActivity<ActivitySettingsSimpleBinding>() {
|
|||||||
R.id.container, when (intent?.action) {
|
R.id.container, when (intent?.action) {
|
||||||
Intent.ACTION_MANAGE_NETWORK_USAGE -> NetworkSettingsFragment()
|
Intent.ACTION_MANAGE_NETWORK_USAGE -> NetworkSettingsFragment()
|
||||||
ACTION_READER -> ReaderSettingsFragment()
|
ACTION_READER -> ReaderSettingsFragment()
|
||||||
|
ACTION_SOURCE -> SourceSettingsFragment.newInstance(
|
||||||
|
intent.getParcelableExtra(EXTRA_SOURCE) ?: MangaSource.LOCAL
|
||||||
|
)
|
||||||
else -> MainSettingsFragment()
|
else -> MainSettingsFragment()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -43,9 +49,17 @@ class SimpleSettingsActivity : BaseActivity<ActivitySettingsSimpleBinding>() {
|
|||||||
|
|
||||||
private const val ACTION_READER =
|
private const val ACTION_READER =
|
||||||
"${BuildConfig.APPLICATION_ID}.action.MANAGE_READER_SETTINGS"
|
"${BuildConfig.APPLICATION_ID}.action.MANAGE_READER_SETTINGS"
|
||||||
|
private const val ACTION_SOURCE =
|
||||||
|
"${BuildConfig.APPLICATION_ID}.action.MANAGE_SOURCE_SETTINGS"
|
||||||
|
private const val EXTRA_SOURCE = "source"
|
||||||
|
|
||||||
fun newReaderSettingsIntent(context: Context) =
|
fun newReaderSettingsIntent(context: Context) =
|
||||||
Intent(context, SimpleSettingsActivity::class.java)
|
Intent(context, SimpleSettingsActivity::class.java)
|
||||||
.setAction(ACTION_READER)
|
.setAction(ACTION_READER)
|
||||||
|
|
||||||
|
fun newSourceSettingsIntent(context: Context, source: MangaSource) =
|
||||||
|
Intent(context, SimpleSettingsActivity::class.java)
|
||||||
|
.setAction(ACTION_SOURCE)
|
||||||
|
.putExtra(EXTRA_SOURCE, source as Parcelable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
package org.koitharu.kotatsu.remotelist.ui
|
package org.koitharu.kotatsu.remotelist.ui
|
||||||
|
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.MenuItem
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.model.MangaFilter
|
import org.koitharu.kotatsu.core.model.MangaFilter
|
||||||
import org.koitharu.kotatsu.core.model.MangaSource
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||||
|
import org.koitharu.kotatsu.reader.ui.SimpleSettingsActivity
|
||||||
import org.koitharu.kotatsu.utils.ext.parcelableArgument
|
import org.koitharu.kotatsu.utils.ext.parcelableArgument
|
||||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||||
|
|
||||||
@@ -29,6 +34,26 @@ class RemoteListFragment : MangaListFragment() {
|
|||||||
super.onFilterChanged(filter)
|
super.onFilterChanged(filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
super.onCreateOptionsMenu(menu, inflater)
|
||||||
|
inflater.inflate(R.menu.opt_list_remote, menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
return when (item.itemId) {
|
||||||
|
R.id.action_source_settings -> {
|
||||||
|
startActivity(
|
||||||
|
SimpleSettingsActivity.newSourceSettingsIntent(
|
||||||
|
context ?: return false,
|
||||||
|
source,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val ARG_SOURCE = "provider"
|
private const val ARG_SOURCE = "provider"
|
||||||
|
|||||||
@@ -90,6 +90,9 @@ class RemoteListViewModel(
|
|||||||
}
|
}
|
||||||
hasNextPage.value = list.isNotEmpty()
|
hasNextPage.value = list.isNotEmpty()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
listError.value = e
|
listError.value = e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
|
|||||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.*
|
import org.koitharu.kotatsu.list.ui.model.*
|
||||||
import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
|
import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class SearchViewModel(
|
class SearchViewModel(
|
||||||
private val repository: MangaRepository,
|
private val repository: MangaRepository,
|
||||||
@@ -74,6 +73,7 @@ class SearchViewModel(
|
|||||||
listError.value = null
|
listError.value = null
|
||||||
val list = repository.getList(
|
val list = repository.getList(
|
||||||
offset = if (append) mangaList.value?.size ?: 0 else 0,
|
offset = if (append) mangaList.value?.size ?: 0 else 0,
|
||||||
|
tags = null,
|
||||||
query = query
|
query = query
|
||||||
)
|
)
|
||||||
if (!append) {
|
if (!append) {
|
||||||
|
|||||||
@@ -76,15 +76,7 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
AppSettings.KEY_COOKIES_CLEAR -> {
|
AppSettings.KEY_COOKIES_CLEAR -> {
|
||||||
viewLifecycleScope.launch {
|
clearCookies()
|
||||||
val cookieJar = get<AndroidCookieJar>()
|
|
||||||
cookieJar.clear()
|
|
||||||
Snackbar.make(
|
|
||||||
listView ?: return@launch,
|
|
||||||
R.string.cookies_cleared,
|
|
||||||
Snackbar.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
AppSettings.KEY_SEARCH_HISTORY_CLEAR -> {
|
AppSettings.KEY_SEARCH_HISTORY_CLEAR -> {
|
||||||
@@ -144,4 +136,22 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
|
|||||||
}
|
}
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun clearCookies() {
|
||||||
|
AlertDialog.Builder(context ?: return)
|
||||||
|
.setTitle(R.string.clear_cookies)
|
||||||
|
.setMessage(R.string.text_clear_cookies_prompt)
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.clear) { _, _ ->
|
||||||
|
viewLifecycleScope.launch {
|
||||||
|
val cookieJar = get<AndroidCookieJar>()
|
||||||
|
cookieJar.clear()
|
||||||
|
Snackbar.make(
|
||||||
|
listView ?: return@launch,
|
||||||
|
R.string.cookies_cleared,
|
||||||
|
Snackbar.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -9,8 +9,10 @@ import androidx.preference.PreferenceFragmentCompat
|
|||||||
import androidx.preference.TwoStatePreference
|
import androidx.preference.TwoStatePreference
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.model.MangaSource
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.core.parser.MangaRepositoryAuthProvider
|
||||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||||
import org.koitharu.kotatsu.core.prefs.SourceSettings
|
import org.koitharu.kotatsu.core.prefs.SourceSettings
|
||||||
|
import org.koitharu.kotatsu.settings.sources.auth.SourceAuthActivity
|
||||||
import org.koitharu.kotatsu.settings.utils.EditTextBindListener
|
import org.koitharu.kotatsu.settings.utils.EditTextBindListener
|
||||||
import org.koitharu.kotatsu.settings.utils.EditTextDefaultSummaryProvider
|
import org.koitharu.kotatsu.settings.utils.EditTextDefaultSummaryProvider
|
||||||
import org.koitharu.kotatsu.utils.ext.mangaRepositoryOf
|
import org.koitharu.kotatsu.utils.ext.mangaRepositoryOf
|
||||||
@@ -20,6 +22,7 @@ import org.koitharu.kotatsu.utils.ext.withArgs
|
|||||||
class SourceSettingsFragment : PreferenceFragmentCompat() {
|
class SourceSettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
private val source by parcelableArgument<MangaSource>(EXTRA_SOURCE)
|
private val source by parcelableArgument<MangaSource>(EXTRA_SOURCE)
|
||||||
|
private var repository: RemoteMangaRepository? = null
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
@@ -29,6 +32,7 @@ class SourceSettingsFragment : PreferenceFragmentCompat() {
|
|||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
preferenceManager.sharedPreferencesName = source.name
|
preferenceManager.sharedPreferencesName = source.name
|
||||||
val repo = mangaRepositoryOf(source) as? RemoteMangaRepository ?: return
|
val repo = mangaRepositoryOf(source) as? RemoteMangaRepository ?: return
|
||||||
|
repository = repo
|
||||||
addPreferencesFromResource(R.xml.pref_source)
|
addPreferencesFromResource(R.xml.pref_source)
|
||||||
val screen = preferenceScreen
|
val screen = preferenceScreen
|
||||||
val prefsMap = ArrayMap<String, Any>(screen.preferenceCount)
|
val prefsMap = ArrayMap<String, Any>(screen.preferenceCount)
|
||||||
@@ -41,13 +45,32 @@ class SourceSettingsFragment : PreferenceFragmentCompat() {
|
|||||||
initPreferenceWithDefaultValue(pref, defValue)
|
initPreferenceWithDefaultValue(pref, defValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
findPreference<Preference>(SourceSettings.KEY_AUTH)?.run {
|
||||||
|
isVisible = repo is MangaRepositoryAuthProvider
|
||||||
|
isEnabled = (repo as? MangaRepositoryAuthProvider)?.isAuthorized() == false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPreferenceTreeClick(preference: Preference?): Boolean {
|
||||||
|
return when (preference?.key) {
|
||||||
|
SourceSettings.KEY_AUTH -> {
|
||||||
|
startActivity(
|
||||||
|
SourceAuthActivity.newIntent(
|
||||||
|
context ?: return false,
|
||||||
|
source,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> super.onPreferenceTreeClick(preference)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initPreferenceWithDefaultValue(preference: Preference, defaultValue: Any) {
|
private fun initPreferenceWithDefaultValue(preference: Preference, defaultValue: Any) {
|
||||||
when(preference) {
|
when (preference) {
|
||||||
is EditTextPreference -> {
|
is EditTextPreference -> {
|
||||||
preference.summaryProvider = EditTextDefaultSummaryProvider(defaultValue.toString())
|
preference.summaryProvider = EditTextDefaultSummaryProvider(defaultValue.toString())
|
||||||
when(preference.key) {
|
when (preference.key) {
|
||||||
SourceSettings.KEY_DOMAIN -> preference.setOnBindEditTextListener(
|
SourceSettings.KEY_DOMAIN -> preference.setOnBindEditTextListener(
|
||||||
EditTextBindListener(
|
EditTextBindListener(
|
||||||
EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_URI,
|
EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_URI,
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.sources.auth
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Parcelable
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.graphics.Insets
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||||
|
import org.koitharu.kotatsu.browser.BrowserCallback
|
||||||
|
import org.koitharu.kotatsu.browser.BrowserClient
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.core.parser.MangaRepositoryAuthProvider
|
||||||
|
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||||
|
import org.koitharu.kotatsu.utils.ext.mangaRepositoryOf
|
||||||
|
|
||||||
|
class SourceAuthActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback {
|
||||||
|
|
||||||
|
private lateinit var repository: MangaRepositoryAuthProvider
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(ActivityBrowserBinding.inflate(layoutInflater))
|
||||||
|
val source = intent?.getParcelableExtra<MangaSource>(EXTRA_SOURCE)
|
||||||
|
if (source == null) {
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
repository = mangaRepositoryOf(source) as? MangaRepositoryAuthProvider ?: run {
|
||||||
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
getString(R.string.auth_not_supported_by, source.title),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
finishAfterTransition()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
supportActionBar?.run {
|
||||||
|
setDisplayHomeAsUpEnabled(true)
|
||||||
|
setHomeAsUpIndicator(R.drawable.ic_cross)
|
||||||
|
}
|
||||||
|
with(binding.webView.settings) {
|
||||||
|
javaScriptEnabled = true
|
||||||
|
}
|
||||||
|
binding.webView.webViewClient = BrowserClient(this)
|
||||||
|
val url = repository.authUrl
|
||||||
|
onTitleChanged(
|
||||||
|
source.title,
|
||||||
|
getString(R.string.loading_)
|
||||||
|
)
|
||||||
|
binding.webView.loadUrl(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
|
||||||
|
android.R.id.home -> {
|
||||||
|
binding.webView.stopLoading()
|
||||||
|
finishAfterTransition()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBackPressed() {
|
||||||
|
if (binding.webView.canGoBack()) {
|
||||||
|
binding.webView.goBack()
|
||||||
|
} else {
|
||||||
|
super.onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
binding.webView.onPause()
|
||||||
|
super.onPause()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
binding.webView.onResume()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLoadingStateChanged(isLoading: Boolean) {
|
||||||
|
binding.progressBar.isVisible = isLoading
|
||||||
|
if (!isLoading && repository.isAuthorized()) {
|
||||||
|
Toast.makeText(this, R.string.auth_complete, Toast.LENGTH_SHORT).show()
|
||||||
|
finishAfterTransition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTitleChanged(title: CharSequence, subtitle: CharSequence?) {
|
||||||
|
this.title = title
|
||||||
|
supportActionBar?.subtitle = subtitle
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onWindowInsetsChanged(insets: Insets) {
|
||||||
|
binding.appbar.updatePadding(top = insets.top)
|
||||||
|
binding.webView.updatePadding(bottom = insets.bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val EXTRA_SOURCE = "source"
|
||||||
|
|
||||||
|
fun newIntent(context: Context, source: MangaSource): Intent {
|
||||||
|
return Intent(context, SourceAuthActivity::class.java)
|
||||||
|
.putExtra(EXTRA_SOURCE, source as Parcelable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
app/src/main/res/menu/opt_list_remote.xml
Normal file
11
app/src/main/res/menu/opt_list_remote.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_source_settings"
|
||||||
|
android:orderInCategory="50"
|
||||||
|
android:title="@string/settings"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
</menu>
|
||||||
@@ -213,24 +213,27 @@
|
|||||||
<string name="other">Другие</string>
|
<string name="other">Другие</string>
|
||||||
<string name="description">Описание</string>
|
<string name="description">Описание</string>
|
||||||
<string name="languages">Языки</string>
|
<string name="languages">Языки</string>
|
||||||
<string name="welcome">Добро пожаловать</string>
|
<string name="welcome">Добро пожаловать</string>
|
||||||
<string name="text_clear_search_history_prompt">Вы действительно хотите удалить все недавние поисковые запросы? Это действие не может быть отменено.</string>
|
<string name="text_clear_search_history_prompt">Вы действительно хотите удалить все недавние поисковые запросы? Это действие не может быть отменено.</string>
|
||||||
<string name="backup_saved">Резервная копия успешно сохранена</string>
|
<string name="backup_saved">Резервная копия успешно сохранена</string>
|
||||||
<string name="tracker_warning">Некоторые производители могут изменять поведение системы, нарушая работу фоновых задач.</string>
|
<string name="tracker_warning">Некоторые производители могут изменять поведение системы, нарушая работу фоновых задач.</string>
|
||||||
<string name="read_more">Подробнее</string>
|
<string name="read_more">Подробнее</string>
|
||||||
<string name="queued">В очереди</string>
|
<string name="queued">В очереди</string>
|
||||||
<string name="text_downloads_holder">На данный момент нет активных загрузок</string>
|
<string name="text_downloads_holder">На данный момент нет активных загрузок</string>
|
||||||
<string name="chapter_is_missing">Глава отсутствует</string>
|
<string name="chapter_is_missing">Глава отсутствует</string>
|
||||||
<string name="chapter_is_missing_text">Эта глава отсутствует на вашем устройстве. Скачайте или прочитайте её онлайн.</string>
|
<string name="chapter_is_missing_text">Эта глава отсутствует на вашем устройстве. Скачайте или прочитайте её онлайн.</string>
|
||||||
<string name="about_app_translation_summary">Помочь с переводом приложения</string>
|
<string name="about_app_translation_summary">Помочь с переводом приложения</string>
|
||||||
<string name="about_app_translation">Перевод</string>
|
<string name="about_app_translation">Перевод</string>
|
||||||
<string name="about_author">Автор</string>
|
<string name="about_author">Автор</string>
|
||||||
<string name="about_feedback_4pda">Тема на 4PDA</string>
|
<string name="about_feedback_4pda">Тема на 4PDA</string>
|
||||||
<string name="about_feedback">Обратная связь</string>
|
<string name="about_feedback">Обратная связь</string>
|
||||||
<string name="about_support_developer">Поддержать разработчика</string>
|
<string name="about_support_developer">Поддержать разработчика</string>
|
||||||
<string name="about_support_developer_summary">Если вам нравится это приложение, вы можете помочь финансово с помощью ЮMoney (бывш. Яндекс.Деньги)</string>
|
<string name="about_support_developer_summary">Если вам нравится это приложение, вы можете помочь финансово с помощью ЮMoney (бывш. Яндекс.Деньги)</string>
|
||||||
<string name="about_gratitudes">Благодарности</string>
|
<string name="about_gratitudes">Благодарности</string>
|
||||||
<string name="about_gratitudes_summary">Эти люди помогают Kotatsu стать лучше!</string>
|
<string name="about_gratitudes_summary">Эти люди помогают Kotatsu стать лучше!</string>
|
||||||
<string name="about_copyright_and_licenses">Авторские права и лицензии</string>
|
<string name="about_copyright_and_licenses">Авторские права и лицензии</string>
|
||||||
<string name="about_license">Лицензия</string>
|
<string name="about_license">Лицензия</string>
|
||||||
|
<string name="auth_complete">Авторизация выполнена</string>
|
||||||
|
<string name="auth_not_supported_by">Авторизация в %s не поддерживается</string>
|
||||||
|
<string name="text_clear_cookies_prompt">Вы выйдете из всех источников, в которых Вы авторизованы</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -216,24 +216,27 @@
|
|||||||
<string name="text_clear_search_history_prompt">Do you really want to remove all recent search queries? This action cannot be undone.</string>
|
<string name="text_clear_search_history_prompt">Do you really want to remove all recent search queries? This action cannot be undone.</string>
|
||||||
<string name="other">Other</string>
|
<string name="other">Other</string>
|
||||||
<string name="languages">Languages</string>
|
<string name="languages">Languages</string>
|
||||||
<string name="welcome">Welcome</string>
|
<string name="welcome">Welcome</string>
|
||||||
<string name="description">Description</string>
|
<string name="description">Description</string>
|
||||||
<string name="backup_saved">Backup saved successfully</string>
|
<string name="backup_saved">Backup saved successfully</string>
|
||||||
<string name="tracker_warning">Some manufacturers can change the system behavior, which may breaks background tasks.</string>
|
<string name="tracker_warning">Some manufacturers can change the system behavior, which may breaks background tasks.</string>
|
||||||
<string name="read_more">Read more</string>
|
<string name="read_more">Read more</string>
|
||||||
<string name="queued">Queued</string>
|
<string name="queued">Queued</string>
|
||||||
<string name="text_downloads_holder">There are currently no active downloads</string>
|
<string name="text_downloads_holder">There are currently no active downloads</string>
|
||||||
<string name="chapter_is_missing_text">This chapter is missing on your device. Download or read it online.</string>
|
<string name="chapter_is_missing_text">This chapter is missing on your device. Download or read it online.</string>
|
||||||
<string name="chapter_is_missing">Chapter is missing</string>
|
<string name="chapter_is_missing">Chapter is missing</string>
|
||||||
<string name="about_app_translation_summary">Translate this app</string>
|
<string name="about_app_translation_summary">Translate this app</string>
|
||||||
<string name="about_app_translation">Translation</string>
|
<string name="about_app_translation">Translation</string>
|
||||||
<string name="about_author">Author</string>
|
<string name="about_author">Author</string>
|
||||||
<string name="about_feedback">Feedback</string>
|
<string name="about_feedback">Feedback</string>
|
||||||
<string name="about_feedback_4pda">Topic on 4PDA</string>
|
<string name="about_feedback_4pda">Topic on 4PDA</string>
|
||||||
<string name="about_support_developer">Support the developer</string>
|
<string name="about_support_developer">Support the developer</string>
|
||||||
<string name="about_support_developer_summary">If you like this app, you can help financially through Yoomoney (ex. Yandex.Money)</string>
|
<string name="about_support_developer_summary">If you like this app, you can help financially through Yoomoney (ex. Yandex.Money)</string>
|
||||||
<string name="about_gratitudes">Gratitudes</string>
|
<string name="about_gratitudes">Gratitudes</string>
|
||||||
<string name="about_gratitudes_summary">These people make Kotatsu become better!</string>
|
<string name="about_gratitudes_summary">These people make Kotatsu become better!</string>
|
||||||
<string name="about_copyright_and_licenses">Copyright & Licenses</string>
|
<string name="about_copyright_and_licenses">Copyright & Licenses</string>
|
||||||
<string name="about_license">License</string>
|
<string name="about_license">License</string>
|
||||||
|
<string name="auth_complete">Authorization complete</string>
|
||||||
|
<string name="auth_not_supported_by">Authorization on %s is not supported</string>
|
||||||
|
<string name="text_clear_cookies_prompt">You will be logged out from all sources that you are authorized in</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -14,4 +14,11 @@
|
|||||||
android:title="@string/use_ssl"
|
android:title="@string/use_ssl"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="auth"
|
||||||
|
android:persistent="false"
|
||||||
|
android:title="@string/sign_in"
|
||||||
|
app:allowDividerAbove="true"
|
||||||
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
Reference in New Issue
Block a user