Browse Source

Merge pull request #899 from nextcloud/fix/neon/request-manager

Fix request manager
pull/903/head
Kate 1 year ago committed by GitHub
parent
commit
90b0434d58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      packages/neon/neon/lib/src/bloc/result.dart
  2. 2
      packages/neon/neon/lib/src/blocs/login_check_account.dart
  3. 2
      packages/neon/neon/lib/src/blocs/login_check_server_status.dart
  4. 2
      packages/neon/neon/lib/src/blocs/login_flow.dart
  5. 10
      packages/neon/neon/lib/src/blocs/unified_search.dart
  6. 4
      packages/neon/neon/lib/src/blocs/user_statuses.dart
  7. 2
      packages/neon/neon/lib/src/utils/request_manager.dart
  8. 32
      packages/neon/neon/test/result_test.dart

32
packages/neon/neon/lib/src/bloc/result.dart

@ -2,28 +2,43 @@ import 'package:meta/meta.dart';
@immutable @immutable
class Result<T> { class Result<T> {
const Result( Result(
this.data, this.data,
this.error, { this.error, {
required this.isLoading, required this.isLoading,
required this.isCached, required this.isCached,
}); }) : assert(
T != Never,
'Result() called without specifying the data type. Call Result<T>() instead',
);
const Result.loading() Result.loading()
: data = null, : data = null,
error = null, error = null,
isLoading = true, isLoading = true,
isCached = false; isCached = false,
assert(
T != Never,
'Result.loading() called without specifying the data type. Call Result<T>.loading() instead',
);
const Result.success(this.data) Result.success(this.data)
: error = null, : error = null,
isLoading = false, isLoading = false,
isCached = false; isCached = false,
assert(
T != Never,
'Result.success() called without specifying the data type. Call Result<T>.success() instead',
);
const Result.error(this.error) Result.error(this.error)
: data = null, : data = null,
isLoading = false, isLoading = false,
isCached = false; isCached = false,
assert(
T != Never,
'Result.error() called without specifying the data type. Call Result<T>.error() instead',
);
final T? data; final T? data;
final Object? error; final Object? error;
@ -55,6 +70,7 @@ class Result<T> {
bool get hasError => error != null; bool get hasError => error != null;
bool get hasData => data != null; bool get hasData => data != null;
bool get hasUncachedData => hasData && !isCached; bool get hasUncachedData => hasData && !isCached;
T get requireData { T get requireData {

2
packages/neon/neon/lib/src/blocs/login_check_account.dart

@ -45,7 +45,7 @@ class LoginCheckAccountBloc extends InteractiveBloc
@override @override
Future<void> refresh() async { Future<void> refresh() async {
state.add(const Result.loading()); state.add(Result.loading());
try { try {
final client = NextcloudClient( final client = NextcloudClient(

2
packages/neon/neon/lib/src/blocs/login_check_server_status.dart

@ -38,7 +38,7 @@ class LoginCheckServerStatusBloc extends InteractiveBloc
@override @override
Future<void> refresh() async { Future<void> refresh() async {
state.add(const Result.loading()); state.add(Result.loading());
try { try {
final client = NextcloudClient( final client = NextcloudClient(

2
packages/neon/neon/lib/src/blocs/login_flow.dart

@ -51,7 +51,7 @@ class LoginFlowBloc extends InteractiveBloc implements LoginFlowBlocEvents, Logi
@override @override
Future<void> refresh() async { Future<void> refresh() async {
try { try {
init.add(const Result.loading()); init.add(Result.loading());
final initResponse = await _client.core.clientFlowLoginV2.init(); final initResponse = await _client.core.clientFlowLoginV2.init();
init.add(Result.success(initResponse.body)); init.add(Result.success(initResponse.body));

10
packages/neon/neon/lib/src/blocs/unified_search.dart

@ -48,7 +48,7 @@ class UnifiedSearchBloc extends InteractiveBloc implements UnifiedSearchBlocEven
@override @override
BehaviorSubject<Result<Map<CoreUnifiedSearchProvider, Result<CoreUnifiedSearchResult>>?>> results = BehaviorSubject<Result<Map<CoreUnifiedSearchProvider, Result<CoreUnifiedSearchResult>>?>> results =
BehaviorSubject.seeded(const Result.success(null)); BehaviorSubject.seeded(Result.success(null));
@override @override
void dispose() { void dispose() {
@ -76,13 +76,13 @@ class UnifiedSearchBloc extends InteractiveBloc implements UnifiedSearchBlocEven
@override @override
void disable() { void disable() {
enabled.add(false); enabled.add(false);
results.add(const Result.success(null)); results.add(Result.success(null));
_term = ''; _term = '';
} }
Future<void> _search() async { Future<void> _search() async {
if (_term.isEmpty) { if (_term.isEmpty) {
results.add(const Result.success(null)); results.add(Result.success(null));
return; return;
} }
@ -107,12 +107,12 @@ class UnifiedSearchBloc extends InteractiveBloc implements UnifiedSearchBlocEven
final Iterable<CoreUnifiedSearchProvider> providers, final Iterable<CoreUnifiedSearchProvider> providers,
) sync* { ) sync* {
for (final provider in providers) { for (final provider in providers) {
yield MapEntry(provider, const Result.loading()); yield MapEntry(provider, Result.loading());
} }
} }
Future<void> _searchProvider(final CoreUnifiedSearchProvider provider) async { Future<void> _searchProvider(final CoreUnifiedSearchProvider provider) async {
_updateResults(provider, const Result.loading()); _updateResults(provider, Result.loading());
try { try {
final response = await _account.client.core.unifiedSearch.search( final response = await _account.client.core.unifiedSearch.search(
providerId: provider.id, providerId: provider.id,

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

@ -58,7 +58,7 @@ class UserStatusesBloc extends InteractiveBloc implements UserStatusesBlocEvents
} }
try { try {
_updateStatus(username, const Result.loading()); _updateStatus(username, Result.loading());
UserStatusPublicInterface? data; UserStatusPublicInterface? data;
@ -90,7 +90,7 @@ class UserStatusesBloc extends InteractiveBloc implements UserStatusesBlocEvents
_updateStatus(username, Result.success(data)); _updateStatus(username, Result.success(data));
} catch (e, s) { } catch (e, s) {
if (e is DynamiteApiException && e.statusCode == 404) { if (e is DynamiteApiException && e.statusCode == 404) {
_updateStatus(username, const Result.success(null)); _updateStatus(username, Result.success(null));
return; return;
} }
debugPrint(e.toString()); debugPrint(e.toString());

2
packages/neon/neon/lib/src/utils/request_manager.dart

@ -102,7 +102,7 @@ class RequestManager {
final int retries = 0, final int retries = 0,
]) async { ]) async {
// emit loading state with the current value if present // emit loading state with the current value if present
final value = subject.valueOrNull?.asLoading() ?? const Result.loading(); final value = subject.valueOrNull?.asLoading() ?? Result.loading();
subject.add(value); subject.add(value);
final key = '$clientID-$k'; final key = '$clientID-$k';

32
packages/neon/neon/test/result_test.dart

@ -8,13 +8,13 @@ void main() {
test('Equality', () { test('Equality', () {
const data = 'someData'; const data = 'someData';
const a = Result( final a = Result(
data, data,
null, null,
isLoading: true, isLoading: true,
isCached: false, isCached: false,
); );
const b = Result( final b = Result(
data, data,
null, null,
isLoading: true, isLoading: true,
@ -31,8 +31,8 @@ void main() {
test('Transform to loading', () { test('Transform to loading', () {
const data = 'someData'; const data = 'someData';
const a = Result.success(data); final a = Result.success(data);
const b = Result( final b = Result(
data, data,
null, null,
isLoading: true, isLoading: true,
@ -46,9 +46,9 @@ void main() {
test('data check', () { test('data check', () {
const data = 'someData'; const data = 'someData';
const a = Result.loading(); final a = Result<String>.loading();
const b = Result.success(data); final b = Result.success(data);
const c = Result( final c = Result(
data, data,
null, null,
isLoading: false, isLoading: false,
@ -68,7 +68,7 @@ void main() {
test('error check', () { test('error check', () {
const error = 'someError'; const error = 'someError';
const a = Result.error(error); final a = Result<String>.error(error);
expect(a.hasError, true); expect(a.hasError, true);
}); });
@ -76,11 +76,25 @@ void main() {
test('transform', () { test('transform', () {
const data = 1; const data = 1;
const a = Result.success(data); final a = Result.success(data);
String transformer(final int data) => data.toString(); String transformer(final int data) => data.toString();
expect(a.transform(transformer), equals(Result.success(data.toString()))); expect(a.transform(transformer), equals(Result.success(data.toString())));
}); });
test('copyWith', () {
expect(Result<dynamic>('String', 'error', isLoading: false, isCached: false).copyWith(data: '').data, '');
expect(Result<String>('String', 'error', isLoading: false, isCached: false).copyWith(data: '').data, '');
expect(Result<dynamic>.loading().copyWith(data: '').isLoading, true);
expect(Result<String>.loading().copyWith(data: '').isLoading, true);
expect(Result<dynamic>.success('String').copyWith(data: '').data, '');
expect(Result<String>.success('String').copyWith(data: '').data, '');
expect(Result<dynamic>.error('error').copyWith(data: '').error, 'error');
expect(Result<String>.error('error').copyWith(data: '').error, 'error');
});
}); });
} }

Loading…
Cancel
Save