diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index bbcbbe7..0000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-name: Feature request
-about: Suggest an idea for this project
-title: ''
-labels: ''
-assignees: ''
-
----
-
-**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
-
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
-
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
-
-**Additional context**
-Add any other context or screenshots about the feature request here.
diff --git a/.gitignore b/.gitignore
index 2d0ebc4..25ea8ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@
/build/
# Web related
+lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
@@ -52,4 +53,4 @@ coverage
.fvm
sqflite_sw.js
-sqlite3.wasm
+sqlite3.wasm
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
index a3868c6..8353687 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -7,8 +7,7 @@
{
"name": "moa_app",
"request": "launch",
- "type": "dart",
- "flutterMode": "debug"
+ "type": "dart"
},
{
"name": "moa_app (profile mode)",
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 2531de0..eecf41d 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -27,10 +27,6 @@ linter:
- comment_references
- prefer_void_to_null
- use_key_in_widget_constructors
- - prefer_const_literals_to_create_immutables
- - prefer_typing_uninitialized_variables
- - unnecessary_getters_setters
- - no_leading_underscores_for_local_identifiers
analyzer:
strong-mode:
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 332a547..f44a1a6 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -5,7 +5,7 @@ PODS:
- AppAuth/Core (1.6.2)
- AppAuth/ExternalUserAgent (1.6.2):
- AppAuth/Core
- - BranchSDK (2.2.1)
+ - BranchSDK (2.2.0)
- Firebase/CoreOnly (10.12.0):
- FirebaseCore (= 10.12.0)
- firebase_core (2.15.1):
@@ -15,7 +15,7 @@ PODS:
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- - FirebaseCoreInternal (10.15.0):
+ - FirebaseCoreInternal (10.12.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- Flutter (1.0.0)
- flutter_branch_sdk (6.4.0):
@@ -40,11 +40,11 @@ PODS:
- AppAuth (~> 1.5)
- GTMAppAuth (~> 1.3)
- GTMSessionFetcher/Core (< 3.0, >= 1.1)
- - GoogleUtilities/Environment (7.11.5):
+ - GoogleUtilities/Environment (7.11.4):
- PromisesObjC (< 3.0, >= 1.2)
- - GoogleUtilities/Logger (7.11.5):
+ - GoogleUtilities/Logger (7.11.4):
- GoogleUtilities/Environment
- - "GoogleUtilities/NSData+zlib (7.11.5)"
+ - "GoogleUtilities/NSData+zlib (7.11.4)"
- GTMAppAuth (1.3.1):
- AppAuth/Core (~> 1.6)
- GTMSessionFetcher/Core (< 3.0, >= 1.5)
@@ -160,11 +160,11 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
AppAuth: 3bb1d1cd9340bd09f5ed189fb00b1cc28e1e8570
- BranchSDK: cb046c2714b03e573484ce9e349e2ddbad7016e8
+ BranchSDK: 8749d10e30725d08b6c188ab90e6fd6223d204db
Firebase: 07150e75d142fb9399f6777fa56a187b17f833a0
firebase_core: 4a3246a02f828a01c74a2c26427037786d90f17f
FirebaseCore: f86a1394906b97ac445ae49c92552a9425831bed
- FirebaseCoreInternal: 2f4bee5ed00301b5e56da0849268797a2dd31fb4
+ FirebaseCoreInternal: 950500ad8a08963657f6d8c67b579740c06d6aa1
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_branch_sdk: da3bece1a03160a8a021ef4ec3d426e89c6da169
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
@@ -174,7 +174,7 @@ SPEC CHECKSUMS:
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
google_sign_in_ios: 1256ff9d941db546373826966720b0c24804bcdd
GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
- GoogleUtilities: 13e2c67ede716b8741c7989e26893d151b2b2084
+ GoogleUtilities: c63691989bf362ba0505507da00eeb326192e83e
GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
@@ -194,4 +194,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 8eb7cecb637c8d903f411e7008dc4a94863ea0c3
-COCOAPODS: 1.13.0
+COCOAPODS: 1.12.1
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 7a4d864..8431221 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -210,10 +210,10 @@
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
- 6DCA4EFC2A15E5C200B62F90 /* Embed Foundation Extensions */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
03396E302AF4D338AAAA8637 /* [CP] Embed Pods Frameworks */,
+ 6DCA4EFC2A15E5C200B62F90 /* Embed Foundation Extensions */,
);
buildRules = (
);
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 2ccf710..f388651 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -60,16 +60,6 @@
com.googleusercontent.apps.152179311533-2lsvtrj7junkos93nd2oekpropcv8929
-
- CFBundleTypeRole
- Editor
- CFBundleURLName
- com.beside.moa
- CFBundleURLSchemes
-
- https
-
-
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
@@ -119,8 +109,6 @@
Need location when in use
NSPhotoLibraryUsageDescription
To upload photos, please allow permission to access your photo library, Pictures are displayed for the purpose of displaying and identifying stored content.
- NSUserTrackingUsageDescription
- App would like to access IDFA for tracking purpose
UIApplicationSupportsIndirectInputEvents
UILaunchStoryboardName
@@ -144,18 +132,6 @@
UIViewControllerBasedStatusBarAppearance
- branch_key
-
- live
- key_live_cAdCkiozDTmbHUBKiCWYplbhrqfE9TOt
- test
- key_test_eunAdbdqxMhgMHBOaCXYobdouujyZVVL
-
- branch_universal_link_domains
-
- moayo.app.link
- moayo-alternate.app.link
-
naverConsumerKey
K10uUCEMBAnAY0ZtJMeo
naverConsumerSecret
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
index 5cbb833..abed031 100644
--- a/ios/Runner/Runner.entitlements
+++ b/ios/Runner/Runner.entitlements
@@ -10,8 +10,7 @@
com.apple.developer.associated-domains
- moa:moayo.app.link
- moa:moayo-alternate.app.link
+ moa:example.com
com.apple.security.application-groups
diff --git a/ios/Runner/RunnerDebug.entitlements b/ios/Runner/RunnerDebug.entitlements
index 5cbb833..abed031 100644
--- a/ios/Runner/RunnerDebug.entitlements
+++ b/ios/Runner/RunnerDebug.entitlements
@@ -10,8 +10,7 @@
com.apple.developer.associated-domains
- moa:moayo.app.link
- moa:moayo-alternate.app.link
+ moa:example.com
com.apple.security.application-groups
diff --git a/ios/fastlane/report.xml b/ios/fastlane/report.xml
index e0ce2cc..9c2d2c4 100644
--- a/ios/fastlane/report.xml
+++ b/ios/fastlane/report.xml
@@ -5,17 +5,17 @@
-
+
-
+
-
+
diff --git a/lib/providers/content_detail_provider.dart b/lib/providers/content_detail_provider.dart
index 5aba1d4..19d8698 100644
--- a/lib/providers/content_detail_provider.dart
+++ b/lib/providers/content_detail_provider.dart
@@ -37,8 +37,8 @@ class ContentDetail extends _$ContentDetail {
}
@override
- Future build({required String id}) async {
- return fetchItem(contentId: id);
+ Future build() async {
+ return null;
}
Future editContent({
@@ -56,8 +56,8 @@ class ContentDetail extends _$ContentDetail {
contentMemo: contentMemo,
hashTagStringList: hashTagStringList,
);
-
- return fetchItem(contentId: contentId);
+ var data = await fetchItem(contentId: contentId);
+ return data;
});
}
}
diff --git a/lib/providers/folder_detail_provider.dart b/lib/providers/folder_detail_provider.dart
index 4c46d9d..a06d889 100644
--- a/lib/providers/folder_detail_provider.dart
+++ b/lib/providers/folder_detail_provider.dart
@@ -11,13 +11,34 @@ part 'folder_detail_provider.g.dart';
@riverpod
class FolderDetail extends _$FolderDetail {
Future> fetchItem({
- required String folderId,
+ required String folderName,
int? page,
int? size,
}) async {
- // todo 처음에 불러오는 page==1 일때 데이터만 캐싱하는 방법을 찾아보자
+ // get the [KeepAliveLink]
+ var link = ref.keepAlive();
+ // a timer to be used by the callbacks below
+ Timer? timer;
+ // An object from package:dio that allows cancelling http requests
+ // When the provider is destroyed, cancel the http request and the timer
+ ref.onDispose(() {
+ timer?.cancel();
+ });
+ // When the last listener is removed, start a timer to dispose the cached data
+ ref.onCancel(() {
+ // start a 30 second timer
+ timer = Timer(const Duration(seconds: 30), () {
+ // dispose on timeout
+ link.close();
+ });
+ });
+ // If the provider is listened again after it was paused, cancel the timer
+ ref.onResume(() {
+ timer?.cancel();
+ });
+
var data = await FolderRepository.instance.getFolderDetailList(
- folderId: folderId,
+ folderName: folderName,
page: page,
size: size,
);
@@ -25,26 +46,8 @@ class FolderDetail extends _$FolderDetail {
}
@override
- Future?> build({required String folderId}) async {
- return fetchItem(folderId: folderId);
- }
-
- Future loadMore({
- required String folderId,
- required int page,
- }) async {
- List res = [];
-
- state = await AsyncValue.guard(() async {
- res = await fetchItem(
- folderId: folderId,
- page: page,
- );
-
- return [...state.value!, ...res];
- });
-
- return res.length;
+ Future?> build() async {
+ return null;
}
Future refresh({required String folderName}) async {
diff --git a/lib/repositories/folder_repository.dart b/lib/repositories/folder_repository.dart
index a467de0..f8d5f8c 100644
--- a/lib/repositories/folder_repository.dart
+++ b/lib/repositories/folder_repository.dart
@@ -11,7 +11,7 @@ abstract class IFolderRepository {
Future editFolderName(
{required String currentFolderName, required String editFolderName});
Future> getFolderDetailList({
- required String folderId,
+ required String folderName,
int? page,
int? size,
});
@@ -92,14 +92,14 @@ class FolderRepository implements IFolderRepository {
@override
Future> getFolderDetailList({
- required String folderId,
+ required String folderName,
int? page = 0,
int? size = 10,
}) async {
var token = await TokenRepository.instance.getToken();
var res = await dio.get(
- '/api/v1/folder/detail/view?folderId=$folderId&page=$page&size=$size',
+ '/api/v1/folder/detail/view?folderName=$folderName&page=$page&size=$size',
options: Options(
headers: {
'Authorization': 'Bearer $token',
diff --git a/lib/screens/home/content_view.dart b/lib/screens/home/content_view.dart
index d6d9bbf..5ee82ee 100644
--- a/lib/screens/home/content_view.dart
+++ b/lib/screens/home/content_view.dart
@@ -6,6 +6,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:moa_app/constants/color_constants.dart';
import 'package:moa_app/constants/file_constants.dart';
import 'package:moa_app/constants/font_constants.dart';
+import 'package:moa_app/models/content_model.dart';
import 'package:moa_app/providers/content_detail_provider.dart';
import 'package:moa_app/providers/folder_detail_provider.dart';
import 'package:moa_app/providers/folder_view_provider.dart';
@@ -36,7 +37,7 @@ class ContentView extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
- var contentAsync = ref.watch(contentDetailProvider(id: id));
+ var contentNotifier = ref.watch(contentDetailProvider.notifier);
var hashtagAsync = ref.watch(hashtagViewProvider.notifier);
var isEditMode = useState(false);
@@ -49,12 +50,7 @@ class ContentView extends HookConsumerWidget {
}
}
- void refreshCache() {
- ref.refresh(folderDetailProvider(folderId: id)).value;
- }
-
void pressConfirm() {
- refreshCache();
context.pop();
}
@@ -65,7 +61,9 @@ class ContentView extends HookConsumerWidget {
void deleteContent() async {
await hashtagAsync.deleteContent(contentId: id);
await ref.read(folderViewProvider.notifier).refresh();
- ref.refresh(folderDetailProvider(folderId: id)).value;
+ await ref
+ .read(folderDetailProvider.notifier)
+ .refresh(folderName: folderName);
if (context.mounted) {
context.pop();
@@ -156,10 +154,6 @@ class ContentView extends HookConsumerWidget {
return Scaffold(
appBar: AppBarBack(
- onPressedBack: () => {
- refreshCache(),
- context.pop(),
- },
title: folderName,
isBottomBorderDisplayed: false,
actions: [
@@ -175,15 +169,47 @@ class ContentView extends HookConsumerWidget {
],
),
body: SafeArea(
- child: contentAsync.when(
- data: (content) {
+ child: FutureBuilder(
+ future: contentNotifier.fetchItem(contentId: id),
+ builder: (context, snapshot) {
+ var content = snapshot.data;
return AnimatedSwitcher(
transitionBuilder: (child, animation) {
return FadeTransition(opacity: animation, child: child);
},
duration: const Duration(milliseconds: 300),
child: () {
- if (content != null) {
+ if ((snapshot.connectionState == ConnectionState.waiting) ||
+ ref.watch(contentDetailProvider).isLoading) {
+ return const LoadingIndicator();
+ }
+ if (snapshot.hasError) {
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ kDebugMode
+ ? snapshot.error.toString()
+ : '취향을 불러오는데 실패했습니다.',
+ style: const TextStyle(
+ color: AppColors.blackColor,
+ fontSize: 16,
+ fontWeight: FontWeight.w600,
+ fontFamily: FontConstants.pretendard,
+ ),
+ ),
+ Button(
+ onPressed: () {
+ ref.refresh(contentDetailProvider).value;
+ },
+ margin: const EdgeInsets.only(
+ left: 100, right: 100, top: 20),
+ text: '다시 시도',
+ ),
+ ],
+ );
+ }
+ if (snapshot.hasData && content != null) {
return isEditMode.value
? SingleChildScrollView(
padding: const EdgeInsets.only(
@@ -332,30 +358,6 @@ class ContentView extends HookConsumerWidget {
}(),
);
},
- error: (error, stackTrace) {
- return Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text(
- kDebugMode ? error.toString() : '취향을 불러오는데 실패했습니다.',
- style: const TextStyle(
- color: AppColors.blackColor,
- fontSize: 16,
- fontWeight: FontWeight.w600,
- fontFamily: FontConstants.pretendard,
- ),
- ),
- Button(
- onPressed: () {
- ref.refresh(contentDetailProvider(id: id)).value;
- },
- margin: const EdgeInsets.only(left: 100, right: 100, top: 20),
- text: '다시 시도',
- ),
- ],
- );
- },
- loading: () => const LoadingIndicator(),
),
),
);
diff --git a/lib/screens/home/edit_content_view.dart b/lib/screens/home/edit_content_view.dart
index 8024121..63a7797 100644
--- a/lib/screens/home/edit_content_view.dart
+++ b/lib/screens/home/edit_content_view.dart
@@ -1,3 +1,4 @@
+import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
@@ -7,7 +8,9 @@ import 'package:moa_app/constants/file_constants.dart';
import 'package:moa_app/constants/font_constants.dart';
import 'package:moa_app/models/content_model.dart';
import 'package:moa_app/providers/content_detail_provider.dart';
+import 'package:moa_app/providers/folder_view_provider.dart';
import 'package:moa_app/providers/hashtag_provider.dart';
+import 'package:moa_app/providers/hashtag_view_provider.dart';
import 'package:moa_app/repositories/content_repository.dart';
import 'package:moa_app/screens/add_content/add_image_content.dart';
import 'package:moa_app/utils/general.dart';
@@ -17,6 +20,7 @@ import 'package:moa_app/widgets/image.dart';
import 'package:moa_app/widgets/loading_indicator.dart';
import 'package:moa_app/widgets/moa_widgets/empty_image.dart';
import 'package:moa_app/widgets/moa_widgets/hashtag_box.dart';
+import 'package:moa_app/widgets/snackbar.dart';
class EditContentView extends HookConsumerWidget {
const EditContentView({
@@ -39,19 +43,35 @@ class EditContentView extends HookConsumerWidget {
var title = useState(content.contentName);
var memo = useState(content.contentMemo);
+ var loading = useState(false);
+
Future saveEditContent() async {
- await ref
- .read(contentDetailProvider(id: content.contentId).notifier)
- .editContent(
- contentId: content.contentId,
- contentName: titleController.text,
- contentMemo: memoController.text,
- hashTagStringList: hashtagList.value.join(','),
- );
- // await ref.read(hashtagViewProvider.notifier).refresh();
- // await ref.read(folderViewProvider.notifier).refresh();
- isEditMode.value = false;
+ try {
+ loading.value = true;
+ await ContentRepository.instance.editContent(
+ contentId: content.contentId,
+ contentName: titleController.text,
+ contentMemo: memoController.text,
+ hashTagStringList: hashtagList.value.join(','),
+ );
+ await ref.read(contentDetailProvider.notifier).editContent(
+ contentId: content.contentId,
+ contentName: titleController.text,
+ contentMemo: memoController.text,
+ hashTagStringList: hashtagList.value.join(','),
+ );
+ await ref.read(hashtagViewProvider.notifier).refresh();
+ await ref.read(folderViewProvider.notifier).refresh();
+ isEditMode.value = false;
+ } catch (e) {
+ if (context.mounted) {
+ snackbar.alert(
+ context, kDebugMode ? e.toString() : '오류가 발생했습니다. 다시 시도해주세요.');
+ }
+ } finally {
+ loading.value = false;
+ }
}
void showEditHashtagModal() {
@@ -211,6 +231,7 @@ class EditContentView extends HookConsumerWidget {
),
const SizedBox(height: 30),
Button(
+ loading: loading.value,
backgroundColor: AppColors.primaryColor,
text: '변경 내용 저장',
onPressed: saveEditContent,
diff --git a/lib/screens/home/folder_detail_view.dart b/lib/screens/home/folder_detail_view.dart
index 368bd6a..ee8f848 100644
--- a/lib/screens/home/folder_detail_view.dart
+++ b/lib/screens/home/folder_detail_view.dart
@@ -1,10 +1,10 @@
-import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_branch_sdk/flutter_branch_sdk.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:moa_app/constants/color_constants.dart';
import 'package:moa_app/constants/file_constants.dart';
+import 'package:moa_app/models/content_model.dart';
import 'package:moa_app/providers/folder_detail_provider.dart';
import 'package:moa_app/screens/home/widgets/type_header.dart';
import 'package:moa_app/utils/router_provider.dart';
@@ -20,11 +20,9 @@ class FolderDetailView extends HookConsumerWidget {
const FolderDetailView({
super.key,
required this.folderName,
- required this.id,
required this.contentCount,
});
final String folderName;
- final String id;
final int contentCount;
@override
@@ -34,25 +32,18 @@ class FolderDetailView extends HookConsumerWidget {
var pageNum = useState(0);
var hasMore = useState(true);
var loading = useState(false);
- var folderDetailAsync = ref.watch(folderDetailProvider(folderId: id));
+ var folderDetailRefresher = useState(false);
+ var folderDetailNotifier = ref.watch(folderDetailProvider.notifier);
Future pullToRefresh() async {
- ref.refresh(folderDetailProvider(folderId: id)).value;
+ ref.refresh(folderDetailProvider).value;
}
void shareFolder() async {
var encodeFolderName = Uri.encodeFull(folderName);
- if (Platform.isIOS) {
- var currentStatus =
- await FlutterBranchSdk.getTrackingAuthorizationStatus();
- if (currentStatus == AppTrackingStatus.notDetermined) {
- await FlutterBranchSdk.requestTrackingAuthorization();
- }
- }
BranchUniversalObject buo = BranchUniversalObject(
canonicalIdentifier:
- '${GoRoutes.folder.fullPath}/$id?folderName=$encodeFolderName&c=$contentCount',
-
+ '${GoRoutes.folder.fullPath}/$encodeFolderName?c=$contentCount',
title: '모아 폴더 공유',
contentDescription: folderName,
// imageUrl:
@@ -64,6 +55,7 @@ class FolderDetailView extends HookConsumerWidget {
feature: 'share',
campaign: 'example_campaign',
);
+
BranchResponse response = await FlutterBranchSdk.getShortUrl(
buo: buo, linkProperties: linkProperties);
if (response.success) {
@@ -77,15 +69,24 @@ class FolderDetailView extends HookConsumerWidget {
void getContentList({required int page}) async {
loading.value = true;
- var length = await ref
- .read(folderDetailProvider(folderId: id).notifier)
- .loadMore(folderId: id, page: page);
+ var res = await folderDetailNotifier.fetchItem(
+ folderName: folderName, page: page);
+ if (page == 0) {
+ contentList.value = res;
+ } else {
+ contentList.value = [...contentList.value, ...res];
+ }
loading.value = false;
- if (length < 10) {
+ if (res.length < 10) {
hasMore.value = false;
}
}
+ useEffect(() {
+ getContentList(page: pageNum.value);
+ return null;
+ }, [folderDetailRefresher.value]);
+
useEffect(() {
controller.addListener(() {
/// load date at when scroll reached -100
@@ -122,47 +123,34 @@ class FolderDetailView extends HookConsumerWidget {
return FadeTransition(opacity: animation, child: child);
},
duration: const Duration(milliseconds: 300),
- child: folderDetailAsync.when(
- loading: () => const LoadingIndicator(),
- error: (error, stackTrace) {
- return const Center(
- child: Text(
- '에러가 발생했어요.\n다시 시도해주세요.',
- textAlign: TextAlign.center,
- ),
- );
- },
- data: (contentList) {
- return () {
- if (contentList != null) {
- return contentList.isEmpty
- ? const EmptyContent(text: '저장된 취향이 없어요!\n취향을 저장해 주세요.')
- : Padding(
- padding: const EdgeInsets.symmetric(horizontal: 15),
- child: Column(
- children: [
- const SizedBox(height: 30),
- TypeHeader(
- count: contentCount, onPressFilter: () {}),
- Expanded(
- child: DynamicGridList(
- controller: controller,
- contentList: contentList,
- pullToRefresh: pullToRefresh,
- folderNameProp: folderName,
- ),
- ),
- (loading.value && pageNum.value != 0)
- ? const LoadingIndicator()
- : const SizedBox(),
- ],
+ child: () {
+ if (loading.value && pageNum.value == 0) {
+ return const LoadingIndicator();
+ }
+ return contentList.value.isEmpty
+ ? const EmptyContent(text: '저장된 취향이 없어요!\n취향을 저장해 주세요.')
+ : Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ child: Column(
+ children: [
+ const SizedBox(height: 30),
+ TypeHeader(count: contentCount, onPressFilter: () {}),
+ Expanded(
+ child: DynamicGridList(
+ controller: controller,
+ contentList: contentList.value,
+ pullToRefresh: pullToRefresh,
+ folderNameProp: folderName,
+ folderDetailRefresher: folderDetailRefresher,
),
- );
- }
- return const SizedBox();
- }();
- },
- ),
+ ),
+ (loading.value && pageNum.value != 0)
+ ? const LoadingIndicator()
+ : const SizedBox(),
+ ],
+ ),
+ );
+ }(),
)),
);
}
diff --git a/lib/screens/home/home.dart b/lib/screens/home/home.dart
index 3369c5f..4153443 100644
--- a/lib/screens/home/home.dart
+++ b/lib/screens/home/home.dart
@@ -72,47 +72,46 @@ class Home extends HookConsumerWidget {
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverAppBar(
- toolbarHeight: 110,
- titleSpacing: 15,
- backgroundColor: AppColors.backgroundColor,
- flexibleSpace: FlexibleSpaceBar(
- background: Stack(
- children: [
- Positioned(
- right: 15,
- top: 3,
- child: Image(
- width: 150,
- height: 182,
- image: Assets.moaBannerImg,
+ toolbarHeight: 110,
+ titleSpacing: 15,
+ backgroundColor: AppColors.backgroundColor,
+ flexibleSpace: FlexibleSpaceBar(
+ background: Stack(
+ children: [
+ Positioned(
+ right: 15,
+ top: 3,
+ child: Image(
+ width: 150,
+ height: 182,
+ image: Assets.moaBannerImg,
+ ),
),
- ),
- ],
- ),
- ),
- title: userAsync.when(
- error: (error, stackTrace) {
- return const SizedBox();
- },
- loading: () => Container(
- margin: const EdgeInsets.only(right: 150),
- alignment: Alignment.centerLeft,
- child: const LoadingIndicator(),
+ ],
+ ),
),
- data: (userInfo) {
- return Container(
+ title: userAsync.when(
+ error: (error, stackTrace) {
+ return const SizedBox();
+ },
+ loading: () => Container(
margin: const EdgeInsets.only(right: 150),
alignment: Alignment.centerLeft,
- child: RichText(
- text: TextSpan(
- text: '안녕하세요,\n${userInfo?.nickname}님!',
- style: const H1TextStyle(),
+ child: const LoadingIndicator(),
+ ),
+ data: (userInfo) {
+ return Container(
+ margin: const EdgeInsets.only(right: 150),
+ alignment: Alignment.centerLeft,
+ child: RichText(
+ text: TextSpan(
+ text: '안녕하세요,\n${userInfo?.nickname}님!',
+ style: const H1TextStyle(),
+ ),
),
- ),
- );
- },
- ),
- ),
+ );
+ },
+ )),
SliverPersistentHeader(
delegate: PersistentTabBar(
tabController: tabController,
@@ -200,13 +199,10 @@ class PersistentTabBar extends SliverPersistentHeaderDelegate {
children: [
RichText(
text: TextSpan(
- style: const Body1TextStyle().merge(
- const TextStyle(
+ style: const TextStyle(
color: AppColors.blackColor,
fontSize: 24,
- fontWeight: FontConstants.fontWeightNormal,
- ),
- ),
+ fontWeight: FontConstants.fontWeightNormal),
children: [
const TextSpan(
text: '지금까지 모아온\n',
@@ -282,10 +278,10 @@ class PersistentTabBar extends SliverPersistentHeaderDelegate {
}
@override
- double get maxExtent => isEditScreen ? 98 : 117;
+ double get maxExtent => isEditScreen ? 99 : 117;
@override
- double get minExtent => isEditScreen ? 98 : 117;
+ double get minExtent => isEditScreen ? 99 : 117;
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
diff --git a/lib/screens/home/tab_view/folder_tab_view.dart b/lib/screens/home/tab_view/folder_tab_view.dart
index 14378dd..73a4caa 100644
--- a/lib/screens/home/tab_view/folder_tab_view.dart
+++ b/lib/screens/home/tab_view/folder_tab_view.dart
@@ -11,7 +11,6 @@ import 'package:moa_app/constants/file_constants.dart';
import 'package:moa_app/models/folder_model.dart';
import 'package:moa_app/providers/folder_view_provider.dart';
import 'package:moa_app/repositories/folder_repository.dart';
-import 'package:moa_app/screens/home/folder_detail_view.dart';
import 'package:moa_app/screens/home/home.dart';
import 'package:moa_app/utils/general.dart';
import 'package:moa_app/utils/logger.dart';
@@ -59,25 +58,17 @@ class FolderTabView extends HookConsumerWidget {
);
}
- void goFolderDetailView({
- required String folderName,
- required int contentCount,
- required String folderId,
- }) {
+ void goFolderDetailView(
+ {required String folderName, required int contentCount}) {
context.go(
- '${GoRoutes.folder.fullPath}/$folderId?folderName=$folderName&c=$contentCount',
- extra: FolderDetailView(
- folderName: folderName,
- id: folderId,
- contentCount: contentCount,
- ));
+ '${GoRoutes.folder.fullPath}/$folderName?c=$contentCount',
+ );
}
void showEditFolderModal({required String folderName}) {
General.instance.showBottomSheet(
context: context,
child: EditContent(
- maxLength: 10,
title: '폴더명 수정',
updatedContentName: updatedContentName,
contentName: folderName,
@@ -233,7 +224,6 @@ class FolderTabView extends HookConsumerWidget {
onPress: () => goFolderDetailView(
folderName: item.folderName,
contentCount: item.count,
- folderId: item.folderId,
),
);
},
diff --git a/lib/screens/on_boarding/input_name_view.dart b/lib/screens/on_boarding/input_name_view.dart
index 6dba370..d654833 100644
--- a/lib/screens/on_boarding/input_name_view.dart
+++ b/lib/screens/on_boarding/input_name_view.dart
@@ -9,7 +9,6 @@ import 'package:moa_app/repositories/non_member_repository.dart';
import 'package:moa_app/repositories/user_repository.dart';
import 'package:moa_app/screens/on_boarding/notice_view.dart';
import 'package:moa_app/utils/router_provider.dart';
-import 'package:moa_app/utils/utils.dart';
import 'package:moa_app/widgets/button.dart';
import 'package:moa_app/widgets/edit_text.dart';
import 'package:moa_app/widgets/moa_widgets/error_text.dart';
@@ -34,6 +33,13 @@ class InputNameView extends HookWidget {
var isNextPage = useState(false);
var focusNode = useFocusNode();
+ bool validateNickname(String value) {
+ const pattern = r'^[가-힣]{2,8}$'; // 정규식 패턴: 한글 2~8글자
+ var regex = RegExp(pattern);
+
+ return regex.hasMatch(value);
+ }
+
void inputUserName() async {
if (!isMember) {
await NonMemberRepository.instance
diff --git a/lib/screens/setting/setting.dart b/lib/screens/setting/setting.dart
index d5d0e9d..4409133 100644
--- a/lib/screens/setting/setting.dart
+++ b/lib/screens/setting/setting.dart
@@ -10,12 +10,10 @@ import 'package:moa_app/providers/token_provider.dart';
import 'package:moa_app/providers/user_provider.dart';
import 'package:moa_app/screens/setting/widgets/setting_list_tile.dart';
import 'package:moa_app/utils/router_provider.dart';
-import 'package:moa_app/utils/utils.dart';
import 'package:moa_app/widgets/alert_dialog.dart';
import 'package:moa_app/widgets/button.dart';
import 'package:moa_app/widgets/edit_text.dart';
import 'package:moa_app/widgets/loading_indicator.dart';
-import 'package:moa_app/widgets/moa_widgets/error_text.dart';
import 'package:moa_app/widgets/snackbar.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart';
@@ -166,7 +164,6 @@ class Setting extends HookConsumerWidget {
nickname.value = value;
},
hintText: userInfo?.nickname,
- maxLength: 8,
)
: InkWell(
overlayColor: MaterialStateProperty.all(
@@ -183,8 +180,7 @@ class Setting extends HookConsumerWidget {
editNicknameMode.value
? Button(
loading: loading.value,
- disabled: nickname.value.isEmpty ||
- !validateNickname(nickname.value),
+ disabled: nickname.value == '',
onPressed: () => editMyNickname(
nickname: nickname.value,
),
@@ -209,13 +205,6 @@ class Setting extends HookConsumerWidget {
],
),
const SizedBox(height: 3),
- ErrorText(
- alignment: MainAxisAlignment.center,
- errorText: '이름은 한글 2~8자로 입력할 수 있어요.',
- errorValidate: nickname.value.isNotEmpty &&
- !validateNickname(nickname.value),
- ),
- const SizedBox(height: 3),
Text(
userInfo?.email ?? '',
style: const Body1TextStyle().merge(TextStyle(
diff --git a/lib/screens/setting/widgets/edit_folder.dart b/lib/screens/setting/widgets/edit_folder.dart
index eb87b2f..3675ada 100644
--- a/lib/screens/setting/widgets/edit_folder.dart
+++ b/lib/screens/setting/widgets/edit_folder.dart
@@ -47,7 +47,6 @@ class EditFolder extends HookConsumerWidget {
context: context,
isScrollControlled: true,
child: EditContent(
- maxLength: 10,
title: '폴더명 수정',
updatedContentName: updatedContentName,
contentName: folderName,
diff --git a/lib/screens/setting/widgets/setting_list_tile.dart b/lib/screens/setting/widgets/setting_list_tile.dart
index faa4ec7..80bd983 100644
--- a/lib/screens/setting/widgets/setting_list_tile.dart
+++ b/lib/screens/setting/widgets/setting_list_tile.dart
@@ -19,9 +19,7 @@ class SettingListTile extends StatelessWidget {
contentPadding: const EdgeInsets.symmetric(horizontal: 20),
title: Text(
title,
- style: const H3TextStyle().merge(
- const TextStyle(fontWeight: FontConstants.fontWeightMedium),
- ),
+ style: const H3TextStyle(),
),
trailing: trailing ??
Transform.rotate(
diff --git a/lib/utils/router_provider.dart b/lib/utils/router_provider.dart
index b419cca..5be9052 100644
--- a/lib/utils/router_provider.dart
+++ b/lib/utils/router_provider.dart
@@ -199,24 +199,23 @@ final routeProvider = Provider(
GoRoute(
parentNavigatorKey: _rootNavigatorKey,
name: GoRoutes.folder.name,
- path: '${GoRoutes.folder.path}/:folderId',
+ path: '${GoRoutes.folder.path}/:folderName',
pageBuilder: (context, state) {
- String folderId = state.pathParameters['folderId']!;
late String decodeFolderName =
- state.uri.queryParameters['folderName']!;
+ state.pathParameters['folderName']!;
- if (isStringEncoded(
- state.uri.queryParameters['folderName']!)) {
+ var parseCount = int.parse(state.uri.queryParameters['c']!);
+
+ if (isStringEncoded(state.pathParameters['folderName']!)) {
decodeFolderName = Uri.decodeFull(
- state.uri.queryParameters['folderName'] ?? '');
+ state.pathParameters['folderName'] ?? '');
}
- var parseCount = int.parse(state.uri.queryParameters['c']!);
+
return buildIosPageTransitions(
context: context,
state: state,
child: FolderDetailView(
folderName: decodeFolderName,
- id: folderId,
contentCount: parseCount,
),
);
diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart
index 04334ec..46ecc86 100644
--- a/lib/utils/utils.dart
+++ b/lib/utils/utils.dart
@@ -38,10 +38,3 @@ bool isStringEncoded(String value) {
return false;
}
}
-
-bool validateNickname(String value) {
- const pattern = r'^[가-힣]{2,8}$'; // 정규식 패턴: 한글 2~8글자
- var regex = RegExp(pattern);
-
- return regex.hasMatch(value);
-}
diff --git a/lib/widgets/app_bar.dart b/lib/widgets/app_bar.dart
index 6027c11..4fe8d80 100644
--- a/lib/widgets/app_bar.dart
+++ b/lib/widgets/app_bar.dart
@@ -55,15 +55,15 @@ class AppBarBack extends StatelessWidget implements PreferredSizeWidget {
elevation: 0,
titleSpacing: 0.0,
centerTitle: true,
- bottom: PreferredSize(
- preferredSize: Size.fromHeight(bottomBorderStyle.height),
- child: Container(
- color: isBottomBorderDisplayed
- ? bottomBorderStyle.color
- : AppColors.whiteColor,
- height: bottomBorderStyle.height,
- ),
- ),
+ bottom: isBottomBorderDisplayed
+ ? PreferredSize(
+ preferredSize: Size.fromHeight(bottomBorderStyle.height),
+ child: Container(
+ color: bottomBorderStyle.color,
+ height: bottomBorderStyle.height,
+ ),
+ )
+ : null,
actions: actions,
);
}
diff --git a/lib/widgets/moa_widgets/dynamic_grid_list.dart b/lib/widgets/moa_widgets/dynamic_grid_list.dart
index 7b5b568..e70425c 100644
--- a/lib/widgets/moa_widgets/dynamic_grid_list.dart
+++ b/lib/widgets/moa_widgets/dynamic_grid_list.dart
@@ -34,7 +34,7 @@ class DynamicGridList extends HookWidget {
required String folderName,
String? contentUrl,
}) async {
- await context.push(
+ var val = await context.push(
'${GoRoutes.content.fullPath}/$contentId',
extra: ContentView(
id: contentId,
diff --git a/lib/widgets/moa_widgets/error_text.dart b/lib/widgets/moa_widgets/error_text.dart
index fc86f5a..a1fcf91 100644
--- a/lib/widgets/moa_widgets/error_text.dart
+++ b/lib/widgets/moa_widgets/error_text.dart
@@ -10,12 +10,10 @@ class ErrorText extends HookWidget {
required this.errorText,
required this.errorValidate,
this.padding,
- this.alignment,
});
final String errorText;
final bool errorValidate;
final EdgeInsets? padding;
- final MainAxisAlignment? alignment;
@override
Widget build(BuildContext context) {
@@ -28,7 +26,6 @@ class ErrorText extends HookWidget {
? Padding(
padding: padding ?? const EdgeInsets.only(top: 5),
child: Row(
- mainAxisAlignment: alignment ?? MainAxisAlignment.start,
children: [
Image(
image: Assets.alert,
diff --git a/pubspec.yaml b/pubspec.yaml
index d030c0f..5b94e82 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -16,7 +16,8 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-version: 1.0.3+18
+version: 1.0.1+15
+
environment:
sdk: ">=3.0.0 <4.0.0"
@@ -97,10 +98,10 @@ dev_dependencies:
flutter_lints: ^2.0.1
test: ^1.22.0
mockito: ^5.3.2
+ build_runner: ^2.3.3
# Rename App Package
# flutter pub run change_app_package_name:main com.new.package.name
change_app_package_name: ^1.1.0
- build_runner: ^2.3.3
freezed: ^2.3.2
json_serializable: ^6.5.4
riverpod_generator: ^2.2.1