From 15e1256b60c21d8d89bc3101bab833c6538ee349 Mon Sep 17 00:00:00 2001 From: AlphanoJack Date: Sat, 17 Aug 2024 18:09:09 +0900 Subject: [PATCH 1/8] separating Camera --- lib/feature/camera/CameraGalleryScreen.dart | 12 ++ lib/feature/camera/CameraPreviewScreen.dart | 13 ++ lib/feature/camera/CameraScreen.dart | 12 ++ .../camera/MyPageProfileImagePreview.dart | 61 ------- lib/feature/camera/ProfileCameraPage.dart | 170 ------------------ .../SettingInsideAccountManagerWidget.dart | 126 ------------- lib/feature/camera/provider/PageProvider.dart | 30 ++-- lib/feature/camera/service/CameraService.dart | 168 +++++++++++++++++ .../camera/widget/CameraButtonWidget.dart | 39 ++++ .../widget/CameraErrorMessageWidget.dart | 27 +++ .../CameraGalleryPageWidget.dart} | 16 +- .../camera/widget/CameraPageWidget.dart | 55 ++++++ .../widget/CameraPreviewPageWidget.dart | 59 ++++++ .../camera/widget/CameraPreviewWidget.dart | 75 ++++++++ .../widget/CircularImagePreviewWidget.dart | 21 +++ lib/feature/login/LoginScreen.dart | 8 +- lib/feature/mypage/MyPageScreen.dart | 7 +- .../widget/MyPageBottomSheet.dart} | 19 +- .../NoticeScreen.dart} | 11 +- lib/router/RouterProvider.dart | 25 ++- lib/services/camera/CameraService.dart | 60 ------- lib/utils/AppStrings.dart | 16 +- .../ShadowStyle.dart} | 4 +- 23 files changed, 557 insertions(+), 477 deletions(-) create mode 100644 lib/feature/camera/CameraGalleryScreen.dart create mode 100644 lib/feature/camera/CameraPreviewScreen.dart create mode 100644 lib/feature/camera/CameraScreen.dart delete mode 100644 lib/feature/camera/MyPageProfileImagePreview.dart delete mode 100644 lib/feature/camera/ProfileCameraPage.dart delete mode 100644 lib/feature/camera/SettingInsideAccountManagerWidget.dart create mode 100644 lib/feature/camera/service/CameraService.dart create mode 100644 lib/feature/camera/widget/CameraButtonWidget.dart create mode 100644 lib/feature/camera/widget/CameraErrorMessageWidget.dart rename lib/feature/camera/{ProfileGalleryPage.dart => widget/CameraGalleryPageWidget.dart} (81%) create mode 100644 lib/feature/camera/widget/CameraPageWidget.dart create mode 100644 lib/feature/camera/widget/CameraPreviewPageWidget.dart create mode 100644 lib/feature/camera/widget/CameraPreviewWidget.dart create mode 100644 lib/feature/camera/widget/CircularImagePreviewWidget.dart rename lib/feature/{camera/SettingsBottomSheet.dart => mypage/widget/MyPageBottomSheet.dart} (80%) rename lib/feature/{camera/setting_inside_notice.dart => notice/NoticeScreen.dart} (89%) delete mode 100644 lib/services/camera/CameraService.dart rename lib/{feature/camera/CameraShadow.dart => utils/ShadowStyle.dart} (88%) diff --git a/lib/feature/camera/CameraGalleryScreen.dart b/lib/feature/camera/CameraGalleryScreen.dart new file mode 100644 index 00000000..c29f41e7 --- /dev/null +++ b/lib/feature/camera/CameraGalleryScreen.dart @@ -0,0 +1,12 @@ +import 'package:blueberry_flutter_template/feature/camera/widget/CameraGalleryPageWidget.dart'; +import 'package:flutter/material.dart'; + +class CameraGalleryScreen extends StatelessWidget { + static const String name = 'CameraGalleryScreen'; + const CameraGalleryScreen({super.key}); + + @override + Widget build(BuildContext context) { + return const CameraGalleryPageWidget(); + } +} diff --git a/lib/feature/camera/CameraPreviewScreen.dart b/lib/feature/camera/CameraPreviewScreen.dart new file mode 100644 index 00000000..cde3abbc --- /dev/null +++ b/lib/feature/camera/CameraPreviewScreen.dart @@ -0,0 +1,13 @@ +import 'package:blueberry_flutter_template/feature/camera/widget/CameraPreviewPageWidget.dart'; +import 'package:flutter/material.dart'; +import 'dart:io'; + +class CameraPreviewScreen extends StatelessWidget { + final File imageFile; + const CameraPreviewScreen(this.imageFile, {super.key}); + + @override + Widget build(BuildContext context) { + return CameraPreviewPageWidget(imageFile: imageFile); + } +} diff --git a/lib/feature/camera/CameraScreen.dart b/lib/feature/camera/CameraScreen.dart new file mode 100644 index 00000000..7c81b61c --- /dev/null +++ b/lib/feature/camera/CameraScreen.dart @@ -0,0 +1,12 @@ +import 'package:blueberry_flutter_template/feature/camera/widget/CameraPageWidget.dart'; +import 'package:flutter/material.dart'; + +class CameraScreen extends StatelessWidget { + static const String name = 'CameraScreen'; + const CameraScreen({super.key}); + + @override + Widget build(BuildContext context) { + return const CameraPageWidget(); + } +} diff --git a/lib/feature/camera/MyPageProfileImagePreview.dart b/lib/feature/camera/MyPageProfileImagePreview.dart deleted file mode 100644 index 94a6e0b1..00000000 --- a/lib/feature/camera/MyPageProfileImagePreview.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'dart:io'; - -import 'package:blueberry_flutter_template/feature/camera/provider/fireStorageServiceProvider.dart'; -import 'package:blueberry_flutter_template/feature/mypage/MyPageScreen.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:go_router/go_router.dart'; - -import '../../services/FirebaseStoreServiceProvider.dart'; - -class SharePostScreen extends ConsumerWidget { - final File imageFile; - - const SharePostScreen(this.imageFile, {super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final storage = ref.read(fireStorageServiceProvider); - final fireStorage = ref.read(firebaseStoreServiceProvider); - final userId = FirebaseAuth.instance.currentUser!.uid; - - return Scaffold( - appBar: AppBar( - title: const Text('프로필 이미지 편집'), - ), - body: Center( - child: Column( - children: [ - ClipOval( - child: Image.file( - imageFile, - width: 100, - height: 100, - fit: BoxFit.cover, - ), - ), - TextButton( - onPressed: () async { - try { - final imageUrl = await storage.uploadImageFromApp( - imageFile, ImageType.profileimage, - fixedFileName: userId); - - // 프로필 이미지 생성 - fireStorage.createProfileIamge(userId, imageUrl); - - // 페이지 이동 - context.goNamed(MyPageScreen.name); - } catch (e) { - print(e); - } - }, - child: const Text('이미지 저장 하기'), - ), - ], - ), - ), - ); - } -} diff --git a/lib/feature/camera/ProfileCameraPage.dart b/lib/feature/camera/ProfileCameraPage.dart deleted file mode 100644 index a55efc83..00000000 --- a/lib/feature/camera/ProfileCameraPage.dart +++ /dev/null @@ -1,170 +0,0 @@ -import 'package:blueberry_flutter_template/feature/camera/CameraShadow.dart'; -import 'package:blueberry_flutter_template/feature/camera/MyPageProfileImagePreview.dart'; -import 'package:blueberry_flutter_template/feature/camera/provider/PageProvider.dart'; -import 'package:blueberry_flutter_template/services/camera/CameraService.dart'; -import 'package:blueberry_flutter_template/utils/AppStrings.dart'; -import 'package:camera/camera.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'dart:io'; -import 'package:path/path.dart'; -import 'package:path_provider/path_provider.dart'; - -class ProfileCameraPage extends ConsumerStatefulWidget { - const ProfileCameraPage({super.key}); - - @override - ConsumerState createState() => _ProfileCameraPageState(); -} - -class _ProfileCameraPageState extends ConsumerState { - final CameraService cameraService = CameraService(); - bool _isPressed = false; - Size size = Size.zero; - - @override - void initState() { - super.initState(); - initializeCamera(); - } - - @override - void dispose() { - cameraService.dispose(); - super.dispose(); - } - - Future initializeCamera() async { - await cameraService.initializeCameras(); - setState(() {}); - } - - @override - Widget build(BuildContext context) { - final pageNotifier = ref.watch(pageProvider.notifier); - size = MediaQuery.of(context).size; - - return Scaffold( - appBar: AppBar( - title: const Text(AppStrings.takeProfilePhoto), - leading: IconButton( - onPressed: () { - pageNotifier.moveToPage(0); - }, - icon: const Icon(Icons.arrow_back), - ), - ), - body: Column( - children: [ - Stack( - children: [ - Container( - width: size.width, - height: size.width * 1.3, - color: Colors.black, - child: cameraService.controller != null - ? _getPreview(cameraService.controller!, context) - : _buildErrorMessage(cameraService.changeCamera), - ), - Positioned( - top: 0, - right: 0, - child: IconButton( - onPressed: () async { - try { - await cameraService.toggleCamera(); - setState(() {}); - } catch (error) { - print("Error toggling camera: $error"); - } - }, - icon: const Icon(Icons.change_circle), - ), - ) - ], - ), - Expanded( - child: Center( - child: GestureDetector( - onTap: () { - _attemptTakePhoto(context); - }, - onTapDown: (_) => setState(() => _isPressed = true), - onTapUp: (_) => setState(() => _isPressed = false), - onTapCancel: () => setState(() => _isPressed = false), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Container( - decoration: ShapeDecoration( - shape: CircleBorder( - side: BorderSide( - color: _isPressed ? Colors.red : Colors.black12, - width: 20, - ), - ), - ), - ), - ), - ), - ), - ), - ], - ), - ); - } - - Widget _getPreview(CameraController controller, BuildContext context) { - return ClipRect( - child: OverflowBox( - alignment: Alignment.center, - child: FittedBox( - fit: BoxFit.fitWidth, - child: Stack(children: [ - SizedBox( - width: size.width, - height: size.width * 1.2, - child: CameraPreview(controller), - ), - Positioned.fill( - child: CustomPaint( - painter: CameraShadow(radius: size.width * 0.48), - ), - ), - ]), - ), - ), - ); - } - - Widget _buildErrorMessage(bool changeCamera) { - return Center( - child: Text( - changeCamera ? AppStrings.setFrontCamera : AppStrings.setBackCamera, - style: const TextStyle(color: Colors.white), - ), - ); - } - - void _attemptTakePhoto(BuildContext context) async { - // file에 접근할꺼임 사진을 촬영하고 저장하기 위해서 - final String timeInMilli = DateTime.now().millisecondsSinceEpoch.toString(); - // 이미지를 저장할때 시간을 기준으로 이미지명을 만들기 위해서 사용함 - try { - final path = - join((await getTemporaryDirectory()).path, '$timeInMilli.png'); - - final XFile file = await cameraService.controller!.takePicture(); - - await file.saveTo(path); - - final File imageFile = File(path); - - if (context.mounted) { - Navigator.of(context).push( - MaterialPageRoute(builder: (_) => SharePostScreen(imageFile))); - } - } catch (e) { - print('Error: $e'); - } - } -} diff --git a/lib/feature/camera/SettingInsideAccountManagerWidget.dart b/lib/feature/camera/SettingInsideAccountManagerWidget.dart deleted file mode 100644 index c923c6be..00000000 --- a/lib/feature/camera/SettingInsideAccountManagerWidget.dart +++ /dev/null @@ -1,126 +0,0 @@ -import 'package:blueberry_flutter_template/services/InAppPurchaseService.dart'; -import 'package:blueberry_flutter_template/utils/AppStrings.dart'; -import 'package:blueberry_flutter_template/core/widget/MiniAvatarWidget.dart'; -import 'package:blueberry_flutter_template/feature/payment/widget/WebPaymentWidget.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:go_router/go_router.dart'; - -import '../payment/provider/UserMemberShipProvider.dart'; - -class SettingAccountManagerWidget extends ConsumerStatefulWidget { - static const String name = 'SettingAccountManagerWidget'; - const SettingAccountManagerWidget({super.key}); - - @override - ConsumerState createState() => - _SettingAccountManagerWidget(); -} - -class _SettingAccountManagerWidget - extends ConsumerState { - bool showNumber = false; - final InAppPurchaseService _purchaseService = InAppPurchaseService(); - - @override - void initState() { - // TODO: implement initState - super.initState(); - _purchaseService.initStoreInfo(); - } - - @override - void dispose() { - // TODO: implement dispose - super.dispose(); - _purchaseService.dispose(); - } - - @override - Widget build(BuildContext context) { - final userMemberShipState = ref.watch(userMemberShipProvider); - - return Scaffold( - appBar: AppBar( - title: const Text("나의 계정 관리"), - ), - body: Column( - children: [ - const Padding( - padding: EdgeInsets.all(10.0), - child: Row( - children: [ - MiniAvatar(), - SizedBox( - width: 20, - ), - Text("홍길동"), - ], - ), - ), - const Divider(), - ListTile( - leading: const Icon(Icons.call), - title: showNumber - ? const Text("010-1234-5678") - : const Text("010-**34-56**"), - trailing: ElevatedButton( - onPressed: () { - setState(() { - showNumber = !showNumber; - }); - }, - child: Container( - child: const Text("보이기"), - ), - ), - ), - const Divider(), - ListTile( - leading: const Icon(Icons.email), - title: userMemberShipState.isMembership - ? const Text(AppStrings.isUserMembership) - : const Text(AppStrings.notUserMembership), - trailing: _inAppPurchaseBtn(userMemberShipState, context), - ), - ], - ), - ); - } - - ElevatedButton _inAppPurchaseBtn( - UserMemberShipState userMemberShipState, BuildContext context) { - return ElevatedButton( - onPressed: userMemberShipState.isMembership - ? null // 이미 멤버십이 있으면 버튼 비활성화 - : () async { - if (kIsWeb) { - context.goNamed(WebPaymentWidget.name); - } else { - // 앱 일때 인앱 결제 처리 - try { - await _purchaseService.buyMembership(); - // 구매 성공 시 상태 업데이트 또는 사용자에게 알림 - await ref - .watch(userMemberShipProvider.notifier) - .loadMembershipStatus(); - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text(AppStrings.successMessage_membership)), - ); - } catch (e) { - // 구매 실패 시 에러 처리 - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text(AppStrings.errorMessage_purchase)), - ); - } - } - }, - child: Container( - child: userMemberShipState.isMembership ? null : const Text("가입 하기"), - ), - ); - } -} diff --git a/lib/feature/camera/provider/PageProvider.dart b/lib/feature/camera/provider/PageProvider.dart index 48eb921d..c2a76a1a 100644 --- a/lib/feature/camera/provider/PageProvider.dart +++ b/lib/feature/camera/provider/PageProvider.dart @@ -1,17 +1,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -class PageState { - final PageController pageController; - final int pageNumber; - - PageState({required this.pageController, required this.pageNumber}); - PageState copyWith({PageController? pageController, int? pageNumber}) { - return PageState( - pageController: pageController ?? this.pageController, - pageNumber: pageNumber ?? this.pageNumber); - } -} +final pageProvider = +StateNotifierProvider.autoDispose((ref) { + return PageProviderNotifier(); +}); class PageProviderNotifier extends StateNotifier { PageProviderNotifier() @@ -24,7 +17,14 @@ class PageProviderNotifier extends StateNotifier { } } -final pageProvider = - StateNotifierProvider.autoDispose((ref) { - return PageProviderNotifier(); -}); +class PageState { + final PageController pageController; + final int pageNumber; + + PageState({required this.pageController, required this.pageNumber}); + PageState copyWith({PageController? pageController, int? pageNumber}) { + return PageState( + pageController: pageController ?? this.pageController, + pageNumber: pageNumber ?? this.pageNumber); + } +} diff --git a/lib/feature/camera/service/CameraService.dart b/lib/feature/camera/service/CameraService.dart new file mode 100644 index 00000000..af1f32bb --- /dev/null +++ b/lib/feature/camera/service/CameraService.dart @@ -0,0 +1,168 @@ +import 'package:blueberry_flutter_template/feature/camera/widget/CameraPreviewPageWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; +import 'dart:io'; +import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; + +class CameraService { + CameraController? controller; + List cameras = []; + bool readyTakePhoto = false; + final ValueNotifier controllerNotifier = ValueNotifier(null); + final ValueNotifier readyTakePhotoNotifier = ValueNotifier(false); + final ValueNotifier cameraDirectionNotifier = ValueNotifier(CameraLensDirection.back); + + Future initializeCameras() async { + cameras = await availableCameras(); + controller = CameraController(cameras[0], ResolutionPreset.high); + await controller!.initialize(); + readyTakePhoto = true; + controllerNotifier.value = controller; + readyTakePhotoNotifier.value = readyTakePhoto; + } + + Future toggleCamera() async { + if (cameras.length < 2) return; + + final lensDirection = controller!.description.lensDirection; + CameraDescription newCamera; + if (lensDirection == CameraLensDirection.back) { + newCamera = cameras.firstWhere( + (camera) => camera.lensDirection == CameraLensDirection.front, + ); + } else { + newCamera = cameras.firstWhere( + (camera) => camera.lensDirection == CameraLensDirection.back, + ); + } + + await controller?.dispose(); + controller = CameraController(newCamera, ResolutionPreset.high); + try { + await controller!.initialize(); + readyTakePhoto = true; + } catch (e) { + print("Error toggling camera: $e"); + readyTakePhoto = false; + } + controllerNotifier.value = controller; + readyTakePhotoNotifier.value = readyTakePhoto; + } + + Future takePhoto() async { + if (controller != null && controller!.value.isInitialized) { + try { + final XFile file = await controller!.takePicture(); + return file; + } catch (e) { + print("Error taking photo: $e"); + return null; + } + } + return null; + } + + void attemptTakePhoto(BuildContext context) async { + final String timeInMilli = DateTime.now().millisecondsSinceEpoch.toString(); + try { + final path = join((await getTemporaryDirectory()).path, '$timeInMilli.png'); + final XFile file = await controller!.takePicture(); + await file.saveTo(path); + final File imageFile = File(path); + + if (context.mounted) { + Navigator.of(context).push( + MaterialPageRoute(builder: (_) => CameraPreviewScreen(imageFile)), + ); + } + } catch (e) { + print('Error: $e'); + } + } + + void dispose() { + controller?.dispose(); + controllerNotifier.dispose(); + readyTakePhotoNotifier.dispose(); + } +} + +// class CameraService { +// CameraController? controller; +// List cameras = []; +// bool _readyTakePhoto = false; +// final bool _changeCamera = false; +// +// +// bool get readyTakePhoto => _readyTakePhoto; +// bool get changeCamera => _changeCamera; +// +// Future initializeCameras() async { +// cameras = await availableCameras(); +// controller = CameraController(cameras[0], ResolutionPreset.high); +// await controller!.initialize(); +// } +// +// Future toggleCamera() async { +// if (cameras.length < 2) return; +// +// final lensDirection = controller!.description.lensDirection; +// CameraDescription newCamera; +// if (lensDirection == CameraLensDirection.back) { +// newCamera = cameras.firstWhere( +// (camera) => camera.lensDirection == CameraLensDirection.front, +// ); +// } else { +// newCamera = cameras.firstWhere( +// (camera) => camera.lensDirection == CameraLensDirection.back, +// ); +// } +// +// await controller?.dispose(); +// controller = CameraController(newCamera, ResolutionPreset.high); +// try { +// await controller!.initialize(); +// _readyTakePhoto = true; +// } catch (e) { +// print("Error toggling camera: $e"); +// _readyTakePhoto = false; +// } +// } +// +// Future takePhoto() async { +// if (controller != null && controller!.value.isInitialized) { +// try { +// final XFile file = await controller!.takePicture(); +// return file; +// } catch (e) { +// print("Error taking photo: $e"); +// return null; +// } +// } +// return null; +// } +// +// void attemptTakePhoto(BuildContext context) async { +// final String timeInMilli = DateTime.now().millisecondsSinceEpoch.toString(); +// try { +// final path = join((await getTemporaryDirectory()).path, '$timeInMilli.png'); +// final XFile file = await controller!.takePicture(); +// await file.saveTo(path); +// final File imageFile = File(path); +// +// if (context.mounted) { +// Navigator.of(context).push( +// MaterialPageRoute(builder: (_) => CameraPreviewScreen(imageFile)), +// ); +// } +// } catch (e) { +// print('Error: $e'); +// } +// } +// +// void dispose() { +// controller!.dispose(); +// } +// } diff --git a/lib/feature/camera/widget/CameraButtonWidget.dart b/lib/feature/camera/widget/CameraButtonWidget.dart new file mode 100644 index 00000000..a3816d4f --- /dev/null +++ b/lib/feature/camera/widget/CameraButtonWidget.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; + +class CameraButtonWidget extends StatefulWidget { + final VoidCallback onTap; + + const CameraButtonWidget({super.key, required this.onTap}); + + @override + State createState() => _CameraButtonWidget(); +} + +class _CameraButtonWidget extends State { + bool _isPressed = false; + + @override + Widget build(BuildContext context) { + return Center( + child: GestureDetector( + onTap: widget.onTap, + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Container( + decoration: ShapeDecoration( + shape: CircleBorder( + side: BorderSide( + color: _isPressed ? Colors.red : Colors.black12, + width: 20, + ), + ), + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/feature/camera/widget/CameraErrorMessageWidget.dart b/lib/feature/camera/widget/CameraErrorMessageWidget.dart new file mode 100644 index 00000000..bbdb2d78 --- /dev/null +++ b/lib/feature/camera/widget/CameraErrorMessageWidget.dart @@ -0,0 +1,27 @@ + +import 'package:blueberry_flutter_template/feature/camera/service/CameraService.dart'; +import 'package:blueberry_flutter_template/utils/AppStrings.dart'; +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; + +class CameraErrorMessageWidget extends StatelessWidget { + final CameraService cameraService; + const CameraErrorMessageWidget({super.key, required this.cameraService}); + + @override + Widget build(BuildContext context) { + return Center( + child: ValueListenableBuilder( + valueListenable: cameraService.cameraDirectionNotifier, + builder: (context, direction, child) { + return Text( + direction == CameraLensDirection.front + ? AppStrings.setFrontCamera + : AppStrings.setBackCamera, + style: const TextStyle(color: Colors.white), + ); + }, + ), + ); + } +} diff --git a/lib/feature/camera/ProfileGalleryPage.dart b/lib/feature/camera/widget/CameraGalleryPageWidget.dart similarity index 81% rename from lib/feature/camera/ProfileGalleryPage.dart rename to lib/feature/camera/widget/CameraGalleryPageWidget.dart index 1791343d..b3059a46 100644 --- a/lib/feature/camera/ProfileGalleryPage.dart +++ b/lib/feature/camera/widget/CameraGalleryPageWidget.dart @@ -1,19 +1,21 @@ import 'dart:io'; +import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; +import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:photo_manager/photo_manager.dart'; -import 'MyPageProfileImagePreview.dart'; +import 'CameraPreviewPageWidget.dart'; -class ProfileGalleryPage extends ConsumerStatefulWidget { - const ProfileGalleryPage({super.key}); +class CameraGalleryPageWidget extends StatefulWidget { + const CameraGalleryPageWidget({super.key}); @override - _ImageGalleryState createState() => _ImageGalleryState(); + State createState() => _CameraGalleryPage(); } -class _ImageGalleryState extends ConsumerState { +class _CameraGalleryPage extends State { final List _imageList = []; int _currentPage = 0; @@ -49,7 +51,7 @@ class _ImageGalleryState extends ConsumerState { }); } else { SnackBar snackBar = SnackBar( - content: const Text("앨범 접근 권한을 허용 해주세요"), + content: const Text(AppStrings.errorMessage_permissionGallery), action: SnackBarAction( label: 'OK', onPressed: () { @@ -63,7 +65,7 @@ class _ImageGalleryState extends ConsumerState { void _navigateToSharePostScreen(File imageFile) { Navigator.of(context).push(MaterialPageRoute( - builder: (context) => SharePostScreen(imageFile), + builder: (context) => CameraPreviewScreen(imageFile), )); } diff --git a/lib/feature/camera/widget/CameraPageWidget.dart b/lib/feature/camera/widget/CameraPageWidget.dart new file mode 100644 index 00000000..100887b0 --- /dev/null +++ b/lib/feature/camera/widget/CameraPageWidget.dart @@ -0,0 +1,55 @@ +import 'package:blueberry_flutter_template/feature/camera/widget/CameraButtonWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/widget/CameraPreviewWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/service/CameraService.dart'; +import 'package:blueberry_flutter_template/utils/AppStrings.dart'; +import 'package:flutter/material.dart'; + + + +class CameraPageWidget extends StatefulWidget { + const CameraPageWidget({super.key}); + + @override + State createState() => _ProfileCameraPageState(); +} + +class _ProfileCameraPageState extends State { + final CameraService cameraService = CameraService(); + + @override + void initState() { + super.initState(); + cameraService.initializeCameras(); + } + + @override + void dispose() { + cameraService.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + + return Scaffold( + appBar: AppBar( + title: const Text(AppStrings.takeProfilePhoto), + ), + body: Column( + children: [ + CameraPreviewWidget( + cameraService: cameraService, + size: size, + ), + Expanded( + child: CameraButtonWidget( + onTap: () => cameraService.attemptTakePhoto(context), + ), + ), + ], + ), + ); + } +} + diff --git a/lib/feature/camera/widget/CameraPreviewPageWidget.dart b/lib/feature/camera/widget/CameraPreviewPageWidget.dart new file mode 100644 index 00000000..096e66a6 --- /dev/null +++ b/lib/feature/camera/widget/CameraPreviewPageWidget.dart @@ -0,0 +1,59 @@ +import 'dart:io'; +import 'package:blueberry_flutter_template/feature/camera/provider/fireStorageServiceProvider.dart'; +import 'package:blueberry_flutter_template/feature/camera/widget/CircularImagePreviewWidget.dart'; +import 'package:blueberry_flutter_template/feature/mypage/MyPageScreen.dart'; +import 'package:blueberry_flutter_template/utils/AppStrings.dart'; +import 'package:blueberry_flutter_template/utils/Talker.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:go_router/go_router.dart'; +import '../../../services/FirebaseStoreServiceProvider.dart'; + +class CameraPreviewPageWidget extends ConsumerWidget { + final File imageFile; + + const CameraPreviewPageWidget({super.key, required this.imageFile}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final storage = ref.read(fireStorageServiceProvider); + final fireStorage = ref.read(firebaseStoreServiceProvider); + final userId = FirebaseAuth.instance.currentUser!.uid; + + return Scaffold( + appBar: AppBar( + title: const Text(AppStrings.previewProfilePhoto), + ), + body: Center( + child: Column( + children: [ + CircularImagePreview(imageFile: imageFile), + makeProfileImageBtn(storage, userId, fireStorage, context), + ], + ), + ), + ); + } + + TextButton makeProfileImageBtn(FirebaseStorageService storage, String userId, FirestoreService fireStorage, BuildContext context) { + return TextButton( + onPressed: () async { + try { + final imageUrl = await storage.uploadImageFromApp( + imageFile, ImageType.profileimage, + fixedFileName: userId); + + // 프로필 이미지 생성 + fireStorage.createProfileIamge(userId, imageUrl); + + // 페이지 이동 + context.goNamed(MyPageScreen.name); + } catch (e) { + talker.error('이미지 저장에 실패했습니다. 다시 시도해주세요.'); + } + }, + child: const Text(AppStrings.savePhoto), + ); + } +} diff --git a/lib/feature/camera/widget/CameraPreviewWidget.dart b/lib/feature/camera/widget/CameraPreviewWidget.dart new file mode 100644 index 00000000..d5b623af --- /dev/null +++ b/lib/feature/camera/widget/CameraPreviewWidget.dart @@ -0,0 +1,75 @@ +import 'package:blueberry_flutter_template/feature/camera/widget/CameraErrorMessageWidget.dart'; +import 'package:blueberry_flutter_template/utils/ShadowStyle.dart'; +import 'package:blueberry_flutter_template/feature/camera/service/CameraService.dart'; +import 'package:blueberry_flutter_template/utils/Talker.dart'; +import 'package:camera/camera.dart'; +import 'package:flutter/material.dart'; + +class CameraPreviewWidget extends StatelessWidget { + final CameraService cameraService; + final Size size; + + + const CameraPreviewWidget({super.key, required this.cameraService, + required this.size,}); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Container( + width: size.width, + height: size.width * 1.3, + color: Colors.black, + child: ValueListenableBuilder( + valueListenable: cameraService.controllerNotifier, + builder: (context, controller, child) { + return controller != null && controller.value.isInitialized + ? _getPreview(controller, context) + : CameraErrorMessageWidget(cameraService: cameraService); + }, + ), + ), + Positioned( + top: 0, + right: 0, + child: IconButton( + onPressed: () async { + try { + await cameraService.toggleCamera(); + } catch (error) { + talker.error("Error toggling camera: $error"); + } + }, + icon: const Icon(Icons.change_circle), + ), + ) + ], + ); + } + + Widget _getPreview(CameraController controller, BuildContext context) { + return ClipRect( + child: OverflowBox( + alignment: Alignment.center, + child: FittedBox( + fit: BoxFit.fitWidth, + child: Stack( + children: [ + SizedBox( + width: size.width, + height: size.width * 1.2, + child: CameraPreview(controller), + ), + Positioned.fill( + child: CustomPaint( + painter: ShadowStyle(radius: size.width * 0.48), + ), + ), + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/feature/camera/widget/CircularImagePreviewWidget.dart b/lib/feature/camera/widget/CircularImagePreviewWidget.dart new file mode 100644 index 00000000..6d915266 --- /dev/null +++ b/lib/feature/camera/widget/CircularImagePreviewWidget.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; +import 'dart:io'; + +class CircularImagePreview extends StatelessWidget { + final File imageFile; + const CircularImagePreview({super.key, required this.imageFile}); + + @override + Widget build(BuildContext context) { + const double circleSize = 100; + + return ClipOval( + child: Image.file( + imageFile, + width: circleSize, + height: circleSize, + fit: BoxFit.cover, + ), + ); + } +} diff --git a/lib/feature/login/LoginScreen.dart b/lib/feature/login/LoginScreen.dart index 0b4b115e..c3b30629 100644 --- a/lib/feature/login/LoginScreen.dart +++ b/lib/feature/login/LoginScreen.dart @@ -1,4 +1,4 @@ -import 'package:blueberry_flutter_template/feature/camera/ProfileCameraPage.dart'; +import 'package:blueberry_flutter_template/feature/camera/widget/CameraPageWidget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; @@ -7,7 +7,7 @@ import '../../core/widget/SquareTitleWidget.dart'; import '../../services/FirebaseAuthServiceProvider.dart'; import '../../services/SocialAuthService.dart'; import '../../utils/AppStrings.dart'; -import '../camera/ProfileGalleryPage.dart'; +import '../camera/widget/CameraGalleryPageWidget.dart'; import '../camera/provider/PageProvider.dart'; import '../mypage/MyPageScreen.dart'; import '../signup/SignUpScreen.dart'; @@ -44,8 +44,8 @@ class LoginScreen extends ConsumerWidget { physics: const NeverScrollableScrollPhysics(), children: const [ MyPageScreen(), - ProfileCameraPage(), - ProfileGalleryPage(), + CameraPageWidget(), + CameraGalleryPageWidget(), ]) : _buildLogin(context, ref), orElse: () => const Center(child: CircularProgressIndicator()), diff --git a/lib/feature/mypage/MyPageScreen.dart b/lib/feature/mypage/MyPageScreen.dart index 22967dd1..08633d8c 100644 --- a/lib/feature/mypage/MyPageScreen.dart +++ b/lib/feature/mypage/MyPageScreen.dart @@ -8,14 +8,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:image_picker/image_picker.dart'; - import '../../core/widget/CustomDividerWidget.dart'; import '../../core/widget/NickNameTextWidget.dart'; import '../../services/FirebaseAuthServiceProvider.dart'; import '../../services/FirebaseStoreServiceProvider.dart'; import '../../utils/AppStrings.dart'; -import '../camera/SettingInsideAccountManagerWidget.dart'; -import '../camera/SettingsBottomSheet.dart'; +import 'widget/MyPageBottomSheet.dart'; import '../camera/provider/fireStorageServiceProvider.dart'; import '../setting/SettingScreen.dart'; @@ -56,7 +54,6 @@ class MyPageScreen extends ConsumerWidget { const CustomDividerWidget(), GestureDetector( onTap: () { - context.goNamed(SettingAccountManagerWidget.name); }, child: const ListTile( leading: Icon(Icons.person), @@ -256,7 +253,7 @@ class MyPageScreen extends ConsumerWidget { padding: MediaQuery.of(context).viewInsets, child: const SizedBox( height: 150, - child: SettingsBottomSheet(), + child: MyPageBottomSheet(), ), ); }); diff --git a/lib/feature/camera/SettingsBottomSheet.dart b/lib/feature/mypage/widget/MyPageBottomSheet.dart similarity index 80% rename from lib/feature/camera/SettingsBottomSheet.dart rename to lib/feature/mypage/widget/MyPageBottomSheet.dart index 195264e5..d7ffc3e3 100644 --- a/lib/feature/camera/SettingsBottomSheet.dart +++ b/lib/feature/mypage/widget/MyPageBottomSheet.dart @@ -1,17 +1,20 @@ +import 'package:blueberry_flutter_template/feature/camera/CameraGalleryScreen.dart'; +import 'package:blueberry_flutter_template/feature/camera/CameraScreen.dart'; import 'package:blueberry_flutter_template/feature/camera/provider/PageProvider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:go_router/go_router.dart'; import 'package:permission_handler/permission_handler.dart'; -class SettingsBottomSheet extends ConsumerStatefulWidget { - const SettingsBottomSheet({super.key}); +class MyPageBottomSheet extends ConsumerStatefulWidget { + const MyPageBottomSheet({super.key}); @override - ConsumerState createState() => - _SettingsBottomSheetState(); + ConsumerState createState() => + _MyPageBottomSheet(); } -class _SettingsBottomSheetState extends ConsumerState { +class _MyPageBottomSheet extends ConsumerState { Future _requestAlbumPermission() async { // 앨범 권한 요청 PermissionStatus photoStatus = await Permission.photos.request(); @@ -45,7 +48,6 @@ class _SettingsBottomSheetState extends ConsumerState { @override Widget build(BuildContext context) { - final pageNotifier = ref.watch(pageProvider.notifier); return Column( children: [ const SizedBox( @@ -53,8 +55,8 @@ class _SettingsBottomSheetState extends ConsumerState { ), TextButton( onPressed: () async { - pageNotifier.moveToPage(1); Navigator.pop(context); + context.goNamed(CameraScreen.name); }, child: const Text("직접 촬영 하기"), ), @@ -62,10 +64,9 @@ class _SettingsBottomSheetState extends ConsumerState { onPressed: () async { bool hasPermission = await _requestAlbumPermission(); if (hasPermission) { - pageNotifier.moveToPage(2); Navigator.pop(context); + context.goNamed(CameraGalleryScreen.name); } else { - pageNotifier.moveToPage(0); Navigator.pop(context); } }, diff --git a/lib/feature/camera/setting_inside_notice.dart b/lib/feature/notice/NoticeScreen.dart similarity index 89% rename from lib/feature/camera/setting_inside_notice.dart rename to lib/feature/notice/NoticeScreen.dart index 5c01b9ba..ae621d16 100644 --- a/lib/feature/camera/setting_inside_notice.dart +++ b/lib/feature/notice/NoticeScreen.dart @@ -2,25 +2,24 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:webview_flutter/webview_flutter.dart'; -class FixSettingNotice extends ConsumerStatefulWidget { - const FixSettingNotice({super.key}); +class NoticeScreen extends ConsumerStatefulWidget { + const NoticeScreen({super.key}); @override - ConsumerState createState() => _FixSettingNoticeState(); + ConsumerState createState() => _NoticeScreen(); } -class _FixSettingNoticeState extends ConsumerState { +class _NoticeScreen extends ConsumerState { bool _isWebViewVisible = false; bool _isWebViewVisible2 = false; late WebViewController _webViewController; - late WebViewController _webViewController2; + @override void initState() { // TODO: implement initState super.initState(); _webViewController = WebViewController(); - _webViewController2 = WebViewController(); } void _toggleWebView() { diff --git a/lib/router/RouterProvider.dart b/lib/router/RouterProvider.dart index a620226c..d8ff8777 100644 --- a/lib/router/RouterProvider.dart +++ b/lib/router/RouterProvider.dart @@ -2,6 +2,10 @@ import 'package:blueberry_flutter_template/feature/admin/AdminLoadingPage.dart'; import 'package:blueberry_flutter_template/feature/admin/AdminScreen.dart'; import 'package:blueberry_flutter_template/feature/admin/AdminUserDetailPage.dart'; import 'package:blueberry_flutter_template/feature/admin/AdminUserListPage.dart'; +import 'package:blueberry_flutter_template/feature/camera/CameraGalleryScreen.dart'; +import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; +import 'package:blueberry_flutter_template/feature/camera/widget/CameraPageWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/CameraScreen.dart'; import 'package:blueberry_flutter_template/feature/chat/ChatScreen.dart'; import 'package:blueberry_flutter_template/feature/payment/widget/WebPaymentWidget.dart'; import 'package:blueberry_flutter_template/feature/setting/SettingScreen.dart'; @@ -12,7 +16,6 @@ import 'package:talker_flutter/talker_flutter.dart'; import '../core/SplashScreen.dart'; import '../core/TopScreen.dart'; -import '../feature/camera/SettingInsideAccountManagerWidget.dart'; import '../feature/chat/ChatRoomScreen.dart'; import '../feature/friend/FriendsListScreen.dart'; import '../feature/mbti/MBTIScreen.dart'; @@ -67,12 +70,6 @@ final routerProvider = Provider((ref) { builder: (context, state) => ResponsiveLayoutBuilder(context, const MyPageScreen()), ), - GoRoute( - path: 'settingaccount', - name: SettingAccountManagerWidget.name, - builder: (context, state) => ResponsiveLayoutBuilder( - context, const SettingAccountManagerWidget()), - ), GoRoute( path: 'webpayment', name: WebPaymentWidget.name, @@ -138,7 +135,19 @@ final routerProvider = Provider((ref) { name: ProfileDetailScreen.name, builder: (context, state) => ResponsiveLayoutBuilder(context, const ProfileDetailScreen()), - ) + ), + GoRoute( + path: 'profilecamera', + name: CameraScreen.name, + builder: (context, state) => + ResponsiveLayoutBuilder(context, const CameraScreen()), + ), + GoRoute( + path: 'profilecameragallery', + name: CameraGalleryScreen.name, + builder: (context, state) => + ResponsiveLayoutBuilder(context, const CameraGalleryScreen()), + ), ], ), ], diff --git a/lib/services/camera/CameraService.dart b/lib/services/camera/CameraService.dart deleted file mode 100644 index efcee70f..00000000 --- a/lib/services/camera/CameraService.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:camera/camera.dart'; - -class CameraService { - CameraController? controller; - List cameras = []; - bool _readyTakePhoto = false; - final bool _changeCamera = false; - - bool get readyTakePhoto => _readyTakePhoto; - bool get changeCamera => _changeCamera; - - Future initializeCameras() async { - cameras = await availableCameras(); - controller = CameraController(cameras[0], ResolutionPreset.high); - await controller!.initialize(); - } - - Future toggleCamera() async { - if (cameras.length < 2) return; - - final lensDirection = controller!.description.lensDirection; - CameraDescription newCamera; - if (lensDirection == CameraLensDirection.back) { - newCamera = cameras.firstWhere( - (camera) => camera.lensDirection == CameraLensDirection.front, - ); - } else { - newCamera = cameras.firstWhere( - (camera) => camera.lensDirection == CameraLensDirection.back, - ); - } - - await controller?.dispose(); - controller = CameraController(newCamera, ResolutionPreset.high); - try { - await controller!.initialize(); - _readyTakePhoto = true; - } catch (e) { - print("Error toggling camera: $e"); - _readyTakePhoto = false; - } - } - - Future takePhoto() async { - if (controller != null && controller!.value.isInitialized) { - try { - final XFile file = await controller!.takePicture(); - return file; - } catch (e) { - print("Error taking photo: $e"); - return null; - } - } - return null; - } - - void dispose() { - controller!.dispose(); - } -} diff --git a/lib/utils/AppStrings.dart b/lib/utils/AppStrings.dart index 686c1f59..8463e340 100644 --- a/lib/utils/AppStrings.dart +++ b/lib/utils/AppStrings.dart @@ -34,6 +34,10 @@ class AppStrings { static const String setBackCamera = '후면 카메라를 불러오는 중 입니다. 잠시만 기다려 주세요'; static const String setFrontCamera = '전면 카메라를 불러오는 중 입니다. 잠시만 기다려 주세요'; + //Save Photo + static const String savePhoto = '이미지 저장 하기'; + static const String previewProfilePhoto = '프로필 사진 미리보기'; + //ChatPage.dart static const String lessonChatScreenTitle = '채팅'; static const String chatRoomScreenTitle = '채팅방 목록'; @@ -166,13 +170,17 @@ class AppStrings { static const String appbar_Text_Logo = 'Petting'; static final List date = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; + // Location Service + static const String errorMessage_sendFailed = '문자 발송 실패'; + static const String button_openConfigMenu = '설정 열기'; + static const String button_sendMessage = '112 문자보내기'; + static const String errorMessage_unknownError = '알 수 없는 오류가 발생했습니다.'; + + //Permission Error + static const String errorMessage_permissionGallery = '앨범 접근 권한을 허용 해주세요'; static const String errorMessage_locationPermissionForeverDenied = '위치 권한이 거부되었습니다. 설정에서 권한을 허용해주세요.'; static const String errorMessage_locationPermissionDisabled = '위치 서비스가 비활성화되어 있습니다. 설정에서 위치 서비스를 활성화해주세요.'; static const String errorMessage_locationPermissionDenied = '위치 권한이 필요합니다.'; - static const String errorMessage_sendFailed = '문자 발송 실패'; - static const String button_openConfigMenu = '설정 열기'; - static const String button_sendMessage = '112 문자보내기'; - static const String errorMessage_unknownError = '알 수 없는 오류가 발생했습니다.'; } diff --git a/lib/feature/camera/CameraShadow.dart b/lib/utils/ShadowStyle.dart similarity index 88% rename from lib/feature/camera/CameraShadow.dart rename to lib/utils/ShadowStyle.dart index f338dc2d..4d585948 100644 --- a/lib/feature/camera/CameraShadow.dart +++ b/lib/utils/ShadowStyle.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -class CameraShadow extends CustomPainter { +class ShadowStyle extends CustomPainter { final double radius; - CameraShadow({required this.radius}); + ShadowStyle({required this.radius}); @override void paint(Canvas canvas, Size size) { From 09097890b64ca5f045f56fd6566af53467990f39 Mon Sep 17 00:00:00 2001 From: AlphanoJack Date: Sat, 17 Aug 2024 18:10:34 +0900 Subject: [PATCH 2/8] =?UTF-8?q?=EB=A9=94=EC=9D=B4=ED=81=AC=20=EC=95=88?= =?UTF-8?q?=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/camera/provider/PageProvider.dart | 2 +- lib/feature/camera/service/CameraService.dart | 14 ++++---- .../camera/widget/CameraButtonWidget.dart | 2 +- .../widget/CameraErrorMessageWidget.dart | 1 - .../widget/CameraGalleryPageWidget.dart | 3 -- .../camera/widget/CameraPageWidget.dart | 3 -- .../widget/CameraPreviewPageWidget.dart | 33 ++++++++++--------- .../camera/widget/CameraPreviewWidget.dart | 10 +++--- lib/feature/mypage/MyPageScreen.dart | 3 +- .../mypage/widget/MyPageBottomSheet.dart | 4 +-- lib/feature/notice/NoticeScreen.dart | 1 - lib/router/RouterProvider.dart | 2 -- 12 files changed, 35 insertions(+), 43 deletions(-) diff --git a/lib/feature/camera/provider/PageProvider.dart b/lib/feature/camera/provider/PageProvider.dart index c2a76a1a..d6c360e4 100644 --- a/lib/feature/camera/provider/PageProvider.dart +++ b/lib/feature/camera/provider/PageProvider.dart @@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; final pageProvider = -StateNotifierProvider.autoDispose((ref) { + StateNotifierProvider.autoDispose((ref) { return PageProviderNotifier(); }); diff --git a/lib/feature/camera/service/CameraService.dart b/lib/feature/camera/service/CameraService.dart index af1f32bb..ec490e39 100644 --- a/lib/feature/camera/service/CameraService.dart +++ b/lib/feature/camera/service/CameraService.dart @@ -1,4 +1,3 @@ -import 'package:blueberry_flutter_template/feature/camera/widget/CameraPreviewPageWidget.dart'; import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; @@ -10,9 +9,11 @@ class CameraService { CameraController? controller; List cameras = []; bool readyTakePhoto = false; - final ValueNotifier controllerNotifier = ValueNotifier(null); + final ValueNotifier controllerNotifier = + ValueNotifier(null); final ValueNotifier readyTakePhotoNotifier = ValueNotifier(false); - final ValueNotifier cameraDirectionNotifier = ValueNotifier(CameraLensDirection.back); + final ValueNotifier cameraDirectionNotifier = + ValueNotifier(CameraLensDirection.back); Future initializeCameras() async { cameras = await availableCameras(); @@ -30,11 +31,11 @@ class CameraService { CameraDescription newCamera; if (lensDirection == CameraLensDirection.back) { newCamera = cameras.firstWhere( - (camera) => camera.lensDirection == CameraLensDirection.front, + (camera) => camera.lensDirection == CameraLensDirection.front, ); } else { newCamera = cameras.firstWhere( - (camera) => camera.lensDirection == CameraLensDirection.back, + (camera) => camera.lensDirection == CameraLensDirection.back, ); } @@ -67,7 +68,8 @@ class CameraService { void attemptTakePhoto(BuildContext context) async { final String timeInMilli = DateTime.now().millisecondsSinceEpoch.toString(); try { - final path = join((await getTemporaryDirectory()).path, '$timeInMilli.png'); + final path = + join((await getTemporaryDirectory()).path, '$timeInMilli.png'); final XFile file = await controller!.takePicture(); await file.saveTo(path); final File imageFile = File(path); diff --git a/lib/feature/camera/widget/CameraButtonWidget.dart b/lib/feature/camera/widget/CameraButtonWidget.dart index a3816d4f..f725bf98 100644 --- a/lib/feature/camera/widget/CameraButtonWidget.dart +++ b/lib/feature/camera/widget/CameraButtonWidget.dart @@ -36,4 +36,4 @@ class _CameraButtonWidget extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/feature/camera/widget/CameraErrorMessageWidget.dart b/lib/feature/camera/widget/CameraErrorMessageWidget.dart index bbdb2d78..65124814 100644 --- a/lib/feature/camera/widget/CameraErrorMessageWidget.dart +++ b/lib/feature/camera/widget/CameraErrorMessageWidget.dart @@ -1,4 +1,3 @@ - import 'package:blueberry_flutter_template/feature/camera/service/CameraService.dart'; import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:camera/camera.dart'; diff --git a/lib/feature/camera/widget/CameraGalleryPageWidget.dart b/lib/feature/camera/widget/CameraGalleryPageWidget.dart index b3059a46..b9454337 100644 --- a/lib/feature/camera/widget/CameraGalleryPageWidget.dart +++ b/lib/feature/camera/widget/CameraGalleryPageWidget.dart @@ -3,11 +3,8 @@ import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.da import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:photo_manager/photo_manager.dart'; -import 'CameraPreviewPageWidget.dart'; - class CameraGalleryPageWidget extends StatefulWidget { const CameraGalleryPageWidget({super.key}); diff --git a/lib/feature/camera/widget/CameraPageWidget.dart b/lib/feature/camera/widget/CameraPageWidget.dart index 100887b0..628f8b2d 100644 --- a/lib/feature/camera/widget/CameraPageWidget.dart +++ b/lib/feature/camera/widget/CameraPageWidget.dart @@ -4,8 +4,6 @@ import 'package:blueberry_flutter_template/feature/camera/service/CameraService. import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:flutter/material.dart'; - - class CameraPageWidget extends StatefulWidget { const CameraPageWidget({super.key}); @@ -52,4 +50,3 @@ class _ProfileCameraPageState extends State { ); } } - diff --git a/lib/feature/camera/widget/CameraPreviewPageWidget.dart b/lib/feature/camera/widget/CameraPreviewPageWidget.dart index 096e66a6..1d33a7ff 100644 --- a/lib/feature/camera/widget/CameraPreviewPageWidget.dart +++ b/lib/feature/camera/widget/CameraPreviewPageWidget.dart @@ -36,24 +36,25 @@ class CameraPreviewPageWidget extends ConsumerWidget { ); } - TextButton makeProfileImageBtn(FirebaseStorageService storage, String userId, FirestoreService fireStorage, BuildContext context) { + TextButton makeProfileImageBtn(FirebaseStorageService storage, String userId, + FirestoreService fireStorage, BuildContext context) { return TextButton( - onPressed: () async { - try { - final imageUrl = await storage.uploadImageFromApp( - imageFile, ImageType.profileimage, - fixedFileName: userId); + onPressed: () async { + try { + final imageUrl = await storage.uploadImageFromApp( + imageFile, ImageType.profileimage, + fixedFileName: userId); - // 프로필 이미지 생성 - fireStorage.createProfileIamge(userId, imageUrl); + // 프로필 이미지 생성 + fireStorage.createProfileIamge(userId, imageUrl); - // 페이지 이동 - context.goNamed(MyPageScreen.name); - } catch (e) { - talker.error('이미지 저장에 실패했습니다. 다시 시도해주세요.'); - } - }, - child: const Text(AppStrings.savePhoto), - ); + // 페이지 이동 + context.goNamed(MyPageScreen.name); + } catch (e) { + talker.error('이미지 저장에 실패했습니다. 다시 시도해주세요.'); + } + }, + child: const Text(AppStrings.savePhoto), + ); } } diff --git a/lib/feature/camera/widget/CameraPreviewWidget.dart b/lib/feature/camera/widget/CameraPreviewWidget.dart index d5b623af..6d6eada9 100644 --- a/lib/feature/camera/widget/CameraPreviewWidget.dart +++ b/lib/feature/camera/widget/CameraPreviewWidget.dart @@ -9,9 +9,11 @@ class CameraPreviewWidget extends StatelessWidget { final CameraService cameraService; final Size size; - - const CameraPreviewWidget({super.key, required this.cameraService, - required this.size,}); + const CameraPreviewWidget({ + super.key, + required this.cameraService, + required this.size, + }); @override Widget build(BuildContext context) { @@ -72,4 +74,4 @@ class CameraPreviewWidget extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/lib/feature/mypage/MyPageScreen.dart b/lib/feature/mypage/MyPageScreen.dart index 08633d8c..da6519ba 100644 --- a/lib/feature/mypage/MyPageScreen.dart +++ b/lib/feature/mypage/MyPageScreen.dart @@ -53,8 +53,7 @@ class MyPageScreen extends ConsumerWidget { ), const CustomDividerWidget(), GestureDetector( - onTap: () { - }, + onTap: () {}, child: const ListTile( leading: Icon(Icons.person), title: Text( diff --git a/lib/feature/mypage/widget/MyPageBottomSheet.dart b/lib/feature/mypage/widget/MyPageBottomSheet.dart index d7ffc3e3..bc325a83 100644 --- a/lib/feature/mypage/widget/MyPageBottomSheet.dart +++ b/lib/feature/mypage/widget/MyPageBottomSheet.dart @@ -1,6 +1,5 @@ import 'package:blueberry_flutter_template/feature/camera/CameraGalleryScreen.dart'; import 'package:blueberry_flutter_template/feature/camera/CameraScreen.dart'; -import 'package:blueberry_flutter_template/feature/camera/provider/PageProvider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; @@ -10,8 +9,7 @@ class MyPageBottomSheet extends ConsumerStatefulWidget { const MyPageBottomSheet({super.key}); @override - ConsumerState createState() => - _MyPageBottomSheet(); + ConsumerState createState() => _MyPageBottomSheet(); } class _MyPageBottomSheet extends ConsumerState { diff --git a/lib/feature/notice/NoticeScreen.dart b/lib/feature/notice/NoticeScreen.dart index ae621d16..0fe1e626 100644 --- a/lib/feature/notice/NoticeScreen.dart +++ b/lib/feature/notice/NoticeScreen.dart @@ -14,7 +14,6 @@ class _NoticeScreen extends ConsumerState { bool _isWebViewVisible2 = false; late WebViewController _webViewController; - @override void initState() { // TODO: implement initState diff --git a/lib/router/RouterProvider.dart b/lib/router/RouterProvider.dart index d8ff8777..251a8327 100644 --- a/lib/router/RouterProvider.dart +++ b/lib/router/RouterProvider.dart @@ -3,8 +3,6 @@ import 'package:blueberry_flutter_template/feature/admin/AdminScreen.dart'; import 'package:blueberry_flutter_template/feature/admin/AdminUserDetailPage.dart'; import 'package:blueberry_flutter_template/feature/admin/AdminUserListPage.dart'; import 'package:blueberry_flutter_template/feature/camera/CameraGalleryScreen.dart'; -import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; -import 'package:blueberry_flutter_template/feature/camera/widget/CameraPageWidget.dart'; import 'package:blueberry_flutter_template/feature/camera/CameraScreen.dart'; import 'package:blueberry_flutter_template/feature/chat/ChatScreen.dart'; import 'package:blueberry_flutter_template/feature/payment/widget/WebPaymentWidget.dart'; From 85c44d504fdd410370c98fd600e06b2b001bb782 Mon Sep 17 00:00:00 2001 From: AlphanoJack Date: Sat, 17 Aug 2024 18:22:22 +0900 Subject: [PATCH 3/8] =?UTF-8?q?AppString=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/mypage/widget/MyPageBottomSheet.dart | 5 +++-- lib/utils/AppStrings.dart | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/feature/mypage/widget/MyPageBottomSheet.dart b/lib/feature/mypage/widget/MyPageBottomSheet.dart index bc325a83..b1e9ab02 100644 --- a/lib/feature/mypage/widget/MyPageBottomSheet.dart +++ b/lib/feature/mypage/widget/MyPageBottomSheet.dart @@ -1,5 +1,6 @@ import 'package:blueberry_flutter_template/feature/camera/CameraGalleryScreen.dart'; import 'package:blueberry_flutter_template/feature/camera/CameraScreen.dart'; +import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; @@ -56,7 +57,7 @@ class _MyPageBottomSheet extends ConsumerState { Navigator.pop(context); context.goNamed(CameraScreen.name); }, - child: const Text("직접 촬영 하기"), + child: const Text(AppStrings.takePhotoDirectly), ), TextButton( onPressed: () async { @@ -68,7 +69,7 @@ class _MyPageBottomSheet extends ConsumerState { Navigator.pop(context); } }, - child: const Text("앨범에서 선택 하기"), + child: const Text(AppStrings.chooseFromGallery), ) ], ); diff --git a/lib/utils/AppStrings.dart b/lib/utils/AppStrings.dart index 8463e340..2d71b5c4 100644 --- a/lib/utils/AppStrings.dart +++ b/lib/utils/AppStrings.dart @@ -33,6 +33,8 @@ class AppStrings { static const String takeProfilePhoto = 'Take a profile photo'; static const String setBackCamera = '후면 카메라를 불러오는 중 입니다. 잠시만 기다려 주세요'; static const String setFrontCamera = '전면 카메라를 불러오는 중 입니다. 잠시만 기다려 주세요'; + static const String takePhotoDirectly = '직접 촬영 하기'; + static const String chooseFromGallery = '앨범에서 선택하기'; //Save Photo static const String savePhoto = '이미지 저장 하기'; From 6cdff083b9b95e54fd76396b8b84cbe0749cb0b3 Mon Sep 17 00:00:00 2001 From: AlphanoJack Date: Sat, 17 Aug 2024 22:37:24 +0900 Subject: [PATCH 4/8] =?UTF-8?q?=EC=88=98=EC=A0=95=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/camera/CameraScreen.dart | 2 +- lib/feature/camera/service/CameraService.dart | 78 ------------------- 2 files changed, 1 insertion(+), 79 deletions(-) diff --git a/lib/feature/camera/CameraScreen.dart b/lib/feature/camera/CameraScreen.dart index 7c81b61c..88dd012f 100644 --- a/lib/feature/camera/CameraScreen.dart +++ b/lib/feature/camera/CameraScreen.dart @@ -9,4 +9,4 @@ class CameraScreen extends StatelessWidget { Widget build(BuildContext context) { return const CameraPageWidget(); } -} +} \ No newline at end of file diff --git a/lib/feature/camera/service/CameraService.dart b/lib/feature/camera/service/CameraService.dart index ec490e39..d1000ca4 100644 --- a/lib/feature/camera/service/CameraService.dart +++ b/lib/feature/camera/service/CameraService.dart @@ -90,81 +90,3 @@ class CameraService { readyTakePhotoNotifier.dispose(); } } - -// class CameraService { -// CameraController? controller; -// List cameras = []; -// bool _readyTakePhoto = false; -// final bool _changeCamera = false; -// -// -// bool get readyTakePhoto => _readyTakePhoto; -// bool get changeCamera => _changeCamera; -// -// Future initializeCameras() async { -// cameras = await availableCameras(); -// controller = CameraController(cameras[0], ResolutionPreset.high); -// await controller!.initialize(); -// } -// -// Future toggleCamera() async { -// if (cameras.length < 2) return; -// -// final lensDirection = controller!.description.lensDirection; -// CameraDescription newCamera; -// if (lensDirection == CameraLensDirection.back) { -// newCamera = cameras.firstWhere( -// (camera) => camera.lensDirection == CameraLensDirection.front, -// ); -// } else { -// newCamera = cameras.firstWhere( -// (camera) => camera.lensDirection == CameraLensDirection.back, -// ); -// } -// -// await controller?.dispose(); -// controller = CameraController(newCamera, ResolutionPreset.high); -// try { -// await controller!.initialize(); -// _readyTakePhoto = true; -// } catch (e) { -// print("Error toggling camera: $e"); -// _readyTakePhoto = false; -// } -// } -// -// Future takePhoto() async { -// if (controller != null && controller!.value.isInitialized) { -// try { -// final XFile file = await controller!.takePicture(); -// return file; -// } catch (e) { -// print("Error taking photo: $e"); -// return null; -// } -// } -// return null; -// } -// -// void attemptTakePhoto(BuildContext context) async { -// final String timeInMilli = DateTime.now().millisecondsSinceEpoch.toString(); -// try { -// final path = join((await getTemporaryDirectory()).path, '$timeInMilli.png'); -// final XFile file = await controller!.takePicture(); -// await file.saveTo(path); -// final File imageFile = File(path); -// -// if (context.mounted) { -// Navigator.of(context).push( -// MaterialPageRoute(builder: (_) => CameraPreviewScreen(imageFile)), -// ); -// } -// } catch (e) { -// print('Error: $e'); -// } -// } -// -// void dispose() { -// controller!.dispose(); -// } -// } From 4162c457b470dc293dae8950568e9a34623ff3f0 Mon Sep 17 00:00:00 2001 From: AlphanoJack Date: Sat, 17 Aug 2024 22:45:12 +0900 Subject: [PATCH 5/8] =?UTF-8?q?talker=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/camera/service/CameraService.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/feature/camera/service/CameraService.dart b/lib/feature/camera/service/CameraService.dart index d1000ca4..c0d8492a 100644 --- a/lib/feature/camera/service/CameraService.dart +++ b/lib/feature/camera/service/CameraService.dart @@ -1,4 +1,5 @@ import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; +import 'package:blueberry_flutter_template/utils/Talker.dart'; import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'dart:io'; @@ -58,7 +59,7 @@ class CameraService { final XFile file = await controller!.takePicture(); return file; } catch (e) { - print("Error taking photo: $e"); + talker.error("Error taking photo: $e"); return null; } } @@ -80,7 +81,7 @@ class CameraService { ); } } catch (e) { - print('Error: $e'); + talker.error('Error: $e'); } } From aaa607e64aad34da534fd691eb58550cbcdb06da Mon Sep 17 00:00:00 2001 From: AlphanoJack Date: Sat, 17 Aug 2024 23:01:44 +0900 Subject: [PATCH 6/8] =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A6=B0=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/camera/CameraGalleryScreen.dart | 98 ++++++++++++++++- lib/feature/camera/CameraScreen.dart | 49 ++++++++- .../widget/CameraGalleryPageWidget.dart | 103 ------------------ .../camera/widget/CameraPageWidget.dart | 52 --------- lib/feature/login/LoginScreen.dart | 8 +- 5 files changed, 144 insertions(+), 166 deletions(-) delete mode 100644 lib/feature/camera/widget/CameraGalleryPageWidget.dart delete mode 100644 lib/feature/camera/widget/CameraPageWidget.dart diff --git a/lib/feature/camera/CameraGalleryScreen.dart b/lib/feature/camera/CameraGalleryScreen.dart index c29f41e7..9d8971ea 100644 --- a/lib/feature/camera/CameraGalleryScreen.dart +++ b/lib/feature/camera/CameraGalleryScreen.dart @@ -1,12 +1,104 @@ -import 'package:blueberry_flutter_template/feature/camera/widget/CameraGalleryPageWidget.dart'; +import 'dart:io'; +import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; +import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:photo_manager/photo_manager.dart'; -class CameraGalleryScreen extends StatelessWidget { +class CameraGalleryScreen extends StatefulWidget { static const String name = 'CameraGalleryScreen'; const CameraGalleryScreen({super.key}); + @override + State createState() => _CameraGalleryPage(); +} + +class _CameraGalleryPage extends State { + final List _imageList = []; + + int _currentPage = 0; + + final int _pageSize = 50; + + @override + void initState() { + super.initState(); + _fetchImages(); + } + + Future _fetchImages() async { + // 권한 요청 + final PermissionState ps = await PhotoManager.requestPermissionExtend(); + if (ps.isAuth || ps.hasAccess) { + // 안드로이드 일때 ps.hasAccess가 없으면 이미지를 못가져옴 + + // 모든 앨범 가져오기 + final List albums = await PhotoManager.getAssetPathList( + onlyAll: true, + ); + if (albums.isEmpty) return; + + final List images = await albums[0].getAssetListPaged( + page: _currentPage, + size: _pageSize, // 가져올 이미지 수 + ); + + setState(() { + _imageList.addAll(images); + _currentPage++; + }); + } else { + SnackBar snackBar = SnackBar( + content: const Text(AppStrings.errorMessage_permissionGallery), + action: SnackBarAction( + label: 'OK', + onPressed: () { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + PhotoManager.openSetting(); + }, + ), + ); + } + } + + void _navigateToSharePostScreen(File imageFile) { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => CameraPreviewScreen(imageFile), + )); + } + @override Widget build(BuildContext context) { - return const CameraGalleryPageWidget(); + return GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 5, + crossAxisSpacing: 5, + ), + itemCount: _imageList.length, + itemBuilder: (context, index) { + return GestureDetector( + onTap: () async { + final File? imageFile = await _imageList[index].file; + if (imageFile != null) { + _navigateToSharePostScreen(imageFile); + } + }, + child: FutureBuilder( + future: _imageList[index].thumbnailData, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.data != null) { + return Image.memory( + snapshot.data!, + fit: BoxFit.cover, + ); + } + return Container(color: Colors.grey); + }, + ), + ); + }, + ); } } diff --git a/lib/feature/camera/CameraScreen.dart b/lib/feature/camera/CameraScreen.dart index 88dd012f..12954b36 100644 --- a/lib/feature/camera/CameraScreen.dart +++ b/lib/feature/camera/CameraScreen.dart @@ -1,12 +1,53 @@ -import 'package:blueberry_flutter_template/feature/camera/widget/CameraPageWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/widget/CameraButtonWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/widget/CameraPreviewWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/service/CameraService.dart'; +import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:flutter/material.dart'; -class CameraScreen extends StatelessWidget { +class CameraScreen extends StatefulWidget { static const String name = 'CameraScreen'; const CameraScreen({super.key}); + @override + State createState() => _ProfileCameraPageState(); +} + +class _ProfileCameraPageState extends State { + final CameraService cameraService = CameraService(); + + @override + void initState() { + super.initState(); + cameraService.initializeCameras(); + } + + @override + void dispose() { + cameraService.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { - return const CameraPageWidget(); + final size = MediaQuery.of(context).size; + + return Scaffold( + appBar: AppBar( + title: const Text(AppStrings.takeProfilePhoto), + ), + body: Column( + children: [ + CameraPreviewWidget( + cameraService: cameraService, + size: size, + ), + Expanded( + child: CameraButtonWidget( + onTap: () => cameraService.attemptTakePhoto(context), + ), + ), + ], + ), + ); } -} \ No newline at end of file +} diff --git a/lib/feature/camera/widget/CameraGalleryPageWidget.dart b/lib/feature/camera/widget/CameraGalleryPageWidget.dart deleted file mode 100644 index b9454337..00000000 --- a/lib/feature/camera/widget/CameraGalleryPageWidget.dart +++ /dev/null @@ -1,103 +0,0 @@ -import 'dart:io'; -import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; -import 'package:blueberry_flutter_template/utils/AppStrings.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:photo_manager/photo_manager.dart'; - -class CameraGalleryPageWidget extends StatefulWidget { - const CameraGalleryPageWidget({super.key}); - - @override - State createState() => _CameraGalleryPage(); -} - -class _CameraGalleryPage extends State { - final List _imageList = []; - - int _currentPage = 0; - - final int _pageSize = 50; - - @override - void initState() { - super.initState(); - _fetchImages(); - } - - Future _fetchImages() async { - // 권한 요청 - final PermissionState ps = await PhotoManager.requestPermissionExtend(); - if (ps.isAuth || ps.hasAccess) { - // 안드로이드 일때 ps.hasAccess가 없으면 이미지를 못가져옴 - - // 모든 앨범 가져오기 - final List albums = await PhotoManager.getAssetPathList( - onlyAll: true, - ); - if (albums.isEmpty) return; - - final List images = await albums[0].getAssetListPaged( - page: _currentPage, - size: _pageSize, // 가져올 이미지 수 - ); - - setState(() { - _imageList.addAll(images); - _currentPage++; - }); - } else { - SnackBar snackBar = SnackBar( - content: const Text(AppStrings.errorMessage_permissionGallery), - action: SnackBarAction( - label: 'OK', - onPressed: () { - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - PhotoManager.openSetting(); - }, - ), - ); - } - } - - void _navigateToSharePostScreen(File imageFile) { - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => CameraPreviewScreen(imageFile), - )); - } - - @override - Widget build(BuildContext context) { - return GridView.builder( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: 5, - crossAxisSpacing: 5, - ), - itemCount: _imageList.length, - itemBuilder: (context, index) { - return GestureDetector( - onTap: () async { - final File? imageFile = await _imageList[index].file; - if (imageFile != null) { - _navigateToSharePostScreen(imageFile); - } - }, - child: FutureBuilder( - future: _imageList[index].thumbnailData, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done && - snapshot.data != null) { - return Image.memory( - snapshot.data!, - fit: BoxFit.cover, - ); - } - return Container(color: Colors.grey); - }, - ), - ); - }, - ); - } -} diff --git a/lib/feature/camera/widget/CameraPageWidget.dart b/lib/feature/camera/widget/CameraPageWidget.dart deleted file mode 100644 index 628f8b2d..00000000 --- a/lib/feature/camera/widget/CameraPageWidget.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:blueberry_flutter_template/feature/camera/widget/CameraButtonWidget.dart'; -import 'package:blueberry_flutter_template/feature/camera/widget/CameraPreviewWidget.dart'; -import 'package:blueberry_flutter_template/feature/camera/service/CameraService.dart'; -import 'package:blueberry_flutter_template/utils/AppStrings.dart'; -import 'package:flutter/material.dart'; - -class CameraPageWidget extends StatefulWidget { - const CameraPageWidget({super.key}); - - @override - State createState() => _ProfileCameraPageState(); -} - -class _ProfileCameraPageState extends State { - final CameraService cameraService = CameraService(); - - @override - void initState() { - super.initState(); - cameraService.initializeCameras(); - } - - @override - void dispose() { - cameraService.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final size = MediaQuery.of(context).size; - - return Scaffold( - appBar: AppBar( - title: const Text(AppStrings.takeProfilePhoto), - ), - body: Column( - children: [ - CameraPreviewWidget( - cameraService: cameraService, - size: size, - ), - Expanded( - child: CameraButtonWidget( - onTap: () => cameraService.attemptTakePhoto(context), - ), - ), - ], - ), - ); - } -} diff --git a/lib/feature/login/LoginScreen.dart b/lib/feature/login/LoginScreen.dart index c3b30629..abf4642e 100644 --- a/lib/feature/login/LoginScreen.dart +++ b/lib/feature/login/LoginScreen.dart @@ -1,4 +1,4 @@ -import 'package:blueberry_flutter_template/feature/camera/widget/CameraPageWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/CameraScreen.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; @@ -7,7 +7,7 @@ import '../../core/widget/SquareTitleWidget.dart'; import '../../services/FirebaseAuthServiceProvider.dart'; import '../../services/SocialAuthService.dart'; import '../../utils/AppStrings.dart'; -import '../camera/widget/CameraGalleryPageWidget.dart'; +import '../camera/CameraGalleryScreen.dart'; import '../camera/provider/PageProvider.dart'; import '../mypage/MyPageScreen.dart'; import '../signup/SignUpScreen.dart'; @@ -44,8 +44,8 @@ class LoginScreen extends ConsumerWidget { physics: const NeverScrollableScrollPhysics(), children: const [ MyPageScreen(), - CameraPageWidget(), - CameraGalleryPageWidget(), + CameraScreen(), + CameraGalleryScreen(), ]) : _buildLogin(context, ref), orElse: () => const Center(child: CircularProgressIndicator()), From deac0c313e7b7521e11b053c3747d8e88d2235fa Mon Sep 17 00:00:00 2001 From: AlphanoJack Date: Sat, 17 Aug 2024 23:07:15 +0900 Subject: [PATCH 7/8] =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=B5=9C=EC=A2=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/camera/CameraGalleryScreen.dart | 4 ++-- lib/feature/camera/CameraPreviewScreen.dart | 13 ------------- ...iewPageWidget.dart => ProfilePreviewScreen.dart} | 10 +++++----- lib/feature/camera/service/CameraService.dart | 5 +++-- ....dart => CircularProfileImagePreviewWidget.dart} | 4 ++-- 5 files changed, 12 insertions(+), 24 deletions(-) delete mode 100644 lib/feature/camera/CameraPreviewScreen.dart rename lib/feature/camera/{widget/CameraPreviewPageWidget.dart => ProfilePreviewScreen.dart} (86%) rename lib/feature/camera/widget/{CircularImagePreviewWidget.dart => CircularProfileImagePreviewWidget.dart} (69%) diff --git a/lib/feature/camera/CameraGalleryScreen.dart b/lib/feature/camera/CameraGalleryScreen.dart index 9d8971ea..45b6e217 100644 --- a/lib/feature/camera/CameraGalleryScreen.dart +++ b/lib/feature/camera/CameraGalleryScreen.dart @@ -1,5 +1,5 @@ import 'dart:io'; -import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; +import 'package:blueberry_flutter_template/feature/camera/ProfilePreviewScreen.dart'; import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -63,7 +63,7 @@ class _CameraGalleryPage extends State { void _navigateToSharePostScreen(File imageFile) { Navigator.of(context).push(MaterialPageRoute( - builder: (context) => CameraPreviewScreen(imageFile), + builder: (context) => ProfilePreviewScreen(imageFile), )); } diff --git a/lib/feature/camera/CameraPreviewScreen.dart b/lib/feature/camera/CameraPreviewScreen.dart deleted file mode 100644 index cde3abbc..00000000 --- a/lib/feature/camera/CameraPreviewScreen.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:blueberry_flutter_template/feature/camera/widget/CameraPreviewPageWidget.dart'; -import 'package:flutter/material.dart'; -import 'dart:io'; - -class CameraPreviewScreen extends StatelessWidget { - final File imageFile; - const CameraPreviewScreen(this.imageFile, {super.key}); - - @override - Widget build(BuildContext context) { - return CameraPreviewPageWidget(imageFile: imageFile); - } -} diff --git a/lib/feature/camera/widget/CameraPreviewPageWidget.dart b/lib/feature/camera/ProfilePreviewScreen.dart similarity index 86% rename from lib/feature/camera/widget/CameraPreviewPageWidget.dart rename to lib/feature/camera/ProfilePreviewScreen.dart index 1d33a7ff..bf21ded0 100644 --- a/lib/feature/camera/widget/CameraPreviewPageWidget.dart +++ b/lib/feature/camera/ProfilePreviewScreen.dart @@ -1,6 +1,6 @@ import 'dart:io'; import 'package:blueberry_flutter_template/feature/camera/provider/fireStorageServiceProvider.dart'; -import 'package:blueberry_flutter_template/feature/camera/widget/CircularImagePreviewWidget.dart'; +import 'package:blueberry_flutter_template/feature/camera/widget/CircularProfileImagePreviewWidget.dart'; import 'package:blueberry_flutter_template/feature/mypage/MyPageScreen.dart'; import 'package:blueberry_flutter_template/utils/AppStrings.dart'; import 'package:blueberry_flutter_template/utils/Talker.dart'; @@ -8,12 +8,12 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; -import '../../../services/FirebaseStoreServiceProvider.dart'; +import '../../services/FirebaseStoreServiceProvider.dart'; -class CameraPreviewPageWidget extends ConsumerWidget { +class ProfilePreviewScreen extends ConsumerWidget { final File imageFile; - const CameraPreviewPageWidget({super.key, required this.imageFile}); + const ProfilePreviewScreen(this.imageFile, {super.key}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -28,7 +28,7 @@ class CameraPreviewPageWidget extends ConsumerWidget { body: Center( child: Column( children: [ - CircularImagePreview(imageFile: imageFile), + CircularProfileImagePreviewWidget(imageFile: imageFile), makeProfileImageBtn(storage, userId, fireStorage, context), ], ), diff --git a/lib/feature/camera/service/CameraService.dart b/lib/feature/camera/service/CameraService.dart index c0d8492a..906947c1 100644 --- a/lib/feature/camera/service/CameraService.dart +++ b/lib/feature/camera/service/CameraService.dart @@ -1,4 +1,5 @@ -import 'package:blueberry_flutter_template/feature/camera/CameraPreviewScreen.dart'; + +import 'package:blueberry_flutter_template/feature/camera/ProfilePreviewScreen.dart'; import 'package:blueberry_flutter_template/utils/Talker.dart'; import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; @@ -77,7 +78,7 @@ class CameraService { if (context.mounted) { Navigator.of(context).push( - MaterialPageRoute(builder: (_) => CameraPreviewScreen(imageFile)), + MaterialPageRoute(builder: (_) => ProfilePreviewScreen(imageFile)), ); } } catch (e) { diff --git a/lib/feature/camera/widget/CircularImagePreviewWidget.dart b/lib/feature/camera/widget/CircularProfileImagePreviewWidget.dart similarity index 69% rename from lib/feature/camera/widget/CircularImagePreviewWidget.dart rename to lib/feature/camera/widget/CircularProfileImagePreviewWidget.dart index 6d915266..704b3ff9 100644 --- a/lib/feature/camera/widget/CircularImagePreviewWidget.dart +++ b/lib/feature/camera/widget/CircularProfileImagePreviewWidget.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'dart:io'; -class CircularImagePreview extends StatelessWidget { +class CircularProfileImagePreviewWidget extends StatelessWidget { final File imageFile; - const CircularImagePreview({super.key, required this.imageFile}); + const CircularProfileImagePreviewWidget({super.key, required this.imageFile}); @override Widget build(BuildContext context) { From d481ee9dd63fef63b6bf36b3b3e165870e718246 Mon Sep 17 00:00:00 2001 From: AlphanoJack <119755459+AlphanoJack@users.noreply.github.com> Date: Sat, 17 Aug 2024 23:56:00 +0900 Subject: [PATCH 8/8] Update RouterProvider.dart --- lib/router/RouterProvider.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/router/RouterProvider.dart b/lib/router/RouterProvider.dart index db8efa76..152355eb 100644 --- a/lib/router/RouterProvider.dart +++ b/lib/router/RouterProvider.dart @@ -160,11 +160,12 @@ final routerProvider = Provider((ref) { builder: (context, state) => ResponsiveLayoutBuilder(context, const CameraGalleryScreen()), ), + GoRoute( path: 'restoredeleteduser', name: RestoreDeletedUserScreen.name, builder: (context, state) => ResponsiveLayoutBuilder( context, const RestoreDeletedUserScreen()), - ) + ), ], ), ],