Browse Source

neon: Refactor UserStatusBloc into UserStatusesBloc

pull/344/head
jld3103 2 years ago
parent
commit
6bd19e32f1
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 2
      packages/neon/neon/lib/neon.dart
  2. 12
      packages/neon/neon/lib/src/blocs/accounts.dart
  3. 61
      packages/neon/neon/lib/src/blocs/user_status.dart
  4. 85
      packages/neon/neon/lib/src/blocs/user_statuses.dart

2
packages/neon/neon/lib/neon.dart

@ -58,7 +58,7 @@ part 'src/blocs/next_push.dart';
part 'src/blocs/push_notifications.dart';
part 'src/blocs/timer.dart';
part 'src/blocs/user_details.dart';
part 'src/blocs/user_status.dart';
part 'src/blocs/user_statuses.dart';
part 'src/interfaces/notifications.dart';
part 'src/pages/account_settings.dart';
part 'src/pages/home.dart';

12
packages/neon/neon/lib/src/blocs/accounts.dart

@ -74,7 +74,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
final _appsBlocs = <String, AppsBloc>{};
final _capabilitiesBlocs = <String, CapabilitiesBloc>{};
final _userDetailsBlocs = <String, UserDetailsBloc>{};
final _userStatusBlocs = <String, UserStatusBloc>{};
final _userStatusesBlocs = <String, UserStatusesBloc>{};
@override
void dispose() {
@ -83,7 +83,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
_appsBlocs.disposeAll();
_capabilitiesBlocs.disposeAll();
_userDetailsBlocs.disposeAll();
_userStatusBlocs.disposeAll();
_userStatusesBlocs.disposeAll();
for (final options in _accountsOptions.values) {
options.dispose();
}
@ -190,12 +190,12 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
);
}
UserStatusBloc getUserStatusBloc(final Account account) {
if (_userStatusBlocs[account.id] != null) {
return _userStatusBlocs[account.id]!;
UserStatusesBloc getUserStatusesBloc(final Account account) {
if (_userStatusesBlocs[account.id] != null) {
return _userStatusesBlocs[account.id]!;
}
return _userStatusBlocs[account.id] = UserStatusBloc(
return _userStatusesBlocs[account.id] = UserStatusesBloc(
_platform,
account,
);

61
packages/neon/neon/lib/src/blocs/user_status.dart

@ -1,61 +0,0 @@
part of '../../neon.dart';
abstract class UserStatusBlocEvents {}
abstract class UserStatusBlocStates {
BehaviorSubject<Result<NextcloudUserStatusStatus?>> get userStatus;
}
class UserStatusBloc extends InteractiveBloc implements UserStatusBlocEvents, UserStatusBlocStates {
UserStatusBloc(
this._platform,
this._account,
) {
_timer = instantPeriodicTimer(
const Duration(minutes: 5),
(final _) async {
await refresh();
},
);
}
final NeonPlatform _platform;
final Account _account;
late Timer _timer;
@override
void dispose() {
_timer.cancel();
unawaited(userStatus.close());
}
@override
BehaviorSubject<Result<NextcloudUserStatusStatus?>> userStatus =
BehaviorSubject<Result<NextcloudUserStatusStatus?>>();
@override
Future refresh() async {
final isAway =
_platform.canUseWindowManager && (!(await windowManager.isFocused()) || !(await windowManager.isVisible()));
try {
final response = await _account.client.userStatus.heartbeat(
status: isAway ? NextcloudUserStatusType.away : NextcloudUserStatusType.online,
);
userStatus.add(Result.success(response.ocs.data));
} catch (e) {
if (e is NextcloudApiException && e.statusCode == 204) {
return;
}
userStatus.add(Result.error(e));
}
}
}
Timer instantPeriodicTimer(
final Duration duration,
final void Function(Timer timer) callback,
) {
final timer = Timer.periodic(duration, callback);
callback(timer);
return timer;
}

85
packages/neon/neon/lib/src/blocs/user_statuses.dart

@ -0,0 +1,85 @@
part of '../../neon.dart';
abstract class UserStatusesBlocEvents {
void load(final String username, {final bool force = false});
}
abstract class UserStatusesBlocStates {
BehaviorSubject<Map<String, Result<NextcloudUserStatusPublicStatus?>>> get statuses;
}
class UserStatusesBloc extends InteractiveBloc implements UserStatusesBlocEvents, UserStatusesBlocStates {
UserStatusesBloc(
this._platform,
this._account,
) {
unawaited(refresh());
_timer = TimerBloc().registerTimer(const Duration(minutes: 5), refresh);
}
final NeonPlatform _platform;
final Account _account;
late final NeonTimer _timer;
@override
void dispose() {
_timer.cancel();
unawaited(statuses.close());
super.dispose();
}
@override
BehaviorSubject<Map<String, Result<NextcloudUserStatusPublicStatus?>>> statuses =
BehaviorSubject<Map<String, Result<NextcloudUserStatusPublicStatus?>>>();
@override
Future refresh() async {
for (final username in _statuses.keys) {
await load(username, force: true);
}
}
@override
Future load(final String username, {final bool force = false}) async {
if (!force && _statuses.containsKey(username)) {
return;
}
try {
_updateStatus(username, Result.loading());
NextcloudUserStatusPublicStatus? data;
if (_account.username == username) {
final isAway =
_platform.canUseWindowManager && (!(await windowManager.isFocused()) || !(await windowManager.isVisible()));
final response = await _account.client.userStatus.heartbeat(
status: isAway ? NextcloudUserStatusType.away : NextcloudUserStatusType.online,
);
data = response.ocs.data.userStatusStatus?.userStatusPublicStatus;
} else {
final response = await _account.client.userStatus.getPublicStatus(userId: username);
data = response.ocs.data.userStatusPublicStatus;
}
_updateStatus(username, Result.success(data));
} catch (e, s) {
if (e is NextcloudApiException && (e.statusCode == 404 || e.statusCode == 204)) {
_updateStatus(username, Result.success(null));
return;
}
debugPrint(e.toString());
debugPrint(s.toString());
_updateStatus(username, Result.error(e));
}
}
Map<String, Result<NextcloudUserStatusPublicStatus?>> get _statuses =>
statuses.valueOrNull ?? <String, Result<NextcloudUserStatusPublicStatus?>>{};
void _updateStatus(final String username, final Result<NextcloudUserStatusPublicStatus?> result) {
statuses.add({
..._statuses,
username: result,
});
}
}
Loading…
Cancel
Save