From f7991e6dbf78e5e49fa0934fbdfd9d9b11ff3cca Mon Sep 17 00:00:00 2001 From: Jonas Lochmann Date: Mon, 9 May 2022 02:00:00 +0200 Subject: [PATCH] Improve the parent key setup flow --- .../android/ui/extension/WizardFlipper.kt | 35 ++++++ .../ui/login/CodeLoginDialogFragment.kt | 39 ------- .../android/ui/login/NewLoginFragment.kt | 99 +++++++---------- .../parent/key/AddUserKeyDialogFragment.kt | 42 ++++++-- .../MissingBarcodeScannerDialogFragment.kt | 57 ++++++++++ .../ui/manage/parent/key/ScanBarcode.kt | 33 ++++++ .../parent/key/ScanKeyDialogFragment.kt | 102 ------------------ app/src/main/res/values-de/strings.xml | 3 +- app/src/main/res/values/strings.xml | 3 +- 9 files changed, 204 insertions(+), 209 deletions(-) create mode 100644 app/src/main/java/io/timelimit/android/ui/extension/WizardFlipper.kt delete mode 100644 app/src/main/java/io/timelimit/android/ui/login/CodeLoginDialogFragment.kt create mode 100644 app/src/main/java/io/timelimit/android/ui/manage/parent/key/MissingBarcodeScannerDialogFragment.kt create mode 100644 app/src/main/java/io/timelimit/android/ui/manage/parent/key/ScanBarcode.kt delete mode 100644 app/src/main/java/io/timelimit/android/ui/manage/parent/key/ScanKeyDialogFragment.kt diff --git a/app/src/main/java/io/timelimit/android/ui/extension/WizardFlipper.kt b/app/src/main/java/io/timelimit/android/ui/extension/WizardFlipper.kt new file mode 100644 index 0000000..87b76c5 --- /dev/null +++ b/app/src/main/java/io/timelimit/android/ui/extension/WizardFlipper.kt @@ -0,0 +1,35 @@ +/* + * TimeLimit Copyright 2019 - 2022 Jonas Lochmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package io.timelimit.android.ui.extension + +import android.widget.ViewFlipper +import io.timelimit.android.R + +fun ViewFlipper.openNextWizardScreen(index: Int) { + if (displayedChild != index) { + setInAnimation(context, R.anim.wizard_open_step_in) + setOutAnimation(context, R.anim.wizard_open_step_out) + displayedChild = index + } +} + +fun ViewFlipper.openPreviousWizardScreen(index: Int) { + if (displayedChild != index) { + setInAnimation(context, R.anim.wizard_close_step_in) + setOutAnimation(context, R.anim.wizard_close_step_out) + displayedChild = index + } +} \ No newline at end of file diff --git a/app/src/main/java/io/timelimit/android/ui/login/CodeLoginDialogFragment.kt b/app/src/main/java/io/timelimit/android/ui/login/CodeLoginDialogFragment.kt deleted file mode 100644 index 273f365..0000000 --- a/app/src/main/java/io/timelimit/android/ui/login/CodeLoginDialogFragment.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * TimeLimit Copyright 2019 - 2020 Jonas Lochmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package io.timelimit.android.ui.login - -import android.widget.Toast -import androidx.fragment.app.FragmentManager -import io.timelimit.android.R -import io.timelimit.android.extensions.showSafe -import io.timelimit.android.ui.manage.parent.key.ScanKeyDialogFragment -import io.timelimit.android.ui.manage.parent.key.ScannedKey - -class CodeLoginDialogFragment: ScanKeyDialogFragment() { - companion object { - private const val DIALOG_TAG = "CodeLoginDialogFragment" - } - - override fun handleResult(key: ScannedKey?) { - if (key == null) { - Toast.makeText(context!!, R.string.manage_user_key_invalid, Toast.LENGTH_SHORT).show() - } else { - (targetFragment as NewLoginFragment).tryCodeLogin(key) - } - } - - fun show(fragmentManager: FragmentManager) = showSafe(fragmentManager, DIALOG_TAG) -} \ No newline at end of file diff --git a/app/src/main/java/io/timelimit/android/ui/login/NewLoginFragment.kt b/app/src/main/java/io/timelimit/android/ui/login/NewLoginFragment.kt index 7a5849a..3c97623 100644 --- a/app/src/main/java/io/timelimit/android/ui/login/NewLoginFragment.kt +++ b/app/src/main/java/io/timelimit/android/ui/login/NewLoginFragment.kt @@ -15,6 +15,7 @@ */ package io.timelimit.android.ui.login +import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent import android.os.Build @@ -26,8 +27,8 @@ import android.view.WindowManager import android.view.inputmethod.InputMethodManager import android.widget.Toast import androidx.fragment.app.DialogFragment +import androidx.fragment.app.viewModels import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.bottomsheet.BottomSheetDialog import io.timelimit.android.R @@ -36,8 +37,12 @@ import io.timelimit.android.data.model.User import io.timelimit.android.databinding.NewLoginFragmentBinding import io.timelimit.android.extensions.setOnEnterListenr import io.timelimit.android.ui.MainActivity +import io.timelimit.android.ui.extension.openNextWizardScreen +import io.timelimit.android.ui.extension.openPreviousWizardScreen import io.timelimit.android.ui.main.ActivityViewModelHolder import io.timelimit.android.ui.main.getActivityViewModel +import io.timelimit.android.ui.manage.parent.key.MissingBarcodeScannerDialogFragment +import io.timelimit.android.ui.manage.parent.key.ScanBarcode import io.timelimit.android.ui.manage.parent.key.ScannedKey import io.timelimit.android.ui.view.KeyboardViewListener @@ -63,15 +68,23 @@ class NewLoginFragment: DialogFragment() { private const val WAITING_FOR_SYNC = 8 } - private val model: LoginDialogFragmentModel by lazy { - ViewModelProviders.of(this).get(LoginDialogFragmentModel::class.java) - } + private val model: LoginDialogFragmentModel by viewModels() + private val inputMethodManager: InputMethodManager by lazy { - context!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager } private val activityModelHolder get() = requireActivity() as ActivityViewModelHolder + private val scanLoginCode = registerForActivityResult(ScanBarcode()) { barcode -> + barcode ?: return@registerForActivityResult + + ScannedKey.tryDecode(barcode).let { key -> + if (key == null) Toast.makeText(requireContext(), R.string.manage_user_key_invalid, Toast.LENGTH_SHORT).show() + else tryCodeLogin(key) + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -80,11 +93,11 @@ class NewLoginFragment: DialogFragment() { } if (savedInstanceState == null) { - model.tryDefaultLogin(getActivityViewModel(activity!!)) + model.tryDefaultLogin(getActivityViewModel(requireActivity())) } } - override fun onCreateDialog(savedInstanceState: Bundle?) = object: BottomSheetDialog(context!!, theme) { + override fun onCreateDialog(savedInstanceState: Bundle?) = object: BottomSheetDialog(requireContext(), theme) { override fun onBackPressed() { if (!model.goBack()) { super.onBackPressed() @@ -130,9 +143,11 @@ class NewLoginFragment: DialogFragment() { } override fun onScanCodeRequested() { - CodeLoginDialogFragment().apply { - setTargetFragment(this@NewLoginFragment, 0) - }.show(parentFragmentManager) + try { + scanLoginCode.launch(null) + } catch (ex: ActivityNotFoundException) { + MissingBarcodeScannerDialogFragment.newInstance().show(parentFragmentManager) + } } } @@ -158,7 +173,7 @@ class NewLoginFragment: DialogFragment() { model.tryParentLogin( password = password.text.toString(), keepSignedIn = checkDontAskAgain.isChecked, - model = getActivityViewModel(activity!!), + model = getActivityViewModel(requireActivity()), setAsDeviceUser = checkAssignMyself.isChecked ) } @@ -203,11 +218,7 @@ class NewLoginFragment: DialogFragment() { dismissAllowingStateLoss() } is UserListLoginDialogStatus -> { - if (binding.switcher.displayedChild != USER_LIST) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_close_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_close_step_out) - binding.switcher.displayedChild = USER_LIST - } + binding.switcher.openPreviousWizardScreen(USER_LIST) val users = status.usersToShow.map { LoginUserAdapterUser(it) } @@ -221,11 +232,7 @@ class NewLoginFragment: DialogFragment() { null } is ParentUserLogin -> { - if (binding.switcher.displayedChild != PARENT_AUTH) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_open_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_open_step_out) - binding.switcher.displayedChild = PARENT_AUTH - } + binding.switcher.openNextWizardScreen(PARENT_AUTH) binding.enterPassword.password.isEnabled = !status.isCheckingPassword @@ -255,7 +262,7 @@ class NewLoginFragment: DialogFragment() { } if (status.wasPasswordWrong) { - Toast.makeText(context!!, R.string.login_snackbar_wrong, Toast.LENGTH_SHORT).show() + Toast.makeText(requireContext(), R.string.login_snackbar_wrong, Toast.LENGTH_SHORT).show() binding.enterPassword.password.setText("") model.resetPasswordWrong() @@ -264,40 +271,24 @@ class NewLoginFragment: DialogFragment() { null } ParentUserLoginMissingTrustedTime -> { - if (binding.switcher.displayedChild != UNVERIFIED_TIME) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_open_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_open_step_out) - binding.switcher.displayedChild = UNVERIFIED_TIME - } + binding.switcher.openNextWizardScreen(UNVERIFIED_TIME) null } is CanNotSignInChildHasNoPassword -> { - if (binding.switcher.displayedChild != CHILD_MISSING_PASSWORD) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_open_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_open_step_out) - binding.switcher.displayedChild = CHILD_MISSING_PASSWORD - } + binding.switcher.openNextWizardScreen(CHILD_MISSING_PASSWORD) binding.childWithoutPassword.childName = status.childName null } is ChildAlreadyDeviceUser -> { - if (binding.switcher.displayedChild != CHILD_ALREADY_CURRENT_USER) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_open_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_open_step_out) - binding.switcher.displayedChild = CHILD_ALREADY_CURRENT_USER - } + binding.switcher.openNextWizardScreen(CHILD_ALREADY_CURRENT_USER) null } is ChildUserLogin -> { - if (binding.switcher.displayedChild != CHILD_AUTH) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_open_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_open_step_out) - binding.switcher.displayedChild = CHILD_AUTH - } + binding.switcher.openNextWizardScreen(CHILD_AUTH) binding.childPassword.password.requestFocus() inputMethodManager.showSoftInput(binding.childPassword.password, 0) @@ -305,7 +296,7 @@ class NewLoginFragment: DialogFragment() { binding.childPassword.password.isEnabled = !status.isCheckingPassword if (status.wasPasswordWrong) { - Toast.makeText(context!!, R.string.login_snackbar_wrong, Toast.LENGTH_SHORT).show() + Toast.makeText(requireContext(), R.string.login_snackbar_wrong, Toast.LENGTH_SHORT).show() binding.childPassword.password.setText("") model.resetPasswordWrong() @@ -314,32 +305,20 @@ class NewLoginFragment: DialogFragment() { null } ChildLoginRequiresPremiumStatus -> { - if (binding.switcher.displayedChild != CHILD_LOGIN_REQUIRES_PREMIUM) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_open_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_open_step_out) - binding.switcher.displayedChild = CHILD_LOGIN_REQUIRES_PREMIUM - } + binding.switcher.openNextWizardScreen(CHILD_LOGIN_REQUIRES_PREMIUM) null } is ParentUserLoginBlockedByCategory -> { - if (binding.switcher.displayedChild != PARENT_LOGIN_BLOCKED) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_open_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_open_step_out) - binding.switcher.displayedChild = PARENT_LOGIN_BLOCKED - } + binding.switcher.openNextWizardScreen(PARENT_LOGIN_BLOCKED) binding.parentLoginBlocked.categoryTitle = status.categoryTitle - binding.parentLoginBlocked.reason = LoginDialogFragmentModel.formatBlockingReasonForLimitLoginCategory(status.reason, context!!) + binding.parentLoginBlocked.reason = LoginDialogFragmentModel.formatBlockingReasonForLimitLoginCategory(status.reason, requireContext()) null } ParentUserLoginWaitingForSync -> { - if (binding.switcher.displayedChild != WAITING_FOR_SYNC) { - binding.switcher.setInAnimation(context!!, R.anim.wizard_open_step_in) - binding.switcher.setOutAnimation(context!!, R.anim.wizard_open_step_out) - binding.switcher.displayedChild = WAITING_FOR_SYNC - } + binding.switcher.openNextWizardScreen(WAITING_FOR_SYNC) null } @@ -350,6 +329,6 @@ class NewLoginFragment: DialogFragment() { } fun tryCodeLogin(code: ScannedKey) { - model.tryCodeLogin(code, getActivityViewModel(activity!!)) + model.tryCodeLogin(code, getActivityViewModel(requireActivity())) } } diff --git a/app/src/main/java/io/timelimit/android/ui/manage/parent/key/AddUserKeyDialogFragment.kt b/app/src/main/java/io/timelimit/android/ui/manage/parent/key/AddUserKeyDialogFragment.kt index 885d177..98e572e 100644 --- a/app/src/main/java/io/timelimit/android/ui/manage/parent/key/AddUserKeyDialogFragment.kt +++ b/app/src/main/java/io/timelimit/android/ui/manage/parent/key/AddUserKeyDialogFragment.kt @@ -1,5 +1,5 @@ /* - * TimeLimit Copyright 2019 - 2020 Jonas Lochmann + * TimeLimit Copyright 2019 - 2022 Jonas Lochmann * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,8 +15,12 @@ */ package io.timelimit.android.ui.manage.parent.key +import android.app.Dialog +import android.content.ActivityNotFoundException import android.os.Bundle import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment import androidx.fragment.app.FragmentManager import io.timelimit.android.R import io.timelimit.android.async.Threads @@ -24,7 +28,7 @@ import io.timelimit.android.data.model.UserKey import io.timelimit.android.extensions.showSafe import io.timelimit.android.logic.DefaultAppLogic -class AddUserKeyDialogFragment: ScanKeyDialogFragment() { +class AddUserKeyDialogFragment: DialogFragment() { companion object { private const val DIALOG_TAG = "AddUserKeyDialogFragment" private const val USER_ID = "userId" @@ -36,13 +40,39 @@ class AddUserKeyDialogFragment: ScanKeyDialogFragment() { } } - override fun handleResult(key: ScannedKey?) { + private val scanBarcode = registerForActivityResult(ScanBarcode()) { result -> + if (result != null) handleResult(ScannedKey.tryDecode(result)) + + dismiss() + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = AlertDialog.Builder(requireContext(), theme) + .setTitle(R.string.manage_user_key_add) + .setMessage(R.string.manage_user_key_info) + .setNegativeButton(R.string.generic_cancel, null) + .setPositiveButton(R.string.generic_go, null) + .create() + .also { dialog -> + dialog.setOnShowListener { + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + try { + scanBarcode.launch(null) + } catch (ex: ActivityNotFoundException) { + MissingBarcodeScannerDialogFragment.newInstance().show(parentFragmentManager) + + dismiss() + } + } + } + } + + private fun handleResult(key: ScannedKey?) { if (key == null) { - Toast.makeText(context!!, R.string.manage_user_key_invalid, Toast.LENGTH_SHORT).show() + Toast.makeText(requireContext(), R.string.manage_user_key_invalid, Toast.LENGTH_SHORT).show() } else { - val context = context!!.applicationContext + val context = requireContext().applicationContext val database = DefaultAppLogic.with(context!!).database - val userId = arguments!!.getString(USER_ID)!! + val userId = requireArguments().getString(USER_ID)!! Threads.database.execute { database.runInTransaction { diff --git a/app/src/main/java/io/timelimit/android/ui/manage/parent/key/MissingBarcodeScannerDialogFragment.kt b/app/src/main/java/io/timelimit/android/ui/manage/parent/key/MissingBarcodeScannerDialogFragment.kt new file mode 100644 index 0000000..d6311b8 --- /dev/null +++ b/app/src/main/java/io/timelimit/android/ui/manage/parent/key/MissingBarcodeScannerDialogFragment.kt @@ -0,0 +1,57 @@ +/* + * TimeLimit Copyright 2019 - 2022 Jonas Lochmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package io.timelimit.android.ui.manage.parent.key + +import android.app.Dialog +import android.content.ActivityNotFoundException +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager +import io.timelimit.android.R +import io.timelimit.android.extensions.showSafe + +class MissingBarcodeScannerDialogFragment: DialogFragment() { + companion object { + private const val DIALOG_TAG = "MissingBarcodeScannerDialogFragment" + + fun newInstance() = MissingBarcodeScannerDialogFragment() + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = AlertDialog.Builder(requireContext(), theme) + .setTitle(R.string.scan_key_missing_title) + .setMessage(R.string.scan_key_missing_text) + .setNegativeButton(R.string.generic_cancel, null) + .setPositiveButton(R.string.scan_key_missing_install) { _, _ -> + try { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse("market://details?id=de.markusfisch.android.binaryeye") + + ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + ) + } catch (ex: ActivityNotFoundException) { + Toast.makeText(requireContext(), R.string.error_general, Toast.LENGTH_SHORT).show() + } + } + .create() + + fun show(fragmentManager: FragmentManager) = showSafe(fragmentManager, DIALOG_TAG) +} \ No newline at end of file diff --git a/app/src/main/java/io/timelimit/android/ui/manage/parent/key/ScanBarcode.kt b/app/src/main/java/io/timelimit/android/ui/manage/parent/key/ScanBarcode.kt new file mode 100644 index 0000000..481fd87 --- /dev/null +++ b/app/src/main/java/io/timelimit/android/ui/manage/parent/key/ScanBarcode.kt @@ -0,0 +1,33 @@ +/* + * TimeLimit Copyright 2019 - 2022 Jonas Lochmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package io.timelimit.android.ui.manage.parent.key + +import android.app.Activity +import android.content.Context +import android.content.Intent +import androidx.activity.result.contract.ActivityResultContract + +class ScanBarcode: ActivityResultContract() { + override fun createIntent(context: Context, input: Unit?): Intent = Intent() + .setPackage("de.markusfisch.android.binaryeye") + .setAction("com.google.zxing.client.android.SCAN") + + override fun parseResult(resultCode: Int, intent: Intent?): String? { + return if (resultCode == Activity.RESULT_OK) { + intent?.getStringExtra("SCAN_RESULT") + } else null + } +} \ No newline at end of file diff --git a/app/src/main/java/io/timelimit/android/ui/manage/parent/key/ScanKeyDialogFragment.kt b/app/src/main/java/io/timelimit/android/ui/manage/parent/key/ScanKeyDialogFragment.kt deleted file mode 100644 index e4868a7..0000000 --- a/app/src/main/java/io/timelimit/android/ui/manage/parent/key/ScanKeyDialogFragment.kt +++ /dev/null @@ -1,102 +0,0 @@ -/* - * TimeLimit Copyright 2019 - 2020 Jonas Lochmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package io.timelimit.android.ui.manage.parent.key - -import android.app.Activity -import android.app.Dialog -import android.content.ActivityNotFoundException -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import android.widget.Toast -import androidx.appcompat.app.AlertDialog -import androidx.fragment.app.DialogFragment -import io.timelimit.android.R - -abstract class ScanKeyDialogFragment: DialogFragment() { - companion object { - private const val CAN_NOT_SCAN = "canNotScan" - private const val REQ_SCAN = 1 - } - - private var canNotScan = false - - final override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - if (savedInstanceState == null) { - try { - startActivityForResult( - Intent() - .setPackage("de.markusfisch.android.binaryeye") - .setAction("com.google.zxing.client.android.SCAN"), - REQ_SCAN - ) - } catch (ex: ActivityNotFoundException) { - canNotScan = true - } - } else { - canNotScan = savedInstanceState.getBoolean(CAN_NOT_SCAN) - } - } - - final override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - if (canNotScan) { - return AlertDialog.Builder(context!!, theme) - .setTitle(R.string.scan_key_missing_title) - .setMessage(R.string.scan_key_missing_text) - .setNegativeButton(R.string.generic_cancel, null) - .setPositiveButton(R.string.scan_key_missing_install) { _, _ -> - try { - startActivity( - Intent( - Intent.ACTION_VIEW, - Uri.parse("market://details?id=de.markusfisch.android.binaryeye") - - ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - ) - } catch (ex: ActivityNotFoundException) { - Toast.makeText(context!!, R.string.error_general, Toast.LENGTH_SHORT).show() - } - } - .create() - } else { - return super.onCreateDialog(savedInstanceState) - } - } - - final override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - - outState.putBoolean(CAN_NOT_SCAN, canNotScan) - } - - final override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - - if (requestCode == REQ_SCAN && (!canNotScan)) { - if (resultCode == Activity.RESULT_OK) { - val key = ScannedKey.tryDecode(data?.getStringExtra("SCAN_RESULT") ?: "") - - handleResult(key) - } - - dismiss() - } - } - - abstract fun handleResult(key: ScannedKey?) -} \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index cf8cd66..bf0474c 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1064,7 +1064,8 @@ Benutzerschlüssel Hiermit kann sich ein Benutzer durch das Scannen eines Barcodes anmelden. Der gescannte Code muss von TimeLimit - generiert worden sein. + generiert worden sein. Dafür muss TimeLimit auf einem anderen Gerät als + Schlüsselgenerator eingerichtet sein. Es gibt keinen Schlüssel für diesen Benutzer Dieser Benutzer hat den Schlüssel %s diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 44139a1..96e4178 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1109,10 +1109,11 @@ User key A key is a barcode which allows the user to sign in by scanning it. This code must be generated by TimeLimit. + This requires TimeLimit at another device configured as key generator. There is no key for this user This user has got the key %s - add key + Add Key remove key The key was added This was no valid TimeLimit key