add check access camera

This commit is contained in:
dranik
2026-05-08 16:57:35 +03:00
parent a53db6eafe
commit bb56008c3d
15 changed files with 372 additions and 10 deletions
@@ -19,19 +19,103 @@ import "../Components"
PageType {
id: root
/** True after "Add Device via QR" until permission result or navigation. */
property bool pendingOpenQrPageAfterCamera: false
/** True after denial: user may enable camera in system settings; resume opens QR page when granted. */
property bool waitingSettingsReturnForQrPage: false
function proceedOpenQrPairingPage() {
PageController.goToPage(PageEnum.PageSettingsApiQrPairingSend)
pendingOpenQrPageAfterCamera = false
waitingSettingsReturnForQrPage = false
}
function showCameraDeniedDrawer() {
showQuestionDrawer(
qsTr("Camera access is required"),
qsTr("Allow camera access to scan the pairing QR code. You can enable it in the system settings for Amnezia VPN."),
qsTr("Open settings"),
qsTr("Cancel"),
function() {
PairingUiController.openPairingCameraAppSettings()
},
function() {
waitingSettingsReturnForQrPage = false
})
}
function tryResumeQrPageAfterCameraSettings() {
if (!waitingSettingsReturnForQrPage || !root.visible) {
return
}
if (PairingUiController.isPairingCameraAccessGranted()) {
proceedOpenQrPairingPage()
}
}
function openAddDeviceViaQr() {
const maxC = ApiAccountInfoModel.data("maxDeviceCount")
const activeC = ApiAccountInfoModel.data("activeDeviceCount")
if (maxC > 0 && activeC >= maxC) {
PageController.goToPage(PageEnum.PageSettingsApiDeviceLimit)
} else {
return
}
if (Qt.platform.os !== "android" && Qt.platform.os !== "ios") {
PageController.goToPage(PageEnum.PageSettingsApiQrPairingSend)
return
}
if (PairingUiController.isPairingCameraAccessGranted()) {
proceedOpenQrPairingPage()
return
}
pendingOpenQrPageAfterCamera = true
PairingUiController.requestPairingCameraAccess()
}
onVisibleChanged: {
if (!visible) {
pendingOpenQrPageAfterCamera = false
waitingSettingsReturnForQrPage = false
}
}
Connections {
target: Qt.application
function onStateChanged() {
if (Qt.application.state !== Qt.ApplicationActive) {
return
}
root.tryResumeQrPageAfterCameraSettings()
}
}
Connections {
target: SettingsController
enabled: Qt.platform.os === "android"
function onActivityResumed() {
root.tryResumeQrPageAfterCameraSettings()
}
}
Connections {
target: PairingUiController
function onPairingCameraAccessFinished(granted) {
if (!root.pendingOpenQrPageAfterCamera) {
return
}
root.pendingOpenQrPageAfterCamera = false
if (granted) {
root.proceedOpenQrPairingPage()
} else {
root.waitingSettingsReturnForQrPage = true
root.showCameraDeniedDrawer()
}
}
function onPhonePairingSucceeded() {
const serverIndex = ServersUiController.getProcessedServerIndex()
if (serverIndex < 0) {
@@ -6,6 +6,7 @@ import QRCodeReader 1.0
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
@@ -23,6 +24,10 @@ PageType {
property int lastInvalidPairingQrToastClockMs: 0
/** iOS may deliver many QR frames; guard duplicate step transitions. */
property bool addDeviceConfirmNavigationScheduled: false
/** Mobile: waiting for camera permission before starting scan UI / Android scanner. */
property bool awaitingCameraPermissionForScan: false
/** After denial on scan screen: user may enable camera in settings. */
property bool waitingSettingsReturnForScan: false
Timer {
id: pairingCameraKickTimer
@@ -31,6 +36,38 @@ PageType {
onTriggered: root.restartPairingIosCamera()
}
function startPairingScanAfterPermission() {
if (Qt.platform.os === "android") {
PairingUiController.openPairingQrScanner()
} else if (Qt.platform.os === "ios") {
root.pairingCameraOpen = true
}
}
function showScanCameraDeniedDrawer() {
showQuestionDrawer(
qsTr("Camera access is required"),
qsTr("Allow camera access to scan the pairing QR code. You can enable it in the system settings for Amnezia VPN."),
qsTr("Open settings"),
qsTr("Cancel"),
function() {
PairingUiController.openPairingCameraAppSettings()
},
function() {
root.waitingSettingsReturnForScan = false
})
}
function tryResumeScanAfterCameraSettings() {
if (!root.waitingSettingsReturnForScan || !root.visible || root.pairingWizardStep !== 0) {
return
}
if (PairingUiController.isPairingCameraAccessGranted()) {
root.waitingSettingsReturnForScan = false
root.startPairingScanAfterPermission()
}
}
function restartPairingIosCamera() {
if (Qt.platform.os !== "ios" || !root.pairingCameraOpen) {
return
@@ -63,6 +100,7 @@ PageType {
pairingQrReader.stopReading()
root.pairingCameraOpen = false
root.pairingWizardStep = 0
root.waitingSettingsReturnForScan = false
if (!root.keepPhonePairingInBackgroundOnClose && !PairingUiController.phonePairingBusy) {
PairingUiController.cancelAllPairingActivity()
}
@@ -70,6 +108,27 @@ PageType {
}
}
Connections {
target: Qt.application
function onStateChanged() {
if (Qt.application.state !== Qt.ApplicationActive) {
return
}
root.tryResumeScanAfterCameraSettings()
}
}
Connections {
target: SettingsController
enabled: Qt.platform.os === "android"
function onActivityResumed() {
root.tryResumeScanAfterCameraSettings()
}
}
Connections {
target: root
function onPairingCameraOpenChanged() {
@@ -161,6 +220,11 @@ PageType {
}
enabled: !PairingUiController.phonePairingBusy
clickedFunc: function() {
if (!PairingUiController.isPairingCameraAccessGranted()) {
root.awaitingCameraPermissionForScan = true
PairingUiController.requestPairingCameraAccess()
return
}
if (Qt.platform.os === "android") {
PairingUiController.openPairingQrScanner()
} else {
@@ -238,14 +302,6 @@ PageType {
wrapMode: Text.Wrap
}
ParagraphTextType {
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
text: qsTr("Devices available with Amnezia Premium: %1").arg(ApiAccountInfoModel.data("availableDeviceSlots"))
wrapMode: Text.Wrap
}
BasicButtonType {
Layout.fillWidth: true
Layout.leftMargin: 16
@@ -296,6 +352,19 @@ PageType {
Connections {
target: PairingUiController
function onPairingCameraAccessFinished(granted) {
if (!root.awaitingCameraPermissionForScan) {
return
}
root.awaitingCameraPermissionForScan = false
if (granted) {
root.startPairingScanAfterPermission()
} else {
root.waitingSettingsReturnForScan = true
root.showScanCameraDeniedDrawer()
}
}
function onPairingUuidFromScan(uuid) {
if (root.addDeviceConfirmNavigationScheduled) {
return