mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-03 09:49:25 +02:00
Improve the parent key setup flow
This commit is contained in:
parent
9c887372f7
commit
f7991e6dbf
9 changed files with 204 additions and 209 deletions
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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)
|
||||
}
|
|
@ -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()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
|
||||
* TimeLimit Copyright <C> 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 {
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<Unit, String?>() {
|
||||
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
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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?)
|
||||
}
|
|
@ -1064,7 +1064,8 @@
|
|||
<string name="manage_user_key_title">Benutzerschlüssel</string>
|
||||
<string name="manage_user_key_info">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.
|
||||
</string>
|
||||
<string name="manage_user_key_not_enrolled">Es gibt keinen Schlüssel für diesen Benutzer</string>
|
||||
<string name="manage_user_key_is_enrolled">Dieser Benutzer hat den Schlüssel %s</string>
|
||||
|
|
|
@ -1109,10 +1109,11 @@
|
|||
<string name="manage_user_key_title">User key</string>
|
||||
<string name="manage_user_key_info">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.
|
||||
</string>
|
||||
<string name="manage_user_key_not_enrolled">There is no key for this user</string>
|
||||
<string name="manage_user_key_is_enrolled">This user has got the key %s</string>
|
||||
<string name="manage_user_key_add">add key</string>
|
||||
<string name="manage_user_key_add">Add Key</string>
|
||||
<string name="manage_user_key_remove">remove key</string>
|
||||
<string name="manage_user_key_added">The key was added</string>
|
||||
<string name="manage_user_key_invalid">This was no valid TimeLimit key</string>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue