Skip to content

Commit 9070579

Browse files
authored
Merge pull request #109 from jungwuk-ryu/develop
deploy(beta): build 75 - 앱 실행시 행사 목록 로딩 인디케이터 표시 및 패치 실패 인디케이터 표시
2 parents eed38ca + 3ce55bf commit 9070579

File tree

12 files changed

+124
-347
lines changed

12 files changed

+124
-347
lines changed

lib/app/api_client.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ class ApiClient extends GetConnect {
7070
}
7171

7272
String buildUserAgent() {
73-
final platform = Platform.isAndroid
73+
final platform = kIsWeb
74+
? 'web'
75+
: Platform.isAndroid
7476
? 'android'
7577
: Platform.isIOS
7678
? 'ios'

lib/app/modules/account/controllers/account_view_controller.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ import 'package:duty_it/app/api_client.dart';
22
import 'package:duty_it/app/core/utils/app_utils.dart';
33
import 'package:duty_it/app/modules/account/widgets/account_bottom_modal.dart';
44
import 'package:duty_it/app/modules/account/widgets/account_dialog.dart';
5-
import 'package:duty_it/app/routes/app_pages.dart';
65
import 'package:duty_it/app/services/auth/auth_service.dart';
76
import 'package:flutter/material.dart';
8-
97
import 'package:get/get.dart';
108

119
class AccountViewController extends GetxController {

lib/app/modules/calendar/controllers/calendar_view_controller.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import 'package:duty_it/app/api_client.dart';
22
import 'package:duty_it/app/core/constants/app_colors.dart';
3-
import 'package:duty_it/app/core/utils/app_utils.dart';
43
import 'package:duty_it/app/core/enums/event_type.dart';
5-
import 'package:duty_it/app/modules/calendar/controllers/date_selection_modal_controller.dart';
4+
import 'package:duty_it/app/core/utils/app_utils.dart';
65
import 'package:duty_it/app/modules/calendar/models/calendar_event.dart';
76
import 'package:duty_it/app/modules/calendar/widgets/date_selection_bottom_modal.dart';
87
import 'package:duty_it/app/services/auth/auth_service.dart';
98
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
109
import 'package:flutter/foundation.dart';
1110
import 'package:flutter/material.dart';
12-
1311
import 'package:get/get.dart';
1412
import 'package:get_storage/get_storage.dart';
1513

@@ -60,7 +58,7 @@ class CalendarViewController extends GetxController {
6058

6159
Stream<List<CalendarEvent>> getCalendarEvents(DateTime date) async* {
6260
if (!Get.find<AuthService>().isLoggined()) return;
63-
61+
6462
try {
6563
var storage = await _cacheStorageFuture;
6664
var cache = storage.read(_dateTimeToCacheKey(date)) ?? [];

lib/app/modules/home/controllers/home_view_controller.dart

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,27 @@ import 'dart:async';
22

33
import 'package:duty_it/app/api_client.dart';
44
import 'package:duty_it/app/core/enums/event_sorting_type.dart';
5+
import 'package:duty_it/app/core/enums/event_type.dart';
6+
import 'package:duty_it/app/core/models/event.dart';
57
import 'package:duty_it/app/core/models/events_response.dart';
6-
import 'package:duty_it/app/modules/home/cache/home_view_cache.dart';
7-
import 'package:duty_it/app/modules/notifications/models/app_notification.dart';
8-
import 'package:duty_it/app/services/auth/auth_service.dart';
9-
import 'package:duty_it/app/services/event/events/event_bookmark_event.dart';
108
import 'package:duty_it/app/core/utils/app_utils.dart';
11-
import 'package:duty_it/app/core/models/event.dart';
12-
import 'package:duty_it/app/core/enums/event_type.dart';
9+
import 'package:duty_it/app/modules/home/cache/home_view_cache.dart';
1310
import 'package:duty_it/app/modules/home/widgets/event_card.dart';
1411
import 'package:duty_it/app/modules/home/widgets/modal/bookmark_bottom_modal.dart';
1512
import 'package:duty_it/app/modules/home/widgets/modal/sorting_bottom_modal.dart';
13+
import 'package:duty_it/app/modules/notifications/models/app_notification.dart';
1614
import 'package:duty_it/app/routes/app_pages.dart';
17-
import 'package:duty_it/app/services/event/app_event_service.dart';
1815
import 'package:duty_it/app/services/app_settings_service.dart';
16+
import 'package:duty_it/app/services/auth/auth_service.dart';
17+
import 'package:duty_it/app/services/event/app_event_service.dart';
18+
import 'package:duty_it/app/services/event/events/event_bookmark_event.dart';
1919
import 'package:duty_it/app/services/search_filter/search_filter_service.dart';
2020
import 'package:firebase_analytics/firebase_analytics.dart';
2121
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
2222
import 'package:flutter/foundation.dart';
2323
import 'package:flutter/material.dart';
2424
import 'package:flutter/services.dart';
2525
import 'package:get/get.dart';
26-
import 'package:get_storage/get_storage.dart';
2726
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
2827
import 'package:synchronized/synchronized.dart';
2928

@@ -33,12 +32,16 @@ class HomeViewController extends GetxController {
3332
final HomeViewCache _cache = HomeViewCache();
3433
final FirebaseAnalytics analytics = FirebaseAnalytics.instance;
3534
final ScrollController scrollController = ScrollController();
35+
final GlobalKey<RefreshIndicatorState> refreshIndicatorKey =
36+
GlobalKey<RefreshIndicatorState>();
37+
38+
bool loadEventListFromCache = true;
3639

3740
AppSettingsService get _settingsService => Get.find<AppSettingsService>();
3841
AppEventService get _eventService => Get.find<AppEventService>();
3942

4043
final Rx<PagingState<String?, EventCard>> _pagingState =
41-
PagingState<String?, EventCard>().obs;
44+
PagingState<String?, EventCard>(isLoading: true).obs;
4245
PagingState<String?, EventCard> get pagingState => _pagingState.value;
4346
set pagingState(state) => _pagingState.value = state;
4447

@@ -98,7 +101,9 @@ class HomeViewController extends GetxController {
98101
);
99102

100103
checkNewNotification();
101-
fetchNextPage(clearPage: true, loadCache: true);
104+
WidgetsBinding.instance.addPostFrameCallback((_) {
105+
refreshIndicatorKey.currentState?.show();
106+
});
102107
}
103108

104109
Future<void> checkNewNotification() async {
@@ -132,21 +137,17 @@ class HomeViewController extends GetxController {
132137
);
133138
}
134139

135-
Future<void> fetchNextPage({
136-
bool clearPage = false,
137-
bool loadCache = false,
138-
}) async {
140+
Future<void> fetchNextPage({bool clearPage = false}) async {
139141
if (!clearPage && pagingState.isLoading) return;
140142
await _pageFetchLock.synchronized(
141-
() async =>
142-
await _fetchNextPage(clearPage: clearPage, loadCache: loadCache),
143+
() async => await _fetchNextPage(clearPage: clearPage),
143144
);
144145
}
145146

146-
Future<void> _fetchNextPage({
147-
bool clearPage = false,
148-
bool loadCache = false,
149-
}) async {
147+
Future<void> _fetchNextPage({bool clearPage = false}) async {
148+
final loadCache = loadEventListFromCache;
149+
loadEventListFromCache = false;
150+
150151
SearchFilterService sfService = Get.find<SearchFilterService>();
151152

152153
// Update paging state
@@ -207,6 +208,7 @@ class HomeViewController extends GetxController {
207208
name: 'fetch_events_page',
208209
parameters: {'clear_page': "$clearPage"},
209210
);
211+
bool hasError = false;
210212
try {
211213
var apiClient = Get.find<ApiClient>();
212214
var reqResult = await apiClient.getEvents(
@@ -255,14 +257,27 @@ class HomeViewController extends GetxController {
255257
_cache.saveEvents(response);
256258
}
257259
} else {
258-
var fail = reqResult as RequestFail;
260+
hasError = true;
259261
if (kDebugMode) {
260262
AppUtils.showSnackBar(
261-
'이벤트 목록을 불러오지 못했습니다: ${fail.serverFail?.message ?? ""}',
263+
'이벤트 목록을 불러오지 못했습니다: ${(reqResult as RequestFail).serverFail?.message ?? ""}',
262264
);
263265
}
264266
}
267+
} catch (ex, st) {
268+
hasError = true;
269+
if (kDebugMode) {
270+
print(ex.toString() + st.toString());
271+
}
272+
FirebaseCrashlytics.instance.recordError(ex, st);
265273
} finally {
274+
if (hasError) {
275+
pagingState = pagingState.copyWith(
276+
keys: clearPage ? [] : Omit(),
277+
pages: clearPage ? [] : Omit(),
278+
error: true,
279+
);
280+
}
266281
pagingState = pagingState.copyWith(isLoading: false);
267282
}
268283
}

lib/app/modules/home/views/home_view.dart

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import 'package:duty_it/app/modules/home/controllers/home_view_controller.dart';
22
import 'package:duty_it/app/modules/home/widgets/event_card.dart';
3+
import 'package:duty_it/app/modules/home/widgets/events_first_page_error_indicator.dart';
34
import 'package:duty_it/app/modules/home/widgets/home_app_bar.dart';
45
import 'package:duty_it/app/modules/home/widgets/home_header.dart';
56
import 'package:duty_it/app/modules/home/widgets/no_bookmarked_item_indicator.dart';
67
import 'package:duty_it/app/modules/home/widgets/no_search_item_indicator.dart';
8+
import 'package:duty_it/app/widgets/app_normal_button.dart';
79
import 'package:flutter/material.dart';
810
import 'package:get/get.dart';
911
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
@@ -17,6 +19,7 @@ class HomeView extends GetView<HomeViewController> {
1719
return Padding(
1820
padding: EdgeInsets.symmetric(horizontal: 16),
1921
child: RefreshIndicator.adaptive(
22+
key: controller.refreshIndicatorKey,
2023
onRefresh: () async {
2124
await controller.fetchNextPage(clearPage: true);
2225
controller.checkNewNotification();
@@ -47,9 +50,11 @@ class HomeView extends GetView<HomeViewController> {
4750
state: controller.pagingState,
4851
fetchNextPage: controller.fetchNextPage,
4952
builderDelegate: PagedChildBuilderDelegate<EventCard>(
53+
animateTransitions: true,
54+
transitionDuration: Duration(milliseconds: 100),
5055
itemBuilder: (context, item, index) => item,
5156
firstPageProgressIndicatorBuilder: (_) =>
52-
Center(child: CircularProgressIndicator.adaptive()),
57+
Center(child: CircularProgressIndicator.adaptive()),
5358
newPageProgressIndicatorBuilder: (_) => Align(
5459
alignment: Alignment.center,
5560
child: SizedBox(
@@ -58,8 +63,6 @@ class HomeView extends GetView<HomeViewController> {
5863
child: CircularProgressIndicator.adaptive(),
5964
),
6065
),
61-
animateTransitions: true,
62-
transitionDuration: Duration(milliseconds: 100),
6366
noItemsFoundIndicatorBuilder: (_) {
6467
HomeTab tab = controller.selectedTab;
6568
if (tab == HomeTab.bookmark) {
@@ -68,6 +71,28 @@ class HomeView extends GetView<HomeViewController> {
6871

6972
return NoSearchItemIndicator();
7073
},
74+
firstPageErrorIndicatorBuilder: (_) => Center(
75+
child: EventsFirstPageErrorIndicator(
76+
controller: controller,
77+
),
78+
),
79+
newPageErrorIndicatorBuilder: (_) => Center(
80+
child: Padding(
81+
padding: EdgeInsetsGeometry.symmetric(
82+
vertical: 5,
83+
horizontal: 10,
84+
),
85+
child: ConstrainedBox(
86+
constraints: BoxConstraints(maxWidth: 200),
87+
child: AppNormalButton(
88+
text: '재시도',
89+
onTap: () async {
90+
await controller.fetchNextPage();
91+
},
92+
),
93+
),
94+
),
95+
),
7196
),
7297
);
7398
}),
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import 'package:duty_it/app/core/constants/app_colors.dart';
2+
import 'package:duty_it/app/modules/home/controllers/home_view_controller.dart';
3+
import 'package:duty_it/app/widgets/app_normal_button.dart';
4+
import 'package:flutter/material.dart';
5+
import 'package:url_launcher/url_launcher_string.dart';
6+
7+
class EventsFirstPageErrorIndicator extends StatelessWidget {
8+
const EventsFirstPageErrorIndicator({
9+
super.key,
10+
required this.controller,
11+
});
12+
13+
final HomeViewController controller;
14+
15+
@override
16+
Widget build(BuildContext context) {
17+
return ConstrainedBox(
18+
constraints: BoxConstraints(maxWidth: 300),
19+
child: Column(
20+
mainAxisAlignment: MainAxisAlignment.center,
21+
children: [
22+
Text('행사 목록을 불러오지 못했어요', textAlign: TextAlign.center),
23+
SizedBox(height: 20),
24+
AppNormalButton(
25+
text: '다시 시도',
26+
onTap: () async {
27+
await controller.fetchNextPage(clearPage: true);
28+
},
29+
),
30+
SizedBox(height: 10),
31+
AppNormalButton(
32+
text: '서비스 상태 확인',
33+
color: AppColors.g05,
34+
onTap: () {
35+
launchUrlString("https://status.dutyit.net");
36+
},
37+
),
38+
],
39+
),
40+
);
41+
}
42+
}

lib/app/modules/splash/controllers/splash_view_controller.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'package:duty_it/app/modules/home/cache/home_view_cache.dart';
2-
import 'package:duty_it/app/modules/home/controllers/home_view_controller.dart';
32
import 'package:duty_it/app/routes/app_pages.dart';
43
import 'package:duty_it/app/services/app_settings_service.dart';
54
import 'package:duty_it/app/services/auth/auth_service.dart';

lib/app/services/auth/auth_service.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'package:duty_it/app/modules/calendar/controllers/calendar_view_controlle
77
import 'package:duty_it/app/services/auth/models/social_login_result.dart';
88
import 'package:duty_it/app/services/auth/strategies/apple_login_strategy.dart';
99
import 'package:duty_it/app/services/auth/strategies/google_login_strategy.dart';
10-
import 'package:duty_it/app/services/auth/strategies/kakao_login_strategy.dart';
1110
import 'package:duty_it/app/services/auth/strategies/social_login_strategy.dart';
1211
import 'package:firebase_auth/firebase_auth.dart';
1312
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
@@ -78,7 +77,6 @@ class AuthService extends GetxService {
7877
}
7978

8079
void _initStrategies() {
81-
_strategies[SocialProvider.kakao] = KakaoLoginStrategy();
8280
_strategies[SocialProvider.google] = GoogleLoginStrategy();
8381
_strategies[SocialProvider.apple] = AppleLoginStrategy();
8482
}

0 commit comments

Comments
 (0)