This commit is contained in:
Zakhar Timoshenko
2023-05-06 16:15:17 +03:00
parent d5c24cd5c8
commit 41551451b0
9 changed files with 218 additions and 17 deletions

View File

@@ -161,6 +161,10 @@
</intent-filter>
</activity>
<activity
android:name=".scrobbling.kitsu.ui.KitsuAuthActivity"
android:exported="false"
android:label="@string/kitsu" />
<service
android:name="org.koitharu.kotatsu.download.ui.service.DownloadService"

View File

@@ -13,5 +13,5 @@ enum class ScrobblerService(
SHIKIMORI(1, R.string.shikimori, R.drawable.ic_shikimori),
ANILIST(2, R.string.anilist, R.drawable.ic_anilist),
MAL(3, R.string.mal, R.drawable.ic_mal),
KITSU(4, R.string.kitsu, R.drawable.ic_script)
KITSU(4, R.string.kitsu, R.drawable.ic_kitsu)
}

View File

@@ -2,14 +2,19 @@ package org.koitharu.kotatsu.scrobbling.kitsu.data
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.util.await
import org.koitharu.kotatsu.parsers.util.parseJson
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerStorage
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
private const val BASE_WEB_URL = "https://kitsu.io"
@@ -24,22 +29,32 @@ class KitsuRepository(
private val clientId = context.getString(R.string.kitsu_clientId)
private val clientSecret = context.getString(R.string.kitsu_clientSecret)
override val oauthUrl: String
get() = "${BASE_WEB_URL}/api/oauth2/token" +
"?username=..." + // Get from AlertDialog...
"&password=..." + // Get from AlertDialog...
"&grant_type=password" +
"&client_id=$clientId" +
"&client_secret=$clientSecret"
override val oauthUrl: String = ""
override val isAuthorized: Boolean
get() = TODO("Not yet implemented")
get() = storage.accessToken != null
override val cachedUser: ScrobblerUser?
get() = TODO("Not yet implemented")
get() {
return storage.user
}
override suspend fun authorize(code: String?) {
TODO("Not yet implemented")
val body = FormBody.Builder()
if (code != null) {
body.add("grant_type", "password")
body.add("username", "test@test")
body.add("password", "test")
} else {
body.add("grant_type", "refresh_token")
body.add("refresh_token", checkNotNull(storage.refreshToken))
}
val request = Request.Builder()
.post(body.build())
.url("${BASE_WEB_URL}/api/oauth/token")
val response = okHttp.newCall(request.build()).await().parseJson()
storage.accessToken = response.getString("access_token")
storage.refreshToken = response.getString("refresh_token")
}
override suspend fun loadUser(): ScrobblerUser {
@@ -51,7 +66,7 @@ class KitsuRepository(
}
override suspend fun unregister(mangaId: Long) {
TODO("Not yet implemented")
return db.scrobblingDao.delete(ScrobblerService.KITSU.id, mangaId)
}
override suspend fun findManga(query: String, offset: Int): List<ScrobblerManga> {

View File

@@ -0,0 +1,32 @@
package org.koitharu.kotatsu.scrobbling.kitsu.ui
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.core.graphics.Insets
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseActivity
import org.koitharu.kotatsu.databinding.ActivityKitsuAuthBinding
class KitsuAuthActivity : BaseActivity<ActivityKitsuAuthBinding>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(ActivityKitsuAuthBinding.inflate(layoutInflater))
}
override fun onWindowInsetsChanged(insets: Insets) {
val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding)
binding.root.setPadding(
basePadding + insets.left,
basePadding + insets.top,
basePadding + insets.right,
basePadding + insets.bottom,
)
}
companion object {
fun newIntent(context: Context) = Intent(context, KitsuAuthActivity::class.java)
}
}

View File

