jld3103
2 years ago
4 changed files with 92 additions and 68 deletions
@ -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; |
|
||||||
} |
|
@ -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…
Reference in new issue