From a9cff12a8b026b1283f9ea7c1ac83b1ed586e1f1 Mon Sep 17 00:00:00 2001 From: jld3103 Date: Sun, 23 Oct 2022 19:39:13 +0200 Subject: [PATCH] neon: Implement user status heartbeat --- .../integration_test/screenshot_test.dart | 1 + packages/neon/lib/main.dart | 1 + packages/neon/lib/src/blocs/accounts.dart | 4 +- packages/neon/lib/src/blocs/user_status.dart | 74 +++++++------------ 4 files changed, 32 insertions(+), 48 deletions(-) diff --git a/packages/neon/integration_test/screenshot_test.dart b/packages/neon/integration_test/screenshot_test.dart index 3c3d9ffe..2225b0cd 100644 --- a/packages/neon/integration_test/screenshot_test.dart +++ b/packages/neon/integration_test/screenshot_test.dart @@ -115,6 +115,7 @@ Future pumpAppPage( final accountsBloc = AccountsBloc( requestManager, + platform, Storage('accounts', sharedPreferences), sharedPreferences, globalOptions, diff --git a/packages/neon/lib/main.dart b/packages/neon/lib/main.dart index 0d1f930b..4549514b 100644 --- a/packages/neon/lib/main.dart +++ b/packages/neon/lib/main.dart @@ -42,6 +42,7 @@ Future main() async { final accountsBloc = AccountsBloc( requestManager, + platform, Storage('accounts', sharedPreferences), sharedPreferences, globalOptions, diff --git a/packages/neon/lib/src/blocs/accounts.dart b/packages/neon/lib/src/blocs/accounts.dart index e6780b4e..6fc7e150 100644 --- a/packages/neon/lib/src/blocs/accounts.dart +++ b/packages/neon/lib/src/blocs/accounts.dart @@ -29,6 +29,7 @@ abstract class AccountsBlocStates { class AccountsBloc extends $AccountsBloc { AccountsBloc( this._requestManager, + this._platform, this._storage, this._sharedPreferences, this._globalOptions, @@ -156,12 +157,13 @@ class AccountsBloc extends $AccountsBloc { return _userStatusBlocs[account.id] = UserStatusBloc( _requestManager, + _platform, account, - _activeAccountSubject, ); } final RequestManager _requestManager; + final NeonPlatform _platform; final Storage _storage; final SharedPreferences _sharedPreferences; final GlobalOptions _globalOptions; diff --git a/packages/neon/lib/src/blocs/user_status.dart b/packages/neon/lib/src/blocs/user_status.dart index 833ae6d4..2a811e79 100644 --- a/packages/neon/lib/src/blocs/user_status.dart +++ b/packages/neon/lib/src/blocs/user_status.dart @@ -1,11 +1,11 @@ import 'dart:async'; -import 'package:flutter/foundation.dart'; import 'package:neon/src/models/account.dart'; import 'package:neon/src/neon.dart'; import 'package:nextcloud/nextcloud.dart'; import 'package:rx_bloc/rx_bloc.dart'; import 'package:rxdart/rxdart.dart'; +import 'package:window_manager/window_manager.dart'; part 'user_status.rxb.g.dart'; @@ -19,67 +19,47 @@ abstract class UserStatusBlocStates { class UserStatusBloc extends $UserStatusBloc { UserStatusBloc( this._requestManager, + this._platform, this._account, - this._activeAccountStream, ) { - _activeAccountStreamSubscription = _activeAccountStream.listen((final activeAccount) { - _cancelTimer(); - final thisAccountActive = activeAccount == _account; - _timer = instantPeriodicTimer( - const Duration(minutes: 5), - (final _) async { - if (thisAccountActive) { - await _heartbeat(); - } - _loadUserStatus(); - }, - ); - }); - } - - void _loadUserStatus() { - // TODO: Fix for no user status - _requestManager - .wrapNextcloud( - _account.client.id, - 'user-status', - () async => _account.client.userStatus.getStatus(), - (final response) => response.ocs.data.userStatus, - previousData: _userStatusSubject.valueOrNull?.data, - ) - .listen(_userStatusSubject.add); + _timer = instantPeriodicTimer( + const Duration(minutes: 5), + (final _) async { + await _heartbeat(); + }, + ); } Future _heartbeat() async { - return; - - // TODO: https://github.com/jld3103/nextcloud-neon/issues/10 - // ignore: dead_code - try { - await _account.client.userStatus.heartbeat(status: UserStatusType.online); - } catch (e) { - debugPrint(e.toString()); - } - } - - void _cancelTimer() { - if (_timer != null) { - _timer!.cancel(); - _timer = null; - } + final isAway = + _platform.canUseWindowManager && (!(await windowManager.isFocused()) || !(await windowManager.isVisible())); + _requestManager.wrapWithoutCache( + () async { + try { + return await _account.client.userStatus.heartbeat( + status: isAway ? UserStatusType.away : UserStatusType.online, + ); + } on ApiException catch (e) { + if (e.statusCode == 204) { + return null; + } + rethrow; + } + }, + ).listen(_userStatusSubject.add); } final RequestManager _requestManager; + final NeonPlatform _platform; final Account _account; - final BehaviorSubject _activeAccountStream; late final StreamSubscription _activeAccountStreamSubscription; - Timer? _timer; + late Timer _timer; final _userStatusSubject = BehaviorSubject>(); @override void dispose() { - _cancelTimer(); + _timer.cancel(); unawaited(_activeAccountStreamSubscription.cancel()); unawaited(_userStatusSubject.close()); super.dispose();