Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
spicy-tomato committed Jul 2, 2021
2 parents dddecc0 + c413cdd commit 39e87dc
Show file tree
Hide file tree
Showing 31 changed files with 340 additions and 248 deletions.
2 changes: 1 addition & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:launchMode="singleTask"
android:showWhenLocked="true"
android:theme="@style/LaunchTheme"
android:turnScreenOn="true"
Expand Down
2 changes: 1 addition & 1 deletion lib/_crawler/bloc/crawler_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class CrawlerBloc extends Bloc<CrawlerEvent, CrawlerState> {
if (state.formStatus.isValidated) {
UserDataModel userDataModel = context.read<UserRepository>().userDataModel;

String idStudent = userDataModel.idStudent;
String idStudent = userDataModel.idUser;
String idAccount = userDataModel.idAccount;

yield state.copyWith(
Expand Down
4 changes: 2 additions & 2 deletions lib/_models/user_data_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ class UserDataModel {
final NotificationServiceController notificationServiceController;
final ExamScheduleServiceController examScheduleServiceController;
final String idAccount;
final String idStudent;
final String idUser;

UserDataModel({
required this.eventServiceController,
required this.scoreServiceController,
required this.notificationServiceController,
required this.examScheduleServiceController,
required this.idAccount,
required this.idStudent,
required this.idUser,
});
}
285 changes: 165 additions & 120 deletions lib/_preload/bloc/preload_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ part 'preload_state.dart';
class PreloadBloc extends Bloc<PreloadEvent, PreloadState> {
final BuildContext context;
final NavigatorState? navigator;
final User user;
final String _idAccount;
final String _idUser;

PreloadBloc({
required this.context,
required this.navigator,
required this.user,
}) : super(PreloadInitial());
required User user,
}) : _idAccount = user.accountId,
_idUser = user.id,
super(PreloadInitial());

@override
Stream<PreloadState> mapEventToState(
Expand All @@ -59,115 +62,127 @@ class PreloadBloc extends Bloc<PreloadEvent, PreloadState> {
Stopwatch stopwatch = Stopwatch()..start();
final minTurnAroundTime = const Duration(seconds: 2);
final ApiUrl apiUrl = AppModeWidget.of(context).apiUrl;
final serviceControllers = _ServiceControllers(
apiUrl: apiUrl,
idUser: _idUser,
idAccount: _idAccount,
);

/// Khởi động các service
final tokenService = TokenService(apiUrl);
await tokenService.init();
await tokenService.upsert(user.id);
await Future.wait([
_upsertToken(apiUrl),
_initControllersAndRefreshServices(serviceControllers, apiUrl),
]);

String idAccount = user.accountId;
String idUser = user.id;
final timeEnded = stopwatch.elapsed;
stopwatch.stop();

final DatabaseProvider databaseProvider = DatabaseProvider();
await databaseProvider.init();
print(timeEnded);

final ServiceControllerData controllerData = ServiceControllerData(
databaseProvider: databaseProvider,
apiUrl: apiUrl,
idUser: idUser,
final userDataModel = UserDataModel(
eventServiceController: serviceControllers.event,
scoreServiceController: serviceControllers.score,
notificationServiceController: serviceControllers.notification,
examScheduleServiceController: serviceControllers.examSchedule,
idAccount: _idAccount,
idUser: _idUser,
);

EventServiceController eventServiceController = EventServiceController(controllerData);
NotificationServiceController notificationServiceController =
NotificationServiceController(controllerData, idAccount);
ScoreServiceController scoreServiceController = ScoreServiceController(controllerData);
ExamScheduleServiceController examScheduleServiceController =
ExamScheduleServiceController(controllerData);

print('Event: ${stopwatch.elapsed}');
await eventServiceController.load();
context.read<UserRepository>().userDataModel = userDataModel;

print('Notification: ${stopwatch.elapsed}');
await notificationServiceController.load();
await Future.delayed(
timeEnded < minTurnAroundTime ? minTurnAroundTime - timeEnded : const Duration(seconds: 0), () async {
await navigator?.pushNamedAndRemoveUntil(Const.defaultPage, (_) => false);
});

print('Score: ${stopwatch.elapsed}');
await scoreServiceController.load();
yield PreloadState.loaded(userDataModel);
}

print('Exam Schedule: ${stopwatch.elapsed}');
await examScheduleServiceController.load();
Stream<PreloadState> _mapPreloadLoadingAfterLoginToState(PreloadLoadingAfterLogin event) async* {
yield PreloadState.loadingAfterLogin();

Map<String, dynamic> versionMap = await VersionService(
Stopwatch stopwatch = Stopwatch()..start();
final minTurnAroundTime = const Duration(seconds: 2);
final ApiUrl apiUrl = AppModeWidget.of(context).apiUrl;
final serviceControllers = _ServiceControllers(
apiUrl: apiUrl,
idStudent: idUser,
).getServerDataVersion();
if (versionMap.isNotEmpty) {
print(versionMap);

DbDataVersion version = eventServiceController.localService.databaseProvider.dataVersion;
idUser: _idUser,
idAccount: _idAccount,
);

if (versionMap['Schedule']! as int > version.schedule) {
await eventServiceController.refresh();
}
if (versionMap['Notification']! as int > version.notification) {
await notificationServiceController.refresh();
}
if (versionMap['Exam_Schedule']! as int > version.examSchedule) {
await examScheduleServiceController.refresh();
} else if (version.examSchedule > 0) {
examScheduleServiceController.setConnected();
}
if (versionMap['Module_Score']! as int > version.score) {
await scoreServiceController.refresh();
} else if (version.score > 0) {
scoreServiceController.setConnected();
}
}
await Future.wait([
_upsertToken(apiUrl),
_initControllersAndRefreshServices(serviceControllers, apiUrl, force: true),
]);

final timeEnded = stopwatch.elapsed;
stopwatch.stop();

print(timeEnded);

context.read<UserRepository>().userDataModel = UserDataModel(
eventServiceController: eventServiceController,
scoreServiceController: scoreServiceController,
notificationServiceController: notificationServiceController,
examScheduleServiceController: examScheduleServiceController,
idAccount: idAccount,
idStudent: idUser,
final userDataModel = UserDataModel(
eventServiceController: serviceControllers.event,
scoreServiceController: serviceControllers.score,
notificationServiceController: serviceControllers.notification,
examScheduleServiceController: serviceControllers.examSchedule,
idAccount: _idAccount,
idUser: _idUser,
);

context.read<UserRepository>().userDataModel = userDataModel;

await Future.delayed(
timeEnded < minTurnAroundTime ? minTurnAroundTime - timeEnded : const Duration(seconds: 0),
() async {
timeEnded < minTurnAroundTime ? minTurnAroundTime - timeEnded : const Duration(seconds: 0), () async {
await navigator?.pushNamedAndRemoveUntil(Const.defaultPage, (_) => false);
});

yield PreloadState.loaded(
eventServiceController: eventServiceController,
scoreServiceController: scoreServiceController,
notificationServiceController: notificationServiceController,
examScheduleServiceController: examScheduleServiceController,
idAccount: idAccount,
idUser: idUser,
);
yield PreloadState.loaded(userDataModel);
}

Stream<PreloadState> _mapPreloadLoadingAfterLoginToState(PreloadLoadingAfterLogin event) async* {
yield PreloadState.loadingAfterLogin();

Stopwatch stopwatch = Stopwatch()..start();
final minTurnAroundTime = const Duration(seconds: 2);
final ApiUrl apiUrl = AppModeWidget.of(context).apiUrl;

/// Khởi động các service
Future<void> _upsertToken(ApiUrl apiUrl) async {
final tokenService = TokenService(apiUrl);
await tokenService.init();
await tokenService.upsert(user.id);
await tokenService.upsert(_idUser);
}

String idAccount = user.accountId;
String idUser = user.id;
Future<void> _initControllersAndRefreshServices(
_ServiceControllers serviceControllers,
ApiUrl apiUrl, {
bool force = false,
}) async {
await serviceControllers.init(loadOldData: !force);

Map<String, dynamic> versionMap = await VersionService(
apiUrl: apiUrl,
idStudent: _idUser,
).getServerDataVersion();

if (versionMap.isNotEmpty) {
print(versionMap);
if (force) {
await serviceControllers.forceRefresh(versionMap);
} else {
await serviceControllers.refresh(versionMap);
}
}
}
}

class _ServiceControllers {
late final EventServiceController event;
late final ScoreServiceController score;
late final NotificationServiceController notification;
late final ExamScheduleServiceController examSchedule;
final ApiUrl apiUrl;
final String idUser;
final String idAccount;

_ServiceControllers({
required this.apiUrl,
required this.idAccount,
required this.idUser,
});

Future<void> init({bool loadOldData = false}) async {
final DatabaseProvider databaseProvider = DatabaseProvider();
await databaseProvider.init();

Expand All @@ -177,52 +192,82 @@ class PreloadBloc extends Bloc<PreloadEvent, PreloadState> {
idUser: idUser,
);

EventServiceController eventServiceController = EventServiceController(controllerData);
ScoreServiceController scoreServiceController = ScoreServiceController(controllerData);
NotificationServiceController notificationServiceController =
NotificationServiceController(controllerData, idAccount);
ExamScheduleServiceController examScheduleServiceController =
ExamScheduleServiceController(controllerData);
event = EventServiceController(controllerData);
score = ScoreServiceController(controllerData);
notification = NotificationServiceController(controllerData, idAccount);
examSchedule = ExamScheduleServiceController(controllerData);

if (loadOldData) {
await Future.wait([
event.load(),
notification.load(),
score.load(),
examSchedule.load(),
]);
}
}

print('Event: ${stopwatch.elapsed}');
await eventServiceController.refresh();
Future<void> refresh(Map<String, dynamic> versionMap) async {
DbDataVersion version = event.localService.databaseProvider.dataVersion;

print('Notification: ${stopwatch.elapsed}');
await notificationServiceController.refresh(getAll: true);
await Future.wait([
_refreshEvent(versionMap['Schedule']! as int, version.schedule),
_refreshNotification(versionMap['Notification']! as int, version.notification),
_refreshExamSchedule(versionMap['Exam_Schedule']! as int, version.examSchedule),
_refreshScore(versionMap['Module_Score']! as int, version.score),
]);
}

print('Score: ${stopwatch.elapsed}');
await scoreServiceController.refresh();
Future<void> forceRefresh(Map<String, dynamic> versionMap) async {
await Future.wait([
_forceRefreshEvent(),
_forceRefreshNotification(getAll: true),
_forceRefreshExamSchedule(versionMap['Exam_Schedule']! as int),
_forceRefreshScore(versionMap['Module_Score']! as int),
]);
}

print('Exam Schedule: ${stopwatch.elapsed}');
await examScheduleServiceController.refresh();
Future<void> _refreshEvent(int serverVersion, localVersion) async {
if (serverVersion > localVersion) {
await _forceRefreshEvent();
}
}

final timeEnded = stopwatch.elapsed;
stopwatch.stop();
Future<void> _forceRefreshEvent() async {
await event.refresh();
}

print(timeEnded);
Future<void> _refreshNotification(int serverVersion, localVersion) async {
if (serverVersion > localVersion) {
await _forceRefreshNotification();
}
}

context.read<UserRepository>().userDataModel = UserDataModel(
eventServiceController: eventServiceController,
scoreServiceController: scoreServiceController,
notificationServiceController: notificationServiceController,
examScheduleServiceController: examScheduleServiceController,
idAccount: idAccount,
idStudent: idUser,
);
Future<void> _forceRefreshNotification({bool getAll = false}) async {
await notification.refresh(getAll: getAll);
}

await Future.delayed(
timeEnded < minTurnAroundTime ? minTurnAroundTime - timeEnded : const Duration(seconds: 0),
() async {
await navigator?.pushNamedAndRemoveUntil(Const.defaultPage, (_) => false);
});
Future<void> _refreshExamSchedule(int serverVersion, localVersion) async {
if (serverVersion > localVersion) {
await _forceRefreshExamSchedule(serverVersion);
} else if (localVersion > 0) {
examSchedule.setConnected();
}
}

yield PreloadState.loaded(
eventServiceController: eventServiceController,
scoreServiceController: scoreServiceController,
notificationServiceController: notificationServiceController,
examScheduleServiceController: examScheduleServiceController,
idAccount: idAccount,
idUser: idUser,
);
Future<void> _forceRefreshExamSchedule([int? newVersion]) async {
await examSchedule.refresh(newVersion);
}

Future<void> _refreshScore(int serverVersion, localVersion) async {
if (serverVersion > localVersion) {
await _forceRefreshScore(serverVersion);
} else if (localVersion > 0) {
score.setConnected();
}
}

Future<void> _forceRefreshScore([int? newVersion]) async {
await score.refresh(newVersion);
}
}
Loading

0 comments on commit 39e87dc

Please sign in to comment.