diff --git a/FCL/src/main/java/com/tungsten/fcl/ui/account/AccountListItem.java b/FCL/src/main/java/com/tungsten/fcl/ui/account/AccountListItem.java index 330d6f61..8786aec8 100644 --- a/FCL/src/main/java/com/tungsten/fcl/ui/account/AccountListItem.java +++ b/FCL/src/main/java/com/tungsten/fcl/ui/account/AccountListItem.java @@ -214,21 +214,25 @@ public class AccountListItem { if (account instanceof ClassicAccount) { CountDownLatch latch = new CountDownLatch(1); AtomicReference res = new AtomicReference<>(null); - ClassicAccountLoginDialog dialog = new ClassicAccountLoginDialog(FCLPath.CONTEXT, (ClassicAccount) account, it -> { - res.set(it); - latch.countDown(); - }, latch::countDown); - dialog.show(); + Schedulers.androidUIThread().execute(() -> { + ClassicAccountLoginDialog dialog = new ClassicAccountLoginDialog(FCLPath.CONTEXT, (ClassicAccount) account, it -> { + res.set(it); + latch.countDown(); + }, latch::countDown); + dialog.show(); + }); latch.await(); return Optional.ofNullable(res.get()).orElseThrow(CancellationException::new); } else if (account instanceof OAuthAccount) { CountDownLatch latch = new CountDownLatch(1); AtomicReference res = new AtomicReference<>(null); - OAuthAccountLoginDialog dialog = new OAuthAccountLoginDialog(FCLPath.CONTEXT, (OAuthAccount) account, it -> { - res.set(it); - latch.countDown(); - }, latch::countDown); - dialog.show(); + Schedulers.androidUIThread().execute(() -> { + OAuthAccountLoginDialog dialog = new OAuthAccountLoginDialog(FCLPath.CONTEXT, (OAuthAccount) account, it -> { + res.set(it); + latch.countDown(); + }, latch::countDown); + dialog.show(); + }); latch.await(); return Optional.ofNullable(res.get()).orElseThrow(CancellationException::new); } diff --git a/FCL/src/main/java/com/tungsten/fcl/ui/account/CreateAccountDialog.java b/FCL/src/main/java/com/tungsten/fcl/ui/account/CreateAccountDialog.java index 751cdff3..214e85d5 100644 --- a/FCL/src/main/java/com/tungsten/fcl/ui/account/CreateAccountDialog.java +++ b/FCL/src/main/java/com/tungsten/fcl/ui/account/CreateAccountDialog.java @@ -41,6 +41,7 @@ import com.tungsten.fclcore.task.Task; import com.tungsten.fclcore.task.TaskExecutor; import com.tungsten.fclcore.util.StringUtils; import com.tungsten.fcllibrary.component.FCLAdapter; +import com.tungsten.fcllibrary.component.dialog.FCLAlertDialog; import com.tungsten.fcllibrary.component.dialog.FCLDialog; import com.tungsten.fcllibrary.component.view.FCLButton; import com.tungsten.fcllibrary.component.view.FCLEditText; @@ -182,7 +183,12 @@ public class CreateAccountDialog extends FCLDialog implements View.OnClickListen if (exception instanceof NoSelectedCharacterException) { dismiss(); } else { - Toast.makeText(getContext(), Accounts.localizeErrorMessage(getContext(), exception), Toast.LENGTH_SHORT).show(); + FCLAlertDialog.Builder builder = new FCLAlertDialog.Builder(getContext()); + builder.setAlertLevel(FCLAlertDialog.AlertLevel.ALERT); + builder.setMessage(Accounts.localizeErrorMessage(getContext(), exception)); + builder.setCancelable(false); + builder.setNegativeButton(getContext().getString(com.tungsten.fcllibrary.R.string.dialog_positive), null); + builder.create().show(); } login.setEnabled(true); cancel.setEnabled(true); @@ -263,16 +269,12 @@ public class CreateAccountDialog extends FCLDialog implements View.OnClickListen this.view = LayoutInflater.from(context).inflate(R.layout.dialog_create_account_microsoft, null); Handler handler = new Handler(); - FXUtils.onChangeAndOperate(CreateAccountDialog.getInstance().deviceCode, deviceCode -> { - handler.post(() -> { - if (deviceCode != null) { - AndroidUtils.copyText(context, deviceCode.getUserCode()); - } - }); - }); - holder.add(Accounts.OAUTH_CALLBACK.onGrantDeviceCode.registerWeak(value -> { - CreateAccountDialog.getInstance().deviceCode.set(value); + FXUtils.onChangeAndOperate(CreateAccountDialog.getInstance().deviceCode, deviceCode -> handler.post(() -> { + if (deviceCode != null) { + AndroidUtils.copyText(context, deviceCode.getUserCode()); + } })); + holder.add(Accounts.OAUTH_CALLBACK.onGrantDeviceCode.registerWeak(value -> CreateAccountDialog.getInstance().deviceCode.set(value))); } @Override diff --git a/FCL/src/main/java/com/tungsten/fcl/ui/account/OAuthAccountLoginDialog.java b/FCL/src/main/java/com/tungsten/fcl/ui/account/OAuthAccountLoginDialog.java index 0e1054bd..d3b69565 100644 --- a/FCL/src/main/java/com/tungsten/fcl/ui/account/OAuthAccountLoginDialog.java +++ b/FCL/src/main/java/com/tungsten/fcl/ui/account/OAuthAccountLoginDialog.java @@ -1,20 +1,91 @@ package com.tungsten.fcl.ui.account; +import static com.tungsten.fclcore.util.Logging.LOG; + import android.content.Context; +import android.view.View; import androidx.annotation.NonNull; +import com.tungsten.fcl.R; +import com.tungsten.fcl.game.OAuthServer; +import com.tungsten.fcl.setting.Accounts; +import com.tungsten.fcl.util.AndroidUtils; +import com.tungsten.fcl.util.FXUtils; +import com.tungsten.fcl.util.WeakListenerHolder; import com.tungsten.fclcore.auth.AuthInfo; import com.tungsten.fclcore.auth.OAuthAccount; +import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty; +import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty; +import com.tungsten.fclcore.task.Schedulers; +import com.tungsten.fclcore.task.Task; +import com.tungsten.fcllibrary.component.dialog.FCLAlertDialog; import com.tungsten.fcllibrary.component.dialog.FCLDialog; +import com.tungsten.fcllibrary.component.view.FCLButton; import java.util.function.Consumer; +import java.util.logging.Level; -public class OAuthAccountLoginDialog extends FCLDialog { +public class OAuthAccountLoginDialog extends FCLDialog implements View.OnClickListener { + private FCLButton positive; + private FCLButton negative; + private final OAuthAccount account; + private final Consumer success; + private final Runnable failed; + private final ObjectProperty deviceCode = new SimpleObjectProperty<>(); + + private final WeakListenerHolder holder = new WeakListenerHolder(); public OAuthAccountLoginDialog(@NonNull Context context, OAuthAccount account, Consumer success, Runnable failed) { super(context); + this.account = account; + this.success = success; + this.failed = failed; + + setContentView(R.layout.dialog_relogin_oauth); + + FXUtils.onChangeAndOperate(deviceCode, deviceCode -> Schedulers.androidUIThread().execute(() -> { + if (deviceCode != null) { + AndroidUtils.copyText(getContext(), deviceCode.getUserCode()); + } + })); + holder.add(Accounts.OAUTH_CALLBACK.onGrantDeviceCode.registerWeak(deviceCode::set)); + + positive = findViewById(R.id.login); + negative = findViewById(R.id.cancel); + + positive.setOnClickListener(this); + negative.setOnClickListener(this); + } + + @Override + public void onClick(View view) { + if (view == positive) { + positive.setEnabled(false); + negative.setEnabled(false); + Task.supplyAsync(account::logInWhenCredentialsExpired) + .whenComplete(Schedulers.androidUIThread(), (authInfo, exception) -> { + if (exception == null) { + success.accept(authInfo); + dismiss(); + } else { + LOG.log(Level.INFO, "Failed to login when credentials expired: " + account, exception); + FCLAlertDialog.Builder builder = new FCLAlertDialog.Builder(getContext()); + builder.setAlertLevel(FCLAlertDialog.AlertLevel.ALERT); + builder.setMessage(Accounts.localizeErrorMessage(getContext(), exception)); + builder.setCancelable(false); + builder.setNegativeButton(getContext().getString(com.tungsten.fcllibrary.R.string.dialog_positive), null); + builder.create().show(); + } + positive.setEnabled(true); + negative.setEnabled(true); + }).start(); + } + if (view == negative) { + failed.run(); + dismiss(); + } } } diff --git a/FCL/src/main/res/layout/dialog_relogin_classic.xml b/FCL/src/main/res/layout/dialog_relogin_classic.xml new file mode 100644 index 00000000..77d9ef65 --- /dev/null +++ b/FCL/src/main/res/layout/dialog_relogin_classic.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/FCL/src/main/res/layout/dialog_relogin_oauth.xml b/FCL/src/main/res/layout/dialog_relogin_oauth.xml new file mode 100644 index 00000000..82c4d003 --- /dev/null +++ b/FCL/src/main/res/layout/dialog_relogin_oauth.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FCL/src/main/res/values-zh/strings.xml b/FCL/src/main/res/values-zh/strings.xml index 5153dc4b..d13d0ec2 100644 --- a/FCL/src/main/res/values-zh/strings.xml +++ b/FCL/src/main/res/values-zh/strings.xml @@ -52,7 +52,7 @@ Microsoft 账户登录完成 请点击“登录”按钮,稍后将自动复制一段代码,在打开的浏览器页面中输入复制的代码并完成登录过程。 重新登录 - 由于账号授权无效,需要重新登录您的微软账号\n请点击“确认”按钮,稍后将自动复制一段代码,在打开的浏览器页面中输入复制的代码并完成登录过程。 + 由于账号授权无效,需要重新登录您的微软账号\n请点击“确认”按钮,稍后将自动复制一段代码,在打开的浏览器页面中输入复制的代码并完成登录过程。 选择角色 选择皮肤文件 没有账户 diff --git a/FCL/src/main/res/values/strings.xml b/FCL/src/main/res/values/strings.xml index a80425a7..50eb3264 100644 --- a/FCL/src/main/res/values/strings.xml +++ b/FCL/src/main/res/values/strings.xml @@ -60,7 +60,7 @@ Microsoft account authorization is now completed. Please click on the "Login" button, a piece of code will be automatically copied later, enter the code in the opened browser to finish the login process. Re-login - Because the account authorization is invalid, you need to re-add your Microsoft account\nPlease click on the "OK" button, a piece of code will be automatically copied later, enter the code in the opened browser to finish the login process. + Because the account authorization is invalid, you need to re-add your Microsoft account\nPlease click on the "OK" button, a piece of code will be automatically copied later, enter the code in the opened browser to finish the login process. Select character Select skin file No account