From ef08923b5be3dafb45d1ff140ce85bc299a848a1 Mon Sep 17 00:00:00 2001 From: boring-km Date: Tue, 31 Oct 2023 21:31:44 +0900 Subject: [PATCH 01/48] [feat] splash_view refactoring --- lib/cubits/folders/get_my_folders_cubit.dart | 7 +- lib/cubits/login/auto_login_cubit.dart | 29 +++++++ lib/di/set_up_get_it.dart | 10 +-- lib/provider/tutorial_provider.dart | 16 ++++ lib/ui/view/splash_view.dart | 86 +++++++++----------- pubspec.yaml | 10 +-- 6 files changed, 97 insertions(+), 61 deletions(-) create mode 100644 lib/cubits/login/auto_login_cubit.dart create mode 100644 lib/provider/tutorial_provider.dart diff --git a/lib/cubits/folders/get_my_folders_cubit.dart b/lib/cubits/folders/get_my_folders_cubit.dart index c3628e42..d1c5f84d 100644 --- a/lib/cubits/folders/get_my_folders_cubit.dart +++ b/lib/cubits/folders/get_my_folders_cubit.dart @@ -24,8 +24,7 @@ class GetFoldersCubit extends Cubit { try { emit(FolderLoadingState()); - final result = await folderApi.getMyFolders(); - result.when( + (await folderApi.getMyFolders()).when( success: (list) { folders = list; emit(FolderLoadedState(folders)); @@ -41,8 +40,7 @@ class GetFoldersCubit extends Cubit { try { emit(FolderLoadingState()); - final result = await folderApi.getMyFoldersWithoutUnclassified(); - result.when( + (await folderApi.getMyFoldersWithoutUnclassified()).when( success: (list) { folders = list; emit(FolderLoadedState(folders)); @@ -78,7 +76,6 @@ class GetFoldersCubit extends Cubit { void filter(String name) { if (name.isEmpty) { emit(FolderLoadedState(folders)); - return; } else { final filtered = []; diff --git a/lib/cubits/login/auto_login_cubit.dart b/lib/cubits/login/auto_login_cubit.dart new file mode 100644 index 00000000..0424e61d --- /dev/null +++ b/lib/cubits/login/auto_login_cubit.dart @@ -0,0 +1,29 @@ +import 'package:ac_project_app/cubits/login/login_user_state.dart'; +import 'package:ac_project_app/di/set_up_get_it.dart'; +import 'package:ac_project_app/provider/api/user/user_api.dart'; +import 'package:ac_project_app/provider/share_data_provider.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class AutoLoginCubit extends Cubit { + AutoLoginCubit() : super(LoginInitialState()); + + void userCheck() { + final user = FirebaseAuth.instance.currentUser; + if (user != null) { + getIt().postUsers().then((result) { + result.when( + success: (data) { + if (data.is_new ?? false) { + emit(LoginInitialState()); + } else { + ShareDataProvider.loadServerDataAtFirst(); + emit(LoginLoadedState(data)); + } + }, + error: (_) => emit(LoginInitialState()), + ); + }); + } + } +} diff --git a/lib/di/set_up_get_it.dart b/lib/di/set_up_get_it.dart index 00e74c79..9df89810 100644 --- a/lib/di/set_up_get_it.dart +++ b/lib/di/set_up_get_it.dart @@ -1,4 +1,5 @@ import 'package:ac_project_app/cubits/folders/get_user_folders_cubit.dart'; +import 'package:ac_project_app/cubits/login/auto_login_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_info_cubit.dart'; import 'package:ac_project_app/provider/api/custom_client.dart'; import 'package:ac_project_app/provider/api/folders/folder_api.dart'; @@ -20,11 +21,10 @@ void locator() { ..registerLazySingleton(() => LinkApi(httpClient)) ..registerLazySingleton(() => ReportApi(httpClient)) ..registerLazySingleton(() => ProfileApi(httpClient)) - ..registerLazySingleton(() => UserApi(httpClient)); - + ..registerLazySingleton(() => UserApi(httpClient)) // Cubits - final profileCubit = GetProfileInfoCubit(); - getIt..registerLazySingleton(GetUserFoldersCubit.new) - ..registerLazySingleton(() => profileCubit); + ..registerLazySingleton(GetUserFoldersCubit.new) + ..registerLazySingleton(GetProfileInfoCubit.new) + ..registerLazySingleton(AutoLoginCubit.new); } diff --git a/lib/provider/tutorial_provider.dart b/lib/provider/tutorial_provider.dart new file mode 100644 index 00000000..183479f0 --- /dev/null +++ b/lib/provider/tutorial_provider.dart @@ -0,0 +1,16 @@ +import 'package:shared_preferences/shared_preferences.dart'; + +void checkTutorial2({ + required void Function() onMoveToTutorialView, + required void Function() onMoveToNextView, +}) { + SharedPreferences.getInstance().then((SharedPreferences prefs) { + final tutorial = prefs.getBool('tutorial2') ?? false; + if (tutorial) { + prefs.setBool('tutorial2', false); + onMoveToTutorialView(); + } else { + onMoveToNextView(); + } + }); +} diff --git a/lib/ui/view/splash_view.dart b/lib/ui/view/splash_view.dart index 48d3e90a..c8575e85 100644 --- a/lib/ui/view/splash_view.dart +++ b/lib/ui/view/splash_view.dart @@ -1,17 +1,16 @@ import 'dart:async'; import 'package:ac_project_app/const/colors.dart'; +import 'package:ac_project_app/cubits/login/auto_login_cubit.dart'; +import 'package:ac_project_app/cubits/login/login_user_state.dart'; import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; -import 'package:ac_project_app/provider/api/user/user_api.dart'; -import 'package:ac_project_app/provider/share_data_provider.dart'; +import 'package:ac_project_app/provider/tutorial_provider.dart'; import 'package:ac_project_app/routes.dart'; -import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:shared_preferences/shared_preferences.dart'; class SplashView extends StatefulWidget { const SplashView({super.key}); @@ -24,51 +23,36 @@ class _SplashViewState extends State with TickerProviderStateMixin { late AnimationController firstAnimationController; late AnimationController secondAnimationController; + final autoLoginCubit = getIt(); + @override void initState() { + autoLoginCubit.userCheck(); setAnimationController(); - _loginAfterAnimation(); + loginAfterAnimation(); super.initState(); } - void _loginAfterAnimation() { + void loginAfterAnimation() { Future.delayed(const Duration(milliseconds: 1500), () { - SharedPreferences.getInstance().then((SharedPreferences prefs) { - final tutorial = prefs.getBool('tutorial2') ?? false; - if (tutorial) { - prefs.setBool('tutorial2', false); - moveToTutorialView(); - } else { - moveToNextView(); - } - }); + checkTutorial2( + onMoveToTutorialView: moveToTutorialView, + onMoveToNextView: moveToNextView, + ); }); } void moveToNextView() { - final user = FirebaseAuth.instance.currentUser; - if (user != null) { - getIt().postUsers().then((result) { - result.when( - success: (data) { - if (data.is_new ?? false) { - moveToLoginView(); - } else { - ShareDataProvider.loadServerDataAtFirst(); - Navigator.pushReplacementNamed( - context, - Routes.home, - arguments: { - 'index': 0, - }, - ); - } - }, - error: (_) => moveToLoginView(), - ); - }); - } else { + if (autoLoginCubit.state is LoginInitialState) { moveToLoginView(); + } else { + Navigator.pushReplacementNamed( + context, + Routes.home, + arguments: { + 'index': 0, + }, + ); } } @@ -79,26 +63,36 @@ class _SplashViewState extends State with TickerProviderStateMixin { Navigator.pushReplacementNamed(context, Routes.tutorial); void setAnimationController() { - firstAnimationController = AnimationController( + setFirstAnimationController(); + setSecondAnimationController(); + firstAnimationController.forward(); + forwardSecondAnimationAfter300mills(); + secondAnimationController.forward(); + } + + void forwardSecondAnimationAfter300mills() { + Timer( + const Duration(milliseconds: 300), + () => secondAnimationController.forward(), + ); + } + + void setSecondAnimationController() { + secondAnimationController = AnimationController( vsync: this, duration: const Duration( milliseconds: 700, ), ); + } - secondAnimationController = AnimationController( + void setFirstAnimationController() { + firstAnimationController = AnimationController( vsync: this, duration: const Duration( milliseconds: 700, ), ); - - firstAnimationController.forward(); - Timer( - const Duration(milliseconds: 300), - () => secondAnimationController.forward(), - ); - secondAnimationController.forward(); } @override diff --git a/pubspec.yaml b/pubspec.yaml index fe339f28..f0517caa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,15 +28,15 @@ dependencies: ## login sign_in_with_apple: ^5.0.0 google_sign_in: ^6.1.5 - firebase_core: ^2.17.0 - firebase_auth: ^4.10.1 - firebase_dynamic_links: ^5.3.7 + firebase_core: ^2.20.0 + firebase_auth: ^4.12.0 + firebase_dynamic_links: ^5.4.2 kakao_flutter_sdk_user: ^1.6.1 flutter_dotenv: ^5.0.2 flutter_naver_login: ^1.8.0 - firebase_auth_mocks: ^0.11.0 + firebase_auth_mocks: ^0.13.0 ## UI Sizer flutter_screenutil: ^5.7.0 @@ -58,7 +58,7 @@ dependencies: carousel_slider: ^4.2.1 lottie: flutter_slidable: ^2.0.0 - firebase_storage: ^11.2.6 + firebase_storage: ^11.4.0 ## lint very_good_analysis: ^4.0.0+1 From 1230b4fbea6ebad43aa2369250a721ead8c7f0bd Mon Sep 17 00:00:00 2001 From: boring-km Date: Fri, 10 Nov 2023 23:56:23 +0900 Subject: [PATCH 02/48] =?UTF-8?q?[feat]=20=ED=99=88=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=81=B4=EB=A6=BD=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20?= =?UTF-8?q?=EA=B1=B8=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes.dart | 2 +- lib/ui/view/home_view.dart | 21 +++++++++++++++- lib/ui/view/upload_view.dart | 47 ++++++------------------------------ 3 files changed, 29 insertions(+), 41 deletions(-) diff --git a/lib/routes.dart b/lib/routes.dart index 5b6afac9..6188a5a8 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -74,7 +74,7 @@ class Pages { case Routes.report: return router.create(child: const ReportView()); case Routes.upload: - return router.create(child: const UploadView()); + return router.create(child: UploadView(args: arguments as Map?)); case Routes.tutorial: return router.create(child: const TutorialView()); default: diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index 13aae0e7..8d8010f3 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -10,11 +10,14 @@ import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/provider/api/folders/folder_api.dart'; import 'package:ac_project_app/provider/kakao/kakao.dart'; +import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/page/home/home_page.dart'; import 'package:ac_project_app/ui/page/my_folder/my_folder_page.dart'; import 'package:ac_project_app/ui/page/my_page/my_page.dart'; import 'package:ac_project_app/util/get_arguments.dart'; +import 'package:ac_project_app/util/url_valid.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -41,6 +44,7 @@ class _HomeViewState extends State with WidgetsBindingObserver { if (!mounted) return; Kakao.receiveLink(context, url: url); }); + checkClipboardLink(); super.initState(); } @@ -54,11 +58,26 @@ class _HomeViewState extends State with WidgetsBindingObserver { void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { getIt().bulkSave(); - Kakao.receiveLink(context); } } + void checkClipboardLink() { + Clipboard.getData(Clipboard.kTextPlain).then((value) { + isValidUrl(value?.text ?? '').then((isValid) { + if (isValid) { + Navigator.pushNamed( + context, + Routes.upload, + arguments: { + 'url': value?.text, + }, + ); + } + }); + }); + } + @override Widget build(BuildContext context) { final args = getArguments(context); diff --git a/lib/ui/view/upload_view.dart b/lib/ui/view/upload_view.dart index dafbad1a..855bebd4 100644 --- a/lib/ui/view/upload_view.dart +++ b/lib/ui/view/upload_view.dart @@ -18,7 +18,6 @@ import 'package:ac_project_app/ui/widget/buttons/bottom_sheet_button.dart'; import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; import 'package:ac_project_app/ui/widget/loading.dart'; import 'package:ac_project_app/util/get_arguments.dart'; -import 'package:ac_project_app/util/url_valid.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -27,13 +26,15 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; class UploadView extends StatefulWidget { - const UploadView({super.key}); + const UploadView({super.key, this.args}); + + final Map? args; @override State createState() => _UploadViewState(); } -class _UploadViewState extends State with WidgetsBindingObserver { +class _UploadViewState extends State { final linkTextController = TextEditingController(); final commentTextController = TextEditingController(); @@ -48,51 +49,19 @@ class _UploadViewState extends State with WidgetsBindingObserver { @override void initState() { - WidgetsBinding.instance.addObserver(this); - setClipboardUrl(); - super.initState(); - } - - @override - void dispose() { - WidgetsBinding.instance.removeObserver(this); - super.dispose(); - } - - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.resumed) { - setClipboardUrl(); + if (widget.args != null) { + linkTextController.text = widget.args!['url'] as String; + buttonState = ButtonState.enabled; } - } - - // 클립보드에 링크 있으면 불러오기 - void setClipboardUrl() { - Clipboard.getData(Clipboard.kTextPlain).then((value) { - isValidUrl(value?.text ?? '').then((result) { - if (result) { - setState(() { - linkTextController.text = value?.text ?? ''; - buttonState = ButtonState.enabled; - }); - } - }); - }); + super.initState(); } @override Widget build(BuildContext context) { final args = getArguments(context); - final url = args['url'] as String? ?? ''; - if (url.isNotEmpty) { - linkTextController.text = url; - } return MultiBlocProvider( providers: [ - BlocProvider( - create: (_) => HomeViewCubit((args['index'] as int?) ?? 0), - ), BlocProvider( create: (_) => GetFoldersCubit(excludeUnclassified: true), ), From 1a37cd7d407ce1e0053c65a9d0a4fc95265fa0b0 Mon Sep 17 00:00:00 2001 From: boring-km Date: Sat, 11 Nov 2023 00:04:17 +0900 Subject: [PATCH 03/48] [version] 1.0.50 update --- .github/workflows/cicd.yml | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index a19bda2d..f758d4b5 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.13.6' + flutter-version: '3.13.9' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.13.6' + flutter-version: '3.13.9' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/pubspec.yaml b/pubspec.yaml index f0517caa..72102f9c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.49+49 +version: 1.0.50+50 environment: sdk: ">=3.0.0 <4.0.0" From fbd887d238245138830dc5b3baf1f7df49e748b5 Mon Sep 17 00:00:00 2001 From: boring-km Date: Tue, 14 Nov 2023 14:34:04 +0900 Subject: [PATCH 04/48] =?UTF-8?q?[feat]=20=ED=81=B4=EB=A6=BD=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EB=A7=81=ED=81=AC=EB=A5=BC=20=ED=99=88=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=8F=8C=EC=95=84=EC=98=AC=20=EB=95=8C=EB=A7=88?= =?UTF-8?q?=EB=8B=A4=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ui/view/home_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index 8d8010f3..b21e026f 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -44,7 +44,6 @@ class _HomeViewState extends State with WidgetsBindingObserver { if (!mounted) return; Kakao.receiveLink(context, url: url); }); - checkClipboardLink(); super.initState(); } @@ -59,6 +58,7 @@ class _HomeViewState extends State with WidgetsBindingObserver { if (state == AppLifecycleState.resumed) { getIt().bulkSave(); Kakao.receiveLink(context); + checkClipboardLink(); } } From 2077cc40e9aceac7bb622a8822febb237a1506bd Mon Sep 17 00:00:00 2001 From: boring-km Date: Tue, 14 Nov 2023 23:05:01 +0900 Subject: [PATCH 05/48] [version] 1.0.51 update --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 72102f9c..4240ed10 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.50+50 +version: 1.0.51+51 environment: sdk: ">=3.0.0 <4.0.0" From 11f2c549fbdf7c743f9c59c304be791b8df68e41 Mon Sep 17 00:00:00 2001 From: boring-km Date: Tue, 14 Nov 2023 23:52:31 +0900 Subject: [PATCH 06/48] =?UTF-8?q?[fix]=201.0.51=20-=20=ED=81=B4=EB=A6=BD?= =?UTF-8?q?=EB=B3=B4=EB=93=9C=EC=97=90=EC=84=9C=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=ED=95=9C=20url=EC=9D=84=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=A9=B4?= =?UTF-8?q?=20=ED=81=B4=EB=A6=BD=EB=B3=B4=EB=93=9C=20=EB=B9=84=EC=9A=B0?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ui/view/home_view.dart | 16 ++++++++++++++-- lib/ui/view/upload_view.dart | 4 ---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index b21e026f..1214d0e0 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -53,19 +53,24 @@ class _HomeViewState extends State with WidgetsBindingObserver { super.dispose(); } + final resumeState = ValueNotifier(true); + @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { + if (!resumeState.value) return; + resetResumeState(); getIt().bulkSave(); Kakao.receiveLink(context); - checkClipboardLink(); + navigateToUploadViewIfClipboardIsValid(); } } - void checkClipboardLink() { + void navigateToUploadViewIfClipboardIsValid() { Clipboard.getData(Clipboard.kTextPlain).then((value) { isValidUrl(value?.text ?? '').then((isValid) { if (isValid) { + Clipboard.setData(const ClipboardData(text: '')); Navigator.pushNamed( context, Routes.upload, @@ -78,6 +83,13 @@ class _HomeViewState extends State with WidgetsBindingObserver { }); } + void resetResumeState() { + resumeState.value = false; + Future.delayed(const Duration(seconds: 3), () { + resumeState.value = true; + }); + } + @override Widget build(BuildContext context) { final args = getArguments(context); diff --git a/lib/ui/view/upload_view.dart b/lib/ui/view/upload_view.dart index 855bebd4..5c64a1b7 100644 --- a/lib/ui/view/upload_view.dart +++ b/lib/ui/view/upload_view.dart @@ -4,7 +4,6 @@ import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/const/strings.dart'; import 'package:ac_project_app/cubits/folders/folders_state.dart'; import 'package:ac_project_app/cubits/folders/get_my_folders_cubit.dart'; -import 'package:ac_project_app/cubits/home_view_cubit.dart'; import 'package:ac_project_app/cubits/links/upload_link_cubit.dart'; import 'package:ac_project_app/cubits/links/upload_result_state.dart'; import 'package:ac_project_app/cubits/sign_up/button_state_cubit.dart'; @@ -17,7 +16,6 @@ import 'package:ac_project_app/ui/widget/add_folder/subtitle.dart'; import 'package:ac_project_app/ui/widget/buttons/bottom_sheet_button.dart'; import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; import 'package:ac_project_app/ui/widget/loading.dart'; -import 'package:ac_project_app/util/get_arguments.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -58,8 +56,6 @@ class _UploadViewState extends State { @override Widget build(BuildContext context) { - final args = getArguments(context); - return MultiBlocProvider( providers: [ BlocProvider( From 90da171aaab9bc2fd1726d54802b7804db8e57a0 Mon Sep 17 00:00:00 2001 From: boring-km Date: Mon, 12 Feb 2024 12:08:24 +0900 Subject: [PATCH 07/48] =?UTF-8?q?[fix]=20=EB=94=94=EC=9E=90=EC=9D=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Base.lproj/MainInterface.storyboard | 6 +- ios/Flutter/AppFrameworkInfo.plist | 2 +- ios/Podfile | 2 +- lib/main.dart | 5 + lib/ui/page/home/home_page.dart | 126 ------------------ lib/ui/view/links/my_link_view.dart | 5 +- lib/ui/view/links/user_feed_view.dart | 6 +- lib/ui/view/user/login_view.dart | 2 + lib/ui/view/user/sign_up_job_view.dart | 1 + .../widget/buttons/bottom_sheet_button.dart | 2 + lib/ui/widget/user/user_info.dart | 49 +------ pubspec.yaml | 14 +- 12 files changed, 32 insertions(+), 188 deletions(-) diff --git a/ios/Extension/Base.lproj/MainInterface.storyboard b/ios/Extension/Base.lproj/MainInterface.storyboard index 24590515..edc59982 100644 --- a/ios/Extension/Base.lproj/MainInterface.storyboard +++ b/ios/Extension/Base.lproj/MainInterface.storyboard @@ -1,9 +1,9 @@ - + - + @@ -718,6 +718,7 @@ + @@ -742,7 +743,6 @@ - diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 9625e105..7c569640 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/ios/Podfile b/ios/Podfile index 271f8bb9..c8de1c42 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '11.0' +# platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. diff --git a/lib/main.dart b/lib/main.dart index 05f7c274..3788a6c2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -51,6 +51,11 @@ class MyApp extends StatelessWidget { theme: ThemeData( fontFamily: FontFamily.pretendard, brightness: Brightness.light, + textButtonTheme: TextButtonThemeData( + style: ButtonStyle( + foregroundColor: MaterialStateProperty.all(Colors.white), + ), + ), progressIndicatorTheme: const ProgressIndicatorThemeData( color: primary600, ), diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index e53767b2..cc284882 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -8,15 +8,11 @@ import 'package:ac_project_app/cubits/links/links_from_selected_job_group_cubit. import 'package:ac_project_app/cubits/profile/profile_info_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_state.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; -import 'package:ac_project_app/gen/fonts.gen.dart'; import 'package:ac_project_app/models/link/link.dart'; -import 'package:ac_project_app/models/user/detail_user.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/widget/dialog/bottom_dialog.dart'; import 'package:ac_project_app/ui/widget/link_hero.dart'; -import 'package:ac_project_app/ui/widget/sliver/custom_header_delegate.dart'; import 'package:ac_project_app/ui/widget/user/user_info.dart'; -import 'package:ac_project_app/util/list_utils.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; @@ -92,10 +88,6 @@ class HomePage extends StatelessWidget { ), ), ), - buildJobListView( - jobContext, - state.jobs.sortMyJobs(profileState.profile), - ), buildListBody(jobContext), ], ), @@ -345,124 +337,6 @@ class HomePage extends StatelessWidget { totalLinks.addAll(links); } - Widget buildJobListView( - BuildContext jobContext, - List jobs, - ) { - return SliverPersistentHeader( - pinned: true, - delegate: CustomHeaderDelegate( - buildJobListWidget(jobContext, jobs), - ), - ); - } - - Widget buildJobListWidget(BuildContext jobContext, List jobs) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - color: Colors.white, - padding: EdgeInsets.only(top: 19.h, left: 12.w, right: 20.w), - child: DefaultTabController( - length: jobs.length, - child: SizedBox( - height: 36.h, - child: Stack( - children: [ - Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: EdgeInsets.only( - left: 15.w, - right: 11.w, - bottom: 1.h, - ), - child: Row( - children: [ - Expanded( - child: Container( - color: greyTab, - height: 1.h, - ), - ), - ], - ), - ), - ), - Container( - margin: EdgeInsets.only(right: 7.w), - child: Builder( - builder: (context) { - final tabs = []; - for (final job in jobs) { - tabs.add( - Padding( - padding: EdgeInsets.symmetric( - vertical: 7.h, - ), - child: Text( - job.name ?? '', - ), - ), - ); - } - return TabBar( - isScrollable: true, - unselectedLabelColor: grey700, - labelColor: primaryTab, - labelPadding: EdgeInsets.symmetric(horizontal: 13.w), - labelStyle: TextStyle( - fontFamily: FontFamily.pretendard, - fontSize: 16.sp, - height: (19 / 16).h, - fontWeight: FontWeight.w800, - ), - unselectedLabelStyle: TextStyle( - fontFamily: FontFamily.pretendard, - fontSize: 16.sp, - height: (19 / 16).h, - fontWeight: FontWeight.bold, - ), - indicator: UnderlineTabIndicator( - borderSide: BorderSide( - color: primaryTab, - width: 2.5.w, - ), - insets: EdgeInsets.symmetric(horizontal: 15.w), - ), - tabs: tabs, - onTap: (index) { - jobContext - .read() - .hasLoadMore = false; - final selectedJobGroupId = jobs[index].id!; - jobContext - .read() - .clear(); - jobContext - .read() - .getSelectedJobLinks(selectedJobGroupId, 0) - .then( - (value) => jobContext - .read() - .scrollController - .jumpTo(0), - ); - }, - ); - }, - ), - ), - ], - ), - ), - ), - ), - ], - ); - } - Future refresh(BuildContext context) async { context.read().refresh(); } diff --git a/lib/ui/view/links/my_link_view.dart b/lib/ui/view/links/my_link_view.dart index 857a23fe..5f49a9b0 100644 --- a/lib/ui/view/links/my_link_view.dart +++ b/lib/ui/view/links/my_link_view.dart @@ -396,6 +396,7 @@ class MyLinkView extends StatelessWidget { return TabBar( isScrollable: true, physics: const ClampingScrollPhysics(), + tabAlignment: TabAlignment.start, unselectedLabelColor: grey700, labelColor: primaryTab, labelStyle: TextStyle( @@ -415,10 +416,6 @@ class MyLinkView extends StatelessWidget { color: primaryTab, width: 2.5.w, ), - insets: EdgeInsets.only( - left: 15.w, - right: 15.w, - ), ), labelPadding: EdgeInsets.symmetric(horizontal: 13.w), tabs: tabs, diff --git a/lib/ui/view/links/user_feed_view.dart b/lib/ui/view/links/user_feed_view.dart index 0cbeebb2..ed74675d 100644 --- a/lib/ui/view/links/user_feed_view.dart +++ b/lib/ui/view/links/user_feed_view.dart @@ -260,7 +260,9 @@ class UserFeedView extends StatelessWidget { ); } return TabBar( + padding: EdgeInsets.zero, isScrollable: true, + tabAlignment: TabAlignment.start, unselectedLabelColor: lightGrey700, labelColor: primaryTab, labelStyle: TextStyle( @@ -280,10 +282,6 @@ class UserFeedView extends StatelessWidget { color: primaryTab, width: 2.5.w, ), - insets: EdgeInsets.only( - left: 15.w, - right: 15.w, - ), ), tabs: tabs, onTap: (index) { diff --git a/lib/ui/view/user/login_view.dart b/lib/ui/view/user/login_view.dart index a20684dc..59a78ed9 100644 --- a/lib/ui/view/user/login_view.dart +++ b/lib/ui/view/user/login_view.dart @@ -417,6 +417,7 @@ class LoginView extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), + foregroundColor: Colors.white, disabledBackgroundColor: secondary, disabledForegroundColor: Colors.white, ), @@ -437,6 +438,7 @@ class LoginView extends StatelessWidget { style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.bold, + color: Colors.white, ), textWidthBasis: TextWidthBasis.parent, ), diff --git a/lib/ui/view/user/sign_up_job_view.dart b/lib/ui/view/user/sign_up_job_view.dart index c197ce32..ca6b10b9 100644 --- a/lib/ui/view/user/sign_up_job_view.dart +++ b/lib/ui/view/user/sign_up_job_view.dart @@ -73,6 +73,7 @@ class SignUpJobView extends StatelessWidget { style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.bold, + color: Colors.white, ), textWidthBasis: TextWidthBasis.parent, ), diff --git a/lib/ui/widget/buttons/bottom_sheet_button.dart b/lib/ui/widget/buttons/bottom_sheet_button.dart index e225c486..5882bcc3 100644 --- a/lib/ui/widget/buttons/bottom_sheet_button.dart +++ b/lib/ui/widget/buttons/bottom_sheet_button.dart @@ -30,6 +30,7 @@ Widget buildBottomSheetButton({ shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), + foregroundColor: Colors.white, disabledBackgroundColor: secondary, disabledForegroundColor: Colors.white, shadowColor: buttonShadow! ? primary600 : Colors.transparent, @@ -40,6 +41,7 @@ Widget buildBottomSheetButton({ style: const TextStyle( fontSize: 17, fontWeight: FontWeight.bold, + color: Colors.white, ), textWidthBasis: TextWidthBasis.parent, ), diff --git a/lib/ui/widget/user/user_info.dart b/lib/ui/widget/user/user_info.dart index e46bfd4e..1e705995 100644 --- a/lib/ui/widget/user/user_info.dart +++ b/lib/ui/widget/user/user_info.dart @@ -58,17 +58,12 @@ Widget UserInfoWidget({ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Text( - link.user?.nickname ?? '', - style: const TextStyle( - color: grey900, - fontWeight: FontWeight.w500, - ), - ), - if (jobVisible ?? true) _UserJobView(link), - ], + Text( + link.user?.nickname ?? '', + style: const TextStyle( + color: grey900, + fontWeight: FontWeight.w500, + ), ), Container( margin: EdgeInsets.only(top: 4.h), @@ -82,38 +77,8 @@ Widget UserInfoWidget({ ), ), ], - ) - ], - ), - ); -} - -Container _UserJobView(Link link) { - return Container( - margin: EdgeInsets.only( - left: 4.w, - ), - decoration: BoxDecoration( - color: primary66_200, - borderRadius: BorderRadius.all( - Radius.circular(4.r), - ), - ), - child: Center( - child: Padding( - padding: EdgeInsets.symmetric( - vertical: 3.h, - horizontal: 4.w, ), - child: Text( - link.user?.jobGroup?.name ?? '', - style: TextStyle( - color: primary600, - fontSize: 10.sp, - letterSpacing: -0.2.w, - ), - ), - ), + ], ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 4240ed10..7ff398bd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: dio: ^5.2.0+1 json_annotation: ^4.8.0 http: ^0.13.6 - cached_network_image: ^3.2.3 + cached_network_image: ^3.3.1 ## Architecture flutter_bloc: ^8.1.3 @@ -28,15 +28,15 @@ dependencies: ## login sign_in_with_apple: ^5.0.0 google_sign_in: ^6.1.5 - firebase_core: ^2.20.0 - firebase_auth: ^4.12.0 - firebase_dynamic_links: ^5.4.2 + firebase_core: + firebase_auth: + firebase_dynamic_links: kakao_flutter_sdk_user: ^1.6.1 flutter_dotenv: ^5.0.2 flutter_naver_login: ^1.8.0 - firebase_auth_mocks: ^0.13.0 + firebase_auth_mocks: ## UI Sizer flutter_screenutil: ^5.7.0 @@ -54,11 +54,11 @@ dependencies: oktoast: share_plus: ^6.3.1 flutter_keyboard_visibility: ^5.4.1 - extended_text: ^11.1.0 + extended_text: ^12.0.1 carousel_slider: ^4.2.1 lottie: flutter_slidable: ^2.0.0 - firebase_storage: ^11.4.0 + firebase_storage: ## lint very_good_analysis: ^4.0.0+1 From 731b2ec38039183277b0a19d8b8b05a289c8a7c3 Mon Sep 17 00:00:00 2001 From: boring-km Date: Tue, 27 Feb 2024 22:36:09 +0900 Subject: [PATCH 08/48] =?UTF-8?q?[feat]=20=EC=A7=81=EC=97=85=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=ED=99=94=EB=A9=B4=20=EC=97=86=EC=95=A0=EA=B8=B0,?= =?UTF-8?q?=20=EB=8B=A4=EB=A5=B8=20=EC=82=AC=EB=9E=8C=20=EB=A7=81=ED=81=AC?= =?UTF-8?q?=20=EB=82=B4=20=ED=8F=B4=EB=8D=94=20=EB=8B=B4=EA=B8=B0=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- lib/cubits/sign_up/job_cubit.dart | 13 - lib/cubits/sign_up/sign_up_cubit.dart | 5 +- lib/routes.dart | 4 - lib/ui/view/links/link_detail_view.dart | 18 +- lib/ui/view/user/sign_up_job_view.dart | 295 ------------------ lib/ui/view/user/sign_up_nickname_view.dart | 39 ++- .../add_folder/horizontal_folder_list.dart | 1 + .../add_folder/show_add_folder_dialog.dart | 1 + lib/ui/widget/bottom_toast.dart | 4 +- lib/ui/widget/move_to_my_folder_dialog.dart | 5 +- lib/util/navigator_utils.dart | 10 + pubspec.yaml | 16 +- test/coverage_test.dart | 2 - 14 files changed, 71 insertions(+), 344 deletions(-) delete mode 100644 lib/cubits/sign_up/job_cubit.dart delete mode 100644 lib/ui/view/user/sign_up_job_view.dart create mode 100644 lib/util/navigator_utils.dart diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a6b826db..5e31d3d3 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ { - JobCubit(): super(null); - - void updateJob(JobGroup? state) { - emit(state); - } - - JobGroup? getJob() => state; -} diff --git a/lib/cubits/sign_up/sign_up_cubit.dart b/lib/cubits/sign_up/sign_up_cubit.dart index 4fbdb031..95e22216 100644 --- a/lib/cubits/sign_up/sign_up_cubit.dart +++ b/lib/cubits/sign_up/sign_up_cubit.dart @@ -12,13 +12,12 @@ class SignUpCubit extends Cubit { final UserApi _userApi = getIt(); - Future> signUp({User? user, String? nickname, JobGroup? job}) async { + Future> signUp({User? user, String? nickname}) async { Log.i(user?.toJson()); - Log.i('nickname: $nickname, job: ${job?.toJson()}'); + Log.i('nickname: $nickname'); final result = await _userApi.patchUsers( nickname: nickname, - jobGroupId: job?.id, ); return result.when( success: (data) { diff --git a/lib/routes.dart b/lib/routes.dart index 6188a5a8..188d2c15 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -12,7 +12,6 @@ import 'package:ac_project_app/ui/view/tutorial_view.dart'; import 'package:ac_project_app/ui/view/upload_view.dart'; import 'package:ac_project_app/ui/view/user/email_login_view.dart'; import 'package:ac_project_app/ui/view/user/login_view.dart'; -import 'package:ac_project_app/ui/view/user/sign_up_job_view.dart'; import 'package:ac_project_app/ui/view/user/sign_up_nickname_view.dart'; import 'package:flutter/material.dart'; @@ -28,7 +27,6 @@ class Routes { static const profile = '/profile'; static const emailLogin = '/emailLogin'; static const login = '/login'; - static const singUpJob = '/signUpJob'; static const signUpNickname = '/signUpNickname'; // etc @@ -63,8 +61,6 @@ class Pages { return router.create(child: const UserFeedView()); case Routes.signUpNickname: return router.create(child: const SignUpNicknameView()); - case Routes.singUpJob: - return router.create(child: const SignUpJobView()); case Routes.myPage: return router.create(child: const MyPage()); case Routes.profile: diff --git a/lib/ui/view/links/link_detail_view.dart b/lib/ui/view/links/link_detail_view.dart index f77fafe4..42d48c5f 100644 --- a/lib/ui/view/links/link_detail_view.dart +++ b/lib/ui/view/links/link_detail_view.dart @@ -59,10 +59,10 @@ class LinkDetailView extends StatelessWidget { builder: (cubitContext, editState) { final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; if (editState == EditState.edit) { - return WillPopScope( - onWillPop: () async { + return PopScope( + onPopInvoked: (bool didPop) { + if (didPop) return; goBackPage(editState, context, link.id); - return true; }, child: buildMainScreen( editState, @@ -356,10 +356,10 @@ class LinkDetailView extends StatelessWidget { visible: isMyLink, child: GestureDetector( onTap: () { - toggleEditorWithDialog(state, cubitContext, link.id); + toggleEditorWithDialog(state, cubitContext, link); }, onDoubleTap: () { - toggleEditorWithDialog(state, cubitContext, link.id); + toggleEditorWithDialog(state, cubitContext, link); }, child: Padding( padding: EdgeInsets.all(12.r), @@ -456,8 +456,9 @@ class LinkDetailView extends StatelessWidget { void toggleEditorWithDialog( EditState state, BuildContext cubitContext, - int? linkId, + Link link, ) { + final linkId = link.id; if (state == EditState.edit) { showWaitDialog( cubitContext, @@ -475,6 +476,11 @@ class LinkDetailView extends StatelessWidget { getValueFromKey(linkId!.toString()).then((temp) { if (temp.isNotEmpty) { cubitContext.read().textController.text = temp; + } else { + cubitContext + .read() + .textController + .text = link.describe ?? ''; } toggleEditor(cubitContext); }); diff --git a/lib/ui/view/user/sign_up_job_view.dart b/lib/ui/view/user/sign_up_job_view.dart deleted file mode 100644 index ca6b10b9..00000000 --- a/lib/ui/view/user/sign_up_job_view.dart +++ /dev/null @@ -1,295 +0,0 @@ -import 'dart:async'; - -import 'package:ac_project_app/const/colors.dart'; -import 'package:ac_project_app/cubits/sign_up/job_cubit.dart'; -import 'package:ac_project_app/cubits/sign_up/job_list_cubit.dart'; -import 'package:ac_project_app/cubits/sign_up/sign_up_cubit.dart'; -import 'package:ac_project_app/models/user/detail_user.dart'; -import 'package:ac_project_app/models/user/user.dart'; -import 'package:ac_project_app/ui/widget/only_back_app_bar.dart'; -import 'package:ac_project_app/util/get_arguments.dart'; -import 'package:ac_project_app/util/logger.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; - -class SignUpJobView extends StatelessWidget { - const SignUpJobView({super.key}); - - @override - Widget build(BuildContext context) { - final arg = getArguments(context); - final nickname = arg['nickname'] as String?; - final user = arg['user'] as User?; - final textController = TextEditingController(); - return MultiBlocProvider( - providers: [ - BlocProvider( - create: (_) => JobCubit(), - ), - BlocProvider( - create: (_) => SignUpCubit(), - ), - ], - child: Scaffold( - appBar: buildBackAppBar(context), - body: SafeArea( - child: Container( - margin: EdgeInsets.fromLTRB(24.w, 16.h, 24.w, 16.w), - child: BlocBuilder( - builder: (context, jobGroup) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '$nickname님의\n직업을 선택해주세요', - style: TextStyle( - fontSize: 24.sp, - fontWeight: FontWeight.bold, - ), - ), - buildJobInput(context, textController), - ], - ), - ElevatedButton( - style: ElevatedButton.styleFrom( - minimumSize: Size.fromHeight(55.h), - backgroundColor: primary800, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12.r), - ), - disabledBackgroundColor: secondary, - disabledForegroundColor: Colors.white, - ), - onPressed: jobGroup != null - ? () async => processSignUp(context, user, nickname) - : null, - child: Text( - '가입완료', - style: TextStyle( - fontSize: 17.sp, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - textWidthBasis: TextWidthBasis.parent, - ), - ), - ], - ); - }, - ), - ), - ), - ), - ); - } - - Future processSignUp( - BuildContext context, - User? user, - String? nickname, - ) async { - final result = await context.read().signUp( - user: user, - nickname: nickname, - job: context.read().getJob(), - ); - result.when( - success: (data) { - Navigator.pushNamedAndRemoveUntil( - context, - data, - (_) => false, - arguments: { - 'index': 0, - }, - ); - }, - error: Log.e, - ); - } - - Widget buildJobInput( - BuildContext context, - TextEditingController textController, - ) { - return Container( - alignment: Alignment.centerLeft, - margin: EdgeInsets.only(top: 30.h), - child: Stack( - alignment: Alignment.centerRight, - children: [ - TextFormField( - autofocus: true, - autofillHints: const ['직업을 선택해주세요'], - controller: textController, - style: TextStyle( - fontSize: 17.sp, - fontWeight: FontWeight.w500, - color: blackBold, - ), - decoration: InputDecoration( - labelText: '직업', - labelStyle: const TextStyle( - color: Color(0xFF9097A3), - fontWeight: FontWeight.w500, - ), - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide(color: primaryTab, width: 2.w), - ), - hintText: '직업을 선택해주세요', - hintStyle: TextStyle( - color: const Color(0xFFD0D1D2), - fontWeight: FontWeight.w500, - fontSize: 17.sp, - ), - contentPadding: EdgeInsets.zero, - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide(color: greyTab, width: 2.w), - ), - ), - readOnly: true, - onTap: () async { - unawaited( - getJobResult(context).then((result) { - context.read().updateJob(result); - changeText(context, textController); - }), - ); - }, - ), - InkWell( - onTap: () { - context.read().updateJob(null); - changeText(context, textController); - }, - child: Padding( - padding: EdgeInsets.all(8.r), - child: Icon( - Icons.close_rounded, - size: 20.r, - color: lightGrey700, - ), - ), - ), - ], - ), - ); - } - - Future getJobResult(BuildContext parentContext) async { - final bottomMargin = MediaQuery.of(parentContext).viewInsets.bottom + 16.h; - - return showModalBottomSheet( - backgroundColor: Colors.transparent, - context: parentContext, - builder: (BuildContext context) { - return Wrap( - children: [ - BlocProvider( - create: (_) => JobListCubit(), - child: BlocBuilder>( - builder: (context, jobs) { - return DecoratedBox( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(30.r), - topRight: Radius.circular(30.r), - ), - ), - child: Container( - margin: EdgeInsets.only( - left: 24.w, - right: 24.w, - top: 32.h, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '직업을 선택해주세요', - style: TextStyle( - fontSize: 20.sp, - fontWeight: FontWeight.bold, - ), - ), - Builder( - builder: (context) { - if (jobs.isEmpty) { - return SizedBox( - height: 300.h, - child: const Center( - child: CircularProgressIndicator(), - ), - ); - } - return buildJobListView(jobs, bottomMargin); - }, - ), - ], - ), - ), - ); - }, - ), - ), - ], - ); - }, - ); - } - - Widget buildJobListView(List jobs, double bottomMargin) { - return Container( - constraints: BoxConstraints( - maxHeight: 431.h, - ), - padding: EdgeInsets.only(bottom: bottomMargin), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Expanded( - child: Padding( - padding: EdgeInsets.only(bottom: 30.h), - child: ListView.builder( - padding: EdgeInsets.symmetric(vertical: 8.h), - shrinkWrap: true, - itemCount: jobs.length, - itemBuilder: (BuildContext context, int index) { - return TextButton( - style: TextButton.styleFrom( - alignment: Alignment.centerLeft, - ), - onPressed: () { - Navigator.pop(context, jobs[index]); - }, - child: Text( - jobs[index].name ?? '', - style: const TextStyle( - color: Colors.black, - ), - textAlign: TextAlign.start, - ), - ); - }, - ), - ), - ), - SizedBox( - height: 24.h, - ), - ], - ), - ); - } - - void changeText(BuildContext context, TextEditingController textController) { - textController.text = - context.read().getJob()?.name ?? '직업을 선택해주세요'; - } -} diff --git a/lib/ui/view/user/sign_up_nickname_view.dart b/lib/ui/view/user/sign_up_nickname_view.dart index 567399f8..353e3cbb 100644 --- a/lib/ui/view/user/sign_up_nickname_view.dart +++ b/lib/ui/view/user/sign_up_nickname_view.dart @@ -4,10 +4,11 @@ import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/cubits/sign_up/button_state_cubit.dart'; import 'package:ac_project_app/cubits/sign_up/nickname_check_cubit.dart'; import 'package:ac_project_app/cubits/sign_up/nickname_cubit.dart'; +import 'package:ac_project_app/cubits/sign_up/sign_up_cubit.dart'; import 'package:ac_project_app/models/user/user.dart'; -import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/widget/buttons/bottom_sheet_button.dart'; import 'package:ac_project_app/ui/widget/only_back_app_bar.dart'; +import 'package:ac_project_app/util/logger.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; @@ -31,6 +32,9 @@ class SignUpNicknameView extends StatelessWidget { BlocProvider( create: (_) => NicknameCheckCubit(), ), + BlocProvider( + create: (_) => SignUpCubit(), + ), ], child: BlocBuilder( builder: (context, nickname) { @@ -57,14 +61,7 @@ class SignUpNicknameView extends StatelessWidget { .isDuplicated(nickname!) .then((bool result) { if (result) { - Navigator.pushNamed( - context, - Routes.singUpJob, - arguments: { - 'nickname': nickname, - 'user': user, - }, - ); + processSignUp(context, user, nickname); } else { formKey.currentState?.validate(); } @@ -208,4 +205,28 @@ class SignUpNicknameView extends StatelessWidget { ), ); } + + Future processSignUp( + BuildContext context, + User? user, + String? nickname, + ) async { + final result = await context.read().signUp( + user: user, + nickname: nickname, + ); + result.when( + success: (data) { + Navigator.pushNamedAndRemoveUntil( + context, + data, + (_) => false, + arguments: { + 'index': 0, + }, + ); + }, + error: Log.e, + ); + } } diff --git a/lib/ui/widget/add_folder/horizontal_folder_list.dart b/lib/ui/widget/add_folder/horizontal_folder_list.dart index 68dca4ea..7da1a1cf 100644 --- a/lib/ui/widget/add_folder/horizontal_folder_list.dart +++ b/lib/ui/widget/add_folder/horizontal_folder_list.dart @@ -45,6 +45,7 @@ Widget buildFolderList({ onTap: () { callback?.call(index, folder); }, + onDoubleTap: () {}, child: Container( margin: EdgeInsets.only( right: rightPadding.toDouble().w, diff --git a/lib/ui/widget/add_folder/show_add_folder_dialog.dart b/lib/ui/widget/add_folder/show_add_folder_dialog.dart index 8893ac87..ed5b1480 100644 --- a/lib/ui/widget/add_folder/show_add_folder_dialog.dart +++ b/lib/ui/widget/add_folder/show_add_folder_dialog.dart @@ -277,6 +277,7 @@ Padding _buildDialogBody( style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.bold, + color: Colors.white, ), textWidthBasis: TextWidthBasis.parent, ), diff --git a/lib/ui/widget/bottom_toast.dart b/lib/ui/widget/bottom_toast.dart index 4bc2fd6c..96c46b7c 100644 --- a/lib/ui/widget/bottom_toast.dart +++ b/lib/ui/widget/bottom_toast.dart @@ -11,7 +11,9 @@ void showBottomToast( String? subMsg, String actionTitle = '확인하기', }) { - ScaffoldMessenger.of(context!).showSnackBar( + if (context == null) return; + + ScaffoldMessenger.of(context).showSnackBar( SnackBar( margin: EdgeInsets.only( left: 21.w, diff --git a/lib/ui/widget/move_to_my_folder_dialog.dart b/lib/ui/widget/move_to_my_folder_dialog.dart index abb64749..cd139eea 100644 --- a/lib/ui/widget/move_to_my_folder_dialog.dart +++ b/lib/ui/widget/move_to_my_folder_dialog.dart @@ -11,6 +11,7 @@ import 'package:ac_project_app/ui/widget/add_folder/folder_add_title.dart'; import 'package:ac_project_app/ui/widget/add_folder/horizontal_folder_list.dart'; import 'package:ac_project_app/ui/widget/bottom_toast.dart'; import 'package:ac_project_app/ui/widget/dialog/bottom_dialog.dart'; +import 'package:ac_project_app/util/navigator_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -89,6 +90,8 @@ void onSelectFolder( Folder folder, BuildContext context, ) { + popIfCan(parentContext); + popIfCan(context); parentContext .read() .completeRegister( @@ -99,8 +102,6 @@ void onSelectFolder( ) .then((result) { if (result == UploadResultState.success) { - Navigator.pop(parentContext); - Navigator.pop(context); showBottomToast( "링크가 '${_getFolderName(folder.name ?? '')}' 폴더에 담겼어요!", context: parentContext, diff --git a/lib/util/navigator_utils.dart b/lib/util/navigator_utils.dart new file mode 100644 index 00000000..53c05c36 --- /dev/null +++ b/lib/util/navigator_utils.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +void popIfCan(BuildContext? context) { + if (context == null) return; + final navigator = Navigator.maybeOf(context); + final canPop = navigator != null && navigator.canPop(); + if (canPop) { + navigator.pop(); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 7ff398bd..01aca400 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,13 +15,13 @@ dependencies: cupertino_icons: ## Network - dio: ^5.2.0+1 + dio: ^5.4.1 json_annotation: ^4.8.0 http: ^0.13.6 cached_network_image: ^3.3.1 ## Architecture - flutter_bloc: ^8.1.3 + flutter_bloc: ^8.1.4 equatable: ^2.0.5 get_it: ^7.6.0 @@ -39,7 +39,7 @@ dependencies: firebase_auth_mocks: ## UI Sizer - flutter_screenutil: ^5.7.0 + flutter_screenutil: ^5.9.0 ## kakao_share kakao_flutter_sdk_share: ^1.6.1 @@ -52,12 +52,12 @@ dependencies: intl: ^0.18.1 path: ^1.8.3 oktoast: - share_plus: ^6.3.1 + share_plus: ^7.2.2 flutter_keyboard_visibility: ^5.4.1 - extended_text: ^12.0.1 + extended_text: ^13.0.0 carousel_slider: ^4.2.1 lottie: - flutter_slidable: ^2.0.0 + flutter_slidable: ^3.0.1 firebase_storage: ## lint @@ -91,10 +91,10 @@ dev_dependencies: bloc_test: ^9.1.2 # for model class - build_runner: ^2.3.3 + build_runner: ^2.4.8 json_serializable: ^6.6.1 analyzer: ^5.10.0 - freezed: ^2.3.2 + freezed: ^2.4.7 flutter: diff --git a/test/coverage_test.dart b/test/coverage_test.dart index 312848f5..a8ce8dff 100644 --- a/test/coverage_test.dart +++ b/test/coverage_test.dart @@ -35,7 +35,6 @@ import 'package:ac_project_app/cubits/profile/selected_image_cubit.dart'; import 'package:ac_project_app/cubits/report/report_cubit.dart'; import 'package:ac_project_app/cubits/scroll/scroll_cubit.dart'; import 'package:ac_project_app/cubits/sign_up/button_state_cubit.dart'; -import 'package:ac_project_app/cubits/sign_up/job_cubit.dart'; import 'package:ac_project_app/cubits/sign_up/job_list_cubit.dart'; import 'package:ac_project_app/cubits/sign_up/nickname_check_cubit.dart'; import 'package:ac_project_app/cubits/sign_up/nickname_cubit.dart'; @@ -104,7 +103,6 @@ import 'package:ac_project_app/ui/view/tutorial_view.dart'; import 'package:ac_project_app/ui/view/upload_view.dart'; import 'package:ac_project_app/ui/view/user/email_login_view.dart'; import 'package:ac_project_app/ui/view/user/login_view.dart'; -import 'package:ac_project_app/ui/view/user/sign_up_job_view.dart'; import 'package:ac_project_app/ui/view/user/sign_up_nickname_view.dart'; import 'package:ac_project_app/ui/widget/add_folder/folder_add_title.dart'; import 'package:ac_project_app/ui/widget/add_folder/horizontal_folder_list.dart'; From 33bf29533367c6488c93b9a69ff830b50ccaa30c Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 6 Mar 2024 00:13:05 +0900 Subject: [PATCH 09/48] =?UTF-8?q?[feat]=20linkpool=20pick=20api=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20=EB=B0=8F=20ui=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../linkpool_pick/linkpool_pick_cubit.dart | 36 ++ .../linkpool_pick_result_state.dart | 37 ++ lib/di/set_up_get_it.dart | 27 +- lib/models/linkpool_pick/linkpool_pick.dart | 42 +++ lib/models/linkpool_pick/linkpool_pick.g.dart | 26 ++ lib/models/net/api_result.g.dart | 2 + lib/models/result.freezed.dart | 72 ++-- lib/models/user/user.freezed.dart | 42 ++- lib/models/user/user.g.dart | 5 +- .../api/linkpool_pick/linkpool_pick_api.dart | 22 ++ lib/ui/page/home/home_page.dart | 324 +++++++++++++----- lib/ui/view/home_view.dart | 2 + 12 files changed, 487 insertions(+), 150 deletions(-) create mode 100644 lib/cubits/linkpool_pick/linkpool_pick_cubit.dart create mode 100644 lib/cubits/linkpool_pick/linkpool_pick_result_state.dart create mode 100644 lib/models/linkpool_pick/linkpool_pick.dart create mode 100644 lib/models/linkpool_pick/linkpool_pick.g.dart create mode 100644 lib/provider/api/linkpool_pick/linkpool_pick_api.dart diff --git a/lib/cubits/linkpool_pick/linkpool_pick_cubit.dart b/lib/cubits/linkpool_pick/linkpool_pick_cubit.dart new file mode 100644 index 00000000..21ef979b --- /dev/null +++ b/lib/cubits/linkpool_pick/linkpool_pick_cubit.dart @@ -0,0 +1,36 @@ +import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_result_state.dart'; +import 'package:ac_project_app/di/set_up_get_it.dart'; +import 'package:ac_project_app/models/linkpool_pick/linkpool_pick.dart'; +import 'package:ac_project_app/models/result.dart'; +import 'package:ac_project_app/provider/api/linkpool_pick/linkpool_pick_api.dart'; +import 'package:ac_project_app/util/logger.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class LinkpoolPickCubit extends Cubit { + LinkpoolPickCubit() : super(LinkpoolPickResultInitialState()) { + loadLinkpoolPicks(); + } + + final LinkpoolPickApi linkpoolPickApi = getIt(); + + void loadLinkpoolPicks() { + linkpoolPickApi + .getLinkpoolPicks() + .then((Result> result) { + result.when( + success: (List data) { + Log.i(data); + if (data.isEmpty) { + emit(LinkpoolPickResultNoDataState()); + } else { + emit(LinkpoolPickResultLoadedState(data)); + } + }, + error: (msg) { + Log.i('pick data'); + emit(LinkpoolPickResultErrorState(msg)); + }, + ); + }); + } +} diff --git a/lib/cubits/linkpool_pick/linkpool_pick_result_state.dart b/lib/cubits/linkpool_pick/linkpool_pick_result_state.dart new file mode 100644 index 00000000..79b9c05e --- /dev/null +++ b/lib/cubits/linkpool_pick/linkpool_pick_result_state.dart @@ -0,0 +1,37 @@ +import 'package:ac_project_app/models/linkpool_pick/linkpool_pick.dart'; +import 'package:equatable/equatable.dart'; + +abstract class LinkpoolPickResultState extends Equatable {} + +class LinkpoolPickResultInitialState extends LinkpoolPickResultState { + @override + List get props => []; +} + +class LinkpoolPickResultLoadingState extends LinkpoolPickResultState { + @override + List get props => []; +} + +class LinkpoolPickResultLoadedState extends LinkpoolPickResultState { + LinkpoolPickResultLoadedState(this.linkpoolPicks); + + final List linkpoolPicks; + + @override + List get props => linkpoolPicks; +} + +class LinkpoolPickResultErrorState extends LinkpoolPickResultState { + LinkpoolPickResultErrorState(this.message); + + final String message; + + @override + List get props => [message]; +} + +class LinkpoolPickResultNoDataState extends LinkpoolPickResultState { + @override + List get props => []; +} diff --git a/lib/di/set_up_get_it.dart b/lib/di/set_up_get_it.dart index 9df89810..91dc0e3d 100644 --- a/lib/di/set_up_get_it.dart +++ b/lib/di/set_up_get_it.dart @@ -1,9 +1,11 @@ import 'package:ac_project_app/cubits/folders/get_user_folders_cubit.dart'; +import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_cubit.dart'; import 'package:ac_project_app/cubits/login/auto_login_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_info_cubit.dart'; import 'package:ac_project_app/provider/api/custom_client.dart'; import 'package:ac_project_app/provider/api/folders/folder_api.dart'; import 'package:ac_project_app/provider/api/folders/link_api.dart'; +import 'package:ac_project_app/provider/api/linkpool_pick/linkpool_pick_api.dart'; import 'package:ac_project_app/provider/api/report/report_api.dart'; import 'package:ac_project_app/provider/api/user/profile_api.dart'; import 'package:ac_project_app/provider/api/user/user_api.dart'; @@ -14,17 +16,20 @@ final getIt = GetIt.instance; void locator() { final httpClient = CustomClient(); - getIt..registerLazySingleton(() => httpClient) + getIt + ..registerLazySingleton(() => httpClient) - // APIs - ..registerLazySingleton(() => FolderApi(httpClient)) - ..registerLazySingleton(() => LinkApi(httpClient)) - ..registerLazySingleton(() => ReportApi(httpClient)) - ..registerLazySingleton(() => ProfileApi(httpClient)) - ..registerLazySingleton(() => UserApi(httpClient)) + // APIs + ..registerLazySingleton(() => FolderApi(httpClient)) + ..registerLazySingleton(() => LinkApi(httpClient)) + ..registerLazySingleton(() => ReportApi(httpClient)) + ..registerLazySingleton(() => ProfileApi(httpClient)) + ..registerLazySingleton(() => UserApi(httpClient)) + ..registerLazySingleton(() => LinkpoolPickApi(httpClient)) - // Cubits - ..registerLazySingleton(GetUserFoldersCubit.new) - ..registerLazySingleton(GetProfileInfoCubit.new) - ..registerLazySingleton(AutoLoginCubit.new); + // Cubits + ..registerLazySingleton(GetUserFoldersCubit.new) + ..registerLazySingleton(GetProfileInfoCubit.new) + ..registerLazySingleton(AutoLoginCubit.new) + ..registerLazySingleton(LinkpoolPickCubit.new); } diff --git a/lib/models/linkpool_pick/linkpool_pick.dart b/lib/models/linkpool_pick/linkpool_pick.dart new file mode 100644 index 00000000..43bf5ada --- /dev/null +++ b/lib/models/linkpool_pick/linkpool_pick.dart @@ -0,0 +1,42 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'linkpool_pick.g.dart'; + +@JsonSerializable() +class LinkpoolPick extends Equatable { + const LinkpoolPick({ + required this.id, + required this.backgroundColor, + required this.title, + required this.image, + required this.describe, + required this.linkId, + }); + + factory LinkpoolPick.fromJson(Map json) => + _$LinkpoolPickFromJson(json); + + static List fromJsonList(List jsonList) { + return jsonList + .map((e) => LinkpoolPick.fromJson(e as Map)) + .toList(); + } + + final int id; + final String backgroundColor; + final String title; + final String image; + final String describe; + final int linkId; + + Map toJson() => _$LinkpoolPickToJson(this); + + @override + List get props => []; + + Color getColor() { + return Color(int.parse(backgroundColor.replaceAll('#', ''), radix: 16)); + } +} diff --git a/lib/models/linkpool_pick/linkpool_pick.g.dart b/lib/models/linkpool_pick/linkpool_pick.g.dart new file mode 100644 index 00000000..c959689b --- /dev/null +++ b/lib/models/linkpool_pick/linkpool_pick.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'linkpool_pick.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LinkpoolPick _$LinkpoolPickFromJson(Map json) => LinkpoolPick( + id: json['id'] as int, + backgroundColor: json['backgroundColor'] as String, + title: json['title'] as String, + image: json['image'] as String, + describe: json['describe'] as String, + linkId: json['linkId'] as int, + ); + +Map _$LinkpoolPickToJson(LinkpoolPick instance) => + { + 'id': instance.id, + 'backgroundColor': instance.backgroundColor, + 'title': instance.title, + 'image': instance.image, + 'describe': instance.describe, + 'linkId': instance.linkId, + }; diff --git a/lib/models/net/api_result.g.dart b/lib/models/net/api_result.g.dart index 15e65a71..7ea770f7 100644 --- a/lib/models/net/api_result.g.dart +++ b/lib/models/net/api_result.g.dart @@ -9,6 +9,7 @@ part of 'api_result.dart'; ApiResult _$ApiResultFromJson(Map json) => ApiResult( status: json['status'] as int?, data: json['data'], + message: json['message'] as String?, error: json['error'] == null ? null : ApiError.fromJson(json['error'] as Map), @@ -16,6 +17,7 @@ ApiResult _$ApiResultFromJson(Map json) => ApiResult( Map _$ApiResultToJson(ApiResult instance) => { 'status': instance.status, + 'message': instance.message, 'error': instance.error?.toJson(), 'data': instance.data, }; diff --git a/lib/models/result.freezed.dart b/lib/models/result.freezed.dart index dec6036d..53ef7a9a 100644 --- a/lib/models/result.freezed.dart +++ b/lib/models/result.freezed.dart @@ -12,7 +12,7 @@ part of 'result.dart'; T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); /// @nodoc mixin _$Result { @@ -74,20 +74,20 @@ class _$ResultCopyWithImpl> } /// @nodoc -abstract class _$$SuccessCopyWith { - factory _$$SuccessCopyWith( - _$Success value, $Res Function(_$Success) then) = - __$$SuccessCopyWithImpl; +abstract class _$$SuccessImplCopyWith { + factory _$$SuccessImplCopyWith( + _$SuccessImpl value, $Res Function(_$SuccessImpl) then) = + __$$SuccessImplCopyWithImpl; @useResult $Res call({T data}); } /// @nodoc -class __$$SuccessCopyWithImpl - extends _$ResultCopyWithImpl> - implements _$$SuccessCopyWith { - __$$SuccessCopyWithImpl( - _$Success _value, $Res Function(_$Success) _then) +class __$$SuccessImplCopyWithImpl + extends _$ResultCopyWithImpl> + implements _$$SuccessImplCopyWith { + __$$SuccessImplCopyWithImpl( + _$SuccessImpl _value, $Res Function(_$SuccessImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -95,7 +95,7 @@ class __$$SuccessCopyWithImpl $Res call({ Object? data = freezed, }) { - return _then(_$Success( + return _then(_$SuccessImpl( freezed == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -106,8 +106,8 @@ class __$$SuccessCopyWithImpl /// @nodoc -class _$Success implements Success { - const _$Success(this.data); +class _$SuccessImpl implements Success { + const _$SuccessImpl(this.data); @override final T data; @@ -118,10 +118,10 @@ class _$Success implements Success { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$Success && + other is _$SuccessImpl && const DeepCollectionEquality().equals(other.data, data)); } @@ -132,8 +132,8 @@ class _$Success implements Success { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$SuccessCopyWith> get copyWith => - __$$SuccessCopyWithImpl>(this, _$identity); + _$$SuccessImplCopyWith> get copyWith => + __$$SuccessImplCopyWithImpl>(this, _$identity); @override @optionalTypeArgs @@ -199,27 +199,29 @@ class _$Success implements Success { } abstract class Success implements Result { - const factory Success(final T data) = _$Success; + const factory Success(final T data) = _$SuccessImpl; T get data; @JsonKey(ignore: true) - _$$SuccessCopyWith> get copyWith => + _$$SuccessImplCopyWith> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$ErrorCopyWith { - factory _$$ErrorCopyWith(_$Error value, $Res Function(_$Error) then) = - __$$ErrorCopyWithImpl; +abstract class _$$ErrorImplCopyWith { + factory _$$ErrorImplCopyWith( + _$ErrorImpl value, $Res Function(_$ErrorImpl) then) = + __$$ErrorImplCopyWithImpl; @useResult $Res call({String message}); } /// @nodoc -class __$$ErrorCopyWithImpl - extends _$ResultCopyWithImpl> - implements _$$ErrorCopyWith { - __$$ErrorCopyWithImpl(_$Error _value, $Res Function(_$Error) _then) +class __$$ErrorImplCopyWithImpl + extends _$ResultCopyWithImpl> + implements _$$ErrorImplCopyWith { + __$$ErrorImplCopyWithImpl( + _$ErrorImpl _value, $Res Function(_$ErrorImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -227,7 +229,7 @@ class __$$ErrorCopyWithImpl $Res call({ Object? message = null, }) { - return _then(_$Error( + return _then(_$ErrorImpl( null == message ? _value.message : message // ignore: cast_nullable_to_non_nullable @@ -238,8 +240,8 @@ class __$$ErrorCopyWithImpl /// @nodoc -class _$Error implements Error { - const _$Error(this.message); +class _$ErrorImpl implements Error { + const _$ErrorImpl(this.message); @override final String message; @@ -250,10 +252,10 @@ class _$Error implements Error { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$Error && + other is _$ErrorImpl && (identical(other.message, message) || other.message == message)); } @@ -263,8 +265,8 @@ class _$Error implements Error { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$ErrorCopyWith> get copyWith => - __$$ErrorCopyWithImpl>(this, _$identity); + _$$ErrorImplCopyWith> get copyWith => + __$$ErrorImplCopyWithImpl>(this, _$identity); @override @optionalTypeArgs @@ -330,10 +332,10 @@ class _$Error implements Error { } abstract class Error implements Result { - const factory Error(final String message) = _$Error; + const factory Error(final String message) = _$ErrorImpl; String get message; @JsonKey(ignore: true) - _$$ErrorCopyWith> get copyWith => + _$$ErrorImplCopyWith> get copyWith => throw _privateConstructorUsedError; } diff --git a/lib/models/user/user.freezed.dart b/lib/models/user/user.freezed.dart index 889568e7..078f37d7 100644 --- a/lib/models/user/user.freezed.dart +++ b/lib/models/user/user.freezed.dart @@ -12,7 +12,7 @@ part of 'user.dart'; T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); User _$UserFromJson(Map json) { return _User.fromJson(json); @@ -66,18 +66,20 @@ class _$UserCopyWithImpl<$Res, $Val extends User> } /// @nodoc -abstract class _$$_UserCopyWith<$Res> implements $UserCopyWith<$Res> { - factory _$$_UserCopyWith(_$_User value, $Res Function(_$_User) then) = - __$$_UserCopyWithImpl<$Res>; +abstract class _$$UserImplCopyWith<$Res> implements $UserCopyWith<$Res> { + factory _$$UserImplCopyWith( + _$UserImpl value, $Res Function(_$UserImpl) then) = + __$$UserImplCopyWithImpl<$Res>; @override @useResult $Res call({int? id, bool? is_new}); } /// @nodoc -class __$$_UserCopyWithImpl<$Res> extends _$UserCopyWithImpl<$Res, _$_User> - implements _$$_UserCopyWith<$Res> { - __$$_UserCopyWithImpl(_$_User _value, $Res Function(_$_User) _then) +class __$$UserImplCopyWithImpl<$Res> + extends _$UserCopyWithImpl<$Res, _$UserImpl> + implements _$$UserImplCopyWith<$Res> { + __$$UserImplCopyWithImpl(_$UserImpl _value, $Res Function(_$UserImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -86,7 +88,7 @@ class __$$_UserCopyWithImpl<$Res> extends _$UserCopyWithImpl<$Res, _$_User> Object? id = freezed, Object? is_new = freezed, }) { - return _then(_$_User( + return _then(_$UserImpl( id: freezed == id ? _value.id : id // ignore: cast_nullable_to_non_nullable @@ -101,10 +103,11 @@ class __$$_UserCopyWithImpl<$Res> extends _$UserCopyWithImpl<$Res, _$_User> /// @nodoc @JsonSerializable() -class _$_User implements _User { - const _$_User({required this.id, required this.is_new}); +class _$UserImpl implements _User { + const _$UserImpl({required this.id, required this.is_new}); - factory _$_User.fromJson(Map json) => _$$_UserFromJson(json); + factory _$UserImpl.fromJson(Map json) => + _$$UserImplFromJson(json); @override final int? id; @@ -117,10 +120,10 @@ class _$_User implements _User { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$_User && + other is _$UserImpl && (identical(other.id, id) || other.id == id) && (identical(other.is_new, is_new) || other.is_new == is_new)); } @@ -132,12 +135,12 @@ class _$_User implements _User { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$_UserCopyWith<_$_User> get copyWith => - __$$_UserCopyWithImpl<_$_User>(this, _$identity); + _$$UserImplCopyWith<_$UserImpl> get copyWith => + __$$UserImplCopyWithImpl<_$UserImpl>(this, _$identity); @override Map toJson() { - return _$$_UserToJson( + return _$$UserImplToJson( this, ); } @@ -145,9 +148,9 @@ class _$_User implements _User { abstract class _User implements User { const factory _User({required final int? id, required final bool? is_new}) = - _$_User; + _$UserImpl; - factory _User.fromJson(Map json) = _$_User.fromJson; + factory _User.fromJson(Map json) = _$UserImpl.fromJson; @override int? get id; @@ -155,5 +158,6 @@ abstract class _User implements User { bool? get is_new; @override @JsonKey(ignore: true) - _$$_UserCopyWith<_$_User> get copyWith => throw _privateConstructorUsedError; + _$$UserImplCopyWith<_$UserImpl> get copyWith => + throw _privateConstructorUsedError; } diff --git a/lib/models/user/user.g.dart b/lib/models/user/user.g.dart index aa1bf47b..1739c5c6 100644 --- a/lib/models/user/user.g.dart +++ b/lib/models/user/user.g.dart @@ -6,12 +6,13 @@ part of 'user.dart'; // JsonSerializableGenerator // ************************************************************************** -_$_User _$$_UserFromJson(Map json) => _$_User( +_$UserImpl _$$UserImplFromJson(Map json) => _$UserImpl( id: json['id'] as int?, is_new: json['is_new'] as bool?, ); -Map _$$_UserToJson(_$_User instance) => { +Map _$$UserImplToJson(_$UserImpl instance) => + { 'id': instance.id, 'is_new': instance.is_new, }; diff --git a/lib/provider/api/linkpool_pick/linkpool_pick_api.dart b/lib/provider/api/linkpool_pick/linkpool_pick_api.dart new file mode 100644 index 00000000..2682c8f6 --- /dev/null +++ b/lib/provider/api/linkpool_pick/linkpool_pick_api.dart @@ -0,0 +1,22 @@ +import 'package:ac_project_app/models/linkpool_pick/linkpool_pick.dart'; +import 'package:ac_project_app/models/result.dart'; +import 'package:ac_project_app/provider/api/custom_client.dart'; + +class LinkpoolPickApi { + LinkpoolPickApi(this._client); + + final CustomClient _client; + + Future>> getLinkpoolPicks() async { + final result = await _client.getUri('/picks'); + + return result.when( + success: (data) { + return Result.success(LinkpoolPick.fromJsonList(data as List)); + }, + error: (msg) { + return Result.error(msg); + }, + ); + } +} diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index cc284882..ce900ccd 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -4,17 +4,22 @@ import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/const/strings.dart'; import 'package:ac_project_app/cubits/home/get_job_list_cubit.dart'; import 'package:ac_project_app/cubits/home/topic_list_state.dart'; +import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_cubit.dart'; +import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_result_state.dart'; import 'package:ac_project_app/cubits/links/links_from_selected_job_group_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_info_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_state.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/models/link/link.dart'; +import 'package:ac_project_app/models/linkpool_pick/linkpool_pick.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/widget/dialog/bottom_dialog.dart'; import 'package:ac_project_app/ui/widget/link_hero.dart'; import 'package:ac_project_app/ui/widget/user/user_info.dart'; +import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -25,86 +30,97 @@ class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, profileState) { - return BlocBuilder( - builder: (jobContext, state) { - if (state is LoadedState && profileState is ProfileLoadedState) { - return SafeArea( - child: NotificationListener( - onNotification: (scrollNotification) { - final metrics = scrollNotification.metrics; - if (metrics.axisDirection != AxisDirection.down) { - return false; - } - if (metrics.extentAfter <= 800) { - context.read().loadMore(); - } - return true; - }, - child: RefreshIndicator( - onRefresh: () => refresh(context), - color: primary600, - child: CustomScrollView( - controller: context - .read() - .scrollController, - slivers: [ - SliverToBoxAdapter( - child: Container( - margin: EdgeInsets.only( - left: 24.w, - right: 24.w, - top: 20.h, - ), - child: GestureDetector( - onTap: () => Navigator.pushNamed( - context, - Routes.search, - arguments: { - 'isMine': false, - }, - ), - child: Container( - decoration: BoxDecoration( - color: ccGrey100, - borderRadius: - BorderRadius.all(Radius.circular(7.r)), - ), - width: double.infinity, - height: 36.h, - margin: EdgeInsets.only(right: 6.w), - child: Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.only(left: 10.w), - child: Assets.images.folderSearchIcon.image( - width: 24.w, - height: 24.h, - ), // Image.asset( - ), - ), - ), - ), - ), + return BlocBuilder( + builder: (pickContext, linkpoolPickState) { + return BlocBuilder( + builder: (context, profileState) { + return BlocBuilder( + builder: (jobContext, state) { + if (state is LoadedState && + profileState is ProfileLoadedState) { + return SafeArea( + child: NotificationListener( + onNotification: (scrollNotification) { + final metrics = scrollNotification.metrics; + if (metrics.axisDirection != AxisDirection.down) { + return false; + } + if (metrics.extentAfter <= 800) { + context + .read() + .loadMore(); + } + return true; + }, + child: RefreshIndicator( + onRefresh: () => refresh(context), + color: primary600, + child: CustomScrollView( + controller: context + .read() + .scrollController, + slivers: [ + SearchBar(context), + LinkpoolPickMenu(context, linkpoolPickState), + buildListBody(jobContext), + ], ), - buildListBody(jobContext), - ], + ), ), - ), - ), - ); - } else { - return const Center( - child: CircularProgressIndicator(), - ); - } + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + }, + ); }, ); }, ); } + SliverToBoxAdapter SearchBar(BuildContext context) { + return SliverToBoxAdapter( + child: Container( + margin: EdgeInsets.only( + left: 24.w, + right: 24.w, + top: 20.h, + ), + child: GestureDetector( + onTap: () => Navigator.pushNamed( + context, + Routes.search, + arguments: { + 'isMine': false, + }, + ), + child: Container( + decoration: BoxDecoration( + color: ccGrey100, + borderRadius: BorderRadius.all(Radius.circular(7.r)), + ), + width: double.infinity, + height: 36.h, + margin: EdgeInsets.only(right: 6.w), + child: Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.only(left: 10.w), + child: Assets.images.folderSearchIcon.image( + width: 24.w, + height: 24.h, + ), // Image.asset( + ), + ), + ), + ), + ), + ); + } + Widget buildListBody(BuildContext parentContext) { final width = MediaQuery.of(parentContext).size.width; final height = MediaQuery.of(parentContext).size.height; @@ -138,16 +154,8 @@ class HomePage extends StatelessWidget { final link = totalLinks[index]; return Column( children: [ - buildBodyListItem(context, link, width, totalLinks), - if (index != totalLinks.length - 1) - Padding( - padding: EdgeInsets.symmetric(horizontal: 24.w), - child: Divider( - height: 1.h, - thickness: 1.w, - color: ccGrey200, - ), - ), + BodyListItem(context, link, width, totalLinks), + GreyDivider(index, totalLinks.length - 1), ], ); }, @@ -159,7 +167,22 @@ class HomePage extends StatelessWidget { ); } - GestureDetector buildBodyListItem( + Widget GreyDivider(int index, int length) { + if (index != length) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 24.w), + child: Divider( + height: 1.h, + thickness: 1.w, + color: ccGrey200, + ), + ); + } else { + return const SizedBox.shrink(); + } + } + + GestureDetector BodyListItem( BuildContext context, Link link, double width, @@ -340,4 +363,139 @@ class HomePage extends StatelessWidget { Future refresh(BuildContext context) async { context.read().refresh(); } + + Widget LinkpoolPickMenu(BuildContext context, LinkpoolPickResultState state) { + Log.i('state: $state'); + if (state is! LinkpoolPickResultLoadedState) { + return const SliverToBoxAdapter(child: SizedBox.shrink()); + } + final linkpoolPicks = state.linkpoolPicks; + return SliverToBoxAdapter( + child: Padding( + padding: EdgeInsets.only(top: 30.h, left: 12.w, bottom: 12.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(left: 13.w, bottom: 16.h), + child: Text( + 'LINKPOOL PICK', + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w600, + color: Colors.black, + ), + ), + ), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + padding: EdgeInsets.symmetric(horizontal: 12.w), + child: Row( + children: [ + for (final pick in linkpoolPicks) + Padding( + padding: EdgeInsets.only(right: 12.w), + child: LinkpoolPickItem(context, pick), + ), + ], + ), + ), + ], + ), + ), + ); + } + + Widget LinkpoolPickItem(BuildContext context, LinkpoolPick pick) { + final width = MediaQuery.of(context).size.width; + + final color = pick.getColor(); + return Container( + width: width - 60.w, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Row( + children: [ + Padding( + padding: EdgeInsets.only(top: 12.h, left: 10.w, bottom: 12.h), + child: Stack( + children: [ + Align( + alignment: Alignment.topLeft, + child: Container( + width: 92.w, + height: 90.w, + color: Colors.transparent, + )), + Padding( + padding: EdgeInsets.only(left: 6.w), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(4.r)), + child: CachedNetworkImage( + imageUrl: pick.image, + width: 86.w, + height: 86.w, + fit: BoxFit.cover, + ), + ), + ), + Padding( + padding: EdgeInsets.only(top: 4.h), + child: Container( + padding: EdgeInsets.only( + top: 3.h, + bottom: 2.h, + left: 6.w, + right: 6.w, + ), + decoration: BoxDecoration( + color: grey900, + borderRadius: BorderRadius.all(Radius.circular(3.r)), + ), + child: Text( + 'PICK', + style: TextStyle( + fontSize: 8.4.sp, + letterSpacing: -0.17, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ), + ), + ], + ), + ), + 10.horizontalSpace, + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '원형들, 힙한 케이크 맛집',//pick.title, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: grey900, + ), + ), + 8.verticalSpace, + Text( + '색다른 음식에 진심인 사람이라면,\n무조건 방문해봐야 할 이색 케이크 맛집',// pick.describe, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: grey600, + ), + ), + ], + ), + ], + ), + ); + } } diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index 1214d0e0..ec16345e 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -4,6 +4,7 @@ import 'package:ac_project_app/cubits/folders/get_my_folders_cubit.dart'; import 'package:ac_project_app/cubits/folders/get_user_folders_cubit.dart'; import 'package:ac_project_app/cubits/home/get_job_list_cubit.dart'; import 'package:ac_project_app/cubits/home_view_cubit.dart'; +import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_cubit.dart'; import 'package:ac_project_app/cubits/links/links_from_selected_job_group_cubit.dart'; import 'package:ac_project_app/cubits/links/upload_link_cubit.dart'; import 'package:ac_project_app/di/set_up_get_it.dart'; @@ -165,6 +166,7 @@ class _HomeViewState extends State with WidgetsBindingObserver { BlocProvider(create: (_) => GetJobListCubit()), BlocProvider(create: (_) => GetUserFoldersCubit()), BlocProvider(create: (_) => UploadLinkCubit()), + BlocProvider(create: (_) => LinkpoolPickCubit()), ], child: const HomePage(), ), From 590629b1b46122b9ed8cf5e03892fb7a403bafa9 Mon Sep 17 00:00:00 2001 From: boring-km Date: Sat, 9 Mar 2024 12:31:23 +0900 Subject: [PATCH 10/48] =?UTF-8?q?[feat]=20linkpool=20pick=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=9D=B4=EB=8F=99=EA=B9=8C=EC=A7=80=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0,=20=EB=B6=88=ED=95=84=EC=9A=94=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../linkpool_pick/linkpool_pick_cubit.dart | 16 +- .../links_from_selected_job_group_cubit.dart | 16 +- lib/cubits/profile/profile_info_cubit.dart | 2 - lib/models/profile/profile.dart | 4 - lib/models/user/detail_user.dart | 15 +- lib/provider/api/folders/link_api.dart | 5 +- lib/ui/page/home/home_page.dart | 264 +++++++++--------- lib/ui/view/home_view.dart | 4 +- lib/ui/view/links/user_feed_view.dart | 2 - lib/util/list_utils.dart | 12 - test/coverage_test.dart | 1 - test/provider/api/folders/link_api_test.dart | 4 +- test/provider/api/user/user_api_test.dart | 8 - .../view/user/change_profile_view_test.dart | 1 - test/util/list_utils_test.dart | 66 ----- 15 files changed, 165 insertions(+), 255 deletions(-) delete mode 100644 lib/util/list_utils.dart delete mode 100644 test/util/list_utils_test.dart diff --git a/lib/cubits/linkpool_pick/linkpool_pick_cubit.dart b/lib/cubits/linkpool_pick/linkpool_pick_cubit.dart index 21ef979b..a77a5754 100644 --- a/lib/cubits/linkpool_pick/linkpool_pick_cubit.dart +++ b/lib/cubits/linkpool_pick/linkpool_pick_cubit.dart @@ -1,7 +1,9 @@ import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_result_state.dart'; import 'package:ac_project_app/di/set_up_get_it.dart'; +import 'package:ac_project_app/models/link/link.dart'; import 'package:ac_project_app/models/linkpool_pick/linkpool_pick.dart'; import 'package:ac_project_app/models/result.dart'; +import 'package:ac_project_app/provider/api/folders/link_api.dart'; import 'package:ac_project_app/provider/api/linkpool_pick/linkpool_pick_api.dart'; import 'package:ac_project_app/util/logger.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -12,6 +14,7 @@ class LinkpoolPickCubit extends Cubit { } final LinkpoolPickApi linkpoolPickApi = getIt(); + final LinkApi linkApi = getIt(); void loadLinkpoolPicks() { linkpoolPickApi @@ -27,10 +30,21 @@ class LinkpoolPickCubit extends Cubit { } }, error: (msg) { - Log.i('pick data'); emit(LinkpoolPickResultErrorState(msg)); }, ); }); } + + Future> getLinkpoolPickLink(int linkpoolPickId) async { + final result = await linkApi.getLinkFromId('$linkpoolPickId'); + return result.when( + success: (data) { + return Result.success(data); + }, + error: (msg) { + return Result.error(msg); + }, + ); + } } diff --git a/lib/cubits/links/links_from_selected_job_group_cubit.dart b/lib/cubits/links/links_from_selected_job_group_cubit.dart index 4f6100be..6343fe3e 100644 --- a/lib/cubits/links/links_from_selected_job_group_cubit.dart +++ b/lib/cubits/links/links_from_selected_job_group_cubit.dart @@ -6,15 +6,14 @@ import 'package:ac_project_app/provider/api/folders/link_api.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class LinksFromSelectedJobGroupCubit extends Cubit> { - LinksFromSelectedJobGroupCubit() : super([]) { +class GetLinksCubit extends Cubit> { + GetLinksCubit() : super([]) { initialize(); } final LinkApi linkApi = getIt(); HasMoreCubit hasMore = HasMoreCubit(); - int selectedJobId = 1; int page = 0; bool hasRefresh = false; List totalLinks = []; @@ -23,13 +22,12 @@ class LinksFromSelectedJobGroupCubit extends Cubit> { void initialize() { emit([]); - getSelectedJobLinks(0, 0); + getLinks(0); } - Future getSelectedJobLinks(int jobGroupId, int pageNum) async { + Future getLinks(int pageNum) async { hasRefresh = false; - selectedJobId = jobGroupId; - final result = await linkApi.getJobGroupLinks(jobGroupId, pageNum); + final result = await linkApi.getLinks(pageNum); result.when( success: (data) { final links = _setScrollState(data); @@ -47,14 +45,14 @@ class LinksFromSelectedJobGroupCubit extends Cubit> { void refresh() { totalLinks.clear(); hasRefresh = true; - getSelectedJobLinks(selectedJobId, 0); + getLinks(0); } bool loadMore() { emit([]); hasLoadMore = hasMore.state == ScrollableType.can; if (hasLoadMore) { - getSelectedJobLinks(selectedJobId, page + 1); + getLinks(page + 1); } return hasLoadMore; } diff --git a/lib/cubits/profile/profile_info_cubit.dart b/lib/cubits/profile/profile_info_cubit.dart index 6ba3021c..2a25b774 100644 --- a/lib/cubits/profile/profile_info_cubit.dart +++ b/lib/cubits/profile/profile_info_cubit.dart @@ -27,7 +27,6 @@ class GetProfileInfoCubit extends Cubit { Profile( id: user.id, nickname: user.nickname, - jobGroup: user.jobGroup, profileImage: user.profile_img, ), ), @@ -58,7 +57,6 @@ class GetProfileInfoCubit extends Cubit { Profile( id: user.id, nickname: user.nickname, - jobGroup: user.jobGroup, profileImage: user.profile_img, ), ), diff --git a/lib/models/profile/profile.dart b/lib/models/profile/profile.dart index dc04d371..41dbadeb 100644 --- a/lib/models/profile/profile.dart +++ b/lib/models/profile/profile.dart @@ -1,16 +1,12 @@ -import 'package:ac_project_app/models/user/detail_user.dart'; - class Profile { Profile({ required this.nickname, required this.profileImage, - required this.jobGroup, this.id, }); int? id; String nickname; String profileImage; - JobGroup? jobGroup; } diff --git a/lib/models/user/detail_user.dart b/lib/models/user/detail_user.dart index dff74c97..c8e06550 100644 --- a/lib/models/user/detail_user.dart +++ b/lib/models/user/detail_user.dart @@ -6,38 +6,31 @@ class DetailUser extends Equatable { DetailUser({ int? id, String? nickname, - JobGroup? jobGroup, String? profile_img, }) { _id = id; _nickname = nickname; - _jobGroup = jobGroup; _profile_img = profile_img; } DetailUser.fromJson(dynamic json) { _id = json['id'] as int?; _nickname = json['nickname'] as String?; - _jobGroup = - json['job_group'] != null ? JobGroup.fromJson(json['job_group']) : null; _profile_img = json['profile_img'] as String?; } late final int? _id; late final String? _nickname; - late final JobGroup? _jobGroup; late final String? _profile_img; DetailUser copyWith({ int? id, String? nickname, - JobGroup? jobGroup, String? profile_img, }) => DetailUser( id: id ?? _id, nickname: nickname ?? _nickname, - jobGroup: jobGroup ?? _jobGroup, profile_img: profile_img ?? _profile_img, ); @@ -45,17 +38,12 @@ class DetailUser extends Equatable { String get nickname => _nickname ?? ''; - JobGroup? get jobGroup => _jobGroup; - String get profile_img => _profile_img ?? ''; Map toJson() { final map = {}; map['id'] = _id; map['nickname'] = _nickname; - if (_jobGroup != null) { - map['job_group'] = _jobGroup?.toJson(); - } map['profile_img'] = _profile_img; return map; } @@ -65,7 +53,6 @@ class DetailUser extends Equatable { final input = other as DetailUser; return input.id == id && input.nickname == nickname && - input.jobGroup == jobGroup && input.profile_img == profile_img; } @@ -75,7 +62,7 @@ class DetailUser extends Equatable { bool isNotEmpty() => _id != null; @override - List get props => [_id, _nickname, _jobGroup, _profile_img]; + List get props => [_id, _nickname, _profile_img]; } /// id : 1 diff --git a/lib/provider/api/folders/link_api.dart b/lib/provider/api/folders/link_api.dart index 5295002f..50d82dbc 100644 --- a/lib/provider/api/folders/link_api.dart +++ b/lib/provider/api/folders/link_api.dart @@ -68,11 +68,10 @@ class LinkApi { ); } - Future> getJobGroupLinks( - int jobGroup, + Future> getLinks( int pageNum, ) async { - final result = await _client.getUri('/job-groups/$jobGroup/links?' + final result = await _client.getUri('/job-groups/0/links?' 'page_no=$pageNum&' 'page_size=10'); diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index ce900ccd..96772f29 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -2,8 +2,6 @@ import 'dart:async'; import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/const/strings.dart'; -import 'package:ac_project_app/cubits/home/get_job_list_cubit.dart'; -import 'package:ac_project_app/cubits/home/topic_list_state.dart'; import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_cubit.dart'; import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_result_state.dart'; import 'package:ac_project_app/cubits/links/links_from_selected_job_group_cubit.dart'; @@ -19,7 +17,6 @@ import 'package:ac_project_app/ui/widget/user/user_info.dart'; import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -34,47 +31,40 @@ class HomePage extends StatelessWidget { builder: (pickContext, linkpoolPickState) { return BlocBuilder( builder: (context, profileState) { - return BlocBuilder( - builder: (jobContext, state) { - if (state is LoadedState && - profileState is ProfileLoadedState) { - return SafeArea( - child: NotificationListener( - onNotification: (scrollNotification) { - final metrics = scrollNotification.metrics; - if (metrics.axisDirection != AxisDirection.down) { - return false; - } - if (metrics.extentAfter <= 800) { - context - .read() - .loadMore(); - } - return true; - }, - child: RefreshIndicator( - onRefresh: () => refresh(context), - color: primary600, - child: CustomScrollView( - controller: context - .read() - .scrollController, - slivers: [ - SearchBar(context), - LinkpoolPickMenu(context, linkpoolPickState), - buildListBody(jobContext), - ], - ), - ), + if (profileState is ProfileLoadedState) { + return SafeArea( + child: NotificationListener( + onNotification: (scrollNotification) { + final metrics = scrollNotification.metrics; + if (metrics.axisDirection != AxisDirection.down) { + return false; + } + if (metrics.extentAfter <= 800) { + context.read().loadMore(); + } + return true; + }, + child: RefreshIndicator( + onRefresh: () => refresh(context), + color: primary600, + child: CustomScrollView( + controller: context + .read() + .scrollController, + slivers: [ + SearchBar(context), + LinkpoolPickMenu(pickContext, linkpoolPickState), + buildListBody(pickContext), + ], ), - ); - } else { - return const Center( - child: CircularProgressIndicator(), - ); - } - }, - ); + ), + ), + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } }, ); }, @@ -125,7 +115,7 @@ class HomePage extends StatelessWidget { final width = MediaQuery.of(parentContext).size.width; final height = MediaQuery.of(parentContext).size.height; - return BlocBuilder>( + return BlocBuilder>( builder: (context, links) { final totalLinks = _setTotalLinks(context, links); if (totalLinks.isEmpty) { @@ -190,13 +180,7 @@ class HomePage extends StatelessWidget { ) { return GestureDetector( onTap: () { - Navigator.pushNamed( - context, - Routes.linkDetail, - arguments: { - 'link': link, - }, - ); + showLinkDetail(context, link); }, child: Container( margin: EdgeInsets.symmetric( @@ -341,27 +325,37 @@ class HomePage extends StatelessWidget { ); } + void showLinkDetail(BuildContext context, Link link) { + Navigator.pushNamed( + context, + Routes.linkDetail, + arguments: { + 'link': link, + }, + ); + } + List _setTotalLinks(BuildContext context, List links) { final totalLinks = - context.watch().totalLinks; - if (context.read().hasRefresh) { + context.watch().totalLinks; + if (context.read().hasRefresh) { totalLinks.clear(); - context.read().hasRefresh = false; + context.read().hasRefresh = false; } totalLinks.addAll(links); return totalLinks; } void addLinks(BuildContext context, List totalLinks, List links) { - if (context.read().hasRefresh) { + if (context.read().hasRefresh) { totalLinks.clear(); - context.read().hasRefresh = false; + context.read().hasRefresh = false; } totalLinks.addAll(links); } Future refresh(BuildContext context) async { - context.read().refresh(); + context.read().refresh(); } Widget LinkpoolPickMenu(BuildContext context, LinkpoolPickResultState state) { @@ -410,91 +404,105 @@ class HomePage extends StatelessWidget { final width = MediaQuery.of(context).size.width; final color = pick.getColor(); - return Container( - width: width - 60.w, - decoration: BoxDecoration( - color: color, - borderRadius: BorderRadius.all(Radius.circular(6.r)), - ), - child: Row( - children: [ - Padding( - padding: EdgeInsets.only(top: 12.h, left: 10.w, bottom: 12.h), - child: Stack( - children: [ - Align( + return GestureDetector( + onTap: () async { + final result = await context + .read() + .getLinkpoolPickLink(pick.linkId); + result.when( + success: (link) { + showLinkDetail(context, link); + }, + error: (msg) {}, + ); + }, + child: Container( + width: width - 60.w, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.all(Radius.circular(6.r)), + ), + child: Row( + children: [ + Padding( + padding: EdgeInsets.only(top: 12.h, left: 10.w, bottom: 12.h), + child: Stack( + children: [ + Align( alignment: Alignment.topLeft, child: Container( width: 92.w, height: 90.w, color: Colors.transparent, - )), - Padding( - padding: EdgeInsets.only(left: 6.w), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(4.r)), - child: CachedNetworkImage( - imageUrl: pick.image, - width: 86.w, - height: 86.w, - fit: BoxFit.cover, ), ), - ), - Padding( - padding: EdgeInsets.only(top: 4.h), - child: Container( - padding: EdgeInsets.only( - top: 3.h, - bottom: 2.h, - left: 6.w, - right: 6.w, - ), - decoration: BoxDecoration( - color: grey900, - borderRadius: BorderRadius.all(Radius.circular(3.r)), + Padding( + padding: EdgeInsets.only(left: 6.w), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(4.r)), + child: CachedNetworkImage( + imageUrl: pick.image, + width: 86.h, + height: 86.h, + fit: BoxFit.cover, + ), ), - child: Text( - 'PICK', - style: TextStyle( - fontSize: 8.4.sp, - letterSpacing: -0.17, - fontWeight: FontWeight.bold, - color: Colors.white, + ), + Padding( + padding: EdgeInsets.only(top: 4.h), + child: Container( + padding: EdgeInsets.only( + top: 3.h, + bottom: 2.h, + left: 6.w, + right: 6.w, + ), + decoration: BoxDecoration( + color: grey900, + borderRadius: BorderRadius.all(Radius.circular(3.r)), + ), + child: Text( + 'PICK', + style: TextStyle( + fontSize: 8.4.sp, + letterSpacing: -0.17, + fontWeight: FontWeight.bold, + color: Colors.white, + ), ), ), ), - ), - ], + ], + ), ), - ), - 10.horizontalSpace, - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '원형들, 힙한 케이크 맛집',//pick.title, - style: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.bold, - color: grey900, + 10.horizontalSpace, + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + pick.title, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: grey900, + ), ), - ), - 8.verticalSpace, - Text( - '색다른 음식에 진심인 사람이라면,\n무조건 방문해봐야 할 이색 케이크 맛집',// pick.describe, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 12.sp, - fontWeight: FontWeight.w500, - color: grey600, + 8.verticalSpace, + Text( + pick.describe, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: grey600, + ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ); } diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index ec16345e..6defe2e7 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -101,7 +101,7 @@ class _HomeViewState extends State with WidgetsBindingObserver { create: (_) => HomeViewCubit((args['index'] as int?) ?? 0), ), BlocProvider( - create: (_) => LinksFromSelectedJobGroupCubit(), + create: (_) => GetLinksCubit(), ), BlocProvider( create: (_) => GetFoldersCubit(), @@ -190,7 +190,7 @@ class _HomeViewState extends State with WidgetsBindingObserver { context.read().getFolders(); context.read().moveTo(index); } else if (index == 1) { - context.read().refresh(); + context.read().refresh(); context.read().moveTo(index); } else { context.read().moveTo(index); diff --git a/lib/ui/view/links/user_feed_view.dart b/lib/ui/view/links/user_feed_view.dart index ed74675d..93297d6d 100644 --- a/lib/ui/view/links/user_feed_view.dart +++ b/lib/ui/view/links/user_feed_view.dart @@ -63,8 +63,6 @@ class UserFeedView extends StatelessWidget { feedContext.read().hasRefresh = false; } - Log.i('links ${links.length}'); - totalLinks.addAll(links); return BlocProvider( create: (_) => ScrollCubit( diff --git a/lib/util/list_utils.dart b/lib/util/list_utils.dart deleted file mode 100644 index 543b546a..00000000 --- a/lib/util/list_utils.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:ac_project_app/models/profile/profile.dart'; -import 'package:ac_project_app/models/user/detail_user.dart'; - -extension SortMyJobs on List { - List sortMyJobs(Profile profile) { - final myJobId = profile.jobGroup!.id!; - final tempJob = firstWhere((element) => element.id == myJobId); - return this - ..remove(tempJob) - ..insert(1, tempJob); - } -} diff --git a/test/coverage_test.dart b/test/coverage_test.dart index a8ce8dff..af714527 100644 --- a/test/coverage_test.dart +++ b/test/coverage_test.dart @@ -125,7 +125,6 @@ import 'package:ac_project_app/util/date_utils.dart'; import 'package:ac_project_app/util/fade_page_route.dart'; import 'package:ac_project_app/util/get_arguments.dart'; import 'package:ac_project_app/util/get_screen_mode.dart'; -import 'package:ac_project_app/util/list_utils.dart'; import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/number_commas.dart'; import 'package:ac_project_app/util/offset_utils.dart'; diff --git a/test/provider/api/folders/link_api_test.dart b/test/provider/api/folders/link_api_test.dart index 1b2f26fc..1375802f 100644 --- a/test/provider/api/folders/link_api_test.dart +++ b/test/provider/api/folders/link_api_test.dart @@ -201,7 +201,7 @@ void main() { 'page_size=10', ); final api = getLinkApi(mockClient); - final result = await api.getJobGroupLinks(jobGroup, pageNum); + final result = await api.getLinks(pageNum); result.when( success: (data) => expect(data, apiExpected.data), @@ -227,7 +227,7 @@ void main() { hasError: true, ); final api = getLinkApi(mockClient); - final result = await api.getJobGroupLinks(jobGroup, pageNum); + final result = await api.getLinks(pageNum); result.when( success: (_) => fail('should be error'), diff --git a/test/provider/api/user/user_api_test.dart b/test/provider/api/user/user_api_test.dart index a5fb6b2a..4b6b496b 100644 --- a/test/provider/api/user/user_api_test.dart +++ b/test/provider/api/user/user_api_test.dart @@ -60,10 +60,6 @@ void main() { data: DetailUser( id: 0, nickname: '테스트', - jobGroup: JobGroup( - id: 1, - name: '개발자', - ), profile_img: '01', // 처음 기본 프로필 이미지는 01번 ), ); @@ -85,10 +81,6 @@ void main() { data: DetailUser( id: 0, nickname: '테스트', - jobGroup: JobGroup( - id: 1, - name: '개발자', - ), profile_img: '01', // 처음 기본 프로필 이미지는 01번 ), ); diff --git a/test/ui/view/user/change_profile_view_test.dart b/test/ui/view/user/change_profile_view_test.dart index f6f4f0a5..e3672ac2 100644 --- a/test/ui/view/user/change_profile_view_test.dart +++ b/test/ui/view/user/change_profile_view_test.dart @@ -15,7 +15,6 @@ void main() { profile: Profile( nickname: '오키', profileImage: '02', - jobGroup: null, ), ); }, diff --git a/test/util/list_utils_test.dart b/test/util/list_utils_test.dart deleted file mode 100644 index a11cede0..00000000 --- a/test/util/list_utils_test.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:ac_project_app/models/profile/profile.dart'; -import 'package:ac_project_app/models/user/detail_user.dart'; -import 'package:ac_project_app/util/list_utils.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group('전체 JobGroup이 포함된 JobGroup 리스트에서 주어진 프로필을 기준으로 정렬하는 테스트', () { - final total = JobGroup(id: 99, name: '전체'); - final jobGroup0 = JobGroup(id: 0, name: '직업 0'); - final jobGroup1 = JobGroup(id: 1, name: '직업 1'); - final jobGroup2 = JobGroup(id: 2, name: '직업 2'); - - late List jobGroups; - - setUp(() { - jobGroups = [ - total, - jobGroup0, - jobGroup1, - jobGroup2, - ]; - }); - - test('이름이 직업 0인 기준으로 정렬하기', () { - final jobGroup0Target = Profile( - nickname: 'boring-km', - profileImage: '01', - jobGroup: jobGroup0, - ); - - final actual = jobGroups.sortMyJobs( - jobGroup0Target, - ); - - expect(actual, [total, jobGroup0, jobGroup1, jobGroup2]); - }); - - test('이름이 직업 1인 기준으로 정렬하기', () { - final jobGroup1Target = Profile( - nickname: 'boring-km', - profileImage: '01', - jobGroup: jobGroup1, - ); - - final actual = jobGroups.sortMyJobs( - jobGroup1Target, - ); - - expect(actual, [total, jobGroup1, jobGroup0, jobGroup2]); - }); - - test('이름이 직업 2인 기준으로 정렬하기', () { - final jobGroup2Target = Profile( - nickname: 'boring-km', - profileImage: '01', - jobGroup: jobGroup2, - ); - - final actual = jobGroups.sortMyJobs( - jobGroup2Target, - ); - - expect(actual, [total, jobGroup2, jobGroup0, jobGroup1]); - }); - }); -} From 1a2a521f62576ffa3197f935648ed3a2ad467fa1 Mon Sep 17 00:00:00 2001 From: boring-km Date: Sat, 9 Mar 2024 13:49:16 +0900 Subject: [PATCH 11/48] =?UTF-8?q?[feat]=20=EB=B9=8C=EB=93=9C=20=EC=88=9C?= =?UTF-8?q?=EC=84=9C=20=EB=B0=8F=20http=20=EB=9D=BC=EC=9D=B4=EB=B8=8C?= =?UTF-8?q?=EB=9F=AC=EB=A6=AC=20=EB=B2=84=EC=A0=84=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Runner.xcodeproj/project.pbxproj | 26 ++++++++++++++++--- .../xcshareddata/swiftpm/Package.resolved | 3 ++- pubspec.yaml | 18 ++++++++----- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 47df3465..e1b24073 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -355,14 +355,15 @@ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( 06D908F3BF919B7EE15A8705 /* [CP] Check Pods Manifest.lock */, + 242C769F86A7805781E3C954 /* [CP] Embed Pods Frameworks */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + AEE2471C28CF82200092F192 /* Embed App Extensions */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 242C769F86A7805781E3C954 /* [CP] Embed Pods Frameworks */, - AEE2471C28CF82200092F192 /* Embed App Extensions */, + 04407A3D77A27457A3AE6C17 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -384,7 +385,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1340; - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 0F872E3A28D875E3002954CC = { @@ -449,6 +450,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 04407A3D77A27457A3AE6C17 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 06D908F3BF919B7EE15A8705 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved index 7340ce68..2ffff48f 100644 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,4 +1,5 @@ { + "originHash" : "f378d0517ac7cb918b2824a5a8a6f024067823ced7c6dd92014d7f870db39003", "pins" : [ { "identity" : "opengraph", @@ -10,5 +11,5 @@ } } ], - "version" : 2 + "version" : 3 } diff --git a/pubspec.yaml b/pubspec.yaml index 01aca400..2d1ccccd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: ## Network dio: ^5.4.1 json_annotation: ^4.8.0 - http: ^0.13.6 + http: ^1.0.0 cached_network_image: ^3.3.1 ## Architecture @@ -28,15 +28,15 @@ dependencies: ## login sign_in_with_apple: ^5.0.0 google_sign_in: ^6.1.5 - firebase_core: - firebase_auth: - firebase_dynamic_links: + firebase_core: 2.27.0 + firebase_auth: 4.17.8 + firebase_dynamic_links: 5.4.17 kakao_flutter_sdk_user: ^1.6.1 flutter_dotenv: ^5.0.2 flutter_naver_login: ^1.8.0 - firebase_auth_mocks: + firebase_auth_mocks: 0.13.0 ## UI Sizer flutter_screenutil: ^5.9.0 @@ -45,7 +45,10 @@ dependencies: kakao_flutter_sdk_share: ^1.6.1 ## Utils - metadata_fetch: ^0.4.1 + metadata_fetch: + git: + url: https://github.com/boring-km/metadata_fetch.git + permission_handler: ^10.2.0 logger: ^1.3.0 path_provider: ^2.0.15 @@ -58,7 +61,7 @@ dependencies: carousel_slider: ^4.2.1 lottie: flutter_slidable: ^3.0.1 - firebase_storage: + firebase_storage: ^11.6.9 ## lint very_good_analysis: ^4.0.0+1 @@ -125,3 +128,4 @@ flutter: weight: 400 - asset: assets/fonts/Roboto/Roboto-Bold.ttf weight: 700 + From ef55faa4711b15ecc5affb57a9cd64dd0d199260 Mon Sep 17 00:00:00 2001 From: boring-km Date: Sat, 9 Mar 2024 14:33:15 +0900 Subject: [PATCH 12/48] =?UTF-8?q?[feat]=201.0.52=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/android_cicd.yml | 2 +- .github/workflows/cicd.yml | 4 ++-- .github/workflows/code_coverage.yml | 2 +- .github/workflows/ios_cicd.yml | 2 +- .../xcshareddata/swiftpm/Package.resolved | 15 --------------- lib/cubits/profile/profile_info_cubit.dart | 1 - lib/ui/page/home/home_page.dart | 2 +- lib/ui/widget/user/user_info.dart | 8 +++++--- pubspec.yaml | 2 +- 9 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/.github/workflows/android_cicd.yml b/.github/workflows/android_cicd.yml index fbd32fda..60e77035 100644 --- a/.github/workflows/android_cicd.yml +++ b/.github/workflows/android_cicd.yml @@ -16,7 +16,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.13.3' + flutter-version: '3.19.1' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index f758d4b5..1c414d14 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.13.9' + flutter-version: '3.19.1' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.13.9' + flutter-version: '3.19.1' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 6c762be3..68c4fdd4 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.13.6' + flutter-version: '3.19.1' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/.github/workflows/ios_cicd.yml b/.github/workflows/ios_cicd.yml index b87f2e60..fbf38ac4 100644 --- a/.github/workflows/ios_cicd.yml +++ b/.github/workflows/ios_cicd.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.13.6' + flutter-version: '3.19.1' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 2ffff48f..00000000 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,15 +0,0 @@ -{ - "originHash" : "f378d0517ac7cb918b2824a5a8a6f024067823ced7c6dd92014d7f870db39003", - "pins" : [ - { - "identity" : "opengraph", - "kind" : "remoteSourceControl", - "location" : "https://github.com/satoshi-takano/OpenGraph", - "state" : { - "revision" : "3ef2b8b9b4972b57e9e78c91c26be770c0110057", - "version" : "1.5.0" - } - } - ], - "version" : 3 -} diff --git a/lib/cubits/profile/profile_info_cubit.dart b/lib/cubits/profile/profile_info_cubit.dart index 2a25b774..4638e578 100644 --- a/lib/cubits/profile/profile_info_cubit.dart +++ b/lib/cubits/profile/profile_info_cubit.dart @@ -16,7 +16,6 @@ class GetProfileInfoCubit extends Cubit { final ProfileApi profileApi = getIt(); Future loadProfileData() async { - if (state == ProfileLoadingState()) return; emit(ProfileLoadingState()); final result = await userApi.getUsers(); diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 96772f29..5100a445 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -144,7 +144,7 @@ class HomePage extends StatelessWidget { final link = totalLinks[index]; return Column( children: [ - BodyListItem(context, link, width, totalLinks), + BodyListItem(parentContext, link, width, totalLinks), GreyDivider(index, totalLinks.length - 1), ], ); diff --git a/lib/ui/widget/user/user_info.dart b/lib/ui/widget/user/user_info.dart index 1e705995..e533c218 100644 --- a/lib/ui/widget/user/user_info.dart +++ b/lib/ui/widget/user/user_info.dart @@ -20,9 +20,11 @@ Widget UserInfoWidget({ final profileInfoCubit = getIt(); final userFoldersCubit = getIt(); - final isMine = - (profileInfoCubit.state as ProfileLoadedState).profile.id == - link.user!.id; + if (profileInfoCubit.state is! ProfileLoadedState) { + await profileInfoCubit.loadProfileData(); + } + + final isMine = (profileInfoCubit.state as ProfileLoadedState).profile.id == link.user!.id; await userFoldersCubit.getFolders(link.user!.id!).then((_) { Navigator.of(context).pushNamed( diff --git a/pubspec.yaml b/pubspec.yaml index 2d1ccccd..3ed868d7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.51+51 +version: 1.0.52+52 environment: sdk: ">=3.0.0 <4.0.0" From 3808e9952fc0169f28ed1f5c5109018644f51497 Mon Sep 17 00:00:00 2001 From: boring-km Date: Mon, 25 Mar 2024 16:01:22 +0900 Subject: [PATCH 13/48] =?UTF-8?q?[fix]=20iOS=20OpenGraph=20=EC=8D=B8?= =?UTF-8?q?=EB=84=A4=EC=9D=BC=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=A0=9C?= =?UTF-8?q?=EB=8C=80=EB=A1=9C=20=EC=95=88=EB=82=98=EC=98=A4=EB=8A=94=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 일단 ("//" 으로 시작하는 링크만) --- .../Base.lproj/MainInterface.storyboard | 26 +++++++++---------- ios/Extension/Utils.swift | 14 ++++++++++ .../ViewController/ShareViewController.swift | 2 +- ios/Podfile | 2 ++ .../xcshareddata/swiftpm/Package.resolved | 15 +++++++++++ pubspec.yaml | 8 +++--- 6 files changed, 49 insertions(+), 18 deletions(-) create mode 100644 ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/ios/Extension/Base.lproj/MainInterface.storyboard b/ios/Extension/Base.lproj/MainInterface.storyboard index edc59982..d9ed6129 100644 --- a/ios/Extension/Base.lproj/MainInterface.storyboard +++ b/ios/Extension/Base.lproj/MainInterface.storyboard @@ -1,9 +1,9 @@ - + - + @@ -599,16 +599,16 @@ - + - + - + - + @@ -678,7 +678,7 @@ - + @@ -730,7 +730,7 @@ - + @@ -886,10 +886,10 @@ - + - + diff --git a/ios/Extension/Utils.swift b/ios/Extension/Utils.swift index b2200a02..9f0a4a39 100644 --- a/ios/Extension/Utils.swift +++ b/ios/Extension/Utils.swift @@ -26,3 +26,17 @@ extension Date { return dateFormatter.date(from: string) } } + +extension URL { + func resolve(_ relativePath: String?) -> String { + if let path = relativePath { + if path.starts(with: "http://") || path.starts(with: "https://") { + return path + } + if path.starts(with: "//") { + return (self.scheme ?? "http") + ":" + path + } + } + return "" + } +} diff --git a/ios/Extension/ViewController/ShareViewController.swift b/ios/Extension/ViewController/ShareViewController.swift index fd8bd57f..1340cf43 100644 --- a/ios/Extension/ViewController/ShareViewController.swift +++ b/ios/Extension/ViewController/ShareViewController.swift @@ -128,7 +128,7 @@ class ShareViewController: UIViewController { let safeTitle = String(htmlEncodedString: rawTitle) ?? "" self.titleText = Data(safeTitle.utf8).base64EncodedString() - self.linkImageUrl = (og[.image] ?? "") + self.linkImageUrl = URL(string: link)?.resolve(og[.image]) UserDefaultsHelper.saveLinkWithoutFolder(link, self.linkImageUrl, self.titleText) } diff --git a/ios/Podfile b/ios/Podfile index c8de1c42..cfe4acd0 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -27,6 +27,8 @@ end require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) +pod 'OpenGraph' + flutter_ios_podfile_setup target 'Runner' do diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..2ffff48f --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,15 @@ +{ + "originHash" : "f378d0517ac7cb918b2824a5a8a6f024067823ced7c6dd92014d7f870db39003", + "pins" : [ + { + "identity" : "opengraph", + "kind" : "remoteSourceControl", + "location" : "https://github.com/satoshi-takano/OpenGraph", + "state" : { + "revision" : "3ef2b8b9b4972b57e9e78c91c26be770c0110057", + "version" : "1.5.0" + } + } + ], + "version" : 3 +} diff --git a/pubspec.yaml b/pubspec.yaml index 3ed868d7..84eb07b6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,9 +28,9 @@ dependencies: ## login sign_in_with_apple: ^5.0.0 google_sign_in: ^6.1.5 - firebase_core: 2.27.0 - firebase_auth: 4.17.8 - firebase_dynamic_links: 5.4.17 + firebase_core: 2.27.1 + firebase_auth: 4.17.9 + firebase_dynamic_links: 5.4.18 kakao_flutter_sdk_user: ^1.6.1 flutter_dotenv: ^5.0.2 @@ -61,7 +61,7 @@ dependencies: carousel_slider: ^4.2.1 lottie: flutter_slidable: ^3.0.1 - firebase_storage: ^11.6.9 + firebase_storage: ^11.6.10 ## lint very_good_analysis: ^4.0.0+1 From cbbb0bdc79b0388767b47e82e1c9b65dec377375 Mon Sep 17 00:00:00 2001 From: boring-km Date: Thu, 28 Mar 2024 13:47:50 +0900 Subject: [PATCH 14/48] =?UTF-8?q?[fix+version]=201.0.53=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 링풀픽 텍스트 안 잘리게 처리 --- .github/workflows/android_cicd.yml | 2 +- .github/workflows/cicd.yml | 4 +-- .github/workflows/code_coverage.yml | 2 +- .github/workflows/ios_cicd.yml | 2 +- android/app/build.gradle | 4 +-- ios/Runner.xcodeproj/project.pbxproj | 42 +++++++--------------- lib/ui/page/home/home_page.dart | 52 ++++++++++++++++------------ pubspec.yaml | 2 +- 8 files changed, 50 insertions(+), 60 deletions(-) diff --git a/.github/workflows/android_cicd.yml b/.github/workflows/android_cicd.yml index 60e77035..62988691 100644 --- a/.github/workflows/android_cicd.yml +++ b/.github/workflows/android_cicd.yml @@ -16,7 +16,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 1c414d14..6964a6ad 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 68c4fdd4..59604364 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/.github/workflows/ios_cicd.yml b/.github/workflows/ios_cicd.yml index fbf38ac4..40cfc0b8 100644 --- a/.github/workflows/ios_cicd.yml +++ b/.github/workflows/ios_cicd.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/android/app/build.gradle b/android/app/build.gradle index 4afa2eff..18849938 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -42,7 +42,7 @@ apply plugin: 'kotlin-parcelize' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 33 + compileSdkVersion 34 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -64,7 +64,7 @@ android { defaultConfig { applicationId "com.mr.ac_project_app" minSdkVersion 24 - targetSdkVersion 33 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName ndk.debugSymbolLevel 'FULL' diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e1b24073..192aa005 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -627,11 +627,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -649,7 +647,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -669,11 +666,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -690,7 +685,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -708,11 +702,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -729,7 +721,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -798,11 +789,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -813,7 +802,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -944,11 +932,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -959,7 +945,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -980,11 +965,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -995,7 +978,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 5100a445..97e3b3c7 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -17,7 +17,9 @@ import 'package:ac_project_app/ui/widget/user/user_info.dart'; import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -476,30 +478,36 @@ class HomePage extends StatelessWidget { ), ), 10.horizontalSpace, - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - pick.title, - style: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.bold, - color: grey900, + Flexible( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(right: 12), + child: Text( + pick.title, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: grey900, + ), + overflow: TextOverflow.ellipsis, + ), ), - ), - 8.verticalSpace, - Text( - pick.describe, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 12.sp, - fontWeight: FontWeight.w500, - color: grey600, + 8.verticalSpace, + Text( + pick.describe, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: grey600, + ), ), - ), - ], + ], + ), ), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index 84eb07b6..d28db32c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.52+52 +version: 1.0.53+53 environment: sdk: ">=3.0.0 <4.0.0" From 21173739e6867e4e0e7a293d1f1f8ab3527ac5c3 Mon Sep 17 00:00:00 2001 From: Kangmin Date: Thu, 28 Mar 2024 13:51:19 +0900 Subject: [PATCH 15/48] 1.0.53 Update (#205) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [fix] iOS OpenGraph 썸네일 이미지 제대로 안나오는 부분 수정 일단 ("//" 으로 시작하는 링크만) * [fix+version] 1.0.53 업데이트 링풀픽 텍스트 안 잘리게 처리 --- .github/workflows/android_cicd.yml | 2 +- .github/workflows/cicd.yml | 4 +- .github/workflows/code_coverage.yml | 2 +- .github/workflows/ios_cicd.yml | 2 +- android/app/build.gradle | 4 +- .../Base.lproj/MainInterface.storyboard | 26 +++++----- ios/Extension/Utils.swift | 14 +++++ .../ViewController/ShareViewController.swift | 2 +- ios/Podfile | 2 + ios/Runner.xcodeproj/project.pbxproj | 42 +++++---------- .../xcshareddata/swiftpm/Package.resolved | 15 ++++++ lib/ui/page/home/home_page.dart | 52 +++++++++++-------- pubspec.yaml | 10 ++-- 13 files changed, 99 insertions(+), 78 deletions(-) create mode 100644 ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/.github/workflows/android_cicd.yml b/.github/workflows/android_cicd.yml index 60e77035..62988691 100644 --- a/.github/workflows/android_cicd.yml +++ b/.github/workflows/android_cicd.yml @@ -16,7 +16,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 1c414d14..6964a6ad 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 68c4fdd4..59604364 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/.github/workflows/ios_cicd.yml b/.github/workflows/ios_cicd.yml index fbf38ac4..40cfc0b8 100644 --- a/.github/workflows/ios_cicd.yml +++ b/.github/workflows/ios_cicd.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.1' + flutter-version: '3.19.4' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/android/app/build.gradle b/android/app/build.gradle index 4afa2eff..18849938 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -42,7 +42,7 @@ apply plugin: 'kotlin-parcelize' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 33 + compileSdkVersion 34 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -64,7 +64,7 @@ android { defaultConfig { applicationId "com.mr.ac_project_app" minSdkVersion 24 - targetSdkVersion 33 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName ndk.debugSymbolLevel 'FULL' diff --git a/ios/Extension/Base.lproj/MainInterface.storyboard b/ios/Extension/Base.lproj/MainInterface.storyboard index edc59982..d9ed6129 100644 --- a/ios/Extension/Base.lproj/MainInterface.storyboard +++ b/ios/Extension/Base.lproj/MainInterface.storyboard @@ -1,9 +1,9 @@ - + - + @@ -599,16 +599,16 @@ - + - + - + - + @@ -678,7 +678,7 @@ - + @@ -730,7 +730,7 @@ - + @@ -886,10 +886,10 @@ - + - + diff --git a/ios/Extension/Utils.swift b/ios/Extension/Utils.swift index b2200a02..9f0a4a39 100644 --- a/ios/Extension/Utils.swift +++ b/ios/Extension/Utils.swift @@ -26,3 +26,17 @@ extension Date { return dateFormatter.date(from: string) } } + +extension URL { + func resolve(_ relativePath: String?) -> String { + if let path = relativePath { + if path.starts(with: "http://") || path.starts(with: "https://") { + return path + } + if path.starts(with: "//") { + return (self.scheme ?? "http") + ":" + path + } + } + return "" + } +} diff --git a/ios/Extension/ViewController/ShareViewController.swift b/ios/Extension/ViewController/ShareViewController.swift index fd8bd57f..1340cf43 100644 --- a/ios/Extension/ViewController/ShareViewController.swift +++ b/ios/Extension/ViewController/ShareViewController.swift @@ -128,7 +128,7 @@ class ShareViewController: UIViewController { let safeTitle = String(htmlEncodedString: rawTitle) ?? "" self.titleText = Data(safeTitle.utf8).base64EncodedString() - self.linkImageUrl = (og[.image] ?? "") + self.linkImageUrl = URL(string: link)?.resolve(og[.image]) UserDefaultsHelper.saveLinkWithoutFolder(link, self.linkImageUrl, self.titleText) } diff --git a/ios/Podfile b/ios/Podfile index c8de1c42..cfe4acd0 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -27,6 +27,8 @@ end require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) +pod 'OpenGraph' + flutter_ios_podfile_setup target 'Runner' do diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e1b24073..192aa005 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -627,11 +627,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -649,7 +647,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -669,11 +666,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -690,7 +685,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -708,11 +702,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -729,7 +721,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -798,11 +789,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -813,7 +802,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -944,11 +932,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -959,7 +945,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -980,11 +965,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -995,7 +978,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..2ffff48f --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,15 @@ +{ + "originHash" : "f378d0517ac7cb918b2824a5a8a6f024067823ced7c6dd92014d7f870db39003", + "pins" : [ + { + "identity" : "opengraph", + "kind" : "remoteSourceControl", + "location" : "https://github.com/satoshi-takano/OpenGraph", + "state" : { + "revision" : "3ef2b8b9b4972b57e9e78c91c26be770c0110057", + "version" : "1.5.0" + } + } + ], + "version" : 3 +} diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 5100a445..97e3b3c7 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -17,7 +17,9 @@ import 'package:ac_project_app/ui/widget/user/user_info.dart'; import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -476,30 +478,36 @@ class HomePage extends StatelessWidget { ), ), 10.horizontalSpace, - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - pick.title, - style: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.bold, - color: grey900, + Flexible( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(right: 12), + child: Text( + pick.title, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: grey900, + ), + overflow: TextOverflow.ellipsis, + ), ), - ), - 8.verticalSpace, - Text( - pick.describe, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 12.sp, - fontWeight: FontWeight.w500, - color: grey600, + 8.verticalSpace, + Text( + pick.describe, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: grey600, + ), ), - ), - ], + ], + ), ), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index 3ed868d7..d28db32c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.52+52 +version: 1.0.53+53 environment: sdk: ">=3.0.0 <4.0.0" @@ -28,9 +28,9 @@ dependencies: ## login sign_in_with_apple: ^5.0.0 google_sign_in: ^6.1.5 - firebase_core: 2.27.0 - firebase_auth: 4.17.8 - firebase_dynamic_links: 5.4.17 + firebase_core: 2.27.1 + firebase_auth: 4.17.9 + firebase_dynamic_links: 5.4.18 kakao_flutter_sdk_user: ^1.6.1 flutter_dotenv: ^5.0.2 @@ -61,7 +61,7 @@ dependencies: carousel_slider: ^4.2.1 lottie: flutter_slidable: ^3.0.1 - firebase_storage: ^11.6.9 + firebase_storage: ^11.6.10 ## lint very_good_analysis: ^4.0.0+1 From b4227153a037187494180eb61b6fcd0b66c35a25 Mon Sep 17 00:00:00 2001 From: boring-km Date: Thu, 28 Mar 2024 17:41:17 +0900 Subject: [PATCH 16/48] =?UTF-8?q?[hotfix]=20Xcode=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EC=84=A4=EC=A0=95=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Runner.xcodeproj/project.pbxproj | 42 ++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 192aa005..e1b24073 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -627,9 +627,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -647,6 +649,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -666,9 +669,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -685,6 +690,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -702,9 +708,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -721,6 +729,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -789,9 +798,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -802,6 +813,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -932,9 +944,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -945,6 +959,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -965,9 +980,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -978,6 +995,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; From c2c19399893dc0bb96c883945753cbb9ac124ab0 Mon Sep 17 00:00:00 2001 From: boring-km Date: Thu, 28 Mar 2024 17:47:21 +0900 Subject: [PATCH 17/48] =?UTF-8?q?[hotfix]=20Xcode=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EB=8B=A4=EC=8B=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2ffff48f..7340ce68 100644 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,4 @@ { - "originHash" : "f378d0517ac7cb918b2824a5a8a6f024067823ced7c6dd92014d7f870db39003", "pins" : [ { "identity" : "opengraph", @@ -11,5 +10,5 @@ } } ], - "version" : 3 + "version" : 2 } From a8c89729122c93390f3b96df2ad2f1f3f470b781 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 3 Apr 2024 21:04:25 +0900 Subject: [PATCH 18/48] =?UTF-8?q?[feat]=201.0.54=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20-=20=EB=A7=81=ED=81=AC?= =?UTF-8?q?=ED=92=80=ED=94=BD=20UI=20=EC=A1=B0=EC=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/android_cicd.yml | 2 +- .github/workflows/cicd.yml | 4 ++-- .github/workflows/code_coverage.yml | 2 +- .github/workflows/ios_cicd.yml | 2 +- lib/models/linkpool_pick/linkpool_pick.dart | 4 ++++ lib/ui/page/home/home_page.dart | 4 ++-- pubspec.yaml | 2 +- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/android_cicd.yml b/.github/workflows/android_cicd.yml index 62988691..5aa59549 100644 --- a/.github/workflows/android_cicd.yml +++ b/.github/workflows/android_cicd.yml @@ -16,7 +16,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 6964a6ad..d26ff1a3 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 59604364..70a860bf 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/.github/workflows/ios_cicd.yml b/.github/workflows/ios_cicd.yml index 40cfc0b8..bbbf8b1b 100644 --- a/.github/workflows/ios_cicd.yml +++ b/.github/workflows/ios_cicd.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/lib/models/linkpool_pick/linkpool_pick.dart b/lib/models/linkpool_pick/linkpool_pick.dart index 43bf5ada..8c373782 100644 --- a/lib/models/linkpool_pick/linkpool_pick.dart +++ b/lib/models/linkpool_pick/linkpool_pick.dart @@ -39,4 +39,8 @@ class LinkpoolPick extends Equatable { Color getColor() { return Color(int.parse(backgroundColor.replaceAll('#', ''), radix: 16)); } + + String getPerfectTitle() { + return title.replaceAll(r'\n', '\n'); + } } diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 97e3b3c7..8c814bcc 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -486,13 +486,13 @@ class HomePage extends StatelessWidget { Padding( padding: const EdgeInsets.only(right: 12), child: Text( - pick.title, + pick.getPerfectTitle(), + maxLines: 2, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.bold, color: grey900, ), - overflow: TextOverflow.ellipsis, ), ), 8.verticalSpace, diff --git a/pubspec.yaml b/pubspec.yaml index d28db32c..96b89dcf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.53+53 +version: 1.0.54+54 environment: sdk: ">=3.0.0 <4.0.0" From 3f684858bf270a114f8077f970f169dbe098b96a Mon Sep 17 00:00:00 2001 From: Kangmin Date: Wed, 3 Apr 2024 21:09:58 +0900 Subject: [PATCH 19/48] 1.0.54 Update (#209) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [fix] iOS OpenGraph 썸네일 이미지 제대로 안나오는 부분 수정 일단 ("//" 으로 시작하는 링크만) * [fix+version] 1.0.53 업데이트 링풀픽 텍스트 안 잘리게 처리 * [hotfix] Xcode 프로젝트 설정 다시 변경 * [hotfix] Xcode 프로젝트 다시 설정 * [feat] 1.0.54 버전 업데이트 - 링크풀픽 UI 조절 --- .github/workflows/android_cicd.yml | 2 +- .github/workflows/cicd.yml | 4 ++-- .github/workflows/code_coverage.yml | 2 +- .github/workflows/ios_cicd.yml | 2 +- ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved | 3 +-- lib/models/linkpool_pick/linkpool_pick.dart | 4 ++++ lib/ui/page/home/home_page.dart | 4 ++-- pubspec.yaml | 2 +- 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/android_cicd.yml b/.github/workflows/android_cicd.yml index 62988691..5aa59549 100644 --- a/.github/workflows/android_cicd.yml +++ b/.github/workflows/android_cicd.yml @@ -16,7 +16,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 6964a6ad..d26ff1a3 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 59604364..70a860bf 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/.github/workflows/ios_cicd.yml b/.github/workflows/ios_cicd.yml index 40cfc0b8..bbbf8b1b 100644 --- a/.github/workflows/ios_cicd.yml +++ b/.github/workflows/ios_cicd.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.4' + flutter-version: '3.19.5' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2ffff48f..7340ce68 100644 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,4 @@ { - "originHash" : "f378d0517ac7cb918b2824a5a8a6f024067823ced7c6dd92014d7f870db39003", "pins" : [ { "identity" : "opengraph", @@ -11,5 +10,5 @@ } } ], - "version" : 3 + "version" : 2 } diff --git a/lib/models/linkpool_pick/linkpool_pick.dart b/lib/models/linkpool_pick/linkpool_pick.dart index 43bf5ada..8c373782 100644 --- a/lib/models/linkpool_pick/linkpool_pick.dart +++ b/lib/models/linkpool_pick/linkpool_pick.dart @@ -39,4 +39,8 @@ class LinkpoolPick extends Equatable { Color getColor() { return Color(int.parse(backgroundColor.replaceAll('#', ''), radix: 16)); } + + String getPerfectTitle() { + return title.replaceAll(r'\n', '\n'); + } } diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 97e3b3c7..8c814bcc 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -486,13 +486,13 @@ class HomePage extends StatelessWidget { Padding( padding: const EdgeInsets.only(right: 12), child: Text( - pick.title, + pick.getPerfectTitle(), + maxLines: 2, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.bold, color: grey900, ), - overflow: TextOverflow.ellipsis, ), ), 8.verticalSpace, diff --git a/pubspec.yaml b/pubspec.yaml index d28db32c..96b89dcf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.53+53 +version: 1.0.54+54 environment: sdk: ">=3.0.0 <4.0.0" From 89a073f62cff35fd26c003ca288c484a95466553 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 3 Apr 2024 21:23:25 +0900 Subject: [PATCH 20/48] =?UTF-8?q?[feat]=201.0.54=20=EB=B2=84=EC=A0=84=20io?= =?UTF-8?q?s=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20Profile=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Runner.xcodeproj/project.pbxproj | 42 ++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 192aa005..e1b24073 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -627,9 +627,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -647,6 +649,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -666,9 +669,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -685,6 +690,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -702,9 +708,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -721,6 +729,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -789,9 +798,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -802,6 +813,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -932,9 +944,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -945,6 +959,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -965,9 +980,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -978,6 +995,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; From d08002d2749f9090ed77192f6832ae6cb6e48ee1 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 10 Apr 2024 21:26:29 +0900 Subject: [PATCH 21/48] =?UTF-8?q?[feat]=201.0.55=20=EB=B2=84=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 디자인에 맞춰 일부 UI 자간 조절 - 업로드 화면에서 또 업로드 화면 열지 않도록 수정 - 마이폴더에서 검색 버그 수정 --- lib/cubits/home/search_links_cubit.dart | 10 ++++++-- lib/provider/upload_state_variable.dart | 1 + lib/ui/page/home/home_page.dart | 5 ++-- lib/ui/page/my_folder/my_folder_page.dart | 2 ++ lib/ui/view/home_view.dart | 29 +++++++++++++---------- lib/ui/view/links/search_view.dart | 3 +++ lib/ui/view/upload_view.dart | 8 +++++++ lib/ui/widget/user/user_info.dart | 1 + pubspec.yaml | 2 +- 9 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 lib/provider/upload_state_variable.dart diff --git a/lib/cubits/home/search_links_cubit.dart b/lib/cubits/home/search_links_cubit.dart index 0753973f..9e4b40c0 100644 --- a/lib/cubits/home/search_links_cubit.dart +++ b/lib/cubits/home/search_links_cubit.dart @@ -13,8 +13,10 @@ class SearchLinksCubit extends Cubit { HasMoreCubit hasMore = HasMoreCubit(); int page = 0; String currentText = ''; + bool isMine = false; Future searchLinks(String text, int pageNum) async { + isMine = false; currentText = text; emit(LinkListLoadingState()); @@ -31,6 +33,7 @@ class SearchLinksCubit extends Cubit { } Future searchMyLinks(String text, int pageNum) async { + isMine = true; currentText = text; emit(LinkListLoadingState()); @@ -46,11 +49,14 @@ class SearchLinksCubit extends Cubit { ); } - Future refresh() => searchLinks(currentText, 0); + Future refresh() => + isMine ? searchMyLinks(currentText, 0) : searchLinks(currentText, 0); void loadMore() { if (hasMore.state == ScrollableType.can) { - searchLinks(currentText, page + 1); + isMine + ? searchMyLinks(currentText, page + 1) + : searchLinks(currentText, page + 1); } } diff --git a/lib/provider/upload_state_variable.dart b/lib/provider/upload_state_variable.dart new file mode 100644 index 00000000..66bd5bba --- /dev/null +++ b/lib/provider/upload_state_variable.dart @@ -0,0 +1 @@ +bool isNotUploadState = true; diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 8c814bcc..9f23cdbf 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -17,9 +17,7 @@ import 'package:ac_project_app/ui/widget/user/user_info.dart'; import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -209,6 +207,7 @@ class HomePage extends StatelessWidget { fontSize: 16.sp, color: grey800, height: (26 / 16).h, + letterSpacing: -0.1, ), ), ], @@ -272,6 +271,7 @@ class HomePage extends StatelessWidget { color: blackBold, fontWeight: FontWeight.bold, fontSize: 16.sp, + letterSpacing: -0.2, ), ), ), @@ -315,6 +315,7 @@ class HomePage extends StatelessWidget { style: TextStyle( color: grey500, fontSize: 12.sp, + letterSpacing: -0.1, ), ), ), diff --git a/lib/ui/page/my_folder/my_folder_page.dart b/lib/ui/page/my_folder/my_folder_page.dart index 583a126a..fefa8264 100644 --- a/lib/ui/page/my_folder/my_folder_page.dart +++ b/lib/ui/page/my_folder/my_folder_page.dart @@ -330,6 +330,7 @@ class _MyFolderPageState extends State fontWeight: FontWeight.bold, fontSize: 16.sp, color: blackBold, + letterSpacing: -0.2, ), ), ), @@ -342,6 +343,7 @@ class _MyFolderPageState extends State fontSize: 12.sp, fontWeight: FontWeight.w500, color: greyText, + letterSpacing: -0.2, ), ), ], diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index 6defe2e7..460b9a4d 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -11,6 +11,7 @@ import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/provider/api/folders/folder_api.dart'; import 'package:ac_project_app/provider/kakao/kakao.dart'; +import 'package:ac_project_app/provider/upload_state_variable.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/page/home/home_page.dart'; import 'package:ac_project_app/ui/page/my_folder/my_folder_page.dart'; @@ -68,20 +69,22 @@ class _HomeViewState extends State with WidgetsBindingObserver { } void navigateToUploadViewIfClipboardIsValid() { - Clipboard.getData(Clipboard.kTextPlain).then((value) { - isValidUrl(value?.text ?? '').then((isValid) { - if (isValid) { - Clipboard.setData(const ClipboardData(text: '')); - Navigator.pushNamed( - context, - Routes.upload, - arguments: { - 'url': value?.text, - }, - ); - } + if (isNotUploadState) { + Clipboard.getData(Clipboard.kTextPlain).then((value) { + isValidUrl(value?.text ?? '').then((isValid) { + if (isValid) { + Clipboard.setData(const ClipboardData(text: '')); + Navigator.pushNamed( + context, + Routes.upload, + arguments: { + 'url': value?.text, + }, + ); + } + }); }); - }); + } } void resetResumeState() { diff --git a/lib/ui/view/links/search_view.dart b/lib/ui/view/links/search_view.dart index 7c70547e..ccc19e0c 100644 --- a/lib/ui/view/links/search_view.dart +++ b/lib/ui/view/links/search_view.dart @@ -214,6 +214,7 @@ class _SearchViewState extends State { fontSize: 16.sp, color: grey800, height: (26 / 16).h, + letterSpacing: -0.1, ), ), ], @@ -284,6 +285,7 @@ class _SearchViewState extends State { color: blackBold, fontWeight: FontWeight.bold, fontSize: 16.sp, + letterSpacing: -0.2, ), ), ), @@ -330,6 +332,7 @@ class _SearchViewState extends State { style: TextStyle( color: grey500, fontSize: 12.sp, + letterSpacing: -0.1, ), ), ), diff --git a/lib/ui/view/upload_view.dart b/lib/ui/view/upload_view.dart index 5c64a1b7..a0355a63 100644 --- a/lib/ui/view/upload_view.dart +++ b/lib/ui/view/upload_view.dart @@ -10,6 +10,7 @@ import 'package:ac_project_app/cubits/sign_up/button_state_cubit.dart'; import 'package:ac_project_app/enums/navigator_pop_type.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/models/link/upload_type.dart'; +import 'package:ac_project_app/provider/upload_state_variable.dart'; import 'package:ac_project_app/ui/widget/add_folder/folder_add_title.dart'; import 'package:ac_project_app/ui/widget/add_folder/horizontal_folder_list.dart'; import 'package:ac_project_app/ui/widget/add_folder/subtitle.dart'; @@ -51,9 +52,16 @@ class _UploadViewState extends State { linkTextController.text = widget.args!['url'] as String; buttonState = ButtonState.enabled; } + isNotUploadState = false; super.initState(); } + @override + void dispose() { + isNotUploadState = true; + super.dispose(); + } + @override Widget build(BuildContext context) { return MultiBlocProvider( diff --git a/lib/ui/widget/user/user_info.dart b/lib/ui/widget/user/user_info.dart index e533c218..6cac48c8 100644 --- a/lib/ui/widget/user/user_info.dart +++ b/lib/ui/widget/user/user_info.dart @@ -65,6 +65,7 @@ Widget UserInfoWidget({ style: const TextStyle( color: grey900, fontWeight: FontWeight.w500, + letterSpacing: -0.2, ), ), Container( diff --git a/pubspec.yaml b/pubspec.yaml index 96b89dcf..49df8395 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.54+54 +version: 1.0.55+55 environment: sdk: ">=3.0.0 <4.0.0" From b3ad1f855287746ecba67533dcace77c61fd3a1f Mon Sep 17 00:00:00 2001 From: Kangmin Date: Wed, 10 Apr 2024 21:28:35 +0900 Subject: [PATCH 22/48] =?UTF-8?q?1.0.55=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20(#210)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [fix] iOS OpenGraph 썸네일 이미지 제대로 안나오는 부분 수정 일단 ("//" 으로 시작하는 링크만) * [fix+version] 1.0.53 업데이트 링풀픽 텍스트 안 잘리게 처리 * [hotfix] Xcode 프로젝트 설정 다시 변경 * [hotfix] Xcode 프로젝트 다시 설정 * [feat] 1.0.54 버전 업데이트 - 링크풀픽 UI 조절 * [feat] 1.0.55 버전 - 디자인에 맞춰 일부 UI 자간 조절 - 업로드 화면에서 또 업로드 화면 열지 않도록 수정 - 마이폴더에서 검색 버그 수정 --- lib/cubits/home/search_links_cubit.dart | 10 ++++++-- lib/provider/upload_state_variable.dart | 1 + lib/ui/page/home/home_page.dart | 5 ++-- lib/ui/page/my_folder/my_folder_page.dart | 2 ++ lib/ui/view/home_view.dart | 29 +++++++++++++---------- lib/ui/view/links/search_view.dart | 3 +++ lib/ui/view/upload_view.dart | 8 +++++++ lib/ui/widget/user/user_info.dart | 1 + pubspec.yaml | 2 +- 9 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 lib/provider/upload_state_variable.dart diff --git a/lib/cubits/home/search_links_cubit.dart b/lib/cubits/home/search_links_cubit.dart index 0753973f..9e4b40c0 100644 --- a/lib/cubits/home/search_links_cubit.dart +++ b/lib/cubits/home/search_links_cubit.dart @@ -13,8 +13,10 @@ class SearchLinksCubit extends Cubit { HasMoreCubit hasMore = HasMoreCubit(); int page = 0; String currentText = ''; + bool isMine = false; Future searchLinks(String text, int pageNum) async { + isMine = false; currentText = text; emit(LinkListLoadingState()); @@ -31,6 +33,7 @@ class SearchLinksCubit extends Cubit { } Future searchMyLinks(String text, int pageNum) async { + isMine = true; currentText = text; emit(LinkListLoadingState()); @@ -46,11 +49,14 @@ class SearchLinksCubit extends Cubit { ); } - Future refresh() => searchLinks(currentText, 0); + Future refresh() => + isMine ? searchMyLinks(currentText, 0) : searchLinks(currentText, 0); void loadMore() { if (hasMore.state == ScrollableType.can) { - searchLinks(currentText, page + 1); + isMine + ? searchMyLinks(currentText, page + 1) + : searchLinks(currentText, page + 1); } } diff --git a/lib/provider/upload_state_variable.dart b/lib/provider/upload_state_variable.dart new file mode 100644 index 00000000..66bd5bba --- /dev/null +++ b/lib/provider/upload_state_variable.dart @@ -0,0 +1 @@ +bool isNotUploadState = true; diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 8c814bcc..9f23cdbf 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -17,9 +17,7 @@ import 'package:ac_project_app/ui/widget/user/user_info.dart'; import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -209,6 +207,7 @@ class HomePage extends StatelessWidget { fontSize: 16.sp, color: grey800, height: (26 / 16).h, + letterSpacing: -0.1, ), ), ], @@ -272,6 +271,7 @@ class HomePage extends StatelessWidget { color: blackBold, fontWeight: FontWeight.bold, fontSize: 16.sp, + letterSpacing: -0.2, ), ), ), @@ -315,6 +315,7 @@ class HomePage extends StatelessWidget { style: TextStyle( color: grey500, fontSize: 12.sp, + letterSpacing: -0.1, ), ), ), diff --git a/lib/ui/page/my_folder/my_folder_page.dart b/lib/ui/page/my_folder/my_folder_page.dart index 583a126a..fefa8264 100644 --- a/lib/ui/page/my_folder/my_folder_page.dart +++ b/lib/ui/page/my_folder/my_folder_page.dart @@ -330,6 +330,7 @@ class _MyFolderPageState extends State fontWeight: FontWeight.bold, fontSize: 16.sp, color: blackBold, + letterSpacing: -0.2, ), ), ), @@ -342,6 +343,7 @@ class _MyFolderPageState extends State fontSize: 12.sp, fontWeight: FontWeight.w500, color: greyText, + letterSpacing: -0.2, ), ), ], diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index 6defe2e7..460b9a4d 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -11,6 +11,7 @@ import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/provider/api/folders/folder_api.dart'; import 'package:ac_project_app/provider/kakao/kakao.dart'; +import 'package:ac_project_app/provider/upload_state_variable.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/page/home/home_page.dart'; import 'package:ac_project_app/ui/page/my_folder/my_folder_page.dart'; @@ -68,20 +69,22 @@ class _HomeViewState extends State with WidgetsBindingObserver { } void navigateToUploadViewIfClipboardIsValid() { - Clipboard.getData(Clipboard.kTextPlain).then((value) { - isValidUrl(value?.text ?? '').then((isValid) { - if (isValid) { - Clipboard.setData(const ClipboardData(text: '')); - Navigator.pushNamed( - context, - Routes.upload, - arguments: { - 'url': value?.text, - }, - ); - } + if (isNotUploadState) { + Clipboard.getData(Clipboard.kTextPlain).then((value) { + isValidUrl(value?.text ?? '').then((isValid) { + if (isValid) { + Clipboard.setData(const ClipboardData(text: '')); + Navigator.pushNamed( + context, + Routes.upload, + arguments: { + 'url': value?.text, + }, + ); + } + }); }); - }); + } } void resetResumeState() { diff --git a/lib/ui/view/links/search_view.dart b/lib/ui/view/links/search_view.dart index 7c70547e..ccc19e0c 100644 --- a/lib/ui/view/links/search_view.dart +++ b/lib/ui/view/links/search_view.dart @@ -214,6 +214,7 @@ class _SearchViewState extends State { fontSize: 16.sp, color: grey800, height: (26 / 16).h, + letterSpacing: -0.1, ), ), ], @@ -284,6 +285,7 @@ class _SearchViewState extends State { color: blackBold, fontWeight: FontWeight.bold, fontSize: 16.sp, + letterSpacing: -0.2, ), ), ), @@ -330,6 +332,7 @@ class _SearchViewState extends State { style: TextStyle( color: grey500, fontSize: 12.sp, + letterSpacing: -0.1, ), ), ), diff --git a/lib/ui/view/upload_view.dart b/lib/ui/view/upload_view.dart index 5c64a1b7..a0355a63 100644 --- a/lib/ui/view/upload_view.dart +++ b/lib/ui/view/upload_view.dart @@ -10,6 +10,7 @@ import 'package:ac_project_app/cubits/sign_up/button_state_cubit.dart'; import 'package:ac_project_app/enums/navigator_pop_type.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/models/link/upload_type.dart'; +import 'package:ac_project_app/provider/upload_state_variable.dart'; import 'package:ac_project_app/ui/widget/add_folder/folder_add_title.dart'; import 'package:ac_project_app/ui/widget/add_folder/horizontal_folder_list.dart'; import 'package:ac_project_app/ui/widget/add_folder/subtitle.dart'; @@ -51,9 +52,16 @@ class _UploadViewState extends State { linkTextController.text = widget.args!['url'] as String; buttonState = ButtonState.enabled; } + isNotUploadState = false; super.initState(); } + @override + void dispose() { + isNotUploadState = true; + super.dispose(); + } + @override Widget build(BuildContext context) { return MultiBlocProvider( diff --git a/lib/ui/widget/user/user_info.dart b/lib/ui/widget/user/user_info.dart index e533c218..6cac48c8 100644 --- a/lib/ui/widget/user/user_info.dart +++ b/lib/ui/widget/user/user_info.dart @@ -65,6 +65,7 @@ Widget UserInfoWidget({ style: const TextStyle( color: grey900, fontWeight: FontWeight.w500, + letterSpacing: -0.2, ), ), Container( diff --git a/pubspec.yaml b/pubspec.yaml index 96b89dcf..49df8395 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.54+54 +version: 1.0.55+55 environment: sdk: ">=3.0.0 <4.0.0" From 160806d58d5a2c69db41f3d8925d7a750e8d4f29 Mon Sep 17 00:00:00 2001 From: boring-km Date: Fri, 19 Apr 2024 14:43:40 +0900 Subject: [PATCH 23/48] =?UTF-8?q?[fix]=20UI=20=EC=88=98=EC=A0=95=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EB=B0=98=EC=98=81=20-=20=EC=9E=90=EA=B0=84,=20?= =?UTF-8?q?=ED=96=89=EA=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ui/page/home/home_page.dart | 57 ++++++++++++++++------------- lib/ui/view/links/my_link_view.dart | 3 ++ 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 9f23cdbf..8a4970b6 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -381,6 +381,7 @@ class HomePage extends StatelessWidget { fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.black, + letterSpacing: -0.2, ), ), ), @@ -426,6 +427,7 @@ class HomePage extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(6.r)), ), child: Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.only(top: 12.h, left: 10.w, bottom: 12.h), @@ -479,35 +481,40 @@ class HomePage extends StatelessWidget { ), ), 10.horizontalSpace, - Flexible( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(right: 12), - child: Text( - pick.getPerfectTitle(), + Padding( + padding: EdgeInsets.only(top: 24.h), + child: Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(right: 12), + child: Text( + pick.getPerfectTitle(), + maxLines: 2, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: grey900, + letterSpacing: -0.17, + height: 21/16, + ), + ), + ), + 3.verticalSpace, + Text( + pick.describe, maxLines: 2, + overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.bold, - color: grey900, + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: grey600, + letterSpacing: -0.17, ), ), - ), - 8.verticalSpace, - Text( - pick.describe, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 12.sp, - fontWeight: FontWeight.w500, - color: grey600, - ), - ), - ], + ], + ), ), ), ], diff --git a/lib/ui/view/links/my_link_view.dart b/lib/ui/view/links/my_link_view.dart index 5f49a9b0..12e3ae4c 100644 --- a/lib/ui/view/links/my_link_view.dart +++ b/lib/ui/view/links/my_link_view.dart @@ -586,6 +586,7 @@ class MyLinkView extends StatelessWidget { color: blackBold, overflow: TextOverflow.ellipsis, height: (19 / 16).h, + letterSpacing: -0.2, ), ), SizedBox(height: 7.h), @@ -596,6 +597,7 @@ class MyLinkView extends StatelessWidget { fontSize: 12.sp, color: greyText, overflow: TextOverflow.ellipsis, + letterSpacing: -0.1, ), ), ], @@ -610,6 +612,7 @@ class MyLinkView extends StatelessWidget { fontSize: 12.sp, color: const Color(0xFFC0C2C4), overflow: TextOverflow.ellipsis, + letterSpacing: -0.1, ), ), ), From 8574870e8639092931b149558109570c945ee793 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 1 May 2024 22:16:46 +0900 Subject: [PATCH 24/48] =?UTF-8?q?[hotfix]=201.0.56=20=EB=B2=84=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 백엔드 API 긴급 변경 - UI 일부 수정 --- lib/const/strings.dart | 2 +- lib/ui/view/links/link_detail_view.dart | 1 + pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/const/strings.dart b/lib/const/strings.dart index 27c559ae..2a9de55d 100644 --- a/lib/const/strings.dart +++ b/lib/const/strings.dart @@ -18,7 +18,7 @@ const helpLink = 'https://linkpoolpd.notion.site/c6ea6729dfac4dbc89c95d294bca43f8'; // API LINK -const baseUrl = 'https://api.linkpool.co.kr'; +const baseUrl = 'http://acprojectapiserver-env.eba-tazwmppk.ap-northeast-2.elasticbeanstalk.com'; //warning message const warningMsgTitle = '링크풀은 건전한 링크 관리 및 공유 문화를 지향해요'; diff --git a/lib/ui/view/links/link_detail_view.dart b/lib/ui/view/links/link_detail_view.dart index 42d48c5f..5cdd495e 100644 --- a/lib/ui/view/links/link_detail_view.dart +++ b/lib/ui/view/links/link_detail_view.dart @@ -110,6 +110,7 @@ class LinkDetailView extends StatelessWidget { ) { return Scaffold( resizeToAvoidBottomInset: false, + backgroundColor: Colors.white, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, diff --git a/pubspec.yaml b/pubspec.yaml index 49df8395..2c8d15a0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.55+55 +version: 1.0.56+56 environment: sdk: ">=3.0.0 <4.0.0" From 21924d0289f08bd46e4d428739c58826147cef36 Mon Sep 17 00:00:00 2001 From: Kangmin Date: Wed, 1 May 2024 22:19:25 +0900 Subject: [PATCH 25/48] =?UTF-8?q?1.0.56=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [fix] UI 수정사항 반영 - 자간, 행간 * [hotfix] 1.0.56 버전 - 백엔드 API 긴급 변경 - UI 일부 수정 --- lib/const/strings.dart | 2 +- lib/ui/page/home/home_page.dart | 57 ++++++++++++++----------- lib/ui/view/links/link_detail_view.dart | 1 + lib/ui/view/links/my_link_view.dart | 3 ++ pubspec.yaml | 2 +- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/lib/const/strings.dart b/lib/const/strings.dart index 27c559ae..2a9de55d 100644 --- a/lib/const/strings.dart +++ b/lib/const/strings.dart @@ -18,7 +18,7 @@ const helpLink = 'https://linkpoolpd.notion.site/c6ea6729dfac4dbc89c95d294bca43f8'; // API LINK -const baseUrl = 'https://api.linkpool.co.kr'; +const baseUrl = 'http://acprojectapiserver-env.eba-tazwmppk.ap-northeast-2.elasticbeanstalk.com'; //warning message const warningMsgTitle = '링크풀은 건전한 링크 관리 및 공유 문화를 지향해요'; diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 9f23cdbf..8a4970b6 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -381,6 +381,7 @@ class HomePage extends StatelessWidget { fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.black, + letterSpacing: -0.2, ), ), ), @@ -426,6 +427,7 @@ class HomePage extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(6.r)), ), child: Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.only(top: 12.h, left: 10.w, bottom: 12.h), @@ -479,35 +481,40 @@ class HomePage extends StatelessWidget { ), ), 10.horizontalSpace, - Flexible( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(right: 12), - child: Text( - pick.getPerfectTitle(), + Padding( + padding: EdgeInsets.only(top: 24.h), + child: Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(right: 12), + child: Text( + pick.getPerfectTitle(), + maxLines: 2, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: grey900, + letterSpacing: -0.17, + height: 21/16, + ), + ), + ), + 3.verticalSpace, + Text( + pick.describe, maxLines: 2, + overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.bold, - color: grey900, + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: grey600, + letterSpacing: -0.17, ), ), - ), - 8.verticalSpace, - Text( - pick.describe, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 12.sp, - fontWeight: FontWeight.w500, - color: grey600, - ), - ), - ], + ], + ), ), ), ], diff --git a/lib/ui/view/links/link_detail_view.dart b/lib/ui/view/links/link_detail_view.dart index 42d48c5f..5cdd495e 100644 --- a/lib/ui/view/links/link_detail_view.dart +++ b/lib/ui/view/links/link_detail_view.dart @@ -110,6 +110,7 @@ class LinkDetailView extends StatelessWidget { ) { return Scaffold( resizeToAvoidBottomInset: false, + backgroundColor: Colors.white, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, diff --git a/lib/ui/view/links/my_link_view.dart b/lib/ui/view/links/my_link_view.dart index 5f49a9b0..12e3ae4c 100644 --- a/lib/ui/view/links/my_link_view.dart +++ b/lib/ui/view/links/my_link_view.dart @@ -586,6 +586,7 @@ class MyLinkView extends StatelessWidget { color: blackBold, overflow: TextOverflow.ellipsis, height: (19 / 16).h, + letterSpacing: -0.2, ), ), SizedBox(height: 7.h), @@ -596,6 +597,7 @@ class MyLinkView extends StatelessWidget { fontSize: 12.sp, color: greyText, overflow: TextOverflow.ellipsis, + letterSpacing: -0.1, ), ), ], @@ -610,6 +612,7 @@ class MyLinkView extends StatelessWidget { fontSize: 12.sp, color: const Color(0xFFC0C2C4), overflow: TextOverflow.ellipsis, + letterSpacing: -0.1, ), ), ), diff --git a/pubspec.yaml b/pubspec.yaml index 49df8395..2c8d15a0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.55+55 +version: 1.0.56+56 environment: sdk: ">=3.0.0 <4.0.0" From 428858be9afa9e5e6bfcb76b3a97f7fdc37f63ca Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 1 May 2024 23:36:54 +0900 Subject: [PATCH 26/48] =?UTF-8?q?[hotfix]=201.0.56=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?ios=20=EA=B8=B4=EA=B8=89=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/main.dart | 2 +- lib/ui/view/tutorial_view.dart | 100 ++++++++++++++++----------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 3788a6c2..41bafec9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -45,7 +45,7 @@ class MyApp extends StatelessWidget { child: OKToast( child: MaterialApp( debugShowCheckedModeBanner: false, - initialRoute: Routes.splash, + initialRoute: Routes.tutorial, onGenerateRoute: Pages.getPages, themeMode: ThemeMode.light, theme: ThemeData( diff --git a/lib/ui/view/tutorial_view.dart b/lib/ui/view/tutorial_view.dart index 03038790..079c0e8a 100644 --- a/lib/ui/view/tutorial_view.dart +++ b/lib/ui/view/tutorial_view.dart @@ -30,61 +30,61 @@ class _TutorialViewState extends State { items: tutorials .map( (tutorial) => Column( - mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - tutorial.image, - height: (height * 0.6).h, - fit: BoxFit.cover, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: tutorials.asMap().entries.map((entry) { - return GestureDetector( - onTap: () => _controller.animateToPage(entry.key), - child: Container( - width: 7.w, - height: 7.h, - margin: EdgeInsets.symmetric( - horizontal: 3.w, - ), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _current == entry.key - ? primary700 - : greyDot, - ), + mainAxisSize: MainAxisSize.min, + children: [ + Image.asset( + tutorial.image, + height: (height * 0.6).h, + fit: BoxFit.cover, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: tutorials.asMap().entries.map((entry) { + return GestureDetector( + onTap: () => _controller.animateToPage(entry.key), + child: Container( + width: 7.w, + height: 7.h, + margin: EdgeInsets.symmetric( + horizontal: 3.w, + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _current == entry.key + ? primary700 + : greyDot, + ), + ), + ); + }).toList(), + ), + SizedBox(height: 22.h), + Text( + tutorial.title, + style: TextStyle( + fontSize: 26.sp, + letterSpacing: -0.2.w, + color: blackTutorial, ), - ); - }).toList(), - ), - SizedBox(height: 22.h), - Text( - tutorial.title, - style: TextStyle( - fontSize: 26.sp, - letterSpacing: -0.2.w, - color: blackTutorial, - ), - ).bold(), - SizedBox(height: 10.h), - Text( - tutorial.subTitle, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14.sp, - color: greyTutorial, - letterSpacing: -0.3.w, - height: 24.h / 14, - ), + ).bold(), + SizedBox(height: 10.h), + Text( + tutorial.subTitle, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14.sp, + color: greyTutorial, + letterSpacing: -0.3.w, + height: 24.h / 14, + ), + ), + ], ), - ], - ), - ) + ) .toList(), carouselController: _controller, options: CarouselOptions( - height: (height * 646 / 812 - 10).h, + height: (height * 2) / 3, viewportFraction: 1, enableInfiniteScroll: false, onPageChanged: (index, reason) { From 97c947b584505f277b4917634d809d32a578b891 Mon Sep 17 00:00:00 2001 From: boring-km Date: Tue, 7 May 2024 23:08:51 +0900 Subject: [PATCH 27/48] =?UTF-8?q?[hotfix]=201.0.57=20=ED=8A=9C=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=EC=96=BC=EB=A1=9C=20=EC=8B=9C=EC=9E=91=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=ED=8A=9C=ED=86=A0=EB=A6=AC=EC=96=BC=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20=EC=95=88=20=EC=9E=98=EB=A6=AC=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cicd.yml | 4 ++-- .github/workflows/code_coverage.yml | 2 +- lib/main.dart | 2 +- lib/ui/view/tutorial_view.dart | 2 +- pubspec.yaml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index d26ff1a3..6bd8cbf0 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.5' + flutter-version: '3.19.6' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.5' + flutter-version: '3.19.6' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 70a860bf..b9e8bbde 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.5' + flutter-version: '3.19.6' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/lib/main.dart b/lib/main.dart index 41bafec9..3788a6c2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -45,7 +45,7 @@ class MyApp extends StatelessWidget { child: OKToast( child: MaterialApp( debugShowCheckedModeBanner: false, - initialRoute: Routes.tutorial, + initialRoute: Routes.splash, onGenerateRoute: Pages.getPages, themeMode: ThemeMode.light, theme: ThemeData( diff --git a/lib/ui/view/tutorial_view.dart b/lib/ui/view/tutorial_view.dart index 079c0e8a..16eb83e9 100644 --- a/lib/ui/view/tutorial_view.dart +++ b/lib/ui/view/tutorial_view.dart @@ -84,7 +84,7 @@ class _TutorialViewState extends State { .toList(), carouselController: _controller, options: CarouselOptions( - height: (height * 2) / 3, + height: (height * 3) / 4, viewportFraction: 1, enableInfiniteScroll: false, onPageChanged: (index, reason) { diff --git a/pubspec.yaml b/pubspec.yaml index 2c8d15a0..b010784b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.56+56 +version: 1.0.57+57 environment: sdk: ">=3.0.0 <4.0.0" From 640056bc3432e6225f635f49bb6b0516001f7811 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 8 May 2024 00:21:00 +0900 Subject: [PATCH 28/48] =?UTF-8?q?[hotfix]=201.0.58=20workflow=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EC=A0=84=EC=9C=BC=EB=A1=9C=20=EB=B0=B0=ED=8F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devtools_options.yaml | 1 + .../xcshareddata/swiftpm/Package.resolved | 14 -------------- lib/ui/view/tutorial_view.dart | 2 +- pubspec.yaml | 2 +- 4 files changed, 3 insertions(+), 16 deletions(-) create mode 100644 devtools_options.yaml delete mode 100644 ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 00000000..7e7e7f67 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1 @@ +extensions: diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 7340ce68..00000000 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,14 +0,0 @@ -{ - "pins" : [ - { - "identity" : "opengraph", - "kind" : "remoteSourceControl", - "location" : "https://github.com/satoshi-takano/OpenGraph", - "state" : { - "revision" : "3ef2b8b9b4972b57e9e78c91c26be770c0110057", - "version" : "1.5.0" - } - } - ], - "version" : 2 -} diff --git a/lib/ui/view/tutorial_view.dart b/lib/ui/view/tutorial_view.dart index 16eb83e9..6462a2d2 100644 --- a/lib/ui/view/tutorial_view.dart +++ b/lib/ui/view/tutorial_view.dart @@ -84,7 +84,7 @@ class _TutorialViewState extends State { .toList(), carouselController: _controller, options: CarouselOptions( - height: (height * 3) / 4, + height: (height * 4) / 5, viewportFraction: 1, enableInfiniteScroll: false, onPageChanged: (index, reason) { diff --git a/pubspec.yaml b/pubspec.yaml index b010784b..0faba2a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.57+57 +version: 1.0.58+58 environment: sdk: ">=3.0.0 <4.0.0" From dad5ca2c66d048d81bf414b50c10094217674757 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 8 May 2024 01:14:45 +0900 Subject: [PATCH 29/48] =?UTF-8?q?[hotfix]=201.0.59=20UI=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 +++- ios/Podfile | 4 +-- ios/Runner.xcodeproj/project.pbxproj | 31 +++++++---------- lib/ui/page/home/home_page.dart | 52 +++++++++++++--------------- pubspec.yaml | 10 +++--- 5 files changed, 48 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 73472c30..f67ea570 100644 --- a/.gitignore +++ b/.gitignore @@ -53,4 +53,8 @@ lib/firebase_options.dart .env # test coverage -coverage \ No newline at end of file +coverage + +# FVM Version Cache +.fvm/ +.fvmrc \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile index cfe4acd0..7a04147c 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '12.0' +# platform :ios, '15.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. @@ -27,8 +27,6 @@ end require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) -pod 'OpenGraph' - flutter_ios_podfile_setup target 'Runner' do diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e1b24073..6467574c 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -14,8 +14,6 @@ 0F872E4128D875E3002954CC /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0F872E3F28D875E3002954CC /* MainInterface.storyboard */; }; 0F872E4528D875E3002954CC /* Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0F872E3B28D875E3002954CC /* Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 0F8AD1C028FC39E30006B1D6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0F8AD1BF28FC39E30006B1D6 /* Images.xcassets */; }; - 0FB992B12917F2C6005F5D9C /* OpenGraph in Frameworks */ = {isa = PBXBuildFile; productRef = 0FB992B02917F2C6005F5D9C /* OpenGraph */; }; - 0FB992B32917F2F4005F5D9C /* OpenGraph in Frameworks */ = {isa = PBXBuildFile; productRef = 0FB992B22917F2F4005F5D9C /* OpenGraph */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 51F09A2629711B8A00BA053D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 51F09A2529711B8A00BA053D /* GoogleService-Info.plist */; }; @@ -38,6 +36,8 @@ AE83E34C291CB70C00A43A2D /* FolderSaveSuccessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE83E34B291CB70C00A43A2D /* FolderSaveSuccessViewController.swift */; }; AE83E34E291CB8FB00A43A2D /* SaveType.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE83E34D291CB8FB00A43A2D /* SaveType.swift */; }; AE83E351291CC6AA00A43A2D /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE83E350291CC6AA00A43A2D /* PaddingLabel.swift */; }; + AE9181C22BEA83D8003E77E3 /* OpenGraph in Frameworks */ = {isa = PBXBuildFile; productRef = AE9181C12BEA83D8003E77E3 /* OpenGraph */; }; + AE9181C42BEA83E0003E77E3 /* OpenGraph in Frameworks */ = {isa = PBXBuildFile; productRef = AE9181C32BEA83E0003E77E3 /* OpenGraph */; }; AEB8CBF52920B0CF00886882 /* TextFieldExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEB8CBF42920B0CF00886882 /* TextFieldExtension.swift */; }; AEDF4C8D291D8226000FC3D7 /* CustomeUIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEDF4C8C291D8226000FC3D7 /* CustomeUIButton.swift */; }; AEDF4C91291D9C25000FC3D7 /* FolderSaveCancelDialogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEDF4C90291D9C25000FC3D7 /* FolderSaveCancelDialogViewController.swift */; }; @@ -62,16 +62,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; AEE2471C28CF82200092F192 /* Embed App Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 12; @@ -127,6 +117,8 @@ AE83E34B291CB70C00A43A2D /* FolderSaveSuccessViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderSaveSuccessViewController.swift; sourceTree = ""; }; AE83E34D291CB8FB00A43A2D /* SaveType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveType.swift; sourceTree = ""; }; AE83E350291CC6AA00A43A2D /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; + AE9181BA2BEA810C003E77E3 /* OpenGraph.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = OpenGraph.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AE9181BD2BEA813C003E77E3 /* OpenGraph.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = OpenGraph.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AE92A668298BF72F0086B31F /* Secrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Secrets.xcconfig; sourceTree = ""; }; AEB8CBF42920B0CF00886882 /* TextFieldExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldExtension.swift; sourceTree = ""; }; AEDF4C8C291D8226000FC3D7 /* CustomeUIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomeUIButton.swift; sourceTree = ""; }; @@ -147,7 +139,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0FB992B32917F2F4005F5D9C /* OpenGraph in Frameworks */, + AE9181C42BEA83E0003E77E3 /* OpenGraph in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -156,7 +148,7 @@ buildActionMask = 2147483647; files = ( 917A62576C496F899ED82BAF /* Pods_Runner.framework in Frameworks */, - 0FB992B12917F2C6005F5D9C /* OpenGraph in Frameworks */, + AE9181C22BEA83D8003E77E3 /* OpenGraph in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -187,6 +179,8 @@ 41380AD61BDA3685827DB58C /* Frameworks */ = { isa = PBXGroup; children = ( + AE9181BD2BEA813C003E77E3 /* OpenGraph.framework */, + AE9181BA2BEA810C003E77E3 /* OpenGraph.framework */, 511FD4830B180C79ED690783 /* Pods_Runner.framework */, ); name = Frameworks; @@ -344,7 +338,7 @@ ); name = Extension; packageProductDependencies = ( - 0FB992B22917F2F4005F5D9C /* OpenGraph */, + AE9181C32BEA83E0003E77E3 /* OpenGraph */, ); productName = Extension; productReference = 0F872E3B28D875E3002954CC /* Extension.appex */; @@ -356,7 +350,6 @@ buildPhases = ( 06D908F3BF919B7EE15A8705 /* [CP] Check Pods Manifest.lock */, 242C769F86A7805781E3C954 /* [CP] Embed Pods Frameworks */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, AEE2471C28CF82200092F192 /* Embed App Extensions */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, @@ -372,7 +365,7 @@ ); name = Runner; packageProductDependencies = ( - 0FB992B02917F2C6005F5D9C /* OpenGraph */, + AE9181C12BEA83D8003E77E3 /* OpenGraph */, ); productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; @@ -1053,12 +1046,12 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 0FB992B02917F2C6005F5D9C /* OpenGraph */ = { + AE9181C12BEA83D8003E77E3 /* OpenGraph */ = { isa = XCSwiftPackageProductDependency; package = 0FB992AF2917F2C6005F5D9C /* XCRemoteSwiftPackageReference "OpenGraph" */; productName = OpenGraph; }; - 0FB992B22917F2F4005F5D9C /* OpenGraph */ = { + AE9181C32BEA83E0003E77E3 /* OpenGraph */ = { isa = XCSwiftPackageProductDependency; package = 0FB992AF2917F2C6005F5D9C /* XCRemoteSwiftPackageReference "OpenGraph" */; productName = OpenGraph; diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 8a4970b6..3c557cad 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -483,38 +483,36 @@ class HomePage extends StatelessWidget { 10.horizontalSpace, Padding( padding: EdgeInsets.only(top: 24.h), - child: Flexible( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(right: 12), - child: Text( - pick.getPerfectTitle(), - maxLines: 2, - style: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.bold, - color: grey900, - letterSpacing: -0.17, - height: 21/16, - ), - ), - ), - 3.verticalSpace, - Text( - pick.describe, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(right: 12), + child: Text( + pick.getPerfectTitle(), maxLines: 2, - overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: 12.sp, - fontWeight: FontWeight.w500, - color: grey600, + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: grey900, letterSpacing: -0.17, + height: 21/16, ), ), - ], - ), + ), + 3.verticalSpace, + Text( + pick.describe, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w500, + color: grey600, + letterSpacing: -0.17, + ), + ), + ], ), ), ], diff --git a/pubspec.yaml b/pubspec.yaml index 0faba2a1..22f00080 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.58+58 +version: 1.0.59+59 environment: sdk: ">=3.0.0 <4.0.0" @@ -28,9 +28,9 @@ dependencies: ## login sign_in_with_apple: ^5.0.0 google_sign_in: ^6.1.5 - firebase_core: 2.27.1 - firebase_auth: 4.17.9 - firebase_dynamic_links: 5.4.18 + firebase_core: 2.31.0 + firebase_auth: 4.19.5 + firebase_dynamic_links: 5.5.5 kakao_flutter_sdk_user: ^1.6.1 flutter_dotenv: ^5.0.2 @@ -61,7 +61,7 @@ dependencies: carousel_slider: ^4.2.1 lottie: flutter_slidable: ^3.0.1 - firebase_storage: ^11.6.10 + firebase_storage: ^11.7.5 ## lint very_good_analysis: ^4.0.0+1 From bcf30b61e76dd7ca9b924b4cbc9afa3b49e18335 Mon Sep 17 00:00:00 2001 From: boring-km Date: Fri, 10 May 2024 13:33:21 +0900 Subject: [PATCH 30/48] =?UTF-8?q?[fix]=201.0.60=20=EC=9D=BC=EB=B6=80=20UI?= =?UTF-8?q?=20=EA=B0=84=EA=B2=A9=20=EC=88=98=EC=A0=95,=20notion=20url=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/.gitignore | 3 +- lib/const/strings.dart | 6 +- lib/main.dart | 1 + lib/ui/view/tutorial_view.dart | 149 +++++++++--------- lib/ui/view/user/email_login_view.dart | 7 +- lib/ui/view/user/sign_up_nickname_view.dart | 3 +- .../widget/buttons/bottom_sheet_button.dart | 62 ++++---- pubspec.yaml | 2 +- 8 files changed, 113 insertions(+), 120 deletions(-) diff --git a/ios/.gitignore b/ios/.gitignore index 3d86bfa9..8b43554c 100644 --- a/ios/.gitignore +++ b/ios/.gitignore @@ -40,4 +40,5 @@ firebase_app_id_file.json fastlane/README.md Runner.ipa Runner.app.* -Secrets.xcconfig \ No newline at end of file +Secrets.xcconfig +/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/lib/const/strings.dart b/lib/const/strings.dart index 2a9de55d..2639f2cf 100644 --- a/lib/const/strings.dart +++ b/lib/const/strings.dart @@ -7,15 +7,15 @@ const approveFirstLink = // 이용 약관 const approveSecondLink = - 'https://linkpoolpd.notion.site/LINKPOOL-6f28bbd4f0914ffdad1614a3655d06fa'; + 'https://heejin-alex.notion.site/LINKPOOL-9c20eb96193e4ff2a5a2aeff8103730c'; // 개인정보 처리방침 const personalInfoLink = - 'https://linkpoolpd.notion.site/LINKPOOL-71b2b45eda864d91882a6995bf20413f'; + 'https://heejin-alex.notion.site/LINKPOOL-84f8e8be14244cd7837889d1ec5800d2'; // 도움말 const helpLink = - 'https://linkpoolpd.notion.site/c6ea6729dfac4dbc89c95d294bca43f8'; + 'https://heejin-alex.notion.site/14514c8fc84442fab1fc34d1377f8fc6'; // API LINK const baseUrl = 'http://acprojectapiserver-env.eba-tazwmppk.ap-northeast-2.elasticbeanstalk.com'; diff --git a/lib/main.dart b/lib/main.dart index 3788a6c2..6342140f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -61,6 +61,7 @@ class MyApp extends StatelessWidget { ), bottomSheetTheme: const BottomSheetThemeData( backgroundColor: Colors.white, + elevation: 0, ), elevatedButtonTheme: ElevatedButtonThemeData( style: ButtonStyle( diff --git a/lib/ui/view/tutorial_view.dart b/lib/ui/view/tutorial_view.dart index 6462a2d2..7eb752a5 100644 --- a/lib/ui/view/tutorial_view.dart +++ b/lib/ui/view/tutorial_view.dart @@ -23,85 +23,80 @@ class _TutorialViewState extends State { final height = MediaQuery.of(context).size.height; return Scaffold( backgroundColor: Colors.white, - body: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - CarouselSlider( - items: tutorials - .map( - (tutorial) => Column( - mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - tutorial.image, - height: (height * 0.6).h, - fit: BoxFit.cover, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: tutorials.asMap().entries.map((entry) { - return GestureDetector( - onTap: () => _controller.animateToPage(entry.key), - child: Container( - width: 7.w, - height: 7.h, - margin: EdgeInsets.symmetric( - horizontal: 3.w, - ), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _current == entry.key - ? primary700 - : greyDot, - ), - ), - ); - }).toList(), - ), - SizedBox(height: 22.h), - Text( - tutorial.title, - style: TextStyle( - fontSize: 26.sp, - letterSpacing: -0.2.w, - color: blackTutorial, - ), - ).bold(), - SizedBox(height: 10.h), - Text( - tutorial.subTitle, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14.sp, - color: greyTutorial, - letterSpacing: -0.3.w, - height: 24.h / 14, + body: CarouselSlider( + items: tutorials + .map( + (tutorial) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + Image.asset( + tutorial.image, + height: (height * 0.6).h, + fit: BoxFit.cover, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: tutorials.asMap().entries.map((entry) { + return GestureDetector( + onTap: () => _controller.animateToPage(entry.key), + child: Container( + width: 7.w, + height: 7.h, + margin: EdgeInsets.symmetric( + horizontal: 3.w, + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _current == entry.key + ? primary700 + : greyDot, + ), ), - ), - ], + ); + }).toList(), ), - ) - .toList(), - carouselController: _controller, - options: CarouselOptions( - height: (height * 4) / 5, - viewportFraction: 1, - enableInfiniteScroll: false, - onPageChanged: (index, reason) { - setState(() { - _current = index; - }); - }, - ), - ), - buildBottomSheetButton( - key: const Key('StartAppButton'), - context: context, - text: '시작하기', - backgroundColor: primary700, - onPressed: moveToLoginView, - ), - ], + SizedBox(height: 22.h), + Text( + tutorial.title, + style: TextStyle( + fontSize: 26.sp, + letterSpacing: -0.2.w, + color: blackTutorial, + ), + ).bold(), + SizedBox(height: 10.h), + Text( + tutorial.subTitle, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14.sp, + color: greyTutorial, + letterSpacing: -0.3.w, + height: 24.h / 14, + ), + ), + ], + ), + ) + .toList(), + carouselController: _controller, + options: CarouselOptions( + height: (height * 4) / 5, + viewportFraction: 1, + enableInfiniteScroll: false, + onPageChanged: (index, reason) { + setState(() { + _current = index; + }); + }, + ), + ), + bottomSheet: buildBottomSheetButton( + key: const Key('StartAppButton'), + context: context, + text: '시작하기', + backgroundColor: primary700, + onPressed: moveToLoginView, ), ); } diff --git a/lib/ui/view/user/email_login_view.dart b/lib/ui/view/user/email_login_view.dart index 4ab3154c..634902e9 100644 --- a/lib/ui/view/user/email_login_view.dart +++ b/lib/ui/view/user/email_login_view.dart @@ -38,8 +38,7 @@ class _EmailLoginViewState extends State Widget build(BuildContext context) { return KeyboardDismissOnTap( child: KeyboardVisibilityBuilder( - builder: (context, visible) { - final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; + builder: (keyboardContext, visible) { return Scaffold( resizeToAvoidBottomInset: false, appBar: buildBackAppBar(context), @@ -188,7 +187,7 @@ class _EmailLoginViewState extends State ), ), ), - SizedBox(height: keyboardHeight), + SizedBox(height: getKeyboardHeight(context)), ], ), ), @@ -216,6 +215,8 @@ class _EmailLoginViewState extends State ); } + double getKeyboardHeight(BuildContext context) => MediaQuery.of(context).padding.bottom; + void backToLogin(BuildContext context) { unawaited(Navigator.pushNamed(context, Routes.login)); } diff --git a/lib/ui/view/user/sign_up_nickname_view.dart b/lib/ui/view/user/sign_up_nickname_view.dart index 353e3cbb..b9aab83e 100644 --- a/lib/ui/view/user/sign_up_nickname_view.dart +++ b/lib/ui/view/user/sign_up_nickname_view.dart @@ -44,8 +44,7 @@ class SignUpNicknameView extends StatelessWidget { return KeyboardDismissOnTap( child: KeyboardVisibilityBuilder( builder: (context, visible) { - final keyboardHeight = - MediaQuery.of(context).viewInsets.bottom; + final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; return Scaffold( resizeToAvoidBottomInset: false, appBar: buildBackAppBar(context), diff --git a/lib/ui/widget/buttons/bottom_sheet_button.dart b/lib/ui/widget/buttons/bottom_sheet_button.dart index 5882bcc3..606c4893 100644 --- a/lib/ui/widget/buttons/bottom_sheet_button.dart +++ b/lib/ui/widget/buttons/bottom_sheet_button.dart @@ -1,7 +1,5 @@ // ignore_for_file: avoid_positional_boolean_parameters -import 'dart:io'; - import 'package:ac_project_app/const/colors.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -15,44 +13,42 @@ Widget buildBottomSheetButton({ Color? backgroundColor, Key? key, }) { - return SafeArea( - child: Padding( - padding: EdgeInsets.only( - bottom: getBottomPadding(context, keyboardVisible), - left: 24.w, - right: 24.w, - ), - child: ElevatedButton( - key: key, - style: ElevatedButton.styleFrom( - minimumSize: Size.fromHeight(55.h), - backgroundColor: backgroundColor ?? primary800, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12.r), - ), - foregroundColor: Colors.white, - disabledBackgroundColor: secondary, - disabledForegroundColor: Colors.white, - shadowColor: buttonShadow! ? primary600 : Colors.transparent, + return Padding( + padding: EdgeInsets.only( + bottom: getBottomPadding(context, keyboardVisible), + left: 24.w, + right: 24.w, + ), + child: ElevatedButton( + key: key, + style: ElevatedButton.styleFrom( + minimumSize: Size.fromHeight(55.h), + backgroundColor: backgroundColor ?? primary800, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12.r), ), - onPressed: onPressed, - child: Text( - text, - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - textWidthBasis: TextWidthBasis.parent, + foregroundColor: Colors.white, + disabledBackgroundColor: secondary, + disabledForegroundColor: Colors.white, + shadowColor: buttonShadow! ? primary600 : Colors.transparent, + ), + onPressed: onPressed, + child: Text( + text, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + color: Colors.white, ), + textWidthBasis: TextWidthBasis.parent, ), ), ); } double getBottomPadding(BuildContext context, bool? keyboardVisible) { - final defaultValue = Platform.isAndroid ? 16.h : 8.h; - final keyboardPadding = (keyboardVisible ?? false) ? 16.h : defaultValue; + final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; + final keyboardPadding = keyboardHeight + 8.h; - return MediaQuery.of(context).viewInsets.bottom + keyboardPadding; + return MediaQuery.of(context).padding.bottom + keyboardPadding; } diff --git a/pubspec.yaml b/pubspec.yaml index 22f00080..671a0e66 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.59+59 +version: 1.0.60+60 environment: sdk: ">=3.0.0 <4.0.0" From 8675cc3968df1dd58c332b86d64e64836bb2edec Mon Sep 17 00:00:00 2001 From: boring-km Date: Thu, 16 May 2024 11:23:18 +0900 Subject: [PATCH 31/48] =?UTF-8?q?[feat]=20firebase=20realtime=20database,?= =?UTF-8?q?=20crashlytics=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/build.gradle | 1 + android/build.gradle | 1 + ios/Runner.xcodeproj/project.pbxproj | 28 +++++++++++++++++++++++++ lib/cubits/login/auto_login_cubit.dart | 29 +++++++++++++++++++++++++- lib/cubits/login/login_user_state.dart | 10 +++++++++ lib/initial_settings.dart | 9 ++++++++ lib/ui/view/splash_view.dart | 13 +++++++++++- pubspec.yaml | 2 ++ 8 files changed, 91 insertions(+), 2 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 18849938..45953f4e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -36,6 +36,7 @@ def kakaoApiKey = signingProperties.getProperty('kakao.api.key') apply plugin: 'com.android.application' // START: FlutterFire Configuration apply plugin: 'com.google.gms.google-services' +apply plugin: 'com.google.firebase.crashlytics' // END: FlutterFire Configuration apply plugin: 'kotlin-android' apply plugin: 'kotlin-parcelize' diff --git a/android/build.gradle b/android/build.gradle index ae605880..a99243d0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -9,6 +9,7 @@ buildscript { classpath 'com.android.tools.build:gradle:7.4.2' // START: FlutterFire Configuration classpath 'com.google.gms:google-services:4.3.15' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' // END: FlutterFire Configuration classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6467574c..f4efeded 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ AEFAAC81291D586A00ED5DDC /* UserDefaultsHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEFAAC80291D586A00ED5DDC /* UserDefaultsHelper.swift */; }; AEFAAC84291D6E1600ED5DDC /* CommentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEFAAC83291D6E1600ED5DDC /* CommentViewController.swift */; }; AEFAAC86291D791700ED5DDC /* PaddingTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEFAAC85291D791700ED5DDC /* PaddingTextField.swift */; }; + E97025A1799B60AA1DA3EE18 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8AF2D531BDA70F0A6D9C0D90 /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -94,6 +95,7 @@ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 77DA2DBBFBCA594F81CC37E1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 8AF2D531BDA70F0A6D9C0D90 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -207,6 +209,7 @@ 97C146EF1CF9000F007C117D /* Products */, B0F7507DCC206DB6EBB05ADC /* Pods */, 41380AD61BDA3685827DB58C /* Frameworks */, + 8AF2D531BDA70F0A6D9C0D90 /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -357,6 +360,7 @@ 97C146EC1CF9000F007C117D /* Resources */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 04407A3D77A27457A3AE6C17 /* [CP] Copy Pods Resources */, + E8FF0151F034C36084045D9B /* [firebase_crashlytics] Crashlytics Upload Symbols */, ); buildRules = ( ); @@ -437,6 +441,7 @@ 51F09A2629711B8A00BA053D /* GoogleService-Info.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + E97025A1799B60AA1DA3EE18 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -530,6 +535,29 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + E8FF0151F034C36084045D9B /* [firebase_crashlytics] Crashlytics Upload Symbols */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}\"", + "\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/\"", + "\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"", + "\"$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)\"", + "\"$(PROJECT_DIR)/firebase_app_id_file.json\"", + ); + name = "[firebase_crashlytics] Crashlytics Upload Symbols"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --flutter-project \"$PROJECT_DIR/firebase_app_id_file.json\" "; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/lib/cubits/login/auto_login_cubit.dart b/lib/cubits/login/auto_login_cubit.dart index 0424e61d..85cadb20 100644 --- a/lib/cubits/login/auto_login_cubit.dart +++ b/lib/cubits/login/auto_login_cubit.dart @@ -3,12 +3,39 @@ import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/provider/api/user/user_api.dart'; import 'package:ac_project_app/provider/share_data_provider.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class AutoLoginCubit extends Cubit { AutoLoginCubit() : super(LoginInitialState()); - void userCheck() { + Future userCheck() async { + + final database = FirebaseDatabase.instance; + final pause = (await getPauseFlag(database)).value as bool? ?? false; + final title = (await getTitle(database)).value as String? ?? ''; + final description = (await getDescription(database)).value as String? ?? ''; + + if (pause) { + emit(InspectionState(title, description)); + } else { + _userCheck(); + } + } + + Future getPauseFlag(FirebaseDatabase database) { + return database.ref('pause').get(); + } + + Future getTitle(FirebaseDatabase database) { + return database.ref('title').get(); + } + + Future getDescription(FirebaseDatabase database) { + return database.ref('description').get(); + } + + void _userCheck() { final user = FirebaseAuth.instance.currentUser; if (user != null) { getIt().postUsers().then((result) { diff --git a/lib/cubits/login/login_user_state.dart b/lib/cubits/login/login_user_state.dart index 40658b9b..ba6d84d7 100644 --- a/lib/cubits/login/login_user_state.dart +++ b/lib/cubits/login/login_user_state.dart @@ -22,6 +22,16 @@ class LoginLoadedState extends LoginUserState { List get props => [user]; } +class InspectionState extends LoginUserState { + InspectionState(this.title, this.description); + + final String title; + final String description; + + @override + List get props => [title, description]; +} + class LoginErrorState extends LoginUserState { LoginErrorState(this.message); diff --git a/lib/initial_settings.dart b/lib/initial_settings.dart index 20198d8d..13e00a23 100644 --- a/lib/initial_settings.dart +++ b/lib/initial_settings.dart @@ -1,8 +1,10 @@ import 'dart:async'; +import 'dart:ui'; import 'package:ac_project_app/firebase_options.dart'; // ignore: depend_on_referenced_packages import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; @@ -31,6 +33,13 @@ Future initSettings() async { } else { Firebase.app(); } + + FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError; + PlatformDispatcher.instance.onError = (error, stackTrace) { + FirebaseCrashlytics.instance.recordError(error, stackTrace, fatal: true); + return true; + }; + _saveFirstInstalled(); } diff --git a/lib/ui/view/splash_view.dart b/lib/ui/view/splash_view.dart index c8575e85..29487253 100644 --- a/lib/ui/view/splash_view.dart +++ b/lib/ui/view/splash_view.dart @@ -7,6 +7,7 @@ import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/provider/tutorial_provider.dart'; import 'package:ac_project_app/routes.dart'; +import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -43,8 +44,18 @@ class _SplashViewState extends State with TickerProviderStateMixin { } void moveToNextView() { - if (autoLoginCubit.state is LoginInitialState) { + final state = autoLoginCubit.state; + if (state is LoginInitialState) { moveToLoginView(); + } else if (state is InspectionState) { + showPopUp( + title: state.title, + content: state.description, + parentContext: context, + callback: () { + Navigator.pop(context); + }, + ); } else { Navigator.pushReplacementNamed( context, diff --git a/pubspec.yaml b/pubspec.yaml index 671a0e66..5b7f2a04 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,6 +31,8 @@ dependencies: firebase_core: 2.31.0 firebase_auth: 4.19.5 firebase_dynamic_links: 5.5.5 + firebase_database: ^10.5.5 + firebase_crashlytics: ^3.5.5 kakao_flutter_sdk_user: ^1.6.1 flutter_dotenv: ^5.0.2 From 4f9b72184b5d6cb2353ef9fb2fc517cf8c8eedc7 Mon Sep 17 00:00:00 2001 From: boring-km Date: Fri, 17 May 2024 15:34:42 +0900 Subject: [PATCH 32/48] =?UTF-8?q?[feat]=20=EC=95=B1=20=EC=A0=90=EA=B2=80?= =?UTF-8?q?=20=EC=8B=9C=20=EC=B0=A8=EB=8B=A8=ED=95=98=EB=8A=94=20=ED=8C=9D?= =?UTF-8?q?=EC=97=85=20=EB=82=98=EC=98=A4=EB=8F=84=EB=A1=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Runner.xcodeproj/project.pbxproj | 40 ++++++++++++++++++- lib/cubits/login/auto_login_cubit.dart | 30 ++++++-------- lib/di/set_up_get_it.dart | 4 +- lib/provider/manager/app_pause_manager.dart | 44 +++++++++++++++++++++ lib/ui/view/home_view.dart | 19 ++++++++- lib/ui/view/splash_view.dart | 1 + 6 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 lib/provider/manager/app_pause_manager.dart diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index f4efeded..7f945971 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -354,6 +354,7 @@ 06D908F3BF919B7EE15A8705 /* [CP] Check Pods Manifest.lock */, 242C769F86A7805781E3C954 /* [CP] Embed Pods Frameworks */, AEE2471C28CF82200092F192 /* Embed App Extensions */, + AE2358E82BF5C1200045890F /* [Crashlytics] Clear dSYM */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, @@ -361,6 +362,7 @@ 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 04407A3D77A27457A3AE6C17 /* [CP] Copy Pods Resources */, E8FF0151F034C36084045D9B /* [firebase_crashlytics] Crashlytics Upload Symbols */, + AE2358E92BF5C1B30045890F /* [Crashlytics] Upload dSYM */, ); buildRules = ( ); @@ -533,7 +535,43 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + }; + AE2358E82BF5C1200045890F /* [Crashlytics] Clear dSYM */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "[Crashlytics] Clear dSYM"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "rm -rf $DWARF_DSYM_FOLDER_PATH/$DWARF_DSYM_FILE_NAME\n"; + }; + AE2358E92BF5C1B30045890F /* [Crashlytics] Upload dSYM */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "[Crashlytics] Upload dSYM"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "sleep 1 # Without this, there seems a chance that the script runs before dSYM generation is finished \n$PODS_ROOT/FirebaseCrashlytics/upload-symbols -gsp $PROJECT_DIR/Runner/GoogleService-Info.plist -p ios $DWARF_DSYM_FOLDER_PATH/$DWARF_DSYM_FILE_NAME\n"; }; E8FF0151F034C36084045D9B /* [firebase_crashlytics] Crashlytics Upload Symbols */ = { isa = PBXShellScriptBuildPhase; diff --git a/lib/cubits/login/auto_login_cubit.dart b/lib/cubits/login/auto_login_cubit.dart index 85cadb20..7e37682e 100644 --- a/lib/cubits/login/auto_login_cubit.dart +++ b/lib/cubits/login/auto_login_cubit.dart @@ -1,38 +1,30 @@ import 'package:ac_project_app/cubits/login/login_user_state.dart'; import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/provider/api/user/user_api.dart'; +import 'package:ac_project_app/provider/manager/app_pause_manager.dart'; import 'package:ac_project_app/provider/share_data_provider.dart'; import 'package:firebase_auth/firebase_auth.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class AutoLoginCubit extends Cubit { AutoLoginCubit() : super(LoginInitialState()); - Future userCheck() async { + final appPauseManager = getIt(); - final database = FirebaseDatabase.instance; - final pause = (await getPauseFlag(database)).value as bool? ?? false; - final title = (await getTitle(database)).value as String? ?? ''; - final description = (await getDescription(database)).value as String? ?? ''; + Future userCheck() async { + final pause = await appPauseManager.getPause(); if (pause) { - emit(InspectionState(title, description)); + await _showInspectionMessage(); } else { _userCheck(); } } - Future getPauseFlag(FirebaseDatabase database) { - return database.ref('pause').get(); - } - - Future getTitle(FirebaseDatabase database) { - return database.ref('title').get(); - } - - Future getDescription(FirebaseDatabase database) { - return database.ref('description').get(); + Future _showInspectionMessage() async { + final title = await appPauseManager.getTitle(); + final description = await appPauseManager.getDescription(); + emit(InspectionState(title, description)); } void _userCheck() { @@ -53,4 +45,8 @@ class AutoLoginCubit extends Cubit { }); } } + + void closeApp() { + appPauseManager.closeApp(); + } } diff --git a/lib/di/set_up_get_it.dart b/lib/di/set_up_get_it.dart index 91dc0e3d..be2466ef 100644 --- a/lib/di/set_up_get_it.dart +++ b/lib/di/set_up_get_it.dart @@ -9,6 +9,7 @@ import 'package:ac_project_app/provider/api/linkpool_pick/linkpool_pick_api.dart import 'package:ac_project_app/provider/api/report/report_api.dart'; import 'package:ac_project_app/provider/api/user/profile_api.dart'; import 'package:ac_project_app/provider/api/user/user_api.dart'; +import 'package:ac_project_app/provider/manager/app_pause_manager.dart'; import 'package:get_it/get_it.dart'; final getIt = GetIt.instance; @@ -31,5 +32,6 @@ void locator() { ..registerLazySingleton(GetUserFoldersCubit.new) ..registerLazySingleton(GetProfileInfoCubit.new) ..registerLazySingleton(AutoLoginCubit.new) - ..registerLazySingleton(LinkpoolPickCubit.new); + ..registerLazySingleton(LinkpoolPickCubit.new) + ..registerLazySingleton(AppPauseManager.new); } diff --git a/lib/provider/manager/app_pause_manager.dart b/lib/provider/manager/app_pause_manager.dart new file mode 100644 index 00000000..f9cc9431 --- /dev/null +++ b/lib/provider/manager/app_pause_manager.dart @@ -0,0 +1,44 @@ +import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:firebase_database/firebase_database.dart'; +import 'package:flutter/material.dart'; + +class AppPauseManager { + final database = FirebaseDatabase.instance; + + Future getPause() async { + return (await database.ref('pause').get()).value as bool? ?? false; + } + + Future getTitle() async { + return (await database.ref('title').get()).value as String? ?? ''; + } + + Future getDescription() async { + return (await database.ref('description').get()).value as String? ?? ''; + } + + Future showPopup(BuildContext context) async { + showPopUp( + title: await getTitle(), + content: await getDescription(), + parentContext: context, + callback: () { + Navigator.pop(context); + closeApp(); + }, + ); + } + + void closeApp() { + FirebaseCrashlytics.instance.crash(); + } + + void showPopupIfPaused(BuildContext context) { + getPause().then((value) { + if (value) { + showPopup(context); + } + }); + } +} diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index 460b9a4d..a962ef03 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/cubits/folders/folder_view_type_cubit.dart'; import 'package:ac_project_app/cubits/folders/get_my_folders_cubit.dart'; @@ -11,6 +13,7 @@ import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/provider/api/folders/folder_api.dart'; import 'package:ac_project_app/provider/kakao/kakao.dart'; +import 'package:ac_project_app/provider/manager/app_pause_manager.dart'; import 'package:ac_project_app/provider/upload_state_variable.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/page/home/home_page.dart'; @@ -34,19 +37,28 @@ class HomeView extends StatefulWidget { class _HomeViewState extends State with WidgetsBindingObserver { final uploadToolTipButtonKey = GlobalKey(); + final appPauseManager = getIt(); @override void initState() { WidgetsBinding.instance.addObserver(this); + saveLinksFromOutside(); + processAfterGetContext(); + super.initState(); + } + + void saveLinksFromOutside() { getIt().bulkSave().then((value) { setState(() {}); }); + } + + void processAfterGetContext() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { final url = await receiveKakaoScheme(); if (!mounted) return; Kakao.receiveLink(context, url: url); }); - super.initState(); } @override @@ -62,6 +74,7 @@ class _HomeViewState extends State with WidgetsBindingObserver { if (state == AppLifecycleState.resumed) { if (!resumeState.value) return; resetResumeState(); + appPauseManager.showPopupIfPaused(context); getIt().bulkSave(); Kakao.receiveLink(context); navigateToUploadViewIfClipboardIsValid(); @@ -227,4 +240,8 @@ class _HomeViewState extends State with WidgetsBindingObserver { } return icons; } + + void checkAppPause(BuildContext context) { + appPauseManager.showPopupIfPaused(context); + } } diff --git a/lib/ui/view/splash_view.dart b/lib/ui/view/splash_view.dart index 29487253..8ed81da6 100644 --- a/lib/ui/view/splash_view.dart +++ b/lib/ui/view/splash_view.dart @@ -54,6 +54,7 @@ class _SplashViewState extends State with TickerProviderStateMixin { parentContext: context, callback: () { Navigator.pop(context); + autoLoginCubit.closeApp(); }, ); } else { From 7f9fa9881b381fb804a598ef69d513764f0c08a7 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 22 May 2024 00:21:52 +0900 Subject: [PATCH 33/48] =?UTF-8?q?[feat]=201.0.61=20=EC=A0=90=EA=B2=80=20?= =?UTF-8?q?=ED=8C=9D=EC=97=85=EC=9C=BC=EB=A1=9C=20=EB=A7=89=EC=9D=84=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20api=20url=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/const/colors.dart | 1 + lib/const/strings.dart | 2 +- lib/cubits/login/auto_login_cubit.dart | 3 +- lib/cubits/login/login_user_state.dart | 5 +- lib/provider/manager/app_pause_manager.dart | 9 +- lib/ui/view/splash_view.dart | 5 +- lib/ui/widget/dialog/center_dialog.dart | 132 ++++++++++++++++++++ pubspec.yaml | 2 +- 8 files changed, 150 insertions(+), 9 deletions(-) diff --git a/lib/const/colors.dart b/lib/const/colors.dart index 1ed15422..718c3119 100644 --- a/lib/const/colors.dart +++ b/lib/const/colors.dart @@ -7,6 +7,7 @@ const grey100 = Color(0xFFF5F7FA); const ccGrey100 = Color(0x99F5F7FA); const grey200 = Color(0xFFE6EAF1); +const grey200_9a = Color(0x9AE6EAF1); const ccGrey200 = Color(0xCCE6EAF1); const grey300 = Color(0xFFCFD4DE); diff --git a/lib/const/strings.dart b/lib/const/strings.dart index 2639f2cf..d19efee3 100644 --- a/lib/const/strings.dart +++ b/lib/const/strings.dart @@ -18,7 +18,7 @@ const helpLink = 'https://heejin-alex.notion.site/14514c8fc84442fab1fc34d1377f8fc6'; // API LINK -const baseUrl = 'http://acprojectapiserver-env.eba-tazwmppk.ap-northeast-2.elasticbeanstalk.com'; +const baseUrl = 'https://api.linkpool.co.kr'; //warning message const warningMsgTitle = '링크풀은 건전한 링크 관리 및 공유 문화를 지향해요'; diff --git a/lib/cubits/login/auto_login_cubit.dart b/lib/cubits/login/auto_login_cubit.dart index 7e37682e..97894061 100644 --- a/lib/cubits/login/auto_login_cubit.dart +++ b/lib/cubits/login/auto_login_cubit.dart @@ -24,7 +24,8 @@ class AutoLoginCubit extends Cubit { Future _showInspectionMessage() async { final title = await appPauseManager.getTitle(); final description = await appPauseManager.getDescription(); - emit(InspectionState(title, description)); + final timeText = await appPauseManager.getTimeText(); + emit(InspectionState(title, description, timeText)); } void _userCheck() { diff --git a/lib/cubits/login/login_user_state.dart b/lib/cubits/login/login_user_state.dart index ba6d84d7..695fd45e 100644 --- a/lib/cubits/login/login_user_state.dart +++ b/lib/cubits/login/login_user_state.dart @@ -23,13 +23,14 @@ class LoginLoadedState extends LoginUserState { } class InspectionState extends LoginUserState { - InspectionState(this.title, this.description); + InspectionState(this.title, this.description, this.timeText); final String title; final String description; + final String timeText; @override - List get props => [title, description]; + List get props => [title, description, timeText]; } class LoginErrorState extends LoginUserState { diff --git a/lib/provider/manager/app_pause_manager.dart b/lib/provider/manager/app_pause_manager.dart index f9cc9431..3b16bc0b 100644 --- a/lib/provider/manager/app_pause_manager.dart +++ b/lib/provider/manager/app_pause_manager.dart @@ -18,10 +18,15 @@ class AppPauseManager { return (await database.ref('description').get()).value as String? ?? ''; } + Future getTimeText() async { + return (await database.ref('time').get()).value as String? ?? ''; + } + Future showPopup(BuildContext context) async { - showPopUp( + showPausePopup( title: await getTitle(), - content: await getDescription(), + description: await getDescription(), + timeText: await getTimeText(), parentContext: context, callback: () { Navigator.pop(context); diff --git a/lib/ui/view/splash_view.dart b/lib/ui/view/splash_view.dart index 8ed81da6..86dd304d 100644 --- a/lib/ui/view/splash_view.dart +++ b/lib/ui/view/splash_view.dart @@ -48,9 +48,10 @@ class _SplashViewState extends State with TickerProviderStateMixin { if (state is LoginInitialState) { moveToLoginView(); } else if (state is InspectionState) { - showPopUp( + showPausePopup( title: state.title, - content: state.description, + description: state.description, + timeText: state.timeText, parentContext: context, callback: () { Navigator.pop(context); diff --git a/lib/ui/widget/dialog/center_dialog.dart b/lib/ui/widget/dialog/center_dialog.dart index 5941f48e..0409f60f 100644 --- a/lib/ui/widget/dialog/center_dialog.dart +++ b/lib/ui/widget/dialog/center_dialog.dart @@ -485,3 +485,135 @@ void showError(BuildContext context) { icon: true, ); } + +void showPausePopup({ + required String title, + required String description, + required String timeText, + required BuildContext parentContext, + required void Function()? callback, + bool icon = false, + String buttonText = '삭제', + bool hasClose = true, +}) { + final width = MediaQuery.of(parentContext).size.width; + showDialog( + context: parentContext, + builder: (BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + insetPadding: EdgeInsets.zero, + child: SizedBox( + width: width - (45.w * 2), + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: icon ? 10.h : 16.h, + ), + Container( + margin: EdgeInsets.only(top: icon ? 14.h : 0, bottom: 10.h), + child: Text( + title, + style: TextStyle( + fontSize: 20.sp, + fontWeight: FontWeight.w700, + letterSpacing: -0.2.w, + height: (23.8 / 20).h, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 14), + child: Text( + description, + textAlign: TextAlign.center, + style: TextStyle( + color: grey500, + fontSize: 14.sp, + letterSpacing: -0.1.w, + fontWeight: FontWeight.w500, + height: (18.9 / 14).h, + ), + ), + ), + 12.verticalSpace, + DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: grey200_9a, + ), + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 14), + child: Text( + '링크풀 서비스 점검시간\n$timeText', + textAlign: TextAlign.center, + style: TextStyle( + color: grey600, + fontSize: 14.sp, + letterSpacing: -0.1.w, + fontWeight: FontWeight.w600, + height: (20 / 14).h, + ), + ), + ), + ), + ), + Container( + margin: EdgeInsets.only( + left: 4.w, + right: 4.w, + bottom: 4.h, + top: 24.h, + ), + child: SizedBox( + width: double.infinity, + height: 48.h, + child: ElevatedButton( + onPressed: callback, + style: ElevatedButton.styleFrom( + backgroundColor: primary600, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + shadowColor: Colors.transparent, + ), + child: Text( + buttonText, + style: TextStyle( + fontFamily: FontFamily.pretendard, + color: Colors.white, + fontSize: 16.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ), + ], + ), + ), + Positioned( + right: 0, + top: 0, + child: IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: const Icon( + Icons.close, + ), + ), + ), + ], + ), + ), + ); + }, + ); +} diff --git a/pubspec.yaml b/pubspec.yaml index 5b7f2a04..3a51482a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.60+60 +version: 1.0.61+61 environment: sdk: ">=3.0.0 <4.0.0" From afe43fa403f8051117aefb3a01a9bb4d44551c84 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 22 May 2024 00:42:16 +0900 Subject: [PATCH 34/48] =?UTF-8?q?[feat]=201.0.62=20=EC=A0=90=EA=B2=80=20?= =?UTF-8?q?=ED=8C=9D=EC=97=85=20=EB=B2=84=ED=8A=BC=20=EB=AC=B8=EA=B5=AC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/android_cicd.yml | 2 +- .github/workflows/cicd.yml | 4 ++-- .github/workflows/code_coverage.yml | 2 +- .github/workflows/ios_cicd.yml | 2 +- lib/ui/widget/dialog/center_dialog.dart | 2 +- pubspec.yaml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/android_cicd.yml b/.github/workflows/android_cicd.yml index 5aa59549..558877e7 100644 --- a/.github/workflows/android_cicd.yml +++ b/.github/workflows/android_cicd.yml @@ -16,7 +16,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.5' + flutter-version: '3.22.0' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 6bd8cbf0..919afd41 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.6' + flutter-version: '3.22.0' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.6' + flutter-version: '3.22.0' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index b9e8bbde..1e64dfc4 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.6' + flutter-version: '3.22.0' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/.github/workflows/ios_cicd.yml b/.github/workflows/ios_cicd.yml index bbbf8b1b..d60d39b3 100644 --- a/.github/workflows/ios_cicd.yml +++ b/.github/workflows/ios_cicd.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.19.5' + flutter-version: '3.22.0' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/lib/ui/widget/dialog/center_dialog.dart b/lib/ui/widget/dialog/center_dialog.dart index 0409f60f..925be32e 100644 --- a/lib/ui/widget/dialog/center_dialog.dart +++ b/lib/ui/widget/dialog/center_dialog.dart @@ -493,7 +493,7 @@ void showPausePopup({ required BuildContext parentContext, required void Function()? callback, bool icon = false, - String buttonText = '삭제', + String buttonText = '확인', bool hasClose = true, }) { final width = MediaQuery.of(parentContext).size.width; diff --git a/pubspec.yaml b/pubspec.yaml index 3a51482a..b62670ec 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.61+61 +version: 1.0.62+62 environment: sdk: ">=3.0.0 <4.0.0" From ebf6a48d93835b1720bf15db58724fc6c6858346 Mon Sep 17 00:00:00 2001 From: boring-km Date: Sun, 16 Jun 2024 11:52:00 +0900 Subject: [PATCH 35/48] =?UTF-8?q?[feat]=201.0.63=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/Monday-Rocket/ac_project_app/issues/217 --- .github/workflows/cicd.yml | 4 +- .github/workflows/code_coverage.yml | 2 +- ios/Runner.xcodeproj/project.pbxproj | 43 ++-- ios/Runner/Info.plist | 74 +++---- lib/cubits/feed/feed_view_cubit.dart | 1 + ..._group_cubit.dart => get_links_cubit.dart} | 1 + lib/cubits/scroll/scroll_cubit.dart | 4 +- lib/main.dart | 7 +- lib/models/folder/folder.dart | 18 ++ lib/ui/page/home/home_page.dart | 10 +- lib/ui/page/my_folder/my_folder_page.dart | 160 --------------- lib/ui/view/home_view.dart | 3 +- lib/ui/view/links/my_link_view.dart | 192 +++++++++++------- lib/ui/view/links/search_view.dart | 32 +-- lib/ui/view/links/user_feed_view.dart | 14 +- lib/ui/view/upload_view.dart | 6 + lib/ui/widget/dialog/bottom_dialog.dart | 175 ++++++++++++++++ lib/ui/widget/dialog/center_dialog.dart | 8 +- .../show_rename_folder_dialog.dart | 27 +-- pubspec.yaml | 2 +- test/coverage_test.dart | 2 +- 21 files changed, 433 insertions(+), 352 deletions(-) rename lib/cubits/links/{links_from_selected_job_group_cubit.dart => get_links_cubit.dart} (98%) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 919afd41..b2650f68 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.0' + flutter-version: '3.22.2' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.0' + flutter-version: '3.22.2' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 1e64dfc4..458fbf36 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.0' + flutter-version: '3.22.2' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 7f945971..b62d9195 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -686,11 +686,10 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -708,7 +707,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -728,11 +726,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -749,7 +745,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -767,11 +762,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -788,7 +781,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -857,11 +849,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -872,7 +862,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1003,11 +992,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -1018,7 +1005,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1039,11 +1025,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -1054,7 +1038,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 17c63c3d..6590057c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -7,7 +7,7 @@ kakaokompassauth kakaolink naversearchapp - naversearchthirdlogin + naversearchthirdlogin CADisableMinimumFrameDurationOnPhone @@ -76,15 +76,15 @@ - CFBundleTypeRole - Editor - CFBundleURLName - naver - CFBundleURLSchemes - - naver - - + CFBundleTypeRole + Editor + CFBundleURLName + naver + CFBundleURLSchemes + + naver + + CFBundleVersion $(FLUTTER_BUILD_NUMBER) @@ -101,26 +101,26 @@ NSAllowsArbitraryLoads NSExceptionDomains - - naver.com - - NSExceptionAllowsInsecureHTTPLoads - - NSExceptionRequiresForwardSecrecy - - NSIncludesSubdomains - - - naver.net - - NSExceptionAllowsInsecureHTTPLoads - - NSExceptionRequiresForwardSecrecy - - NSIncludesSubdomains - - - + + naver.com + + NSExceptionAllowsInsecureHTTPLoads + + NSExceptionRequiresForwardSecrecy + + NSIncludesSubdomains + + + naver.net + + NSExceptionAllowsInsecureHTTPLoads + + NSExceptionRequiresForwardSecrecy + + NSIncludesSubdomains + + + NSBonjourServices @@ -154,12 +154,12 @@ UIViewControllerBasedStatusBarAppearance naverConsumerKey - ${NAVER_CLIENT_ID} - naverConsumerSecret - ${NAVER_CLIENT_SECRET} - naverServiceAppName - ${NAVER_CLIENT_NAME} - naverServiceAppUrlScheme - linkpool + ${NAVER_CLIENT_ID} + naverConsumerSecret + ${NAVER_CLIENT_SECRET} + naverServiceAppName + ${NAVER_CLIENT_NAME} + naverServiceAppUrlScheme + linkpool diff --git a/lib/cubits/feed/feed_view_cubit.dart b/lib/cubits/feed/feed_view_cubit.dart index 2cdb0573..ddb536ff 100644 --- a/lib/cubits/feed/feed_view_cubit.dart +++ b/lib/cubits/feed/feed_view_cubit.dart @@ -36,6 +36,7 @@ class FeedViewCubit extends Cubit> { result.when( success: (data) { final links = _setScrollState(data); + totalLinks.addAll(links); emit(links); }, error: (msg) { diff --git a/lib/cubits/links/links_from_selected_job_group_cubit.dart b/lib/cubits/links/get_links_cubit.dart similarity index 98% rename from lib/cubits/links/links_from_selected_job_group_cubit.dart rename to lib/cubits/links/get_links_cubit.dart index 6343fe3e..0dd1ab58 100644 --- a/lib/cubits/links/links_from_selected_job_group_cubit.dart +++ b/lib/cubits/links/get_links_cubit.dart @@ -31,6 +31,7 @@ class GetLinksCubit extends Cubit> { result.when( success: (data) { final links = _setScrollState(data); + totalLinks.addAll(links); emit(links); }, error: (msg) {}, diff --git a/lib/cubits/scroll/scroll_cubit.dart b/lib/cubits/scroll/scroll_cubit.dart index fcf88087..6846c2fa 100644 --- a/lib/cubits/scroll/scroll_cubit.dart +++ b/lib/cubits/scroll/scroll_cubit.dart @@ -1,3 +1,4 @@ +import 'package:ac_project_app/util/logger.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -12,7 +13,8 @@ class ScrollCubit extends Cubit { late ScrollController scrollController; void scrollListener() { - if (scrollController.offset > 5) { + Log.i('offset: ${scrollController.offset}'); + if (scrollController.offset > 10) { emit(true); } else { emit(false); diff --git a/lib/main.dart b/lib/main.dart index 6342140f..e52004d5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -53,19 +53,22 @@ class MyApp extends StatelessWidget { brightness: Brightness.light, textButtonTheme: TextButtonThemeData( style: ButtonStyle( - foregroundColor: MaterialStateProperty.all(Colors.white), + foregroundColor: WidgetStateProperty.all(Colors.white), ), ), progressIndicatorTheme: const ProgressIndicatorThemeData( color: primary600, ), + appBarTheme: const AppBarTheme( + backgroundColor: Colors.transparent, + ), bottomSheetTheme: const BottomSheetThemeData( backgroundColor: Colors.white, elevation: 0, ), elevatedButtonTheme: ElevatedButtonThemeData( style: ButtonStyle( - shadowColor: MaterialStateProperty.all(primary700), + shadowColor: WidgetStateProperty.all(primary700), ), ), ), diff --git a/lib/models/folder/folder.dart b/lib/models/folder/folder.dart index 73d31481..de2bd80d 100644 --- a/lib/models/folder/folder.dart +++ b/lib/models/folder/folder.dart @@ -37,4 +37,22 @@ class Folder extends Equatable { List get props => [id, thumbnail, visible, name, links]; + Folder copyWith({ + int? id, + String? thumbnail, + bool? visible, + String? name, + int? links, + String? time, + bool? isClassified, + }) { + return Folder( + id: id ?? this.id, + thumbnail: thumbnail ?? this.thumbnail, + visible: visible ?? this.visible, + name: name ?? this.name, + links: links ?? this.links, + time: time ?? this.time, + ); + } } diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 3c557cad..8f672c0a 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -4,7 +4,7 @@ import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/const/strings.dart'; import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_cubit.dart'; import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_result_state.dart'; -import 'package:ac_project_app/cubits/links/links_from_selected_job_group_cubit.dart'; +import 'package:ac_project_app/cubits/links/get_links_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_info_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_state.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; @@ -117,7 +117,13 @@ class HomePage extends StatelessWidget { return BlocBuilder>( builder: (context, links) { - final totalLinks = _setTotalLinks(context, links); + final totalLinks = + context.watch().totalLinks; + if (context.read().hasRefresh) { + totalLinks.clear(); + context.read().hasRefresh = false; + } + if (totalLinks.isEmpty) { return SliverToBoxAdapter( child: Center( diff --git a/lib/ui/page/my_folder/my_folder_page.dart b/lib/ui/page/my_folder/my_folder_page.dart index fefa8264..8fe7dccb 100644 --- a/lib/ui/page/my_folder/my_folder_page.dart +++ b/lib/ui/page/my_folder/my_folder_page.dart @@ -1,7 +1,6 @@ // ignore_for_file: avoid_positional_boolean_parameters import 'dart:async'; -import 'dart:io'; import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/cubits/folders/folder_view_type_cubit.dart'; @@ -9,18 +8,14 @@ import 'package:ac_project_app/cubits/folders/folders_state.dart'; import 'package:ac_project_app/cubits/folders/get_my_folders_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_info_cubit.dart'; import 'package:ac_project_app/cubits/profile/profile_state.dart'; -import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/models/folder/folder.dart'; import 'package:ac_project_app/models/profile/profile_image.dart'; -import 'package:ac_project_app/provider/kakao/kakao.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/widget/add_folder/show_add_folder_dialog.dart'; import 'package:ac_project_app/ui/widget/buttons/upload_button.dart'; import 'package:ac_project_app/ui/widget/custom_reorderable_list_view.dart'; import 'package:ac_project_app/ui/widget/dialog/bottom_dialog.dart'; -import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; -import 'package:ac_project_app/ui/widget/rename_folder/show_rename_folder_dialog.dart'; import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/number_commas.dart'; import 'package:flutter/material.dart'; @@ -395,159 +390,4 @@ class _MyFolderPageState extends State ), ); } - - Future showFolderOptionsDialog( - List folders, - Folder currFolder, - BuildContext parentContext, - ) async { - final visible = currFolder.visible ?? false; - return showModalBottomSheet( - backgroundColor: Colors.transparent, - context: parentContext, - isScrollControlled: true, - builder: (BuildContext context) { - return Wrap( - children: [ - DecoratedBox( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20.r), - topRight: Radius.circular(20.r), - ), - ), - child: Padding( - padding: EdgeInsets.only( - top: 29.h, - bottom: Platform.isAndroid - ? MediaQuery.of(context).padding.bottom - : 0, - ), - child: Column( - children: [ - Container( - margin: EdgeInsets.only(left: 30.w, right: 20.w), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '폴더 옵션', - style: TextStyle( - color: grey800, - fontSize: 20.sp, - fontWeight: FontWeight.bold, - ), - ), - InkWell( - onTap: () => Navigator.pop(context), - child: Icon( - Icons.close_rounded, - size: 24.r, - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only( - top: 17.h, - left: 6.w, - right: 6.w, - bottom: 20.h, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BottomListItem( - visible ? '비공개로 전환' : '공개로 전환', - callback: () { - changeFolderVisible( - parentContext, - currFolder, - ); - }, - ), - BottomListItem( - '폴더명 변경', - callback: () { - changeFolderName( - parentContext, - folders, - currFolder, - ); - }, - ), - BottomListItem( - '폴더 삭제', - callback: () { - deleteFolderDialog(parentContext, currFolder); - }, - ), - BottomListItem( - '카카오톡 폴더 공유', - callback: () { - final profileInfoCubit = - getIt(); - if (profileInfoCubit.state - is ProfileLoadedState) { - final profile = (profileInfoCubit.state - as ProfileLoadedState) - .profile; - - if (currFolder.visible ?? false) { - Kakao.sendFolderKakaoShare( - currFolder, - profile, - ); - } else { - showPopUp( - title: '폴더를 공개해 주세요', - content: '카카오톡 폴더 공유는\n공개 폴더로 전환 후 가능해요!', - parentContext: parentContext, - callback: () => Navigator.pop(context), - icon: true, - iconImage: Assets.images.icLockColor - .image(width: 27.w, height: 27.w), - ); - } - } - }, - ), - ], - ), - ), - ], - ), - ), - ), - ], - ); - }, - ); - } - - void changeFolderVisible(BuildContext context, Folder folder) { - context.read().transferVisible(folder).then((value) { - Navigator.pop(context); - }); - } - - void changeFolderName( - BuildContext context, - List folders, - Folder currFolder, - ) { - showRenameFolderDialog( - context, - currFolder: currFolder, - folders: folders, - ).then((value) { - value = value ?? false; - if (value) { - Navigator.pop(context, true); - context.read().getFolders(); - } - }); - } } diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index a962ef03..259e82c9 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -7,7 +7,7 @@ import 'package:ac_project_app/cubits/folders/get_user_folders_cubit.dart'; import 'package:ac_project_app/cubits/home/get_job_list_cubit.dart'; import 'package:ac_project_app/cubits/home_view_cubit.dart'; import 'package:ac_project_app/cubits/linkpool_pick/linkpool_pick_cubit.dart'; -import 'package:ac_project_app/cubits/links/links_from_selected_job_group_cubit.dart'; +import 'package:ac_project_app/cubits/links/get_links_cubit.dart'; import 'package:ac_project_app/cubits/links/upload_link_cubit.dart'; import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; @@ -201,6 +201,7 @@ class _HomeViewState extends State with WidgetsBindingObserver { showUnselectedLabels: true, items: bottomItems, currentIndex: index, + backgroundColor: Colors.white, onTap: (index) { if (index == 0) { context.read().getFolders(); diff --git a/lib/ui/view/links/my_link_view.dart b/lib/ui/view/links/my_link_view.dart index 12e3ae4c..4618f953 100644 --- a/lib/ui/view/links/my_link_view.dart +++ b/lib/ui/view/links/my_link_view.dart @@ -16,6 +16,7 @@ import 'package:ac_project_app/provider/tool_tip_check.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/widget/bottom_toast.dart'; import 'package:ac_project_app/ui/widget/buttons/upload_button.dart'; +import 'package:ac_project_app/ui/widget/dialog/bottom_dialog.dart'; import 'package:ac_project_app/ui/widget/link_hero.dart'; import 'package:ac_project_app/ui/widget/scaffold_with_stack_widget.dart'; import 'package:ac_project_app/ui/widget/shape/reverse_triangle_painter.dart'; @@ -68,78 +69,15 @@ class MyLinkView extends StatelessWidget { child: BlocBuilder( builder: (context, folder) { return ScaffoldWithStackWidget( - scaffold: Scaffold( - backgroundColor: Colors.white, - body: SafeArea( - child: BlocBuilder( - builder: (cubitContext, state) { - return Stack( - children: [ - NotificationListener( - onNotification: (scrollEnd) { - final metrics = scrollEnd.metrics; - if (metrics.atEdge && metrics.pixels != 0) { - context - .read() - .loadMore(); - } - return true; - }, - child: CustomScrollView( - //crossAxisAlignment: CrossAxisAlignment.start, - slivers: [ - buildTopAppBar(context), - buildTitleBar(folder), - buildContentsCountText(cubitContext), - buildSearchBar(context, links), - buildTabBar( - folders, - tabIndex, - folder, - links, - onChangeIndex: (int index) { - // tabIndex = index; - }, - ), - buildBodyList( - folder: folder, - width: width, - context: cubitContext, - totalLinks: links, - state: state, - folderState: folderState, - foldersContext: foldersContext, - ), - ], - ), - ), - FloatingUploadButton( - context, - callback: () { - links.clear(); - context - .read() - .refresh(); - }, - ), - if (state is LinkListLoadingState || - state is LinkListInitialState) - Center( - child: Container( - margin: EdgeInsets.only(bottom: 30.h), - child: const CircularProgressIndicator( - color: primary600, - ), - ), - ) - else - const SizedBox.shrink(), - ], - ); - }, - ), - ), + scaffold: LinkView( + context, + folders, + folder, + links, + tabIndex, + width, + folderState, + foldersContext, ), widget: BlocBuilder( builder: (ctx, widgetOffset) { @@ -215,8 +153,90 @@ class MyLinkView extends StatelessWidget { ); } + Scaffold LinkView( + BuildContext context, + List folders, + Folder folder, + List links, + int tabIndex, + double width, + FoldersState folderState, + BuildContext foldersContext, + ) { + return Scaffold( + backgroundColor: Colors.white, + body: SafeArea( + child: BlocBuilder( + builder: (cubitContext, state) { + return Stack( + children: [ + NotificationListener( + onNotification: (scrollEnd) { + final metrics = scrollEnd.metrics; + if (metrics.atEdge && metrics.pixels != 0) { + context.read().loadMore(); + } + return true; + }, + child: CustomScrollView( + //crossAxisAlignment: CrossAxisAlignment.start, + slivers: [ + buildTopAppBar(context, folders, folder), + buildTitleBar(folder), + buildContentsCountText(cubitContext), + buildSearchBar(context, links), + buildTabBar( + folders, + tabIndex, + folder, + links, + onChangeIndex: (int index) { + // tabIndex = index; + }, + ), + buildBodyList( + folder: folder, + width: width, + context: cubitContext, + totalLinks: links, + state: state, + folderState: folderState, + foldersContext: foldersContext, + ), + ], + ), + ), + FloatingUploadButton( + context, + callback: () { + links.clear(); + context.read().refresh(); + }, + ), + if (state is LinkListLoadingState || + state is LinkListInitialState) + Center( + child: Container( + margin: EdgeInsets.only(bottom: 30.h), + child: const CircularProgressIndicator( + color: primary600, + ), + ), + ) + else + const SizedBox.shrink(), + ], + ); + }, + ), + ), + ); + } + Widget buildTopAppBar( BuildContext context, + List folders, + Folder folder, ) { return SliverAppBar( pinned: true, @@ -228,7 +248,31 @@ class MyLinkView extends StatelessWidget { color: grey900, padding: EdgeInsets.only(left: 20.w, right: 8.w), ), - backgroundColor: Colors.white, + actions: [ + InkWell( + onTap: () { + showFolderOptionsDialog( + folders, + folder, + context, + fromLinkView: true, + ); + }, + child: Container( + margin: EdgeInsets.only(right: 24.w), + child: SvgPicture.asset( + Assets.images.more, + width: 25.w, + height: 25.h, + ), + ), + ), + ], + flexibleSpace: FlexibleSpaceBar( + background: Container( + color: Colors.white, + ), + ), elevation: 0, systemOverlayStyle: SystemUiOverlayStyle.dark, ); @@ -268,7 +312,7 @@ class MyLinkView extends StatelessWidget { child: Container( margin: EdgeInsets.only(left: 24.w, top: 3.h), child: Text( - '콘텐츠 ${addCommasFrom(count)}개', + '링크 ${addCommasFrom(count)}개', style: TextStyle( color: greyText, fontWeight: FontWeight.w500, diff --git a/lib/ui/view/links/search_view.dart b/lib/ui/view/links/search_view.dart index ccc19e0c..1eca4fe4 100644 --- a/lib/ui/view/links/search_view.dart +++ b/lib/ui/view/links/search_view.dart @@ -95,22 +95,12 @@ class _SearchViewState extends State { color: grey900, padding: EdgeInsets.only(left: 20.w, right: 8.w), ), - title: searchState ? buildSearchBar() : buildEmptySearchBar(), + title: searchState ? buildSearchBar(totalLinks, isMine, context) : buildEmptySearchBar(), titleSpacing: 0, actions: [ Center( child: InkWell( - onTap: buttonState - ? () { - totalLinks.clear(); - final text = textController.text; - if (isMine) { - context.read().searchMyLinks(text, 0); - } else { - context.read().searchLinks(text, 0); - } - } - : null, + onTap: () => onTapSearch(totalLinks, isMine, context), child: Padding( padding: EdgeInsets.only( left: 16.w, @@ -133,6 +123,18 @@ class _SearchViewState extends State { ); } + void onTapSearch(List totalLinks, bool isMine, BuildContext context) { + if (buttonState) { + totalLinks.clear(); + final text = textController.text; + if (isMine) { + context.read().searchMyLinks(text, 0); + } else { + context.read().searchLinks(text, 0); + } + } + } + Widget buildListBody( BuildContext parentContext, List totalLinks, @@ -358,7 +360,7 @@ class _SearchViewState extends State { ); } - Widget buildSearchBar() { + Widget buildSearchBar(List totalLinks, bool isMine, BuildContext context) { return Center( child: Container( margin: EdgeInsets.only(left: 10.w), @@ -379,6 +381,10 @@ class _SearchViewState extends State { fontSize: 14.sp, fontWeight: FontWeight.w400, ), + textInputAction: TextInputAction.search, + onSubmitted: (value) { + onTapSearch(totalLinks, isMine, context); + }, decoration: InputDecoration( border: InputBorder.none, focusedBorder: InputBorder.none, diff --git a/lib/ui/view/links/user_feed_view.dart b/lib/ui/view/links/user_feed_view.dart index 93297d6d..df4233e5 100644 --- a/lib/ui/view/links/user_feed_view.dart +++ b/lib/ui/view/links/user_feed_view.dart @@ -63,7 +63,6 @@ class UserFeedView extends StatelessWidget { feedContext.read().hasRefresh = false; } - totalLinks.addAll(links); return BlocProvider( create: (_) => ScrollCubit( feedContext.read().scrollController, @@ -145,7 +144,7 @@ class UserFeedView extends StatelessWidget { ], ), ), - FolderNameListView(context, folders), + FolderNameListView(context, folders, feedContext.read().scrollController), buildListBody( context, totalLinks, @@ -200,15 +199,20 @@ class UserFeedView extends StatelessWidget { else const SizedBox.shrink(), ], - backgroundColor: !isMove ? Colors.transparent : Colors.white, - systemOverlayStyle: SystemUiOverlayStyle.dark, + flexibleSpace: FlexibleSpaceBar( + background: Container( + color: !isMove ? Colors.transparent : Colors.white, + ), + ), elevation: 0, + systemOverlayStyle: SystemUiOverlayStyle.dark, ); } Widget FolderNameListView( BuildContext parentContext, List folders, + ScrollController scrollController, ) { return SliverToBoxAdapter( child: Container( @@ -286,7 +290,7 @@ class UserFeedView extends StatelessWidget { final cubit = context.read(); cubit.totalLinks.clear(); cubit.selectFolder(index).then( - (value) => cubit.scrollController.jumpTo(0), + (value) => scrollController.jumpTo(0), ); }, ); diff --git a/lib/ui/view/upload_view.dart b/lib/ui/view/upload_view.dart index a0355a63..fda9a9f4 100644 --- a/lib/ui/view/upload_view.dart +++ b/lib/ui/view/upload_view.dart @@ -14,6 +14,7 @@ import 'package:ac_project_app/provider/upload_state_variable.dart'; import 'package:ac_project_app/ui/widget/add_folder/folder_add_title.dart'; import 'package:ac_project_app/ui/widget/add_folder/horizontal_folder_list.dart'; import 'package:ac_project_app/ui/widget/add_folder/subtitle.dart'; +import 'package:ac_project_app/ui/widget/bottom_toast.dart'; import 'package:ac_project_app/ui/widget/buttons/bottom_sheet_button.dart'; import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; import 'package:ac_project_app/ui/widget/loading.dart'; @@ -400,6 +401,11 @@ class _UploadViewState extends State { ) .then((result) { if (result == UploadResultState.success) { + showBottomToast( + context: context, + '링크 등록 완료', + duration: 1000, + ); Navigator.pop(context, NavigatorPopType.saveLink); } else if (result == UploadResultState.duplicated) { showPopUp( diff --git a/lib/ui/widget/dialog/bottom_dialog.dart b/lib/ui/widget/dialog/bottom_dialog.dart index 38265639..9f61e79c 100644 --- a/lib/ui/widget/dialog/bottom_dialog.dart +++ b/lib/ui/widget/dialog/bottom_dialog.dart @@ -4,6 +4,9 @@ import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/cubits/folders/folder_name_cubit.dart'; import 'package:ac_project_app/cubits/folders/folders_state.dart'; import 'package:ac_project_app/cubits/folders/get_my_folders_cubit.dart'; +import 'package:ac_project_app/cubits/folders/get_selected_folder_cubit.dart'; +import 'package:ac_project_app/cubits/profile/profile_info_cubit.dart'; +import 'package:ac_project_app/cubits/profile/profile_state.dart'; import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/models/folder/folder.dart'; @@ -19,6 +22,7 @@ import 'package:ac_project_app/ui/widget/add_folder/horizontal_folder_list.dart' import 'package:ac_project_app/ui/widget/bottom_toast.dart'; import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; import 'package:ac_project_app/ui/widget/move_to_my_folder_dialog.dart'; +import 'package:ac_project_app/ui/widget/rename_folder/show_rename_folder_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -495,3 +499,174 @@ void runCallback( moveToMyLinksView?.call(parentContext, folders, folders.length - 1); callback?.call(); } + +Future showFolderOptionsDialog( + List folders, + Folder currFolder, + BuildContext parentContext, { + bool fromLinkView = false, +}) async { + final visible = currFolder.visible ?? false; + return showModalBottomSheet( + backgroundColor: Colors.transparent, + context: parentContext, + isScrollControlled: true, + builder: (BuildContext context) { + return Wrap( + children: [ + DecoratedBox( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20.r), + topRight: Radius.circular(20.r), + ), + ), + child: Padding( + padding: EdgeInsets.only( + top: 29.h, + bottom: Platform.isAndroid + ? MediaQuery.of(context).padding.bottom + : 0, + ), + child: Column( + children: [ + Container( + margin: EdgeInsets.only(left: 30.w, right: 20.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '폴더 옵션', + style: TextStyle( + color: grey800, + fontSize: 20.sp, + fontWeight: FontWeight.bold, + ), + ), + InkWell( + onTap: () => Navigator.pop(context), + child: Icon( + Icons.close_rounded, + size: 24.r, + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only( + top: 17.h, + left: 6.w, + right: 6.w, + bottom: 20.h, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BottomListItem( + visible ? '비공개로 전환' : '공개로 전환', + callback: () { + changeFolderVisible( + parentContext, + currFolder, + ); + }, + ), + BottomListItem( + '폴더명 변경', + callback: () { + changeFolderName( + parentContext, + folders, + currFolder, + ); + }, + ), + BottomListItem( + '폴더 삭제', + callback: () { + deleteFolderDialog( + parentContext, + currFolder, + callback: () { + if (fromLinkView) { + Navigator.pop(parentContext); + } + }, + ); + }, + ), + BottomListItem( + '카카오톡 폴더 공유', + callback: () { + final profileInfoCubit = + getIt(); + if (profileInfoCubit.state is ProfileLoadedState) { + final profile = + (profileInfoCubit.state as ProfileLoadedState) + .profile; + + if (currFolder.visible ?? false) { + Kakao.sendFolderKakaoShare( + currFolder, + profile, + ); + } else { + showPopUp( + title: '폴더를 공개해 주세요', + content: '카카오톡 폴더 공유는\n공개 폴더로 전환 후 가능해요!', + parentContext: parentContext, + callback: () => Navigator.pop(context), + icon: true, + iconImage: Assets.images.icLockColor + .image(width: 27.w, height: 27.w), + ); + } + } + }, + ), + ], + ), + ), + ], + ), + ), + ), + ], + ); + }, + ); +} + +void changeFolderVisible(BuildContext context, Folder folder) { + context.read().transferVisible(folder).then((value) { + Navigator.pop(context); + if (value) { + context + .read() + .update(folder.copyWith(visible: !(folder.visible ?? false))); + } + }); +} + +void changeFolderName( + BuildContext context, + List folders, + Folder currFolder, +) { + showRenameFolderDialog( + context, + currFolder: currFolder, + folders: folders, + ).then((name) { + name = name ?? ''; + if (name.isNotEmpty) { + Navigator.pop(context, true); + context.read().getFolders(); + context + .read() + .update(currFolder.copyWith(name: name)); + } + }); +} diff --git a/lib/ui/widget/dialog/center_dialog.dart b/lib/ui/widget/dialog/center_dialog.dart index 925be32e..8a28b8e6 100644 --- a/lib/ui/widget/dialog/center_dialog.dart +++ b/lib/ui/widget/dialog/center_dialog.dart @@ -235,7 +235,7 @@ void showEmailPopUp({ } -void deleteFolderDialog(BuildContext context, Folder folder) { +void deleteFolderDialog(BuildContext context, Folder folder, {void Function()? callback}) { final width = MediaQuery.of(context).size.width; showDialog( context: context, @@ -325,10 +325,7 @@ void deleteFolderDialog(BuildContext context, Folder folder) { }, ).then((bool? value) { Navigator.pop(context); - if (value ?? false) { - // 삭제 토스트가 두번뜨는 이슈 수정 - //showBottomToast(context:context,'폴더가 삭제되었어요!'); - } + callback?.call(); }); } @@ -503,6 +500,7 @@ void showPausePopup({ return Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), insetPadding: EdgeInsets.zero, + backgroundColor: Colors.white, child: SizedBox( width: width - (45.w * 2), child: Stack( diff --git a/lib/ui/widget/rename_folder/show_rename_folder_dialog.dart b/lib/ui/widget/rename_folder/show_rename_folder_dialog.dart index 6ee40f83..0a00be46 100644 --- a/lib/ui/widget/rename_folder/show_rename_folder_dialog.dart +++ b/lib/ui/widget/rename_folder/show_rename_folder_dialog.dart @@ -15,7 +15,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -Future showRenameFolderDialog( +Future showRenameFolderDialog( BuildContext parentContext, { required List folders, required Folder currFolder, @@ -24,7 +24,7 @@ Future showRenameFolderDialog( }) async { final formKey = GlobalKey(); - return showModalBottomSheet( + return showModalBottomSheet( backgroundColor: Colors.transparent, context: parentContext, isScrollControlled: true, @@ -94,13 +94,9 @@ Padding _buildDialogBody( child: InkWell( onTap: () { final cubit = context.read(); - cubit - .changeName( - currFolder, - context.read().state, - ) - .then((result) { - Navigator.pop(context, true); + final name = context.read().state; + cubit.changeName(currFolder, name).then((result) { + Navigator.pop(context, name); cubit.getFolders(); if (result) { showBottomToast( @@ -226,13 +222,9 @@ Padding _buildDialogBody( ), onPressed: () { final cubit = context.read(); - cubit - .changeName( - currFolder, - context.read().state, - ) - .then((result) { - Navigator.pop(context, true); + final name = context.read().state; + cubit.changeName(currFolder, name).then((result) { + Navigator.pop(context, name); cubit.getFolders(); if (result) { showBottomToast( @@ -247,13 +239,14 @@ Padding _buildDialogBody( style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.bold, + color: Colors.white, ), textWidthBasis: TextWidthBasis.parent, ), ), ); }, - ) + ), ], ); }, diff --git a/pubspec.yaml b/pubspec.yaml index b62670ec..ca81e197 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.62+62 +version: 1.0.63+63 environment: sdk: ">=3.0.0 <4.0.0" diff --git a/test/coverage_test.dart b/test/coverage_test.dart index af714527..53003e4c 100644 --- a/test/coverage_test.dart +++ b/test/coverage_test.dart @@ -23,7 +23,7 @@ import 'package:ac_project_app/cubits/links/feed_data_state.dart'; import 'package:ac_project_app/cubits/links/has_more_cubit.dart'; import 'package:ac_project_app/cubits/links/link_list_state.dart'; import 'package:ac_project_app/cubits/links/links_from_selected_folder_cubit.dart'; -import 'package:ac_project_app/cubits/links/links_from_selected_job_group_cubit.dart'; +import 'package:ac_project_app/cubits/links/get_links_cubit.dart'; import 'package:ac_project_app/cubits/links/upload_link_cubit.dart'; import 'package:ac_project_app/cubits/links/upload_result_state.dart'; import 'package:ac_project_app/cubits/login/login_cubit.dart'; From 50e63ae3a86ef6143550792e21daca739b36f517 Mon Sep 17 00:00:00 2001 From: boring-km Date: Sun, 16 Jun 2024 20:23:47 +0900 Subject: [PATCH 36/48] =?UTF-8?q?[fix]=20=EB=B0=B0=ED=8F=AC=EC=9A=A9=20pro?= =?UTF-8?q?file=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Runner.xcodeproj/project.pbxproj | 42 ++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index b62d9195..af263790 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -686,10 +686,12 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -707,6 +709,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -726,9 +729,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -745,6 +750,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -762,9 +768,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -781,6 +789,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -849,9 +858,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -862,6 +873,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -992,9 +1004,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -1005,6 +1019,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1025,9 +1040,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -1038,6 +1055,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; From f33e6e0a34af16bf4e7f72322848fa91b8d93742 Mon Sep 17 00:00:00 2001 From: boring-km Date: Sun, 16 Jun 2024 20:39:54 +0900 Subject: [PATCH 37/48] =?UTF-8?q?[fix]=20Android=20AD=5FID=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 58de43fd..4a9369c9 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + Date: Sun, 23 Jun 2024 01:30:37 +0900 Subject: [PATCH 38/48] =?UTF-8?q?[fix]=201.0.64=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검색창에서 링크 여러번 뜨는 오류 수정 - 마이페이지 화면에서 API 중복 호출되는 버그 수정 - 점검 화면 수정 - 프로필 이미지 변경 화면 버튼 글자 색 변경 --- lib/cubits/home/search_links_cubit.dart | 19 ++- lib/ui/page/home/home_page.dart | 13 --- lib/ui/page/my_page/my_page.dart | 14 ++- lib/ui/view/links/search_view.dart | 135 +++++++++++----------- lib/ui/view/profile/profile_selector.dart | 1 + lib/ui/widget/dialog/center_dialog.dart | 16 +-- pubspec.yaml | 2 +- 7 files changed, 101 insertions(+), 99 deletions(-) diff --git a/lib/cubits/home/search_links_cubit.dart b/lib/cubits/home/search_links_cubit.dart index 9e4b40c0..8b913bfa 100644 --- a/lib/cubits/home/search_links_cubit.dart +++ b/lib/cubits/home/search_links_cubit.dart @@ -14,16 +14,20 @@ class SearchLinksCubit extends Cubit { int page = 0; String currentText = ''; bool isMine = false; + bool hasAdded = true; + final totalLinks = []; Future searchLinks(String text, int pageNum) async { isMine = false; currentText = text; + hasAdded = true; emit(LinkListLoadingState()); final result = await linkApi.searchOtherLinks(text, pageNum); result.when( success: (data) { final links = _setScrollState(data); + totalLinks.addAll(links); emit(LinkListLoadedState(links)); }, error: (msg) { @@ -49,17 +53,24 @@ class SearchLinksCubit extends Cubit { ); } - Future refresh() => - isMine ? searchMyLinks(currentText, 0) : searchLinks(currentText, 0); + void refresh() { + totalLinks.clear(); + isMine ? searchMyLinks(currentText, 0) : searchLinks(currentText, 0); + } void loadMore() { if (hasMore.state == ScrollableType.can) { + hasAdded = true; isMine ? searchMyLinks(currentText, page + 1) : searchLinks(currentText, page + 1); } } + void loadedNewLinks() { + hasAdded = false; + } + List _setScrollState(SearchedLinks data) { page = data.pageNum ?? 0; final hasPage = data.hasMorePage(); @@ -67,4 +78,8 @@ class SearchLinksCubit extends Cubit { return data.contents ?? []; } + + void clear() { + totalLinks.clear(); + } } diff --git a/lib/ui/page/home/home_page.dart b/lib/ui/page/home/home_page.dart index 8f672c0a..e8cf1ed5 100644 --- a/lib/ui/page/home/home_page.dart +++ b/lib/ui/page/home/home_page.dart @@ -14,7 +14,6 @@ import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/widget/dialog/bottom_dialog.dart'; import 'package:ac_project_app/ui/widget/link_hero.dart'; import 'package:ac_project_app/ui/widget/user/user_info.dart'; -import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; @@ -344,17 +343,6 @@ class HomePage extends StatelessWidget { ); } - List _setTotalLinks(BuildContext context, List links) { - final totalLinks = - context.watch().totalLinks; - if (context.read().hasRefresh) { - totalLinks.clear(); - context.read().hasRefresh = false; - } - totalLinks.addAll(links); - return totalLinks; - } - void addLinks(BuildContext context, List totalLinks, List links) { if (context.read().hasRefresh) { totalLinks.clear(); @@ -368,7 +356,6 @@ class HomePage extends StatelessWidget { } Widget LinkpoolPickMenu(BuildContext context, LinkpoolPickResultState state) { - Log.i('state: $state'); if (state is! LinkpoolPickResultLoadedState) { return const SliverToBoxAdapter(child: SizedBox.shrink()); } diff --git a/lib/ui/page/my_page/my_page.dart b/lib/ui/page/my_page/my_page.dart index 8d5d1355..1413c7c5 100644 --- a/lib/ui/page/my_page/my_page.dart +++ b/lib/ui/page/my_page/my_page.dart @@ -19,13 +19,23 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:url_launcher/url_launcher.dart'; -class MyPage extends StatelessWidget { +class MyPage extends StatefulWidget { const MyPage({super.key}); @override - Widget build(BuildContext context) { + State createState() => _MyPageState(); +} + +class _MyPageState extends State { + + @override + void initState() { context.read().loadProfileData(); + super.initState(); + } + @override + Widget build(BuildContext context) { return Column( children: [ BlocBuilder( diff --git a/lib/ui/view/links/search_view.dart b/lib/ui/view/links/search_view.dart index 1eca4fe4..01a24cc0 100644 --- a/lib/ui/view/links/search_view.dart +++ b/lib/ui/view/links/search_view.dart @@ -42,7 +42,6 @@ class _SearchViewState extends State { Widget build(BuildContext context) { final args = getArguments(context); final isMine = args['isMine'] as bool; - final totalLinks = []; return MultiBlocProvider( providers: [ @@ -68,8 +67,8 @@ class _SearchViewState extends State { builder: (context, visible) { return Scaffold( backgroundColor: Colors.white, - appBar: _buildAppBar(context, totalLinks, isMine), - body: buildListBody(context, totalLinks, isMine), + appBar: _buildAppBar(context, isMine), + body: buildListBody(context, isMine), ); }, ), @@ -79,7 +78,6 @@ class _SearchViewState extends State { AppBar _buildAppBar( BuildContext context, - List totalLinks, bool isMine, ) { return AppBar( @@ -95,12 +93,17 @@ class _SearchViewState extends State { color: grey900, padding: EdgeInsets.only(left: 20.w, right: 8.w), ), - title: searchState ? buildSearchBar(totalLinks, isMine, context) : buildEmptySearchBar(), + flexibleSpace: FlexibleSpaceBar( + background: Container( + color: Colors.white, + ), + ), + title: searchState ? buildSearchBar(isMine, context) : buildEmptySearchBar(), titleSpacing: 0, actions: [ Center( child: InkWell( - onTap: () => onTapSearch(totalLinks, isMine, context), + onTap: () => onTapSearch(isMine, context), child: Padding( padding: EdgeInsets.only( left: 16.w, @@ -123,9 +126,9 @@ class _SearchViewState extends State { ); } - void onTapSearch(List totalLinks, bool isMine, BuildContext context) { + void onTapSearch(bool isMine, BuildContext context) { if (buttonState) { - totalLinks.clear(); + context.read().clear(); final text = textController.text; if (isMine) { context.read().searchMyLinks(text, 0); @@ -137,18 +140,13 @@ class _SearchViewState extends State { Widget buildListBody( BuildContext parentContext, - List totalLinks, bool isMine, ) { final width = MediaQuery.of(parentContext).size.width; return BlocBuilder( builder: (context, state) { - if (state is LinkListLoadedState) { - final links = state.links; - totalLinks.addAll(links); - } - + final totalLinks = context.read().totalLinks; if (totalLinks.isEmpty) { return Center( child: Text( @@ -360,64 +358,68 @@ class _SearchViewState extends State { ); } - Widget buildSearchBar(List totalLinks, bool isMine, BuildContext context) { + Widget buildSearchBar(bool isMine, BuildContext context) { return Center( child: Container( margin: EdgeInsets.only(left: 10.w), - child: Container( - decoration: BoxDecoration( - color: grey100, - borderRadius: BorderRadius.all(Radius.circular(7.r)), - ), - height: 36.h, - child: Center( - child: TextField( - textAlignVertical: TextAlignVertical.center, - controller: textController, - cursorColor: grey800, - autofocus: true, - style: TextStyle( - color: grey800, - fontSize: 14.sp, - fontWeight: FontWeight.w400, + child: BlocBuilder( + builder: (context, state) { + return Container( + decoration: BoxDecoration( + color: grey100, + borderRadius: BorderRadius.all(Radius.circular(7.r)), ), - textInputAction: TextInputAction.search, - onSubmitted: (value) { - onTapSearch(totalLinks, isMine, context); - }, - decoration: InputDecoration( - border: InputBorder.none, - focusedBorder: InputBorder.none, - isDense: true, - hintText: '검색어를 입력해주세요', - hintStyle: TextStyle( - fontSize: 14.sp, - letterSpacing: -0.1.w, - height: (18 / 14).h, - color: lightGrey700, - ), - contentPadding: EdgeInsets.symmetric( - horizontal: 10.w, - vertical: 9.h, - ), - suffixIcon: InkWell( - onTap: () { - textController.text = ''; + height: 36.h, + child: Center( + child: TextField( + textAlignVertical: TextAlignVertical.center, + controller: textController, + cursorColor: grey800, + autofocus: true, + style: TextStyle( + color: grey800, + fontSize: 14.sp, + fontWeight: FontWeight.w400, + ), + textInputAction: TextInputAction.search, + onSubmitted: (value) { + onTapSearch(isMine, context); }, - child: Icon( - CupertinoIcons.clear_circled_solid, - color: grey400, - size: 20.r, + decoration: InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + isDense: true, + hintText: '검색어를 입력해주세요', + hintStyle: TextStyle( + fontSize: 14.sp, + letterSpacing: -0.1.w, + height: (18 / 14).h, + color: lightGrey700, + ), + contentPadding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 9.h, + ), + suffixIcon: InkWell( + onTap: () { + textController.text = ''; + }, + child: Icon( + CupertinoIcons.clear_circled_solid, + color: grey400, + size: 20.r, + ), + ), ), + onChanged: (value) { + setState(() { + buttonState = value.isNotEmpty; + }); + }, ), ), - onChanged: (value) { - setState(() { - buttonState = value.isNotEmpty; - }); - }, - ), - ), + ); + }, ), ), ); @@ -467,9 +469,6 @@ class _SearchViewState extends State { } Future refresh(BuildContext context, List totalLinks) async { - if (totalLinks.isNotEmpty) { - totalLinks.clear(); - unawaited(context.read().refresh()); - } + context.read().refresh(); } } diff --git a/lib/ui/view/profile/profile_selector.dart b/lib/ui/view/profile/profile_selector.dart index 5216b281..0f6829cb 100644 --- a/lib/ui/view/profile/profile_selector.dart +++ b/lib/ui/view/profile/profile_selector.dart @@ -120,6 +120,7 @@ class _ProfileSelectorState extends State { style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.bold, + color: Colors.white, ), textWidthBasis: TextWidthBasis.parent, ), diff --git a/lib/ui/widget/dialog/center_dialog.dart b/lib/ui/widget/dialog/center_dialog.dart index 8a28b8e6..f85e161b 100644 --- a/lib/ui/widget/dialog/center_dialog.dart +++ b/lib/ui/widget/dialog/center_dialog.dart @@ -596,22 +596,12 @@ void showPausePopup({ ], ), ), - Positioned( - right: 0, - top: 0, - child: IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: const Icon( - Icons.close, - ), - ), - ), ], ), ), ); }, - ); + ).then((_) { + callback?.call(); + }); } diff --git a/pubspec.yaml b/pubspec.yaml index ca81e197..a50779d6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.63+63 +version: 1.0.64+64 environment: sdk: ">=3.0.0 <4.0.0" From 0ab100662d10ee127b0476e43e7193eb61f4b2d6 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 31 Jul 2024 22:06:36 +0900 Subject: [PATCH 39/48] =?UTF-8?q?[fix]=20=EC=95=88=EB=93=9C=EB=A1=9C?= =?UTF-8?q?=EC=9D=B4=EB=93=9C=20=EB=B9=8C=EB=93=9C=20=EA=B2=BD=EA=B3=A0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cicd.yml | 4 +-- .github/workflows/code_coverage.yml | 2 +- android/app/build.gradle | 25 ++++++----------- android/build.gradle | 19 +------------ android/settings.gradle | 32 +++++++++++++++------ ios/Runner.xcodeproj/project.pbxproj | 42 ++++++++-------------------- 6 files changed, 49 insertions(+), 75 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index b2650f68..8279d1b0 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.2' + flutter-version: '3.22.3' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.2' + flutter-version: '3.22.3' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 458fbf36..822af8d4 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.2' + flutter-version: '3.22.3' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/android/app/build.gradle b/android/app/build.gradle index 45953f4e..d74b2581 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,3 +1,12 @@ +plugins { + id "com.android.application" + id "dev.flutter.flutter-gradle-plugin" + id "kotlin-android" + id "kotlin-parcelize" + id 'com.google.gms.google-services' + id 'com.google.firebase.crashlytics' +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +15,6 @@ if (localPropertiesFile.exists()) { } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new FileNotFoundException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = 1 @@ -33,15 +37,6 @@ def _keyPassword = signingProperties.getProperty('key.password') def _storePassword = signingProperties.getProperty('store.password') def kakaoApiKey = signingProperties.getProperty('kakao.api.key') -apply plugin: 'com.android.application' -// START: FlutterFire Configuration -apply plugin: 'com.google.gms.google-services' -apply plugin: 'com.google.firebase.crashlytics' -// END: FlutterFire Configuration -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-parcelize' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { compileSdkVersion 34 @@ -97,8 +92,6 @@ flutter { } dependencies { - //noinspection GradleDependency,DifferentStdlibGradleVersion - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" //noinspection GradleDependency implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.activity:activity-ktx:1.6.1' diff --git a/android/build.gradle b/android/build.gradle index a99243d0..8f31e8ca 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,20 +1,3 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - // START: FlutterFire Configuration - classpath 'com.google.gms:google-services:4.3.15' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' - // END: FlutterFire Configuration - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - allprojects { repositories { google() @@ -32,4 +15,4 @@ subprojects { tasks.register("clean", Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/android/settings.gradle b/android/settings.gradle index 44e62bcf..133ccec5 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,11 +1,27 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.4.2" apply false + id "org.jetbrains.kotlin.android" version "1.7.10" apply false + id 'com.google.gms.google-services' version '4.3.15' apply false + id 'com.google.firebase.crashlytics' version '2.8.1' apply false +} + +include ":app" \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index af263790..b62d9195 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -686,12 +686,10 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -709,7 +707,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -729,11 +726,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -750,7 +745,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -768,11 +762,9 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -789,7 +781,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -858,11 +849,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -873,7 +862,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1004,11 +992,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -1019,7 +1005,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1040,11 +1025,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; + DEVELOPMENT_TEAM = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -1055,7 +1038,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; From a949d26cb8990212714750cd54f8d7443f6bb892 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 31 Jul 2024 22:44:27 +0900 Subject: [PATCH 40/48] =?UTF-8?q?[fix]=20=EC=95=B1=20=EB=82=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=A7=81=ED=81=AC=20=EB=B3=B5=EC=82=AC=20=EC=8B=9C?= =?UTF-8?q?=20=EC=97=85=EB=A1=9C=EB=93=9C=20=ED=99=94=EB=A9=B4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + 업로드 화면 UI 일부 잘림 해결 --- lib/provider/check_clipboard_link.dart | 10 ++++++++++ lib/ui/view/home_view.dart | 5 ++++- lib/ui/view/upload_view.dart | 25 +++++++++++++++++-------- lib/ui/widget/dialog/bottom_dialog.dart | 22 +++++++++------------- 4 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 lib/provider/check_clipboard_link.dart diff --git a/lib/provider/check_clipboard_link.dart b/lib/provider/check_clipboard_link.dart new file mode 100644 index 00000000..28477dae --- /dev/null +++ b/lib/provider/check_clipboard_link.dart @@ -0,0 +1,10 @@ +String? _checkClipboardLink = ''; + +bool isClipboardLink(String? text) { + if (text == null || text.isEmpty) return false; + return text == _checkClipboardLink; +} + +void setClipboardLink(String? text) { + _checkClipboardLink = text; +} diff --git a/lib/ui/view/home_view.dart b/lib/ui/view/home_view.dart index 259e82c9..2755e95e 100644 --- a/lib/ui/view/home_view.dart +++ b/lib/ui/view/home_view.dart @@ -12,6 +12,7 @@ import 'package:ac_project_app/cubits/links/upload_link_cubit.dart'; import 'package:ac_project_app/di/set_up_get_it.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/provider/api/folders/folder_api.dart'; +import 'package:ac_project_app/provider/check_clipboard_link.dart'; import 'package:ac_project_app/provider/kakao/kakao.dart'; import 'package:ac_project_app/provider/manager/app_pause_manager.dart'; import 'package:ac_project_app/provider/upload_state_variable.dart'; @@ -86,12 +87,14 @@ class _HomeViewState extends State with WidgetsBindingObserver { Clipboard.getData(Clipboard.kTextPlain).then((value) { isValidUrl(value?.text ?? '').then((isValid) { if (isValid) { + final url = value!.text; + if (isClipboardLink(url)) return; Clipboard.setData(const ClipboardData(text: '')); Navigator.pushNamed( context, Routes.upload, arguments: { - 'url': value?.text, + 'url': url, }, ); } diff --git a/lib/ui/view/upload_view.dart b/lib/ui/view/upload_view.dart index fda9a9f4..3d563390 100644 --- a/lib/ui/view/upload_view.dart +++ b/lib/ui/view/upload_view.dart @@ -189,7 +189,7 @@ class _UploadViewState extends State { margin: EdgeInsets.only( right: 24.w, ), - height: 78.h, + decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(8.r)), color: grey50, @@ -199,7 +199,10 @@ class _UploadViewState extends State { child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SvgPicture.asset(Assets.images.warningMark), + Padding( + padding: EdgeInsets.only(top: 3.h), + child: SvgPicture.asset(Assets.images.warningMark), + ), SizedBox(width: 4.w), Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -215,12 +218,18 @@ class _UploadViewState extends State { SizedBox( height: 6.h, ), - Text( - warningMsgContent, - style: TextStyle( - fontWeight: FontWeight.w500, - color: grey400, - fontSize: 11.sp, + SizedBox( + width: 280.h, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Text( + warningMsgContent, + style: TextStyle( + fontWeight: FontWeight.w500, + color: grey400, + fontSize: 11.sp, + ), + ), ), ), ], diff --git a/lib/ui/widget/dialog/bottom_dialog.dart b/lib/ui/widget/dialog/bottom_dialog.dart index 9f61e79c..d546aacd 100644 --- a/lib/ui/widget/dialog/bottom_dialog.dart +++ b/lib/ui/widget/dialog/bottom_dialog.dart @@ -14,6 +14,7 @@ import 'package:ac_project_app/models/link/link.dart'; import 'package:ac_project_app/models/report/report_type.dart'; import 'package:ac_project_app/models/user/detail_user.dart'; import 'package:ac_project_app/provider/api/folders/link_api.dart'; +import 'package:ac_project_app/provider/check_clipboard_link.dart'; import 'package:ac_project_app/provider/kakao/kakao.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/page/my_folder/folder_visible_state.dart'; @@ -24,7 +25,6 @@ import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; import 'package:ac_project_app/ui/widget/move_to_my_folder_dialog.dart'; import 'package:ac_project_app/ui/widget/rename_folder/show_rename_folder_dialog.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:share_plus/share_plus.dart'; @@ -67,18 +67,11 @@ Future showMyLinkOptionsDialog( BottomListItem( '공유', callback: () { + setClipboardLink(link.url); Share.share( link.url ?? '', subject: link.title, ); - Clipboard.setData( - ClipboardData(text: link.url ?? ''), - ).then( - (value) => showBottomToast( - context: context, - '링크 주소가 복사 되었어요!', - ), - ); }, ), BottomListItem( @@ -259,10 +252,13 @@ Future showLinkOptionsDialog( children: [ BottomListItem( '공유', - callback: () => Share.share( - link.url ?? '', - subject: link.title, - ), + callback: () { + setClipboardLink(link.url); + Share.share( + link.url ?? '', + subject: link.title, + ); + }, ), BottomListItem( '카카오톡 공유', From 3d788b270293fbadf7f3eb555c4a8f66af612fc6 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 31 Jul 2024 23:53:28 +0900 Subject: [PATCH 41/48] =?UTF-8?q?[fix]=20=EC=82=AD=EC=A0=9C=20slidable=20?= =?UTF-8?q?=EC=97=AC=EB=9F=AC=EA=B0=9C=20=ED=99=9C=EC=84=B1=ED=99=94=20?= =?UTF-8?q?=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95,=20=EB=A7=81=ED=81=AC=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20=EA=B7=B8?= =?UTF-8?q?=20=ED=99=94=EB=A9=B4=EC=97=90=20=EB=A8=B8=EB=AC=BC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/cubits/links/detail_edit_cubit.dart | 20 ++-- lib/cubits/links/edit_state.dart | 18 +++- lib/ui/view/links/link_detail_view.dart | 93 +++++++++++++------ lib/ui/view/links/my_link_view.dart | 63 +++++++------ .../widget/slidable/link_slidable_widget.dart | 2 +- pubspec.yaml | 2 +- 6 files changed, 129 insertions(+), 69 deletions(-) diff --git a/lib/cubits/links/detail_edit_cubit.dart b/lib/cubits/links/detail_edit_cubit.dart index a22bafca..f9ed8d78 100644 --- a/lib/cubits/links/detail_edit_cubit.dart +++ b/lib/cubits/links/detail_edit_cubit.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DetailEditCubit extends Cubit { - DetailEditCubit(Object? argument) : super(EditState.view) { + DetailEditCubit(Object? argument) : super(EditState(EditStateType.view)) { if (argument is Map) { final link = (argument['link'] ?? const Link()) as Link; textController.text = link.describe ?? ''; @@ -17,15 +17,23 @@ class DetailEditCubit extends Cubit { final textController = TextEditingController(); void toggle() { - if (state == EditState.view) { - emit(EditState.edit); + if (state.type == EditStateType.view) { + emit(state.copyWith(type: EditStateType.edit)); } else { - emit(EditState.view); + emit(state.copyWith(type: EditStateType.view)); } } - Future saveComment(Link link) async { + void toggleEdit(Link link) { + emit(state.copyWith(type: EditStateType.editedView, link: link)); + } + + Future saveComment(Link link) async { final newLink = link.copyWith(describe: textController.text); - return linkApi.patchLink(newLink); + if (await linkApi.patchLink(newLink)) { + return newLink; + } else { + return link; + } } } diff --git a/lib/cubits/links/edit_state.dart b/lib/cubits/links/edit_state.dart index 8f50e735..49953701 100644 --- a/lib/cubits/links/edit_state.dart +++ b/lib/cubits/links/edit_state.dart @@ -1 +1,17 @@ -enum EditState { edit, view } +import 'package:ac_project_app/models/link/link.dart'; + +class EditState { + EditState(this.type, {this.link}); + + final EditStateType type; + final Link? link; + + EditState copyWith({EditStateType? type, Link? link}) { + return EditState( + type ?? this.type, + link: link ?? this.link, + ); + } +} + +enum EditStateType { edit, view, editedView } diff --git a/lib/ui/view/links/link_detail_view.dart b/lib/ui/view/links/link_detail_view.dart index 5cdd495e..b4292839 100644 --- a/lib/ui/view/links/link_detail_view.dart +++ b/lib/ui/view/links/link_detail_view.dart @@ -26,21 +26,31 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:url_launcher/url_launcher.dart'; -class LinkDetailView extends StatelessWidget { +class LinkDetailView extends StatefulWidget { const LinkDetailView({super.key}); + @override + State createState() => _LinkDetailViewState(); +} + +class _LinkDetailViewState extends State { + + final scrollController = ScrollController(); + late Link? globalLink; + late bool? isMine; + late bool linkVisible; + @override Widget build(BuildContext context) { final args = getArguments(context); - final link = args['link'] as Link; - final isMine = args['isMine'] as bool?; - final linkVisible = args['visible'] as bool? ?? true; - final scrollController = ScrollController(); + globalLink = args['link'] as Link; + isMine = args['isMine'] as bool?; + linkVisible = args['visible'] as bool? ?? true; final profileState = context.watch().state; var isMyLink = false; if (profileState is ProfileLoadedState) { - isMyLink = profileState.profile.id == link.user?.id; + isMyLink = profileState.profile.id == globalLink!.user?.id; } if (isMine ?? false) { isMyLink = true; @@ -48,7 +58,7 @@ class LinkDetailView extends StatelessWidget { return MultiBlocProvider( providers: [ - BlocProvider(create: (_) => DetailEditCubit(link)), + BlocProvider(create: (_) => DetailEditCubit(globalLink)), BlocProvider(create: (_) => GetUserFoldersCubit()), BlocProvider(create: (_) => UploadLinkCubit()), ], @@ -58,17 +68,18 @@ class LinkDetailView extends StatelessWidget { return BlocBuilder( builder: (cubitContext, editState) { final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; - if (editState == EditState.edit) { + if (editState.type == EditStateType.edit) { return PopScope( onPopInvoked: (bool didPop) { + Log.d('onPopInvoked edit: $didPop'); if (didPop) return; - goBackPage(editState, context, link.id); + goBackPage(editState, context, globalLink!.id); }, child: buildMainScreen( editState, context, isMyLink, - link, + globalLink!, scrollController, cubitContext, keyboardHeight, @@ -77,16 +88,24 @@ class LinkDetailView extends StatelessWidget { ), ); } else { - return buildMainScreen( - editState, - context, - isMyLink, - link, - scrollController, - cubitContext, - keyboardHeight, - visible, - linkVisible, + return PopScope( + onPopInvoked: (bool didPop) { + Log.d('onPopInvoked ${editState.type}: $didPop'); + if (didPop) return; + changePreviousViewIfEdited(editState, context); + }, + canPop: false, + child: buildMainScreen( + editState, + context, + isMyLink, + editState.link ?? globalLink!, + scrollController, + cubitContext, + keyboardHeight, + visible, + linkVisible, + ), ); } }, @@ -97,6 +116,15 @@ class LinkDetailView extends StatelessWidget { ); } + void changePreviousViewIfEdited(EditState editState, BuildContext context) { + Log.d('changePreviousViewIfEdited: ${editState.type}'); + if (editState.type == EditStateType.editedView) { + Navigator.pop(context, 'changed'); + } else { + Navigator.pop(context); + } + } + Scaffold buildMainScreen( EditState editState, BuildContext context, @@ -156,16 +184,19 @@ class LinkDetailView extends StatelessWidget { ), bottomSheet: Builder( builder: (_) { - if (editState == EditState.edit) { + if (editState.type == EditStateType.edit) { return buildBottomSheetButton( context: context, text: '확인', keyboardVisible: visible, - onPressed: () => - cubitContext.read().saveComment(link).then( - (value) => - value ? Navigator.pop(context, 'changed') : null, - ), + onPressed: () { + cubitContext.read().saveComment(link).then((newLink) { + cubitContext.read().toggleEdit(newLink); + setState(() { + globalLink = newLink; + }); + }); + }, ); } else { return const SizedBox.shrink(); @@ -176,7 +207,7 @@ class LinkDetailView extends StatelessWidget { } void goBackPage(EditState editState, BuildContext context, int? linkId) { - if (editState == EditState.edit) { + if (editState.type == EditStateType.edit) { showWaitDialog( context, callback: () { @@ -187,6 +218,8 @@ class LinkDetailView extends StatelessWidget { }); }, ); + } else if (editState.type == EditStateType.editedView) { + Navigator.pop(context, 'changed'); } else { Navigator.pop(context); } @@ -214,7 +247,7 @@ class LinkDetailView extends StatelessWidget { ) { return SingleChildScrollView( controller: scrollController, - reverse: state == EditState.edit, + reverse: state.type == EditStateType.edit, child: Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 14.h), child: Column( @@ -380,7 +413,7 @@ class LinkDetailView extends StatelessWidget { ), Builder( builder: (_) { - if (state == EditState.view) { + if (state.type == EditStateType.view || state.type == EditStateType.editedView) { return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -460,7 +493,7 @@ class LinkDetailView extends StatelessWidget { Link link, ) { final linkId = link.id; - if (state == EditState.edit) { + if (state.type == EditStateType.edit) { showWaitDialog( cubitContext, callback: () { diff --git a/lib/ui/view/links/my_link_view.dart b/lib/ui/view/links/my_link_view.dart index 4618f953..5be52193 100644 --- a/lib/ui/view/links/my_link_view.dart +++ b/lib/ui/view/links/my_link_view.dart @@ -30,6 +30,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:flutter_svg/flutter_svg.dart'; class MyLinkView extends StatelessWidget { @@ -501,39 +502,41 @@ class MyLinkView extends StatelessWidget { final links = state.links; totalLinks.addAll(links); } - return SliverList( - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - final link = totalLinks[index]; - return Column( - children: [ - buildLinkItem( - context, - link, - totalLinks, - foldersContext, - folder, - index, - width, - ), - if (index != totalLinks.length - 1) - Padding( - padding: EdgeInsets.symmetric(horizontal: 24.w), - child: Padding( + return SlidableAutoCloseBehavior( + child: SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, int index) { + final link = totalLinks[index]; + return Column( + children: [ + buildLinkItem( + context, + link, + totalLinks, + foldersContext, + folder, + index, + width, + ), + if (index != totalLinks.length - 1) + Padding( padding: EdgeInsets.symmetric(horizontal: 24.w), - child: Divider( - height: 1.h, - thickness: 1.h, - color: greyTab, - indent: 24.w, - endIndent: 24.w, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 24.w), + child: Divider( + height: 1.h, + thickness: 1.h, + color: greyTab, + indent: 24.w, + endIndent: 24.w, + ), ), ), - ), - ], - ); - }, - childCount: totalLinks.length, + ], + ); + }, + childCount: totalLinks.length, + ), ), ); } diff --git a/lib/ui/widget/slidable/link_slidable_widget.dart b/lib/ui/widget/slidable/link_slidable_widget.dart index 7c878170..f8d8e3c3 100644 --- a/lib/ui/widget/slidable/link_slidable_widget.dart +++ b/lib/ui/widget/slidable/link_slidable_widget.dart @@ -46,7 +46,7 @@ class LinkSlidAbleWidget extends StatelessWidget { ), ), ), - ) + ), ], ), child: child, diff --git a/pubspec.yaml b/pubspec.yaml index a50779d6..9bdf8f1f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,7 +62,7 @@ dependencies: extended_text: ^13.0.0 carousel_slider: ^4.2.1 lottie: - flutter_slidable: ^3.0.1 + flutter_slidable: ^3.1.1 firebase_storage: ^11.7.5 ## lint From d6de7504cd8b3e84fc9e0a00de586390d3392ba3 Mon Sep 17 00:00:00 2001 From: boring-km Date: Thu, 1 Aug 2024 00:04:30 +0900 Subject: [PATCH 42/48] =?UTF-8?q?[fix]=20=EB=A7=88=EC=9D=B4=ED=8F=B4?= =?UTF-8?q?=EB=8D=94=20>=20=EB=A7=81=ED=81=AC=EB=AA=A9=EB=A1=9D=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B2=80=EC=83=89=20=EC=95=88=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EC=9D=B4=EC=8A=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/cubits/home/search_links_cubit.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cubits/home/search_links_cubit.dart b/lib/cubits/home/search_links_cubit.dart index 8b913bfa..66e8e164 100644 --- a/lib/cubits/home/search_links_cubit.dart +++ b/lib/cubits/home/search_links_cubit.dart @@ -45,6 +45,7 @@ class SearchLinksCubit extends Cubit { result.when( success: (data) { final links = _setScrollState(data); + totalLinks.addAll(links); emit(LinkListLoadedState(links)); }, error: (msg) { From 30c59db54910d66ead2cdec5f64f01b28c019c92 Mon Sep 17 00:00:00 2001 From: boring-km Date: Thu, 1 Aug 2024 00:04:54 +0900 Subject: [PATCH 43/48] [version] 1.0.65 update --- ios/Runner.xcodeproj/project.pbxproj | 42 ++++++++++++++++++++-------- pubspec.yaml | 2 +- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index b62d9195..af263790 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -686,10 +686,12 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -707,6 +709,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -726,9 +729,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -745,6 +750,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -762,9 +768,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extension/Extension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Extension/Info.plist; @@ -781,6 +789,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp.Extension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp.Extension"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -849,9 +858,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -862,6 +873,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -992,9 +1004,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -1005,6 +1019,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1025,9 +1040,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 18; - DEVELOPMENT_TEAM = T583WJWNAK; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = T583WJWNAK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -1038,6 +1055,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.mr.acProjectApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.mr.acProjectApp"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; diff --git a/pubspec.yaml b/pubspec.yaml index 9bdf8f1f..07dea952 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.64+64 +version: 1.0.65+65 environment: sdk: ">=3.0.0 <4.0.0" From e1b5b678f77230cbf0f44241d145db0fcc123ab9 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 4 Sep 2024 13:28:36 +0900 Subject: [PATCH 44/48] =?UTF-8?q?[fix]=20=EC=9D=BC=EB=B6=80=20=EB=9D=BC?= =?UTF-8?q?=EC=9D=B4=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Runner/AppDelegate.swift | 2 +- lib/ui/view/tutorial_view.dart | 8 ++++---- pubspec.yaml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index a8bfa376..50325a86 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,7 +2,7 @@ import UIKit import Flutter import NaverThirdPartyLogin -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( diff --git a/lib/ui/view/tutorial_view.dart b/lib/ui/view/tutorial_view.dart index 7eb752a5..b90a95fa 100644 --- a/lib/ui/view/tutorial_view.dart +++ b/lib/ui/view/tutorial_view.dart @@ -3,7 +3,7 @@ import 'package:ac_project_app/const/strings.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/widget/buttons/bottom_sheet_button.dart'; import 'package:ac_project_app/ui/widget/text/custom_font.dart'; -import 'package:carousel_slider/carousel_slider.dart'; +import 'package:carousel_slider/carousel_slider.dart' as cs; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -16,14 +16,14 @@ class TutorialView extends StatefulWidget { class _TutorialViewState extends State { int _current = 0; - final CarouselController _controller = CarouselController(); + final cs.CarouselSliderController _controller = cs.CarouselSliderController(); @override Widget build(BuildContext context) { final height = MediaQuery.of(context).size.height; return Scaffold( backgroundColor: Colors.white, - body: CarouselSlider( + body: cs.CarouselSlider( items: tutorials .map( (tutorial) => Column( @@ -80,7 +80,7 @@ class _TutorialViewState extends State { ) .toList(), carouselController: _controller, - options: CarouselOptions( + options: cs.CarouselOptions( height: (height * 4) / 5, viewportFraction: 1, enableInfiniteScroll: false, diff --git a/pubspec.yaml b/pubspec.yaml index 07dea952..7a26a9fa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,8 +59,8 @@ dependencies: oktoast: share_plus: ^7.2.2 flutter_keyboard_visibility: ^5.4.1 - extended_text: ^13.0.0 - carousel_slider: ^4.2.1 + extended_text: ^14.0.1 + carousel_slider: ^5.0.0 lottie: flutter_slidable: ^3.1.1 firebase_storage: ^11.7.5 From b0f20e7e844c9a743254940f91aaec540739b7df Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 4 Sep 2024 13:28:36 +0900 Subject: [PATCH 45/48] =?UTF-8?q?[refactor,=20fix]=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EB=B2=84?= =?UTF-8?q?=EC=A0=84=20=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 폴더 명이 화면 밖으로 나갈 때 이슈 수정 - 링크 메타데이터 정보 표시 기능 추가 --- ios/Runner/AppDelegate.swift | 6 +- lib/cubits/links/upload_link_cubit.dart | 50 +++- lib/cubits/links/upload_result_state.dart | 16 +- lib/main.dart | 1 - lib/provider/login/naver_login.dart | 1 + lib/ui/view/links/link_detail_view.dart | 8 +- lib/ui/view/links/my_link_view.dart | 22 +- lib/ui/view/links/user_feed_view.dart | 7 +- lib/ui/view/profile/profile_selector.dart | 1 + lib/ui/view/tutorial_view.dart | 8 +- lib/ui/view/upload_view.dart | 240 +++++++++++----- lib/ui/view/user/email_login_view.dart | 12 +- lib/ui/view/user/login_view.dart | 17 +- .../add_folder/horizontal_folder_list.dart | 257 ++++++++++++------ lib/ui/widget/only_back_app_bar.dart | 1 + lib/util/url_loader.dart | 4 + pubspec.yaml | 25 +- 17 files changed, 462 insertions(+), 214 deletions(-) diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index a8bfa376..1eb905f4 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,7 +2,7 @@ import UIKit import Flutter import NaverThirdPartyLogin -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( @@ -42,8 +42,8 @@ import NaverThirdPartyLogin super.application(app, open:url, options: options) return true } else if url.absoluteString.contains("thirdPartyLoginResult") { - NaverThirdPartyLoginConnection.getSharedInstance().application(app, open: url, options: options) - return true + let result = NaverThirdPartyLoginConnection.getSharedInstance().application(app, open: url, options: options) + return result } else { return true } diff --git a/lib/cubits/links/upload_link_cubit.dart b/lib/cubits/links/upload_link_cubit.dart index cad41af9..b808b50d 100644 --- a/lib/cubits/links/upload_link_cubit.dart +++ b/lib/cubits/links/upload_link_cubit.dart @@ -7,14 +7,16 @@ import 'package:ac_project_app/util/logger.dart'; import 'package:ac_project_app/util/string_utils.dart'; import 'package:ac_project_app/util/url_loader.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:metadata_fetch/src/parsers/base_parser.dart'; -class UploadLinkCubit extends Cubit { - UploadLinkCubit() : super(UploadResultState.success); +class UploadLinkCubit extends Cubit { + UploadLinkCubit() + : super(UploadResult(state: UploadResultState.none, metadata: null)); final LinkApi linkApi = getIt(); // ignore: avoid_positional_boolean_parameters - Future completeRegister( + Future completeRegister( String url, String describe, int? folderId, @@ -23,24 +25,42 @@ class UploadLinkCubit extends Cubit { try { final metadata = await UrlLoader.loadData(url); final rawTitle = metadata.title ?? ''; - final result = await linkApi.postLink( - Link( - url: url, - image: metadata.image, - title: getShortTitle(rawTitle), - describe: describe, - folderId: folderId, - time: getCurrentTime(), - inflowType: uploadType.name, + + final result = UploadResult( + state: await linkApi.postLink( + Link( + url: url, + image: metadata.image, + title: getShortTitle(rawTitle), + describe: describe, + folderId: folderId, + time: getCurrentTime(), + inflowType: uploadType.name, + ), ), + metadata: metadata, ); - emit(result); return result; } catch (e) { Log.e(e); - emit(UploadResultState.error); - return UploadResultState.error; + final errorResult = UploadResult(state: UploadResultState.error, metadata: null); + emit(errorResult); + return errorResult; + } + } + + bool isValidateUrl(String url) { + return UrlLoader.isValidateUrl(url); + } + + Future getMetadata(String validUrl) async { + emit(UploadResult(state: UploadResultState.isValid, metadata: await UrlLoader.loadData(validUrl))); + } + + void validateMetadata(String url) { + if (isValidateUrl(url)) { + getMetadata(url); } } } diff --git a/lib/cubits/links/upload_result_state.dart b/lib/cubits/links/upload_result_state.dart index 62fd9e76..cff5bdf5 100644 --- a/lib/cubits/links/upload_result_state.dart +++ b/lib/cubits/links/upload_result_state.dart @@ -1,3 +1,17 @@ +import 'package:metadata_fetch/metadata_fetch.dart'; + +class UploadResult { + + UploadResult({required this.state, required this.metadata}); + + final UploadResultState state; + final Metadata? metadata; + + bool isNotValidAndSuccess() { + return state != UploadResultState.isValid && state != UploadResultState.success; + } +} + enum UploadResultState { - success, duplicated, apiError, error + none, isValid, success, duplicated, apiError, error } diff --git a/lib/main.dart b/lib/main.dart index e52004d5..1f7f247e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -25,7 +25,6 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - //Setting SystemUIOverlay SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( statusBarColor: Colors.transparent, diff --git a/lib/provider/login/naver_login.dart b/lib/provider/login/naver_login.dart index 125891db..2c73706c 100644 --- a/lib/provider/login/naver_login.dart +++ b/lib/provider/login/naver_login.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:ac_project_app/cubits/login/login_type.dart'; import 'package:ac_project_app/provider/login/firebase_auth_remote_data_source.dart'; +import 'package:ac_project_app/util/logger.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_naver_login/flutter_naver_login.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/lib/ui/view/links/link_detail_view.dart b/lib/ui/view/links/link_detail_view.dart index b4292839..73b4585f 100644 --- a/lib/ui/view/links/link_detail_view.dart +++ b/lib/ui/view/links/link_detail_view.dart @@ -70,7 +70,7 @@ class _LinkDetailViewState extends State { final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; if (editState.type == EditStateType.edit) { return PopScope( - onPopInvoked: (bool didPop) { + onPopInvokedWithResult: (bool didPop, _) { Log.d('onPopInvoked edit: $didPop'); if (didPop) return; goBackPage(editState, context, globalLink!.id); @@ -89,7 +89,7 @@ class _LinkDetailViewState extends State { ); } else { return PopScope( - onPopInvoked: (bool didPop) { + onPopInvokedWithResult: (bool didPop, _) { Log.d('onPopInvoked ${editState.type}: $didPop'); if (didPop) return; changePreviousViewIfEdited(editState, context); @@ -140,8 +140,9 @@ class _LinkDetailViewState extends State { resizeToAvoidBottomInset: false, backgroundColor: Colors.white, appBar: AppBar( - backgroundColor: Colors.transparent, + backgroundColor: Colors.white, elevation: 0, + scrolledUnderElevation: 0, leading: IconButton( onPressed: () { goBackPage(editState, context, link.id); @@ -250,6 +251,7 @@ class _LinkDetailViewState extends State { reverse: state.type == EditStateType.edit, child: Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 14.h), + color: Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/ui/view/links/my_link_view.dart b/lib/ui/view/links/my_link_view.dart index 5be52193..81c0f7d3 100644 --- a/lib/ui/view/links/my_link_view.dart +++ b/lib/ui/view/links/my_link_view.dart @@ -286,12 +286,16 @@ class MyLinkView extends StatelessWidget { margin: EdgeInsets.only(left: 24.w, right: 12.w, top: 10.h), child: Row( children: [ - Text( - classified ? folder.name! : '미분류', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 30.sp, - height: (36 / 30).h, + SizedBox( + width: 250.w, + child: Text( + classified ? folder.name! : '미분류', + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 30.sp, + height: (36 / 30).h, + ), ), ), if (!(folder.visible ?? false)) @@ -428,12 +432,16 @@ class MyLinkView extends StatelessWidget { final tabs = []; for (final folder in folders) { tabs.add( - Padding( + Container( + constraints: BoxConstraints( + maxWidth: 100.w, + ), padding: EdgeInsets.symmetric( vertical: 7.h, ), child: Text( folder.name ?? '', + overflow: TextOverflow.ellipsis, ), ), ); diff --git a/lib/ui/view/links/user_feed_view.dart b/lib/ui/view/links/user_feed_view.dart index df4233e5..bbd8016a 100644 --- a/lib/ui/view/links/user_feed_view.dart +++ b/lib/ui/view/links/user_feed_view.dart @@ -169,6 +169,7 @@ class UserFeedView extends StatelessWidget { ) { return SliverAppBar( pinned: true, + scrolledUnderElevation: 0, leading: IconButton( onPressed: () { Navigator.pop(context); @@ -251,12 +252,16 @@ class UserFeedView extends StatelessWidget { final tabs = []; for (final folder in folders) { tabs.add( - Padding( + Container( + constraints: BoxConstraints( + maxWidth: 100.w, + ), padding: EdgeInsets.symmetric( vertical: 7.h, ), child: Text( folder.name ?? '', + overflow: TextOverflow.ellipsis, ), ), ); diff --git a/lib/ui/view/profile/profile_selector.dart b/lib/ui/view/profile/profile_selector.dart index 0f6829cb..143c4580 100644 --- a/lib/ui/view/profile/profile_selector.dart +++ b/lib/ui/view/profile/profile_selector.dart @@ -182,6 +182,7 @@ class _ProfileSelectorState extends State { return AppBar( backgroundColor: Colors.white, elevation: 0.5, + scrolledUnderElevation: 0.5, shadowColor: grey100, systemOverlayStyle: SystemUiOverlayStyle.dark, leading: IconButton( diff --git a/lib/ui/view/tutorial_view.dart b/lib/ui/view/tutorial_view.dart index 7eb752a5..b90a95fa 100644 --- a/lib/ui/view/tutorial_view.dart +++ b/lib/ui/view/tutorial_view.dart @@ -3,7 +3,7 @@ import 'package:ac_project_app/const/strings.dart'; import 'package:ac_project_app/routes.dart'; import 'package:ac_project_app/ui/widget/buttons/bottom_sheet_button.dart'; import 'package:ac_project_app/ui/widget/text/custom_font.dart'; -import 'package:carousel_slider/carousel_slider.dart'; +import 'package:carousel_slider/carousel_slider.dart' as cs; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -16,14 +16,14 @@ class TutorialView extends StatefulWidget { class _TutorialViewState extends State { int _current = 0; - final CarouselController _controller = CarouselController(); + final cs.CarouselSliderController _controller = cs.CarouselSliderController(); @override Widget build(BuildContext context) { final height = MediaQuery.of(context).size.height; return Scaffold( backgroundColor: Colors.white, - body: CarouselSlider( + body: cs.CarouselSlider( items: tutorials .map( (tutorial) => Column( @@ -80,7 +80,7 @@ class _TutorialViewState extends State { ) .toList(), carouselController: _controller, - options: CarouselOptions( + options: cs.CarouselOptions( height: (height * 4) / 5, viewportFraction: 1, enableInfiniteScroll: false, diff --git a/lib/ui/view/upload_view.dart b/lib/ui/view/upload_view.dart index 3d563390..e61a3992 100644 --- a/lib/ui/view/upload_view.dart +++ b/lib/ui/view/upload_view.dart @@ -18,12 +18,14 @@ import 'package:ac_project_app/ui/widget/bottom_toast.dart'; import 'package:ac_project_app/ui/widget/buttons/bottom_sheet_button.dart'; import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; import 'package:ac_project_app/ui/widget/loading.dart'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:metadata_fetch/metadata_fetch.dart'; class UploadView extends StatefulWidget { const UploadView({super.key, this.args}); @@ -42,7 +44,7 @@ class _UploadViewState extends State { final firstScrollController = ScrollController(); final secondScrollController = ScrollController(); ButtonState buttonState = ButtonState.disabled; - int selectedIndex = -1; + int selectedIndex = 0; int? selectedFolderId; bool isSavedNewFolder = false; bool isLoading = false; @@ -68,7 +70,7 @@ class _UploadViewState extends State { return MultiBlocProvider( providers: [ BlocProvider( - create: (_) => GetFoldersCubit(excludeUnclassified: true), + create: (_) => GetFoldersCubit(), ), BlocProvider( create: (_) => UploadLinkCubit(), @@ -91,6 +93,7 @@ class _UploadViewState extends State { ), backgroundColor: Colors.transparent, elevation: 0, + scrolledUnderElevation: 0, systemOverlayStyle: SystemUiOverlayStyle.dark, title: Text( '업로드', @@ -321,80 +324,185 @@ class _UploadViewState extends State { } Widget buildLinkTextField() { - return BlocBuilder( - builder: (context, state) { - final linkError = state == UploadResultState.error; - return Container( - margin: EdgeInsets.only( - top: 14.h, - right: 24.w, - bottom: 15.h, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - DecoratedBox( - decoration: BoxDecoration( - border: Border.all(color: linkError ? redError2 : grey100), - borderRadius: BorderRadius.all(Radius.circular(12.r)), - color: grey100, - ), - child: SingleChildScrollView( - padding: EdgeInsets.zero, - controller: firstScrollController, - child: SizedBox( - height: 80.h, - child: TextField( - controller: linkTextController, + return BlocBuilder( + builder: (context, uploadResult) { + final linkError = uploadResult.state == UploadResultState.error; + return Column( + children: [ + buildBodyListItem(uploadResult), + Container( + margin: EdgeInsets.only( + top: 14.h, + right: 24.w, + bottom: 15.h, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DecoratedBox( + decoration: BoxDecoration( + border: Border.all(color: linkError ? redError2 : grey100), + borderRadius: BorderRadius.all(Radius.circular(12.r)), + color: grey100, + ), + child: SingleChildScrollView( + padding: EdgeInsets.zero, + controller: firstScrollController, + child: SizedBox( + height: 80.h, + child: TextField( + controller: linkTextController, + style: TextStyle( + fontSize: 14.sp, + height: (16.7 / 14).h, + color: grey600, + letterSpacing: -0.3.w, + ), + cursorColor: primary600, + keyboardType: TextInputType.multiline, + maxLines: null, + decoration: InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + isDense: true, + contentPadding: EdgeInsets.symmetric( + vertical: 15.h, + horizontal: 16.w, + ), + hintText: '링크를 여기에 불러주세요', + hintStyle: TextStyle( + color: grey400, + fontSize: 14.sp, + letterSpacing: -0.3.w, + ), + ), + onChanged: (url) => setState(() { + if (url.isNotEmpty) { + buttonState = ButtonState.enabled; + } + context.read().validateMetadata(url); + }), + ), + ), + ), + ), + Padding( + padding: EdgeInsets.only(top: 6.h), + child: Text( + '링크 형식으로 입력해 주세요', style: TextStyle( - fontSize: 14.sp, - height: (16.7 / 14).h, - color: grey600, - letterSpacing: -0.3.w, + color: linkError ? redError2 : Colors.white, + fontWeight: FontWeight.w500, + fontSize: 12.sp, + height: (14.3 / 12).h, ), - cursorColor: primary600, - keyboardType: TextInputType.multiline, - maxLines: null, - decoration: InputDecoration( - border: InputBorder.none, - focusedBorder: InputBorder.none, - isDense: true, - contentPadding: EdgeInsets.symmetric( - vertical: 15.h, - horizontal: 16.w, + ), + ), + ], + ), + ), + ], + ); + }, + ); + } + + Widget buildBodyListItem(UploadResult result) { + if (result.isNotValidAndSuccess()) { + return const SizedBox.shrink(); + } + final metadata = result.metadata!; + return Container( + margin: EdgeInsets.only( + top: 18.h, + left: 6.w, + right: 24.w, + bottom: 18.h, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 115.h, + child: Container( + margin: EdgeInsets.symmetric(vertical: 5.h), + width: 130.w, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + metadata.title ?? '', + maxLines: 1, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16.sp, + color: blackBold, + overflow: TextOverflow.ellipsis, + height: (19 / 16).h, + letterSpacing: -0.2, + ), ), - hintText: '링크를 여기에 불러주세요', - hintStyle: TextStyle( - color: grey400, - fontSize: 14.sp, - letterSpacing: -0.3.w, + SizedBox(height: 7.h), + Text( + metadata.description ?? '\n\n', + maxLines: 2, + style: TextStyle( + fontSize: 12.sp, + color: greyText, + overflow: TextOverflow.ellipsis, + letterSpacing: -0.1, + ), ), - ), - onChanged: (value) => setState(() { - if (value.isNotEmpty) { - buttonState = ButtonState.enabled; - } - }), + ], ), ), - ), + ], ), - Padding( - padding: EdgeInsets.only(top: 6.h), - child: Text( - '링크 형식으로 입력해 주세요', - style: TextStyle( - color: linkError ? redError2 : Colors.white, - fontWeight: FontWeight.w500, - fontSize: 12.sp, - height: (14.3 / 12).h, + ), + ), + Padding( + padding: EdgeInsets.only(right: 4.w), + child: ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(7.r), + ), + child: ColoredBox( + color: grey100, + child: metadata.image != null && metadata.image!.isNotEmpty + ? CachedNetworkImage( + imageUrl: metadata.image ?? '', + imageBuilder: (context, imageProvider) => Container( + width: 159.w, + height: 116.h, + decoration: BoxDecoration( + image: DecorationImage( + image: imageProvider, + fit: BoxFit.cover, + ), + ), ), + errorWidget: (_, __, ___) { + return SizedBox( + width: 159.w, + height: 116.h, + ); + }, + ) + : SizedBox( + width: 159.w, + height: 116.h, ), ), - ], + ), ), - ); - }, + ], + ), ); } @@ -409,7 +517,7 @@ class _UploadViewState extends State { UploadType.create, ) .then((result) { - if (result == UploadResultState.success) { + if (result.state == UploadResultState.success) { showBottomToast( context: context, '링크 등록 완료', diff --git a/lib/ui/view/user/email_login_view.dart b/lib/ui/view/user/email_login_view.dart index 634902e9..3b76bd36 100644 --- a/lib/ui/view/user/email_login_view.dart +++ b/lib/ui/view/user/email_login_view.dart @@ -12,8 +12,8 @@ import 'package:ac_project_app/ui/widget/buttons/bottom_sheet_button.dart'; import 'package:ac_project_app/ui/widget/dialog/center_dialog.dart'; import 'package:ac_project_app/ui/widget/only_back_app_bar.dart'; import 'package:ac_project_app/util/logger.dart'; +import 'package:app_links/app_links.dart'; import 'package:firebase_auth/firebase_auth.dart'; -import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; import 'package:flutter/material.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -243,15 +243,15 @@ class _EmailLoginViewState extends State } void retrieveDynamicLinkAndSignIn() { - FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) { - final deepLink = dynamicLinkData.link; + final appLinks = AppLinks(); + appLinks.uriLinkStream.listen((uri) { final validLink = - FirebaseAuth.instance.isSignInWithEmailLink(deepLink.toString()); + FirebaseAuth.instance.isSignInWithEmailLink(uri.toString()); if (validLink) { - final continueUrl = deepLink.queryParameters['continueUrl'] ?? ''; + final continueUrl = uri.queryParameters['continueUrl'] ?? ''; final email = Uri.parse(continueUrl).queryParameters['email'] ?? ''; - _handleLink(email, deepLink.toString()); + _handleLink(email, uri.toString()); } }); } diff --git a/lib/ui/view/user/login_view.dart b/lib/ui/view/user/login_view.dart index 59a78ed9..bfd355dc 100644 --- a/lib/ui/view/user/login_view.dart +++ b/lib/ui/view/user/login_view.dart @@ -15,8 +15,8 @@ import 'package:ac_project_app/ui/widget/bottom_toast.dart'; import 'package:ac_project_app/ui/widget/buttons/apple/apple_login_button.dart'; import 'package:ac_project_app/ui/widget/text/custom_font.dart'; import 'package:ac_project_app/util/logger.dart'; +import 'package:app_links/app_links.dart'; import 'package:firebase_auth/firebase_auth.dart'; -import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -61,17 +61,16 @@ class LoginView extends StatelessWidget { } void retrieveDynamicLinkAndSignIn(BuildContext context) { - FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) { - context.read().loading(); - - final deepLink = dynamicLinkData.link; - final validLink = - FirebaseAuth.instance.isSignInWithEmailLink(deepLink.toString()); + final appLinks = AppLinks(); + appLinks.uriLinkStream.listen((uri) { + context.read().loading(); + final validLink = FirebaseAuth.instance.isSignInWithEmailLink(uri.toString()); if (validLink) { - final continueUrl = deepLink.queryParameters['continueUrl'] ?? ''; + final link = uri.queryParameters['link'] ?? ''; + final continueUrl = Uri.parse(link).queryParameters['continueUrl'] ?? ''; final email = Uri.parse(continueUrl).queryParameters['email'] ?? ''; - _handleLink(email, deepLink.toString(), context); + _handleLink(email, uri.toString(), context); } else { context.read().showError('이메일 로그인/회원가입 실패'); } diff --git a/lib/ui/widget/add_folder/horizontal_folder_list.dart b/lib/ui/widget/add_folder/horizontal_folder_list.dart index 7da1a1cf..ceb692ad 100644 --- a/lib/ui/widget/add_folder/horizontal_folder_list.dart +++ b/lib/ui/widget/add_folder/horizontal_folder_list.dart @@ -2,6 +2,7 @@ import 'package:ac_project_app/const/colors.dart'; import 'package:ac_project_app/cubits/folders/folders_state.dart'; import 'package:ac_project_app/gen/assets.gen.dart'; import 'package:ac_project_app/models/folder/folder.dart'; +import 'package:ac_project_app/util/logger.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -16,6 +17,7 @@ Widget buildFolderList({ final scrollController = ScrollController(); if (state is FolderLoadedState) { final folders = state.folders; + Log.i('folder length: ${folders.length}'); void gotoLastIndex() { scrollController.animateTo( @@ -37,100 +39,181 @@ Widget buildFolderList({ controller: scrollController, itemCount: folders.length, scrollDirection: Axis.horizontal, - itemBuilder: (_, index) { - final folder = folders[index]; - final rightPadding = index != folders.length - 1 ? 12 : 24; - final visible = folder.visible ?? false; - return GestureDetector( - onTap: () { - callback?.call(index, folder); - }, - onDoubleTap: () {}, - child: Container( - margin: EdgeInsets.only( - right: rightPadding.toDouble().w, + itemBuilder: (_, i) { + return FolderItem(i, folders, callback, selectedIndex); + }, + ), + ); + } else { + return SizedBox(height: 115.h); + } +} + +GestureDetector FolderItem(int i, List folders, + void Function(int index, Folder folder)? callback, int? selectedIndex) { + final folder = folders[i]; + final rightPadding = i != folders.length - 1 ? 12 : 24; + final visible = folder.visible ?? false; + return GestureDetector( + onTap: () { + callback?.call(i, folder); + }, + onDoubleTap: () {}, + child: Container( + margin: EdgeInsets.only( + right: rightPadding.toDouble().w, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Stack( + children: [ + Container( + width: 95.w, + height: 95.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(32.r)), + color: grey100, + ), + child: ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(32.r), + ), + child: ColoredBox( + color: grey100, + child: folder.thumbnail != null && + (folder.thumbnail?.isNotEmpty ?? false) + ? Image.network( + folder.thumbnail!, + width: 95.w, + height: 95.h, + fit: BoxFit.cover, + errorBuilder: (_, __, ___) => emptyFolderView(), + ) + : emptyFolderView(), + ), + ), ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Stack( - children: [ - Container( - width: 95.w, - height: 95.h, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(32.r)), - color: grey100, - ), - child: ClipRRect( - borderRadius: BorderRadius.all( - Radius.circular(32.r), - ), - child: ColoredBox( - color: grey100, - child: folder.thumbnail != null && - (folder.thumbnail?.isNotEmpty ?? false) - ? Image.network( - folder.thumbnail!, - width: 95.w, - height: 95.h, - fit: BoxFit.cover, - errorBuilder: (_, __, ___) => - emptyFolderView(), - ) - : emptyFolderView(), - ), - ), - ), - Visibility( - visible: selectedIndex == index, - child: Container( - width: 95.w, - height: 95.h, - decoration: BoxDecoration( - borderRadius: - BorderRadius.all(Radius.circular(32.r)), - color: secondary400, - ), - ), - ), - if (!visible) - SizedBox( - width: 95.w, - height: 95.h, - child: Align( - alignment: Alignment.bottomRight, - child: Padding( - padding: EdgeInsets.only(bottom: 3.h), - child: Assets.images.icLockPng.image(), - ), - ), - ) - else - const SizedBox.shrink(), - ], + Visibility( + visible: selectedIndex == i, + child: Container( + width: 95.w, + height: 95.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(32.r)), + color: secondary400, ), - SizedBox(height: 6.h), - Text( - folder.name ?? '', - style: TextStyle( - color: grey700, - fontWeight: FontWeight.w500, - fontSize: 12.sp, - letterSpacing: -0.3.w, - height: (14.3 / 12).h, + ), + ), + if (!visible) + SizedBox( + width: 95.w, + height: 95.h, + child: Align( + alignment: Alignment.bottomRight, + child: Padding( + padding: EdgeInsets.only(bottom: 3.h), + child: Assets.images.icLockPng.image(), ), ), - ], + ) + else + const SizedBox.shrink(), + ], + ), + SizedBox(height: 6.h), + SizedBox( + width: 95.w, + child: Text( + folder.name ?? '', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: TextStyle( + color: grey700, + fontWeight: FontWeight.w500, + fontSize: 12.sp, + letterSpacing: -0.3.w, + height: (14.3 / 12).h, ), ), - ); - }, + ), + ], ), - ); - } else { - return SizedBox(height: 115.h); - } + ), + ); +} + +Widget UnclassifiedItem(int? selectedIndex, void Function() callback) { + return GestureDetector( + onTap: () { + callback.call(); + }, + onDoubleTap: () {}, + child: Column( + children: [ + Stack( + children: [ + Container( + width: 95.w, + height: 95.h, + margin: EdgeInsets.only(right: 12.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(32.r)), + color: grey100, + ), + child: ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(32.r), + ), + child: ColoredBox( + color: grey100, + child: emptyFolderView(), + ), + ), + ), + Visibility( + visible: selectedIndex == 0, + child: Container( + width: 95.w, + height: 95.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(32.r)), + color: secondary400, + ), + ), + ), + SizedBox( + width: 95.w, + height: 95.h, + child: Align( + alignment: Alignment.bottomRight, + child: Padding( + padding: EdgeInsets.only(bottom: 3.h), + child: Assets.images.icLockPng.image(), + ), + ), + ), + ], + ), + SizedBox(height: 6.h), + SizedBox( + width: 95.w, + child: Text( + '미분류', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: TextStyle( + color: grey700, + fontWeight: FontWeight.w500, + fontSize: 12.sp, + letterSpacing: -0.3.w, + height: (14.3 / 12).h, + ), + ), + ), + ], + ), + ); } Container emptyFolderView() { diff --git a/lib/ui/widget/only_back_app_bar.dart b/lib/ui/widget/only_back_app_bar.dart index fb52fc65..5c517c00 100644 --- a/lib/ui/widget/only_back_app_bar.dart +++ b/lib/ui/widget/only_back_app_bar.dart @@ -21,6 +21,7 @@ AppBar buildBackAppBar(BuildContext context, {void Function()? callback}) { ), backgroundColor: Colors.transparent, elevation: 0, + scrolledUnderElevation: 0, systemOverlayStyle: SystemUiOverlayStyle.dark, ); } diff --git a/lib/util/url_loader.dart b/lib/util/url_loader.dart index f039e2ab..c4e1647e 100644 --- a/lib/util/url_loader.dart +++ b/lib/util/url_loader.dart @@ -55,4 +55,8 @@ class UrlLoader { return null; } } + + static bool isValidateUrl(String url) { + return Uri.parse(url).isAbsolute; + } } diff --git a/pubspec.yaml b/pubspec.yaml index 07dea952..e3fdb8cd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,17 +28,19 @@ dependencies: ## login sign_in_with_apple: ^5.0.0 google_sign_in: ^6.1.5 - firebase_core: 2.31.0 - firebase_auth: 4.19.5 - firebase_dynamic_links: 5.5.5 - firebase_database: ^10.5.5 - firebase_crashlytics: ^3.5.5 + firebase_core: ^3.6.0 + firebase_auth: ^5.3.1 + firebase_database: ^11.1.4 + firebase_crashlytics: ^4.1.3 kakao_flutter_sdk_user: ^1.6.1 flutter_dotenv: ^5.0.2 - flutter_naver_login: ^1.8.0 + flutter_naver_login: ^2.0.0 - firebase_auth_mocks: 0.13.0 + firebase_auth_mocks: ^0.14.1 + + # app link + app_links: ^6.3.2 ## UI Sizer flutter_screenutil: ^5.9.0 @@ -59,11 +61,11 @@ dependencies: oktoast: share_plus: ^7.2.2 flutter_keyboard_visibility: ^5.4.1 - extended_text: ^13.0.0 - carousel_slider: ^4.2.1 + extended_text: ^14.0.1 + carousel_slider: ^5.0.0 lottie: flutter_slidable: ^3.1.1 - firebase_storage: ^11.7.5 + firebase_storage: ^12.3.3 ## lint very_good_analysis: ^4.0.0+1 @@ -80,7 +82,8 @@ dependencies: freezed_annotation: ^2.2.0 ## Web - url_launcher: ^6.1.10 + url_launcher: ^6.3.1 + url_launcher_ios: ^6.3.1 # for mock test mockito: ^5.4.0 From a9779bd85f333470fea0cf6b285ad01b594002a0 Mon Sep 17 00:00:00 2001 From: boring-km Date: Wed, 16 Oct 2024 16:24:12 +0900 Subject: [PATCH 46/48] [version] 1.0.66 update --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index e3fdb8cd..431f9403 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: 링크풀 - 체계적인 링크 관리의 시작 publish_to: 'none' -version: 1.0.65+65 +version: 1.0.66+66 environment: sdk: ">=3.0.0 <4.0.0" From 844f9e83212f94938f5583a1412491c152df19e5 Mon Sep 17 00:00:00 2001 From: boring-km Date: Mon, 21 Oct 2024 10:07:38 +0900 Subject: [PATCH 47/48] [chore] flutter workflow version up --- .github/workflows/android_cicd.yml | 2 +- .github/workflows/cicd.yml | 4 ++-- .github/workflows/code_coverage.yml | 2 +- .github/workflows/ios_cicd.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/android_cicd.yml b/.github/workflows/android_cicd.yml index 558877e7..c6533c3b 100644 --- a/.github/workflows/android_cicd.yml +++ b/.github/workflows/android_cicd.yml @@ -16,7 +16,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.0' + flutter-version: '3.24.3' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 8279d1b0..90f5807e 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.3' + flutter-version: '3.24.3' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' @@ -60,7 +60,7 @@ jobs: java-version: '11.x' - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.3' + flutter-version: '3.24.3' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index 822af8d4..377d5022 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.3' + flutter-version: '3.24.3' - name: Install packages run: flutter pub get - run: echo '${{ secrets.DOTENV }}' | base64 -d > .env diff --git a/.github/workflows/ios_cicd.yml b/.github/workflows/ios_cicd.yml index d60d39b3..c6d1477e 100644 --- a/.github/workflows/ios_cicd.yml +++ b/.github/workflows/ios_cicd.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2.8.0 with: - flutter-version: '3.22.0' + flutter-version: '3.24.3' - uses: ruby/setup-ruby@v1 with: ruby-version: '3.1.2' From adf7cb2c1197c884eab9076115a359d23fa637c5 Mon Sep 17 00:00:00 2001 From: boring-km Date: Mon, 21 Oct 2024 10:49:08 +0900 Subject: [PATCH 48/48] [fix] android gradle version up --- android/gradle/wrapper/gradle-wrapper.properties | 4 +++- android/settings.gradle | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 8049c684..a4413138 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/android/settings.gradle b/android/settings.gradle index 133ccec5..1fdcb45e 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -19,7 +19,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "7.4.2" apply false - id "org.jetbrains.kotlin.android" version "1.7.10" apply false + id "org.jetbrains.kotlin.android" version "1.9.25" apply false id 'com.google.gms.google-services' version '4.3.15' apply false id 'com.google.firebase.crashlytics' version '2.8.1' apply false }