Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor setting page and TabView #495

Merged
merged 28 commits into from
Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
FILE_FIREBASE_IOS_PRODUCTION: ${{ secrets.FILE_FIREBASE_IOS_PRODUCTION }}
- uses: subosito/flutter-action@v1
with:
flutter-version: '2.8.1'
flutter-version: '2.10.0'
- run: flutter pub get
- name: Run iOS
run: flutter build ios --debug --no-codesign --flavor development --target lib/main.dev.dart --no-sound-null-safety
Expand All @@ -45,7 +45,7 @@ jobs:
FILE_FIREBASE_ANDROID_PRODUCTION: ${{ secrets.FILE_FIREBASE_ANDROID_PRODUCTION }}
- uses: subosito/flutter-action@v1
with:
flutter-version: '2.8.1'
flutter-version: '2.10.0'
- run: flutter pub get
- run: flutter build apk --debug --flavor development --target lib/main.dev.dart --no-sound-null-safety
test:
Expand All @@ -58,6 +58,6 @@ jobs:
java-version: '12.x'
- uses: subosito/flutter-action@v1
with:
flutter-version: '2.8.1'
flutter-version: '2.10.0'
- run: flutter pub get
- run: flutter test
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 30
compileSdkVersion 31

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -47,7 +47,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.mizuki.Ohashi.Pilll"
minSdkVersion 23
targetSdkVersion 30
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
Expand Down
3 changes: 2 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:name="${applicationName}"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.3.50'
ext.kotlin_version = '1.6.10'
repositories {
google()
jcenter()
Expand Down
4 changes: 2 additions & 2 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ PODS:
- Firebase/Messaging (= 8.9.0)
- firebase_core
- Flutter
- firebase_remote_config (1.0.3):
- firebase_remote_config (2.0.0):
- Firebase/RemoteConfig (= 8.9.0)
- firebase_core
- Flutter
Expand Down Expand Up @@ -311,7 +311,7 @@ SPEC CHECKSUMS:
firebase_core: c263d7daf1dc92fcd9895e6abdc04872b0ee07ff
firebase_crashlytics: 9cbd5d9e8560b218f02fce3c7359567ac822d05f
firebase_messaging: dff5cd08781ee1de988565a83c977e435405cd7e
firebase_remote_config: fad608e4093070bc3759f2d2beb566d4259451b2
firebase_remote_config: 467ffe569bc5625f8264f9aeefec2b8786fd1399
FirebaseABTesting: fc7255f7e96d3cf7a1131fd68636c47e312cef76
FirebaseAnalytics: 4ab446ce08a3fe52e8a4303dd997cf26276bf968
FirebaseAuth: 2b78b2a32c07b3ecfa4970bdf1d3632b8304099b
Expand Down
3 changes: 3 additions & 0 deletions lib/domain/calendar/calendar_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:pilll/domain/home/home_page.dart';
import 'package:pilll/domain/calendar/calendar_page_store.dart';
import 'package:flutter/material.dart';
import 'package:pilll/error/universal_error_page.dart';
import 'package:pilll/hooks/automatic_keep_alive_client_mixin.dart';

class CalendarPage extends HookConsumerWidget {
@override
Expand All @@ -21,6 +22,8 @@ class CalendarPage extends HookConsumerWidget {
final state = ref.watch(calendarPageStateStoreProvider);
homeKey.currentState?.diaries = state.diariesForMonth;

useAutomaticKeepAlive(wantKeepAlive: true);

final exception = state.exception;
if (exception != null) {
return UniversalErrorPage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class InitialSettingPillSheetGroupPage extends HookConsumerWidget {

useEffect(() {
store.fetch();
return null;
}, [authStream]);

useEffect(() {
Expand All @@ -49,6 +50,8 @@ class InitialSettingPillSheetGroupPage extends HookConsumerWidget {
AppRouter.signinAccount(context);
}
}

return null;
}, [state.userIsNotAnonymous, state.accountType, state.settingIsExist]);

return HUD(
Expand Down
3 changes: 3 additions & 0 deletions lib/domain/menstruation/menstruation_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'package:pilll/domain/menstruation/menstruation_select_modify_type_sheet.
import 'package:pilll/domain/record/weekday_badge.dart';
import 'package:pilll/domain/menstruation/menstruation_store.dart';
import 'package:pilll/error/universal_error_page.dart';
import 'package:pilll/hooks/automatic_keep_alive_client_mixin.dart';
import 'package:pilll/util/datetime/day.dart';
import 'package:pilll/util/formatter/date_time_formatter.dart';

Expand All @@ -33,6 +34,8 @@ class MenstruationPage extends HookConsumerWidget {
final store = ref.watch(menstruationsStoreProvider.notifier);
final state = ref.watch(menstruationsStoreProvider);

useAutomaticKeepAlive(wantKeepAlive: true);

if (state.exception != null) {
return UniversalErrorPage(
error: state.exception,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,5 +190,6 @@ class NotificationBar extends HookConsumerWidget {
},
);
}
return null;
}
}
2 changes: 2 additions & 0 deletions lib/domain/record/record_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import 'package:pilll/error/universal_error_page.dart';
import 'package:pilll/components/atoms/color.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:pilll/hooks/automatic_keep_alive_client_mixin.dart';

class RecordPage extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final state = ref.watch(recordPageStoreProvider);
final store = ref.watch(recordPageStoreProvider.notifier);
useAutomaticKeepAlive(wantKeepAlive: true);

final exception = state.exception;
if (exception != null) {
Expand Down
2 changes: 1 addition & 1 deletion lib/domain/root/root.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class RootState extends State<Root> {

_decideScreenType() async {
const minimumSupportedAppVersionKey = "minimum_supported_app_version";
final remoteConfig = RemoteConfig.instance;
final remoteConfig = FirebaseRemoteConfig.instance;
await remoteConfig.setConfigSettings(
RemoteConfigSettings(
minimumFetchInterval: Duration(seconds: 0),
Expand Down
2 changes: 1 addition & 1 deletion lib/domain/settings/reminder_times_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ReminderTimesPage extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final store = ref.watch(settingStoreProvider.notifier);
final state = ref.watch(settingStoreProvider);
final state = ref.watch(settingStateProvider);
final setting = state.setting;

if (setting == null) {
Expand Down
7 changes: 7 additions & 0 deletions lib/domain/settings/setting_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import 'package:pilll/domain/settings/components/rows/update_from_132.dart';
import 'package:pilll/domain/settings/components/setting_section_title.dart';
import 'package:pilll/domain/settings/setting_page_state.dart';
import 'package:pilll/error/universal_error_page.dart';
import 'package:pilll/hooks/automatic_keep_alive_client_mixin.dart';
import 'package:pilll/inquiry/inquiry.dart';
import 'package:pilll/domain/settings/setting_page_store.dart';
import 'package:pilll/components/atoms/color.dart';
Expand All @@ -44,6 +45,12 @@ class SettingPage extends HookConsumerWidget {
final store = ref.watch(settingStoreProvider.notifier);
final state = ref.watch(settingStoreProvider);

useAutomaticKeepAlive(wantKeepAlive: true);
useEffect(() {
store.setup();
return store.cancel;
}, const []);

return Scaffold(
backgroundColor: PilllColors.background,
appBar: AppBar(
Expand Down
2 changes: 1 addition & 1 deletion lib/domain/settings/setting_page_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ part 'setting_page_state.freezed.dart';
class SettingState with _$SettingState {
const SettingState._();
const factory SettingState({
required Setting? setting,
Setting? setting,
PillSheetGroup? latestPillSheetGroup,
@Default(false) bool userIsUpdatedFrom132,
@Default(false) bool isPremium,
Expand Down
6 changes: 3 additions & 3 deletions lib/domain/settings/setting_page_state.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class _$SettingStateTearOff {
const _$SettingStateTearOff();

_SettingState call(
{required Setting? setting,
{Setting? setting,
PillSheetGroup? latestPillSheetGroup,
bool userIsUpdatedFrom132 = false,
bool isPremium = false,
Expand Down Expand Up @@ -221,7 +221,7 @@ class __$SettingStateCopyWithImpl<$Res> extends _$SettingStateCopyWithImpl<$Res>

class _$_SettingState extends _SettingState {
const _$_SettingState(
{required this.setting,
{this.setting,
this.latestPillSheetGroup,
this.userIsUpdatedFrom132 = false,
this.isPremium = false,
Expand Down Expand Up @@ -289,7 +289,7 @@ class _$_SettingState extends _SettingState {

abstract class _SettingState extends SettingState {
const factory _SettingState(
{required Setting? setting,
{Setting? setting,
PillSheetGroup? latestPillSheetGroup,
bool userIsUpdatedFrom132,
bool isPremium,
Expand Down
49 changes: 25 additions & 24 deletions lib/domain/settings/setting_page_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,26 @@ class SettingStateStore extends StateNotifier<SettingState> {
this._userService,
this._pillSheetModifiedHistoryService,
this._pillSheetGroupService,
) : super(SettingState(setting: null)) {
reset();
) : super(SettingState());

void reset() {
state = SettingState();
setup();
}

void reset() async {
setup() {
try {
state = state.copyWith(exception: null);
final storage = await SharedPreferences.getInstance();
final userIsMigratedFrom132 =
storage.containsKey(StringKey.salvagedOldStartTakenDate) &&
storage.containsKey(StringKey.salvagedOldLastTakenDate);
final setting = await _settingService.fetch();
final pillSheetGroup = await _pillSheetGroupService.fetchLatest();
final user = await _userService.fetch();
this.state = SettingState(
setting: setting,
userIsUpdatedFrom132: userIsMigratedFrom132,
latestPillSheetGroup: pillSheetGroup,
isPremium: user.isPremium,
isTrial: user.isTrial,
trialDeadlineDate: user.trialDeadlineDate,
);
Future(() async {
final storage = await SharedPreferences.getInstance();
final userIsMigratedFrom132 =
storage.containsKey(StringKey.salvagedOldStartTakenDate) &&
storage.containsKey(StringKey.salvagedOldLastTakenDate);

state = SettingState(
userIsUpdatedFrom132: userIsMigratedFrom132,
);
});

_subscribe();
} catch (exception) {
state = state.copyWith(exception: exception);
Expand All @@ -72,16 +70,15 @@ class SettingStateStore extends StateNotifier<SettingState> {
StreamSubscription? _pillSheetGroupCanceller;
StreamSubscription? _userSubscribeCanceller;
void _subscribe() {
_settingCanceller?.cancel();
cancel();

_settingCanceller = _settingService.stream().listen((event) {
state = state.copyWith(setting: event);
});
_pillSheetGroupCanceller?.cancel();
_pillSheetGroupCanceller =
_pillSheetGroupService.streamForLatest().listen((event) {
state = state.copyWith(latestPillSheetGroup: event);
});
_userSubscribeCanceller?.cancel();
_userSubscribeCanceller = _userService.stream().listen((event) {
state = state.copyWith(
isPremium: event.isPremium,
Expand All @@ -91,11 +88,15 @@ class SettingStateStore extends StateNotifier<SettingState> {
});
}

@override
void dispose() {
void cancel() {
_settingCanceller?.cancel();
_pillSheetGroupCanceller?.cancel();
_userSubscribeCanceller?.cancel();
}

@override
void dispose() {
cancel();
super.dispose();
}

Expand Down
70 changes: 70 additions & 0 deletions lib/hooks/automatic_keep_alive_client_mixin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

// Ref: https://github.com/rrousselGit/flutter_hooks/issues/101#issuecomment-762121053
// Re implement useAutomaticKeepAlive with NNDB
void useAutomaticKeepAlive({
bool? wantKeepAlive,
}) =>
use(_AutomaticKeepAliveHook(
wantKeepAlive: wantKeepAlive ?? true,
));

class _AutomaticKeepAliveHook extends Hook<void> {
final bool wantKeepAlive;

_AutomaticKeepAliveHook({required this.wantKeepAlive});

@override
HookState<void, _AutomaticKeepAliveHook> createState() =>
_AutomaticKeepAliveHookState();
}

class _AutomaticKeepAliveHookState
extends HookState<void, _AutomaticKeepAliveHook> {
KeepAliveHandle? _keepAliveHandle;

void _ensureKeepAlive() {
assert(_keepAliveHandle == null);
final keepAliveHandle = KeepAliveHandle();
_keepAliveHandle = keepAliveHandle;
KeepAliveNotification(keepAliveHandle).dispatch(context);
}

void _releaseKeepAlive() {
_keepAliveHandle?.release();
_keepAliveHandle = null;
}

void updateKeepAlive() {
if (hook.wantKeepAlive) {
if (_keepAliveHandle == null) _ensureKeepAlive();
} else {
if (_keepAliveHandle != null) _releaseKeepAlive();
}
}

@override
void initHook() {
super.initHook();
if (hook.wantKeepAlive) _ensureKeepAlive();
}

@override
void build(BuildContext context) {
if (hook.wantKeepAlive && _keepAliveHandle == null) _ensureKeepAlive();
return null;
}

@override
void deactivate() {
if (_keepAliveHandle != null) _releaseKeepAlive();
super.deactivate();
}

@override
Object get debugValue => _keepAliveHandle ?? "NULL";

@override
String get debugLabel => 'useAutomaticKeepAlive';
}
Loading