fix: запрос разрешение на фотку в фото пикере
This commit is contained in:
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import 'package:komet/backend/modules/contacts.dart';
|
import 'package:komet/backend/modules/contacts.dart';
|
||||||
import 'package:komet/core/config/app_frost.dart';
|
import 'package:komet/core/config/app_frost.dart';
|
||||||
@@ -882,6 +883,8 @@ class _KeepAlivePageState extends State<_KeepAlivePage>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum _CameraAccess { unknown, granted, denied }
|
||||||
|
|
||||||
class _CameraTile extends StatefulWidget {
|
class _CameraTile extends StatefulWidget {
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final ColorScheme cs;
|
final ColorScheme cs;
|
||||||
@@ -893,30 +896,59 @@ class _CameraTile extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CameraTileState extends State<_CameraTile> with WidgetsBindingObserver {
|
class _CameraTileState extends State<_CameraTile> with WidgetsBindingObserver {
|
||||||
|
static const String _askedKey = 'komet_camera_permission_asked';
|
||||||
|
|
||||||
CameraController? _controller;
|
CameraController? _controller;
|
||||||
bool _starting = false;
|
bool _starting = false;
|
||||||
|
_CameraAccess _access = _CameraAccess.unknown;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
_maybeStartPreview();
|
_resolveAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
if (state == AppLifecycleState.resumed) {
|
if (state == AppLifecycleState.resumed) {
|
||||||
_maybeStartPreview();
|
_resolveAccess();
|
||||||
} else if (state == AppLifecycleState.inactive ||
|
} else if (state == AppLifecycleState.inactive ||
|
||||||
state == AppLifecycleState.paused) {
|
state == AppLifecycleState.paused) {
|
||||||
_stopPreview();
|
_stopPreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _maybeStartPreview() async {
|
Future<void> _resolveAccess() async {
|
||||||
if (_starting || _controller != null) return;
|
|
||||||
if (!(Platform.isAndroid || Platform.isIOS)) return;
|
if (!(Platform.isAndroid || Platform.isIOS)) return;
|
||||||
if (!await Permission.camera.status.isGranted) return;
|
|
||||||
|
var status = await Permission.camera.status;
|
||||||
|
if (status.isDenied) {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
if (!(prefs.getBool(_askedKey) ?? false)) {
|
||||||
|
await prefs.setBool(_askedKey, true);
|
||||||
|
status = await Permission.camera.request();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
|
final granted = status.isGranted;
|
||||||
|
setState(
|
||||||
|
() => _access = granted ? _CameraAccess.granted : _CameraAccess.denied,
|
||||||
|
);
|
||||||
|
if (granted) _startPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTap() {
|
||||||
|
if (_access == _CameraAccess.denied) {
|
||||||
|
openAppSettings();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
widget.onTap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _startPreview() async {
|
||||||
|
if (_starting || _controller != null) return;
|
||||||
_starting = true;
|
_starting = true;
|
||||||
try {
|
try {
|
||||||
final cameras = await availableCameras();
|
final cameras = await availableCameras();
|
||||||
@@ -962,9 +994,11 @@ class _CameraTileState extends State<_CameraTile> with WidgetsBindingObserver {
|
|||||||
final cs = widget.cs;
|
final cs = widget.cs;
|
||||||
final controller = _controller;
|
final controller = _controller;
|
||||||
final hasPreview = controller != null && controller.value.isInitialized;
|
final hasPreview = controller != null && controller.value.isInitialized;
|
||||||
|
final denied = _access == _CameraAccess.denied;
|
||||||
|
final l10n = AppLocalizations.of(context)!;
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: widget.onTap,
|
onTap: _onTap,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
@@ -997,14 +1031,19 @@ class _CameraTileState extends State<_CameraTile> with WidgetsBindingObserver {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
Symbols.photo_camera,
|
denied
|
||||||
|
? Symbols.no_photography
|
||||||
|
: Symbols.photo_camera,
|
||||||
size: 34,
|
size: 34,
|
||||||
color: cs.onSurface,
|
color: cs.onSurface,
|
||||||
weight: 400,
|
weight: 400,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
Text(
|
Text(
|
||||||
AppLocalizations.of(context)!.attachSheetCamera,
|
denied
|
||||||
|
? l10n.attachSheetCameraAllow
|
||||||
|
: l10n.attachSheetCamera,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: cs.onSurfaceVariant,
|
color: cs.onSurfaceVariant,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
|||||||
@@ -977,6 +977,7 @@
|
|||||||
"attachSheetSettings": "Settings",
|
"attachSheetSettings": "Settings",
|
||||||
"attachSheetAddCaptionHint": "Add a caption...",
|
"attachSheetAddCaptionHint": "Add a caption...",
|
||||||
"attachSheetCamera": "Camera",
|
"attachSheetCamera": "Camera",
|
||||||
|
"attachSheetCameraAllow": "Allow camera",
|
||||||
"photoEditorApplyFailed": "Couldn't apply",
|
"photoEditorApplyFailed": "Couldn't apply",
|
||||||
"photoEditorFlipTooltip": "Flip",
|
"photoEditorFlipTooltip": "Flip",
|
||||||
"photoEditorRotateTooltip": "Rotate",
|
"photoEditorRotateTooltip": "Rotate",
|
||||||
|
|||||||
@@ -4400,6 +4400,12 @@ abstract class AppLocalizations {
|
|||||||
/// **'Camera'**
|
/// **'Camera'**
|
||||||
String get attachSheetCamera;
|
String get attachSheetCamera;
|
||||||
|
|
||||||
|
/// No description provided for @attachSheetCameraAllow.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Allow camera'**
|
||||||
|
String get attachSheetCameraAllow;
|
||||||
|
|
||||||
/// No description provided for @photoEditorApplyFailed.
|
/// No description provided for @photoEditorApplyFailed.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|||||||
@@ -2287,6 +2287,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get attachSheetCamera => 'Camera';
|
String get attachSheetCamera => 'Camera';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get attachSheetCameraAllow => 'Allow camera';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get photoEditorApplyFailed => 'Couldn\'t apply';
|
String get photoEditorApplyFailed => 'Couldn\'t apply';
|
||||||
|
|
||||||
|
|||||||
@@ -2301,6 +2301,9 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get attachSheetCamera => 'Камера';
|
String get attachSheetCamera => 'Камера';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get attachSheetCameraAllow => 'Разрешите камеру';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get photoEditorApplyFailed => 'Не удалось применить';
|
String get photoEditorApplyFailed => 'Не удалось применить';
|
||||||
|
|
||||||
|
|||||||
@@ -742,6 +742,7 @@
|
|||||||
"attachSheetSettings": "Настройки",
|
"attachSheetSettings": "Настройки",
|
||||||
"attachSheetAddCaptionHint": "Добавить подпись...",
|
"attachSheetAddCaptionHint": "Добавить подпись...",
|
||||||
"attachSheetCamera": "Камера",
|
"attachSheetCamera": "Камера",
|
||||||
|
"attachSheetCameraAllow": "Разрешите камеру",
|
||||||
"photoEditorApplyFailed": "Не удалось применить",
|
"photoEditorApplyFailed": "Не удалось применить",
|
||||||
"photoEditorFlipTooltip": "Отразить",
|
"photoEditorFlipTooltip": "Отразить",
|
||||||
"photoEditorRotateTooltip": "Повернуть",
|
"photoEditorRotateTooltip": "Повернуть",
|
||||||
|
|||||||
Reference in New Issue
Block a user