Add fullscreen QR code viewer for easier scanning

- Create QRCodeFullscreenActivity for large QR code display
- Add click listener to QR code image in PolycentricBackupActivity
- Add visual feedback with ripple effect and hint text
- Add localized strings for fullscreen hint
- Update layout to include hint text below QR code
- Add activity to AndroidManifest.xml

This makes it much easier to scan QR codes by providing
a fullscreen view when tapping the QR code image.
This commit is contained in:
Trevor
2025-08-13 11:59:56 -05:00
parent 4b3e89d0af
commit cb74e82fa1
9 changed files with 152 additions and 1 deletions
+4
View File
@@ -242,5 +242,9 @@
android:name=".activities.PolycentricModerationActivity"
android:exported="false"
android:screenOrientation="portrait" />
<activity
android:name=".activities.QRCodeFullscreenActivity"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
</application>
</manifest>
@@ -22,6 +22,7 @@ import com.futo.platformplayer.states.StateApp
import com.futo.platformplayer.states.StateApp.Companion.withContext
import com.futo.platformplayer.states.StatePolycentric
import com.futo.platformplayer.views.buttons.BigButton
import com.futo.platformplayer.activities.QRCodeFullscreenActivity
import com.futo.polycentric.core.ContentType
import com.futo.polycentric.core.SignedEvent
import com.futo.polycentric.core.StorageTypeCRDTItem
@@ -49,6 +50,7 @@ class PolycentricBackupActivity : AppCompatActivity() {
private lateinit var _imageQR: ImageView;
private lateinit var _exportBundle: String;
private lateinit var _textQR: TextView;
private lateinit var _textQRHint: TextView;
private lateinit var _loader: View
override fun attachBaseContext(newBase: Context?) {
@@ -64,6 +66,7 @@ class PolycentricBackupActivity : AppCompatActivity() {
_buttonCopy = findViewById(R.id.button_copy)
_imageQR = findViewById(R.id.image_qr)
_textQR = findViewById(R.id.text_qr)
_textQRHint = findViewById(R.id.text_qr_hint)
_loader = findViewById(R.id.progress_loader)
findViewById<ImageButton>(R.id.button_back).setOnClickListener {
finish();
@@ -71,6 +74,7 @@ class PolycentricBackupActivity : AppCompatActivity() {
_imageQR.visibility = View.INVISIBLE
_textQR.visibility = View.INVISIBLE
_textQRHint.visibility = View.INVISIBLE
_loader.visibility = View.VISIBLE
_buttonShare.visibility = View.INVISIBLE
_buttonCopy.visibility = View.INVISIBLE
@@ -92,8 +96,15 @@ class PolycentricBackupActivity : AppCompatActivity() {
_imageQR.setImageBitmap(pair.second)
_imageQR.visibility = View.VISIBLE
_textQR.visibility = View.VISIBLE
_textQRHint.visibility = View.VISIBLE
_buttonShare.visibility = View.VISIBLE
_buttonCopy.visibility = View.VISIBLE
// Add click listener to open QR code in fullscreen
_imageQR.setOnClickListener {
val intent = QRCodeFullscreenActivity.createIntent(this@PolycentricBackupActivity, pair.second, _exportBundle)
startActivity(intent)
}
} catch (e: Exception) {
Logger.e(TAG, getString(R.string.failed_to_generate_qr_code), e)
@@ -107,6 +118,7 @@ class PolycentricBackupActivity : AppCompatActivity() {
}
_textQR.text = errorMessage
_textQR.visibility = View.VISIBLE
_textQRHint.visibility = View.INVISIBLE
_buttonShare.visibility = View.VISIBLE
_buttonCopy.visibility = View.VISIBLE
@@ -0,0 +1,62 @@
package com.futo.platformplayer.activities
import android.content.Context
import android.graphics.Bitmap
import android.os.Bundle
import android.view.View
import android.widget.ImageButton
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import com.futo.platformplayer.R
import com.futo.platformplayer.setNavigationBarColorAndIcons
import com.futo.platformplayer.states.StateApp
class QRCodeFullscreenActivity : AppCompatActivity() {
companion object {
private const val EXTRA_QR_BITMAP = "qr_bitmap"
private const val EXTRA_QR_TEXT = "qr_text"
fun createIntent(context: Context, qrBitmap: Bitmap, qrText: String): android.content.Intent {
return android.content.Intent(context, QRCodeFullscreenActivity::class.java).apply {
putExtra(EXTRA_QR_BITMAP, qrBitmap)
putExtra(EXTRA_QR_TEXT, qrText)
}
}
}
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(StateApp.instance.getLocaleContext(newBase))
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_qr_code_fullscreen)
setNavigationBarColorAndIcons()
val qrBitmap = intent.getParcelableExtra<Bitmap>(EXTRA_QR_BITMAP)
val qrText = intent.getStringExtra(EXTRA_QR_TEXT)
val imageQR = findViewById<ImageView>(R.id.image_qr_fullscreen)
val buttonBack = findViewById<ImageButton>(R.id.button_back_fullscreen)
val buttonClose = findViewById<ImageButton>(R.id.button_close_fullscreen)
// Set the QR code image
qrBitmap?.let { bitmap ->
imageQR.setImageBitmap(bitmap)
}
// Set click listeners
buttonBack.setOnClickListener {
finish()
}
buttonClose.setOnClickListener {
finish()
}
// Make the entire QR code area clickable to close
imageQR.setOnClickListener {
finish()
}
}
}
@@ -29,6 +29,8 @@
android:id="@+id/image_qr"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:padding="8dp"
app:srcCompat="@drawable/ic_qr"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
@@ -47,6 +49,19 @@
app:layout_constraintLeft_toLeftOf="@id/image_qr"
app:layout_constraintRight_toRightOf="@id/image_qr" />
<TextView
android:id="@+id/text_qr_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tap_qr_code_for_fullscreen"
android:fontFamily="@font/inter_light"
android:textSize="14dp"
android:textColor="@color/gray_400"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/text_qr"
app:layout_constraintLeft_toLeftOf="@id/text_qr"
app:layout_constraintRight_toRightOf="@id/text_qr" />
<LinearLayout
android:id="@+id/layout_buttons"
android:layout_width="match_parent"
@@ -55,7 +70,7 @@
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginTop="30dp"
app:layout_constraintTop_toBottomOf="@id/text_qr"
app:layout_constraintTop_toBottomOf="@id/text_qr_hint"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<!-- Top navigation bar -->
<ImageButton
android:id="@+id/button_back_fullscreen"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="@string/cd_button_back"
android:padding="10dp"
android:scaleType="fitCenter"
android:background="?android:attr/selectableItemBackgroundBorderless"
app:srcCompat="@drawable/ic_back_thin_white_16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp" />
<ImageButton
android:id="@+id/button_close_fullscreen"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="@string/cd_button_close"
android:padding="10dp"
android:scaleType="fitCenter"
android:background="?android:attr/selectableItemBackgroundBorderless"
app:srcCompat="@drawable/ic_close"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" />
<!-- Full screen QR code -->
<ImageView
android:id="@+id/image_qr_fullscreen"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitCenter"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:padding="40dp"
app:layout_constraintTop_toBottomOf="@id/button_back_fullscreen"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
+1
View File
@@ -405,6 +405,7 @@
<string name="failed_to_parse_newpipe_subscriptions">Fehler beim Parsen von NewPipe-Abonnements</string>
<string name="failed_to_generate_qr_code">Fehler beim Generieren des QR-Codes</string>
<string name="qr_code_too_large_use_text_below">QR-Code zu groß. Verwenden Sie den Text unten, um Ihr Profil zu teilen.</string>
<string name="tap_qr_code_for_fullscreen">Tippen Sie auf den QR-Code für Vollbildansicht</string>
<string name="share_text">Text teilen</string>
<string name="copied_text">Text kopiert</string>
<string name="must_be_at_least_3_characters_long">Muss mindestens 3 Zeichen lang sein.</string>
+1
View File
@@ -382,6 +382,7 @@
<string name="failed_to_parse_newpipe_subscriptions">Error al analizar las suscripciones de NewPipe</string>
<string name="failed_to_generate_qr_code">Error al generar el código QR</string>
<string name="qr_code_too_large_use_text_below">Código QR demasiado grande. Use el texto de abajo para compartir su perfil.</string>
<string name="tap_qr_code_for_fullscreen">Toca el código QR para vista completa</string>
<string name="share_text">Compartir texto</string>
<string name="copied_text">Texto copiado</string>
<string name="must_be_at_least_3_characters_long">Debe tener al menos 3 caracteres de longitud.</string>
+1
View File
@@ -421,6 +421,7 @@
<string name="failed_to_parse_newpipe_subscriptions">Échec de l\'analyse des abonnements NewPipe</string>
<string name="failed_to_generate_qr_code">Échec de la génération du code QR</string>
<string name="qr_code_too_large_use_text_below">Code QR trop volumineux. Utilisez le texte ci-dessous pour partager votre profil.</string>
<string name="tap_qr_code_for_fullscreen">Appuyez sur le code QR pour la vue plein écran</string>
<string name="share_text">Partager le texte</string>
<string name="copied_text">Texte copié</string>
<string name="must_be_at_least_3_characters_long">Doit comporter au moins 3 caractères.</string>
+1
View File
@@ -643,6 +643,7 @@
<string name="failed_to_parse_newpipe_subscriptions">Failed to parse NewPipe Subscriptions</string>
<string name="failed_to_generate_qr_code">Failed to generate QR code</string>
<string name="qr_code_too_large_use_text_below">QR code too large. Use the text below to share your profile.</string>
<string name="tap_qr_code_for_fullscreen">Tap QR code for fullscreen view</string>
<string name="share_text">Share Text</string>
<string name="copied_text">Copied Text</string>
<string name="must_be_at_least_3_characters_long">Must be at least 3 characters long.</string>