@@ -18,6 +18,7 @@ import org.koitharu.kotatsu.scrobbling.anilist.data.AniListRepository
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
import org.koitharu.kotatsu.scrobbling.common.ui.config.ScrobblerConfigActivity
import org.koitharu.kotatsu.scrobbling.kitsu.data.KitsuRepository
import org.koitharu.kotatsu.scrobbling.kitsu.ui.KitsuAuthActivity
import org.koitharu.kotatsu.scrobbling.mal.data.MALRepository
import org.koitharu.kotatsu.scrobbling.shikimori.data.ShikimoriRepository
import org.koitharu.kotatsu.sync.domain.SyncController
@@ -146,6 +147,9 @@ class ServicesSettingsFragment : BasePreferenceFragment(R.string.services) {
private fun launchScrobblerAuth(repository: org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository) {
runCatching {
if (repository.oauthUrl.isBlank()) {
startActivity(KitsuAuthActivity.newIntent(requireContext()))
}
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(repository.oauthUrl)
startActivity(intent)

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M1.429,5.441a12.478,12.478 0,0 0,1.916 2.056c0.011,0.011 0.022,0.011 0.022,0.022 0.452,0.387 1.313,0.947 1.937,1.173 0,0 3.886,1.496 4.091,1.582a1.4,1.4 0,0 0,0.237 0.075,0.694 0.694,0 0,0 0.808,-0.549c0.011,-0.065 0.022,-0.172 0.022,-0.248L10.462,5.161c0.011,-0.667 -0.205,-1.679 -0.398,-2.239 0,-0.011 -0.011,-0.022 -0.011,-0.032A11.979,11.979 0,0 0,8.824 0.36L8.781,0.285a0.697,0.697 0,0 0,-0.958 -0.162c-0.054,0.032 -0.086,0.075 -0.129,0.119L7.608,0.36a4.743,4.743 0,0 0,-0.786 3.412,8.212 8.212,0 0,0 -0.775,0.463c-0.043,0.032 -0.42,0.291 -0.71,0.56A4.803,4.803 0,0 0,1.87 4.3c-0.043,0.011 -0.097,0.021 -0.14,0.032 -0.054,0.022 -0.107,0.043 -0.151,0.076a0.702,0.702 0,0 0,-0.193 0.958l0.043,0.075zM8.222,1.07c0.366,0.614 0.678,1.249 0.925,1.917 -0.495,0.086 -0.98,0.215 -1.453,0.388a3.918,3.918 0,0 1,0.528 -2.305zM4.658,5.463a7.467,7.467 0,0 0,-0.893 1.216,11.68 11.68,0 0,1 -1.453,-1.55 3.825,3.825 0,0 1,2.346 0.334zM17.706,5.161a7.673,7.673 0,0 0,-2.347 -0.474,7.583 7.583,0 0,0 -3.811,0.818l-0.215,0.108v3.918c0,0.054 0,0.258 -0.032,0.431a1.535,1.535 0,0 1,-0.646 0.98,1.545 1.545,0 0,1 -1.152,0.247 2.618,2.618 0,0 1,-0.409 -0.118,747.6 747.6,0 0,1 -3.402,-1.313 8.9,8.9 0,0 0,-0.323 -0.129,30.597 30.597,0 0,0 -3.822,3.832l-0.075,0.086a0.698,0.698 0,0 0,0.538 1.098,0.676 0.676,0 0,0 0.42,-0.118c0.011,-0.011 0.022,-0.022 0.043,-0.032 1.313,-0.947 2.756,-1.712 4.284,-2.325a0.7,0.7 0,0 1,0.818 0.13,0.704 0.704,0 0,1 0.054,0.915l-0.237,0.388a20.277,20.277 0,0 0,-1.97 4.306l-0.032,0.129a0.646,0.646 0,0 0,0.108 0.538,0.713 0.713,0 0,0 0.549,0.301 0.657,0.657 0,0 0,0.42 -0.118c0.054,-0.043 0.108,-0.086 0.151,-0.14l0.043,-0.065a18.95,18.95 0,0 1,1.765 -2.153,20.156 20.156,0 0,1 10.797,-6.018c0.032,-0.011 0.065,-0.011 0.097,-0.011 0.237,0.011 0.42,0.215 0.409,0.452a0.424,0.424 0,0 1,-0.344 0.398c-3.908,0.829 -10.948,5.469 -8.483,12.208 0.043,0.108 0.075,0.172 0.129,0.269a0.71,0.71 0,0 0,0.538 0.301,0.742 0.742,0 0,0 0.657,-0.398c0.398,-0.754 1.152,-1.593 3.326,-2.497 6.061,-2.508 7.062,-6.093 7.17,-8.364v-0.129a7.716,7.716 0,0 0,-5.016 -7.451zM11.623,22.923c-0.56,-1.669 -0.506,-3.283 0.151,-4.823 1.26,2.035 3.456,2.207 3.456,2.207 -2.25,0.937 -3.133,1.863 -3.607,2.616z"
android:fillColor="#000000"/>
</vector>

View File

@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/screen_padding">
<TextView
android:id="@+id/textView_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:drawablePadding="16dp"
android:gravity="center_horizontal"
android:text="@string/kitsu"
android:textAppearance="?textAppearanceHeadline5"
app:drawableTint="?colorPrimary"
app:drawableTopCompat="@drawable/ic_kitsu"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="12dp"
android:gravity="center_horizontal"
android:text="@string/email_password_enter_hint"
android:textAppearance="?textAppearanceSubtitle1" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/layout_email"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_below="@id/textView_subtitle"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="30dp"
app:errorIconDrawable="@null"
app:hintEnabled="false">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints="emailAddress"
android:imeOptions="actionDone"
android:inputType="textEmailAddress"
android:singleLine="true"
android:textSize="16sp"
tools:hint="Email" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/layout_password"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_below="@id/layout_email"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="8dp"
app:endIconMode="password_toggle"
app:errorIconDrawable="@null"
app:hintEnabled="false">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints="password"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:maxLength="24"
android:singleLine="true"
android:textSize="16sp"
tools:hint="Password" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/button_cancel"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:text="@android:string/cancel" />
<Button
android:id="@+id/button_done"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:enabled="false"
android:text="@string/done"
tools:ignore="RelativeOverlap" />
</RelativeLayout>
<FrameLayout
android:id="@+id/layout_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<com.google.android.material.progressindicator.CircularProgressIndicator
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true" />
</FrameLayout>
</LinearLayout>

View File

@@ -436,4 +436,5 @@
<string name="sync_auth_hint">You can sign in into an existing account or create a new one</string>
<string name="find_similar">Find similar</string>
<string name="kitsu" translatable="false">Kitsu</string>
<string name="email_password_enter_hint">Enter your email and password to continue</string>
</resources>

View File

@@ -12,21 +12,26 @@
<PreferenceCategory android:title="@string/tracking">
<Preference
android:key="shikimori"
android:title="@string/shikimori"
app:icon="@drawable/ic_shikimori" />
<Preference
android:key="anilist"
android:title="@string/anilist"
app:icon="@drawable/ic_anilist" />
<Preference
android:key="kitsu"
android:title="@string/kitsu"
app:icon="@drawable/ic_kitsu" />
<Preference
android:key="mal"
android:title="@string/mal"
app:icon="@drawable/ic_mal" />
<Preference
android:key="shikimori"
android:title="@string/shikimori"
app:icon="@drawable/ic_shikimori" />
</PreferenceCategory>
</PreferenceScreen>