Tweak QR code translations (#1347)

This commit is contained in:
Leendert de Borst
2025-11-17 09:33:11 +01:00
parent f7b0084eba
commit 5367c5eb34
4 changed files with 39 additions and 22 deletions

View File

@@ -11,6 +11,7 @@ import { ThemedButton } from '@/components/themed/ThemedButton';
import { ThemedContainer } from '@/components/themed/ThemedContainer';
import { ThemedScrollView } from '@/components/themed/ThemedScrollView';
import { ThemedText } from '@/components/themed/ThemedText';
import { UsernameDisplay } from '@/components/ui/UsernameDisplay';
import { useApp } from '@/context/AppContext';
import { useWebApi } from '@/context/WebApiContext';
import NativeVaultManager from '@/specs/NativeVaultManager';
@@ -70,15 +71,13 @@ export default function QRConfirmScreen() : React.ReactNode {
});
} catch (error) {
console.error('Mobile unlock error:', error);
let errorMsg = t('settings.qrScanner.mobileUnlock.genericError');
let errorMsg = t('common.errors.unknownErrorTryAgain');
if (error instanceof Error) {
if (error.message.includes('ENCRYPTION_ERROR')) {
errorMsg = t('settings.qrScanner.mobileUnlock.vaultLocked');
} else if (error.message.includes('404')) {
if (error.message.includes('404')) {
errorMsg = t('settings.qrScanner.mobileUnlock.requestExpired');
} else if (error.message.includes('401') || error.message.includes('403')) {
errorMsg = t('settings.qrScanner.mobileUnlock.unauthorized');
} else {
errorMsg = t('common.errors.unknownErrorTryAgain');
}
}
@@ -186,9 +185,13 @@ export default function QRConfirmScreen() : React.ReactNode {
confirmationText: {
fontSize: 16,
lineHeight: 24,
marginBottom: 12,
marginBottom: 16,
textAlign: 'center',
},
usernameDisplayContainer: {
marginBottom: 12,
width: '100%',
},
buttonContainer: {
gap: 12,
marginTop: 20,
@@ -223,8 +226,11 @@ export default function QRConfirmScreen() : React.ReactNode {
{t('settings.qrScanner.mobileUnlock.confirmTitle')}
</ThemedText>
<ThemedText style={styles.confirmationText}>
{t('settings.qrScanner.mobileUnlock.confirmMessage', { username })}
{t('settings.qrScanner.mobileUnlock.confirmMessage')}
</ThemedText>
<View style={styles.usernameDisplayContainer}>
<UsernameDisplay />
</View>
</View>
<View style={styles.buttonContainer}>

View File

@@ -94,7 +94,7 @@ export default function QRResultScreen() : React.ReactNode {
<ThemedText style={styles.message}>
{message || (isSuccess
? t('settings.qrScanner.mobileUnlock.successDescription')
: t('settings.qrScanner.mobileUnlock.genericError'))}
: t('common.errors.unknownErrorTryAgain'))}
</ThemedText>
</View>
</View>

View File

@@ -118,13 +118,13 @@ export default function QRScannerScreen() : React.ReactNode {
setIsLoadingAfterScan(false);
console.error('QR validation error:', error);
let errorMsg = t('settings.qrScanner.mobileUnlock.genericError');
let errorMsg = t('common.errors.unknownErrorTryAgain');
if (error instanceof Error) {
if (error.message.includes('404')) {
errorMsg = t('settings.qrScanner.mobileUnlock.requestExpired');
} else if (error.message.includes('401') || error.message.includes('403')) {
errorMsg = t('settings.qrScanner.mobileUnlock.unauthorized');
} else {
errorMsg = t('common.errors.unknownErrorTryAgain');
}
}
@@ -138,6 +138,7 @@ export default function QRScannerScreen() : React.ReactNode {
/**
* Handle barcode scanned - validate request and navigate to confirmation.
* Only processes AliasVault QR codes, silently ignores others.
*/
const handleBarcodeScanned = useCallback(({ data }: { data: string }) : void => {
// Prevent multiple scans
@@ -148,21 +149,14 @@ export default function QRScannerScreen() : React.ReactNode {
// Parse the QR code to determine its type
const parsedData = parseQRCode(data);
// Silently ignore non-AliasVault QR codes
if (!parsedData.type) {
Alert.alert(
t('settings.qrScanner.invalidQrCode'),
t('settings.qrScanner.notAliasVaultQr'),
[{ text: t('common.ok'), /**
* Go back to the settings tab.
*/
onPress: (): void => router.back() }]
);
return;
}
// Validate the request and navigate (with min 500ms loading)
validateAndNavigate(parsedData);
}, [isLoadingAfterScan, t, validateAndNavigate]);
}, [isLoadingAfterScan, validateAndNavigate]);
// Handle QR code URL passed from deep link (e.g., from native camera)
useEffect(() => {

View File

@@ -8,7 +8,7 @@
"no": "No",
"ok": "OK",
"continue": "Continue",
"loading": "Loading...",
"loading": "Loading",
"error": "Error",
"success": "Success",
"never": "Never",
@@ -395,6 +395,23 @@
"failedToDelete": "Failed to delete account. Please try again.",
"usernameNotFound": "Username not found. Please login again."
}
},
"qrScanner": {
"title": "QR Code Scanner",
"scanningMessage": "Point your camera at the QR code",
"invalidQrCode": "Invalid QR Code",
"notAliasVaultQr": "This is not a valid AliasVault QR code. Please scan a QR code generated by AliasVault.",
"cameraPermissionTitle": "Camera Permission Required",
"cameraPermissionMessage": "Please allow camera access to scan QR codes.",
"mobileUnlock": {
"confirmTitle": "Confirm Login",
"confirmMessage": "You are about to log in on a remote device with your account. This other device will have full access to your vault. Only proceed if you trust this device.",
"successTitle": "Device Unlocked",
"successDescription": "The remote device has been successfully unlocked.",
"requestExpired": "This unlock request has expired. Please generate a new QR code.",
"authenticationFailed": "Authentication failed. Please try again.",
"authenticationRequired": "Authentication required to confirm this action."
}
}
},
"navigation": {