Browse Source

neon: Implement user status heartbeat

pull/98/head
jld3103 2 years ago
parent
commit
a9cff12a8b
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 1
      packages/neon/integration_test/screenshot_test.dart
  2. 1
      packages/neon/lib/main.dart
  3. 4
      packages/neon/lib/src/blocs/accounts.dart
  4. 56
      packages/neon/lib/src/blocs/user_status.dart

1
packages/neon/integration_test/screenshot_test.dart

@ -115,6 +115,7 @@ Future pumpAppPage(
final accountsBloc = AccountsBloc( final accountsBloc = AccountsBloc(
requestManager, requestManager,
platform,
Storage('accounts', sharedPreferences), Storage('accounts', sharedPreferences),
sharedPreferences, sharedPreferences,
globalOptions, globalOptions,

1
packages/neon/lib/main.dart

@ -42,6 +42,7 @@ Future main() async {
final accountsBloc = AccountsBloc( final accountsBloc = AccountsBloc(
requestManager, requestManager,
platform,
Storage('accounts', sharedPreferences), Storage('accounts', sharedPreferences),
sharedPreferences, sharedPreferences,
globalOptions, globalOptions,

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

@ -29,6 +29,7 @@ abstract class AccountsBlocStates {
class AccountsBloc extends $AccountsBloc { class AccountsBloc extends $AccountsBloc {
AccountsBloc( AccountsBloc(
this._requestManager, this._requestManager,
this._platform,
this._storage, this._storage,
this._sharedPreferences, this._sharedPreferences,
this._globalOptions, this._globalOptions,
@ -156,12 +157,13 @@ class AccountsBloc extends $AccountsBloc {
return _userStatusBlocs[account.id] = UserStatusBloc( return _userStatusBlocs[account.id] = UserStatusBloc(
_requestManager, _requestManager,
_platform,
account, account,
_activeAccountSubject,
); );
} }
final RequestManager _requestManager; final RequestManager _requestManager;
final NeonPlatform _platform;
final Storage _storage; final Storage _storage;
final SharedPreferences _sharedPreferences; final SharedPreferences _sharedPreferences;
final GlobalOptions _globalOptions; final GlobalOptions _globalOptions;

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

@ -1,11 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/neon.dart'; import 'package:neon/src/neon.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:rx_bloc/rx_bloc.dart'; import 'package:rx_bloc/rx_bloc.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
import 'package:window_manager/window_manager.dart';
part 'user_status.rxb.g.dart'; part 'user_status.rxb.g.dart';
@ -19,67 +19,47 @@ abstract class UserStatusBlocStates {
class UserStatusBloc extends $UserStatusBloc { class UserStatusBloc extends $UserStatusBloc {
UserStatusBloc( UserStatusBloc(
this._requestManager, this._requestManager,
this._platform,
this._account, this._account,
this._activeAccountStream,
) { ) {
_activeAccountStreamSubscription = _activeAccountStream.listen((final activeAccount) {
_cancelTimer();
final thisAccountActive = activeAccount == _account;
_timer = instantPeriodicTimer( _timer = instantPeriodicTimer(
const Duration(minutes: 5), const Duration(minutes: 5),
(final _) async { (final _) async {
if (thisAccountActive) {
await _heartbeat(); await _heartbeat();
}
_loadUserStatus();
}, },
); );
});
}
void _loadUserStatus() {
// TODO: Fix for no user status
_requestManager
.wrapNextcloud<UserStatus?, UserStatusGetUserStatus>(
_account.client.id,
'user-status',
() async => _account.client.userStatus.getStatus(),
(final response) => response.ocs.data.userStatus,
previousData: _userStatusSubject.valueOrNull?.data,
)
.listen(_userStatusSubject.add);
} }
Future _heartbeat() async { Future _heartbeat() async {
return; final isAway =
_platform.canUseWindowManager && (!(await windowManager.isFocused()) || !(await windowManager.isVisible()));
// TODO: https://github.com/jld3103/nextcloud-neon/issues/10 _requestManager.wrapWithoutCache(
// ignore: dead_code () async {
try { try {
await _account.client.userStatus.heartbeat(status: UserStatusType.online); return await _account.client.userStatus.heartbeat(
} catch (e) { status: isAway ? UserStatusType.away : UserStatusType.online,
debugPrint(e.toString()); );
} } on ApiException catch (e) {
if (e.statusCode == 204) {
return null;
} }
rethrow;
void _cancelTimer() {
if (_timer != null) {
_timer!.cancel();
_timer = null;
} }
},
).listen(_userStatusSubject.add);
} }
final RequestManager _requestManager; final RequestManager _requestManager;
final NeonPlatform _platform;
final Account _account; final Account _account;
final BehaviorSubject<Account?> _activeAccountStream;
late final StreamSubscription<Account?> _activeAccountStreamSubscription; late final StreamSubscription<Account?> _activeAccountStreamSubscription;
Timer? _timer; late Timer _timer;
final _userStatusSubject = BehaviorSubject<Result<UserStatus?>>(); final _userStatusSubject = BehaviorSubject<Result<UserStatus?>>();
@override @override
void dispose() { void dispose() {
_cancelTimer(); _timer.cancel();
unawaited(_activeAccountStreamSubscription.cancel()); unawaited(_activeAccountStreamSubscription.cancel());
unawaited(_userStatusSubject.close()); unawaited(_userStatusSubject.close());
super.dispose(); super.dispose();

Loading…
Cancel
Save