From aa12c9d9ab47fe72b2c51af4d2a229cf8a72084e Mon Sep 17 00:00:00 2001 From: Sang-oh Kim Date: Fri, 16 Feb 2024 18:34:38 +0900 Subject: [PATCH 1/8] =?UTF-8?q?Refactor(post=5Fview=5Futils.dart):=20setVo?= =?UTF-8?q?te=20public=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 다른 파일에서도 사용할 수 있도록 함. --- lib/utils/post_view_utils.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/utils/post_view_utils.dart b/lib/utils/post_view_utils.dart index 8a8b2c2b..9e5e80c7 100644 --- a/lib/utils/post_view_utils.dart +++ b/lib/utils/post_view_utils.dart @@ -42,7 +42,7 @@ class ArticleController { ); if (postRes.statusCode != 200) return false; } - _setVote(true); + setVote(true); return true; } @@ -62,14 +62,14 @@ class ArticleController { ); if (postRes.statusCode != 200) return false; } - _setVote(false); + setVote(false); return true; } /// 멤버 변수 model 내부의 /// 좋아요, 싫어요 상태를 [value]에 맞게 한번에 업데이트. /// value: true = 좋아요, false = 싫어요 - void _setVote(bool value) { + void setVote(bool value) { /* positive_vote_count, negative_vote_count 모두 int? 타입이므로 null일 경우 0으로 초기화함. */ model.positive_vote_count ??= 0; From 1a1d0cbfc9b0ee15b17871c5fdb087f7f8c4440a Mon Sep 17 00:00:00 2001 From: Sang-oh Kim Date: Fri, 16 Feb 2024 18:36:02 +0900 Subject: [PATCH 2/8] =?UTF-8?q?Feat(post=5Fview=5Futils.dart):=20setVote?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit posVote, negVote 함수에서 setVote를 호출하지 않도록 함 --- lib/utils/post_view_utils.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/utils/post_view_utils.dart b/lib/utils/post_view_utils.dart index 9e5e80c7..ed5306e9 100644 --- a/lib/utils/post_view_utils.dart +++ b/lib/utils/post_view_utils.dart @@ -42,7 +42,6 @@ class ArticleController { ); if (postRes.statusCode != 200) return false; } - setVote(true); return true; } @@ -62,7 +61,6 @@ class ArticleController { ); if (postRes.statusCode != 200) return false; } - setVote(false); return true; } From 78f7805d05be751dcc3f92cc46d211f5f2f277c8 Mon Sep 17 00:00:00 2001 From: Sang-oh Kim Date: Fri, 16 Feb 2024 20:45:18 +0900 Subject: [PATCH 3/8] =?UTF-8?q?Feat(user=5Fprovider.dart):=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20response=20=EB=A6=AC=ED=84=B4=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 2 +- lib/providers/user_provider.dart | 63 +++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b9618dfc..9da25273 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -168,4 +168,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 40e3ca182cfbd571c46e751b6eb8a6f2cbbf72fc -COCOAPODS: 1.15.2 +COCOAPODS: 1.14.3 diff --git a/lib/providers/user_provider.dart b/lib/providers/user_provider.dart index 95e0e7e2..87c51579 100644 --- a/lib/providers/user_provider.dart +++ b/lib/providers/user_provider.dart @@ -176,8 +176,25 @@ class UserProvider with ChangeNotifier { late dynamic response; try { response = await dio.post(totUrl, data: payload); - } catch (error) { - debugPrint("POST /api/$apiUrl failed with error: $error"); + } on DioException catch (e) { + debugPrint("getApiRes failed with DioException: $e"); + // 서버에서 response를 보냈지만 invalid한 statusCode일 때 + if (e.response != null) { + debugPrint("${e.response!.data}"); + debugPrint("${e.response!.headers}"); + debugPrint("${e.response!.requestOptions}"); + return e.response; + } + // request의 setting, sending에서 문제 발생 + // requestOption, message를 출력. + else { + debugPrint("${e.requestOptions}"); + debugPrint("${e.message}"); + return null; + } + } catch (e) { + debugPrint("_fetchUser failed with error: $e"); + return null; } return response; } @@ -192,8 +209,25 @@ class UserProvider with ChangeNotifier { late dynamic response; try { response = await dio.delete(totUrl, data: payload); - } catch (error) { - debugPrint("DELETE /api/$apiUrl failed with error: $error"); + } on DioException catch (e) { + debugPrint("getApiRes failed with DioException: $e"); + // 서버에서 response를 보냈지만 invalid한 statusCode일 때 + if (e.response != null) { + debugPrint("${e.response!.data}"); + debugPrint("${e.response!.headers}"); + debugPrint("${e.response!.requestOptions}"); + return e.response; + } + // request의 setting, sending에서 문제 발생 + // requestOption, message를 출력. + else { + debugPrint("${e.requestOptions}"); + debugPrint("${e.message}"); + return null; + } + } catch (e) { + debugPrint("_fetchUser failed with error: $e"); + return null; } return response; } @@ -208,8 +242,25 @@ class UserProvider with ChangeNotifier { late dynamic response; try { response = await dio.patch(totUrl, data: payload); - } catch (error) { - debugPrint("PATCH /api/$apiUrl failed with error: $error"); + } on DioException catch (e) { + debugPrint("getApiRes failed with DioException: $e"); + // 서버에서 response를 보냈지만 invalid한 statusCode일 때 + if (e.response != null) { + debugPrint("${e.response!.data}"); + debugPrint("${e.response!.headers}"); + debugPrint("${e.response!.requestOptions}"); + return e.response; + } + // request의 setting, sending에서 문제 발생 + // requestOption, message를 출력. + else { + debugPrint("${e.requestOptions}"); + debugPrint("${e.message}"); + return null; + } + } catch (e) { + debugPrint("_fetchUser failed with error: $e"); + return null; } return response; } From 8975ce0937b6781097e6bad4dba6030f2a92a04e Mon Sep 17 00:00:00 2001 From: Sang-oh Kim Date: Fri, 16 Feb 2024 20:51:10 +0900 Subject: [PATCH 4/8] =?UTF-8?q?Feat:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=EC=86=8D=EB=8F=84=20=EC=A6=9D=EA=B0=80=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/post_view_page.dart | 8 +++++++- lib/utils/post_view_utils.dart | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/pages/post_view_page.dart b/lib/pages/post_view_page.dart index 32f23e9e..f0a90f4b 100644 --- a/lib/pages/post_view_page.dart +++ b/lib/pages/post_view_page.dart @@ -753,11 +753,17 @@ class _PostViewPageState extends State { // 좋아요 버튼 InkWell( onTap: () async { + ArticleController(model: _article, userProvider: userProvider).setVote(true); + _updateState(); bool res = await ArticleController( model: _article, userProvider: userProvider, ).posVote(); - if (res) _updateState(); + debugPrint('좋아요 결과 ${res}'); + if (!res) { + ArticleController(model: _article, userProvider: userProvider).setVote(true); + _updateState(); + } }, child: _buildVoteIcons( true, _article.my_vote, ColorsInfo.posVote, 20.17, 22), diff --git a/lib/utils/post_view_utils.dart b/lib/utils/post_view_utils.dart index ed5306e9..5ff25959 100644 --- a/lib/utils/post_view_utils.dart +++ b/lib/utils/post_view_utils.dart @@ -35,7 +35,7 @@ class ArticleController { var cancelRes = await userProvider.postApiRes( "articles/$id/vote_cancel/", ); - if (cancelRes.statusCode != 200) return false; + if (cancelRes == null || cancelRes.statusCode != 200) return false; } else { var postRes = await userProvider.postApiRes( "articles/$id/vote_positive/", From 7d7168f761cf29aa7144f71ba535b580446e0ba4 Mon Sep 17 00:00:00 2001 From: Sang-oh Kim Date: Fri, 16 Feb 2024 20:59:24 +0900 Subject: [PATCH 5/8] =?UTF-8?q?Feat:=20=EC=8B=AB=EC=96=B4=EC=9A=94=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=EC=86=8D=EB=8F=84=20=ED=96=A5=EC=83=81=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/post_view_page.dart | 17 ++++++++++++----- lib/utils/post_view_utils.dart | 6 +++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/pages/post_view_page.dart b/lib/pages/post_view_page.dart index f0a90f4b..563a94b3 100644 --- a/lib/pages/post_view_page.dart +++ b/lib/pages/post_view_page.dart @@ -753,6 +753,7 @@ class _PostViewPageState extends State { // 좋아요 버튼 InkWell( onTap: () async { + // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 ArticleController(model: _article, userProvider: userProvider).setVote(true); _updateState(); bool res = await ArticleController( @@ -780,13 +781,19 @@ class _PostViewPageState extends State { const SizedBox(width: 20), // 싫어요 버튼 InkWell( - onTap: () { - ArticleController( + onTap: () async { + // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 + ArticleController(model: _article, userProvider: userProvider).setVote(false); + _updateState(); + bool res = await ArticleController( model: _article, userProvider: userProvider, - ).negVote().then((result) { - if (result) _updateState(); - }); + ).negVote(); + debugPrint('싫어요 결과 ${res}'); + if (!res) { + ArticleController(model: _article, userProvider: userProvider).setVote(false); + _updateState(); + } }, child: _buildVoteIcons( false, _article.my_vote, ColorsInfo.negVote, 20.17, 22), diff --git a/lib/utils/post_view_utils.dart b/lib/utils/post_view_utils.dart index 5ff25959..36383e3d 100644 --- a/lib/utils/post_view_utils.dart +++ b/lib/utils/post_view_utils.dart @@ -40,7 +40,7 @@ class ArticleController { var postRes = await userProvider.postApiRes( "articles/$id/vote_positive/", ); - if (postRes.statusCode != 200) return false; + if (postRes == null || postRes.statusCode != 200) return false; } return true; } @@ -54,12 +54,12 @@ class ArticleController { var cancelRes = await userProvider.postApiRes( "articles/$id/vote_cancel/", ); - if (cancelRes.statusCode != 200) return false; + if (cancelRes == null || cancelRes.statusCode != 200) return false; } else { var postRes = await userProvider.postApiRes( "articles/$id/vote_negative/", ); - if (postRes.statusCode != 200) return false; + if (postRes == null || postRes.statusCode != 200) return false; } return true; } From b959398058fe87df96245c0397e01602dc4fb271 Mon Sep 17 00:00:00 2001 From: Sang-oh Kim Date: Fri, 16 Feb 2024 21:04:04 +0900 Subject: [PATCH 6/8] =?UTF-8?q?Feat:=20=EB=8C=93=EA=B8=80=EC=97=90?= =?UTF-8?q?=EB=8F=84=20=EB=8F=99=EC=9D=BC=ED=95=9C=20=EC=86=8D=EB=8F=84?= =?UTF-8?q?=ED=96=A5=EC=83=81=20=EB=A1=9C=EC=A7=81=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/post_view_page.dart | 54 ++++++++++++++++++++++++++-------- lib/utils/post_view_utils.dart | 10 +++---- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/lib/pages/post_view_page.dart b/lib/pages/post_view_page.dart index 563a94b3..8a2bbcf1 100644 --- a/lib/pages/post_view_page.dart +++ b/lib/pages/post_view_page.dart @@ -754,7 +754,8 @@ class _PostViewPageState extends State { InkWell( onTap: () async { // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 - ArticleController(model: _article, userProvider: userProvider).setVote(true); + ArticleController(model: _article, userProvider: userProvider) + .setVote(true); _updateState(); bool res = await ArticleController( model: _article, @@ -762,7 +763,8 @@ class _PostViewPageState extends State { ).posVote(); debugPrint('좋아요 결과 ${res}'); if (!res) { - ArticleController(model: _article, userProvider: userProvider).setVote(true); + ArticleController(model: _article, userProvider: userProvider) + .setVote(true); _updateState(); } }, @@ -783,7 +785,8 @@ class _PostViewPageState extends State { InkWell( onTap: () async { // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 - ArticleController(model: _article, userProvider: userProvider).setVote(false); + ArticleController(model: _article, userProvider: userProvider) + .setVote(false); _updateState(); bool res = await ArticleController( model: _article, @@ -791,7 +794,8 @@ class _PostViewPageState extends State { ).negVote(); debugPrint('싫어요 결과 ${res}'); if (!res) { - ArticleController(model: _article, userProvider: userProvider).setVote(false); + ArticleController(model: _article, userProvider: userProvider) + .setVote(false); _updateState(); } }, @@ -1345,13 +1349,25 @@ class _PostViewPageState extends State { child: Row( children: [ InkWell( - onTap: () { + onTap: () async { + // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 CommentController( - model: curComment, + model: curComment, + userProvider: userProvider) + .setVote(true); + _updateState(); + bool res = await ArticleController( + model: _article, userProvider: userProvider, - ).posVote().then((result) { - if (result) _updateState(); - }); + ).posVote(); + debugPrint('좋아요 결과 ${res}'); + if (!res) { + CommentController( + model: curComment, + userProvider: userProvider) + .setVote(true); + _updateState(); + } }, child: _buildVoteIcons(true, curComment.my_vote, ColorsInfo.posVote, 11.52, 12.57), @@ -1370,12 +1386,24 @@ class _PostViewPageState extends State { const SizedBox(width: 12), InkWell( onTap: () async { + // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 CommentController( - model: curComment, + model: curComment, + userProvider: userProvider) + .setVote(false); + _updateState(); + bool res = await ArticleController( + model: _article, userProvider: userProvider, - ).negVote().then((result) { - if (result) _updateState(); - }); + ).negVote(); + debugPrint('좋아요 결과 ${res}'); + if (!res) { + CommentController( + model: curComment, + userProvider: userProvider) + .setVote(false); + _updateState(); + } }, child: _buildVoteIcons( false, diff --git a/lib/utils/post_view_utils.dart b/lib/utils/post_view_utils.dart index 36383e3d..de81b5b5 100644 --- a/lib/utils/post_view_utils.dart +++ b/lib/utils/post_view_utils.dart @@ -266,14 +266,13 @@ class CommentController { var cancelRes = await userProvider.postApiRes( "comments/$id/vote_cancel/", ); - if (cancelRes.statusCode != 200) return false; + if (cancelRes == null || cancelRes.statusCode != 200) return false; } else { var postRes = await userProvider.postApiRes( "comments/$id/vote_positive/", ); - if (postRes.statusCode != 200) return false; + if (postRes == null || postRes.statusCode != 200) return false; } - setVote(true); return true; } @@ -285,14 +284,13 @@ class CommentController { var cancelRes = await userProvider.postApiRes( "comments/$id/vote_cancel/", ); - if (cancelRes.statusCode != 200) return false; + if (cancelRes == null || cancelRes.statusCode != 200) return false; } else { var postRes = await userProvider.postApiRes( "comments/$id/vote_negative/", ); - if (postRes.statusCode != 200) return false; + if (postRes == null || postRes.statusCode != 200) return false; } - setVote(false); return true; } From e42abd571bdf7723f3051c7d5277e535856d3b06 Mon Sep 17 00:00:00 2001 From: Sang-oh Kim Date: Fri, 16 Feb 2024 21:04:43 +0900 Subject: [PATCH 7/8] =?UTF-8?q?Comment:=20api=20=ED=98=B8=EC=B6=9C=20todo?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/post_view_page.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pages/post_view_page.dart b/lib/pages/post_view_page.dart index 8a2bbcf1..a94d65ec 100644 --- a/lib/pages/post_view_page.dart +++ b/lib/pages/post_view_page.dart @@ -28,6 +28,8 @@ import 'package:new_ara_app/utils/profile_image.dart'; import 'package:new_ara_app/utils/handle_hidden.dart'; import 'package:new_ara_app/widgets/snackbar_noti.dart'; +// TODO: Dio 사용방식 createDioWithHeaders~ 로 변경하기 + /// 하나의 post에 대한 내용 뷰, 이벤트 처리를 모두 담당하는 StatefulWidget. class PostViewPage extends StatefulWidget { /// 보여주고 싶은 대상 post의 id. From e1948cd08a5e755748b9b486d42b3c76de025e01 Mon Sep 17 00:00:00 2001 From: Sang-oh Kim Date: Fri, 16 Feb 2024 21:39:03 +0900 Subject: [PATCH 8/8] =?UTF-8?q?Fix(post=5Fview=5Fpage.dart):=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=88=98=EC=A0=95=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존의 모델을 수정하고 요청을 보내면 기존의 작업을 취소하는 API가 호출되기 때문에 원래 모델을 복사하는 형태로 수정함. --- lib/pages/post_view_page.dart | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/pages/post_view_page.dart b/lib/pages/post_view_page.dart index a94d65ec..87026334 100644 --- a/lib/pages/post_view_page.dart +++ b/lib/pages/post_view_page.dart @@ -754,13 +754,15 @@ class _PostViewPageState extends State { children: [ // 좋아요 버튼 InkWell( + // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 onTap: () async { - // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 + // 원래의 상태를 보관하기 위해 임시 모델 생성 + ArticleModel tmpArticle = ArticleModel.fromJson(_article.toJson()); ArticleController(model: _article, userProvider: userProvider) .setVote(true); _updateState(); bool res = await ArticleController( - model: _article, + model: tmpArticle, userProvider: userProvider, ).posVote(); debugPrint('좋아요 결과 ${res}'); @@ -785,13 +787,15 @@ class _PostViewPageState extends State { const SizedBox(width: 20), // 싫어요 버튼 InkWell( + // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 onTap: () async { - // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 + // 원래의 상태를 보관하기 위해 임시 모델 생성 + ArticleModel tmpArticle = ArticleModel.fromJson(_article.toJson()); ArticleController(model: _article, userProvider: userProvider) .setVote(false); _updateState(); bool res = await ArticleController( - model: _article, + model: tmpArticle, userProvider: userProvider, ).negVote(); debugPrint('싫어요 결과 ${res}'); @@ -1351,15 +1355,20 @@ class _PostViewPageState extends State { child: Row( children: [ InkWell( + // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 onTap: () async { - // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 + // 원래 모델값을 저장하기 위해 임시 모델 생성 + CommentNestedCommentListActionModel + tmpCurComment = + CommentNestedCommentListActionModel + .fromJson(curComment.toJson()); CommentController( model: curComment, userProvider: userProvider) .setVote(true); _updateState(); - bool res = await ArticleController( - model: _article, + bool res = await CommentController( + model: tmpCurComment, userProvider: userProvider, ).posVote(); debugPrint('좋아요 결과 ${res}'); @@ -1387,15 +1396,20 @@ class _PostViewPageState extends State { ), const SizedBox(width: 12), InkWell( + // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 onTap: () async { - // API 요청 이전에 먼저 state를 변경한 뒤에 요청 결과에 따라 처리하기 + // 원래 모델값을 저장하기 위해 임시 모델 생성 + CommentNestedCommentListActionModel + tmpCurComment = + CommentNestedCommentListActionModel + .fromJson(curComment.toJson()); CommentController( model: curComment, userProvider: userProvider) .setVote(false); _updateState(); - bool res = await ArticleController( - model: _article, + bool res = await CommentController( + model: tmpCurComment, userProvider: userProvider, ).negVote(); debugPrint('좋아요 결과 ${res}');