diff --git a/app/src/main/java/org/fedorahosted/freeotp/ui/MainActivity.kt b/app/src/main/java/org/fedorahosted/freeotp/ui/MainActivity.kt index a9e7f81..da51b8a 100644 --- a/app/src/main/java/org/fedorahosted/freeotp/ui/MainActivity.kt +++ b/app/src/main/java/org/fedorahosted/freeotp/ui/MainActivity.kt @@ -126,6 +126,20 @@ class MainActivity : AppCompatActivity() { windowInsets } + ViewCompat.setOnApplyWindowInsetsListener(binding.addTokenFab) { view, windowInsets -> + val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val marginParams = view.layoutParams as android.view.ViewGroup.MarginLayoutParams + marginParams.bottomMargin = resources.getDimensionPixelSize(R.dimen.space_3) + insets.bottom + if (view.layoutDirection == View.LAYOUT_DIRECTION_RTL) { + marginParams.leftMargin = resources.getDimensionPixelSize(R.dimen.space_3) + insets.left + } else { + marginParams.rightMargin = resources.getDimensionPixelSize(R.dimen.space_3) + insets.right + } + view.layoutParams = marginParams + windowInsets + } + + viewModel.migrateOldData() binding.tokenList.adapter = tokenListAdapter @@ -341,13 +355,33 @@ class MainActivity : AppCompatActivity() { val uri = intent.data if (uri != null) { - lifecycleScope.launch { - try { - otpTokenDatabase.otpTokenDao().insert(OtpTokenFactory.createFromUri(uri)) - } catch (e: Exception) { - Snackbar.make(binding.rootView, R.string.invalid_token_uri_received, Snackbar.LENGTH_SHORT) - .show() - } + val rawPath = uri.path?.trimStart('/') ?: "" + + // Account is required; reject the intent silently if absent + val account = rawPath.substringAfter(":", "").ifEmpty { null } ?: return + + // Issuer is optional; can be empty + val issuer = uri.getQueryParameter("issuer") ?: rawPath.substringBefore(":") + + // Post to ensure the window is attached before showing the dialog. + // onNewIntent may be called from onCreate before setContentView completes. + window.decorView.post { + MaterialAlertDialogBuilder(this) + .setTitle(R.string.add_token_confirmation_title) + .setMessage(getString(R.string.add_token_confirmation_message, issuer, account)) + .setIcon(R.drawable.alert) + .setPositiveButton(R.string.ok_text) { _, _ -> + lifecycleScope.launch { + try { + otpTokenDatabase.otpTokenDao().insert(OtpTokenFactory.createFromUri(uri)) + } catch (e: Exception) { + Snackbar.make(binding.rootView, R.string.invalid_token_uri_received, Snackbar.LENGTH_SHORT) + .show() + } + } + } + .setNegativeButton(R.string.cancel_text, null) + .show() } } } @@ -526,4 +560,4 @@ class MainActivity : AppCompatActivity() { const val SCREENSHOT_MODE_EXTRA = "screenshot_mode" const val SHARE_FROM_PACKAGE_NAME_INTENT_EXTRA = "shareFromPackageName" } -} +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 450cf29..eaed69d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -61,6 +61,8 @@ Authentication required Please use biometric or PIN to authenticate FreeOTP+ Unable to authenticate. Do you have screen lock enabled with PIN / biometric enabled? + Add OTP Account? + An external source wants to add an OTP account:\n\nIssuer: %1$s\nAccount: %2$s\n\nOnly proceed if you trust this source. 5 6 @@ -80,4 +82,4 @@ Category All categories Uncategorized - + \ No newline at end of file