RetroAchievements - Android login callback

Modify the RetroAchievements login code in Android to pass in a callback, pop a message if login fails, close the login box if it succeeds.
This commit is contained in:
LillyJadeKatrin
2025-11-18 20:40:15 -05:00
parent 1e0f6a557e
commit ddced1a070
8 changed files with 87 additions and 12 deletions
@@ -2,12 +2,21 @@
package org.dolphinemu.dolphinemu.features.settings.model
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
object AchievementModel {
@JvmStatic
external fun init()
suspend fun asyncLogin(password: String): Boolean {
return withContext(Dispatchers.IO) {
login(password)
}
}
@JvmStatic
external fun login(password: String)
private external fun login(password: String): Boolean
@JvmStatic
external fun logout()
@@ -7,12 +7,15 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import org.dolphinemu.dolphinemu.databinding.DialogLoginBinding
import org.dolphinemu.dolphinemu.features.settings.model.AchievementModel.login
import org.dolphinemu.dolphinemu.dialogs.AlertMessage
import org.dolphinemu.dolphinemu.features.settings.model.AchievementModel.asyncLogin
import org.dolphinemu.dolphinemu.features.settings.model.NativeConfig
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting
class LoginDialog : DialogFragment() {
class LoginDialog(val parent: SettingsFragmentPresenter) : DialogFragment() {
private var _binding: DialogLoginBinding? = null
private val binding get() = _binding!!
@@ -43,9 +46,18 @@ class LoginDialog : DialogFragment() {
}
private fun onLoginClicked() {
binding.loginFailed.visibility = View.GONE
binding.loginInProgress.visibility = View.VISIBLE
StringSetting.ACHIEVEMENTS_USERNAME.setString(NativeConfig.LAYER_BASE_OR_CURRENT,
binding.usernameInput.text.toString())
login(binding.passwordInput.text.toString())
dismiss()
lifecycleScope.launch {
if (asyncLogin(binding.passwordInput.text.toString())) {
parent.loadSettingsList()
dismiss()
} else {
binding.loginInProgress.visibility = View.GONE
binding.loginFailed.visibility = View.VISIBLE
}
}
}
}
@@ -101,7 +101,7 @@ class SettingsFragmentPresenter(
}
}
private fun loadSettingsList() {
fun loadSettingsList() {
val sl = ArrayList<SettingsItem>()
when (menuTag) {
MenuTag.SETTINGS -> addTopLevelSettings(sl)
@@ -964,7 +964,7 @@ class SettingsFragmentPresenter(
0,
false
) {
fragmentView.showDialogFragment(LoginDialog())
fragmentView.showDialogFragment(LoginDialog(this))
loadSettingsList()
})
} else {
@@ -36,7 +36,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/spacing_large"
app:layout_constraintBottom_toTopOf="@id/button_cancel"
app:layout_constraintBottom_toTopOf="@id/login_in_progress"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/username">
@@ -53,6 +53,38 @@
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/login_in_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="@string/achievements_login_in_progress"
android:textAlignment="center"
android:textColor="?attr/colorOnErrorContainer"
android:visibility="invisible"
android:clickable="false"
android:focusable="false"
app:layout_constraintBottom_toTopOf="@id/login_failed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/password"/>
<TextView
android:id="@+id/login_failed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="@string/achievements_login_failed"
android:textAlignment="center"
android:textColor="?attr/colorOnErrorContainer"
android:visibility="invisible"
android:clickable="false"
android:focusable="false"
app:layout_constraintBottom_toTopOf="@id/button_cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/login_in_progress"/>
<Button
android:id="@+id/button_cancel"
android:layout_width="0dp"
@@ -62,7 +94,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/button_login"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/password" />
app:layout_constraintTop_toBottomOf="@id/login_failed" />
<Button
android:id="@+id/button_login"
@@ -73,6 +105,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/button_cancel"
app:layout_constraintTop_toBottomOf="@id/password" />
app:layout_constraintTop_toBottomOf="@id/login_failed" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -966,4 +966,6 @@ It can efficiently compress both junk data and encrypted Wii data.
<string name="achievements_password">Password</string>
<string name="achievements_login">Log In</string>
<string name="achievements_logout">Log Out</string>
<string name="achievements_login_in_progress">Logging In</string>
<string name="achievements_login_failed">Login Failed</string>
</resources>