relatica/lib/riverpod_controllers/search_result_services.dart

67 wiersze
2.0 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:result_monad/result_monad.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/auth/profile.dart';
import '../models/exec_error.dart';
import '../models/networking/paging_data.dart';
import '../models/search_results.dart';
import '../models/search_types.dart';
import 'networking/friendica_search_client_services.dart';
part 'search_result_services.g.dart';
@Riverpod(keepAlive: true)
SharedPreferences sharedPreferences(Ref ref) => throw UnimplementedError();
@riverpod
class SearchResultsManager extends _$SearchResultsManager {
var nextPage = const PagingData();
var searchResult = SearchResults.empty();
@override
Future<Result<SearchResults, ExecError>> build(
Profile profile,
SearchTypes searchType,
String searchText, {
int limit = 50,
}) async {
if (searchText.isEmpty) {
return Result.ok(searchResult);
}
final result = await updateSearchResults(reset: true);
return result;
}
Future<Result<SearchResults, ExecError>> updateSearchResults(
{bool reset = true}) async {
if (reset) {
nextPage = PagingData(limit: limit);
searchResult = SearchResults.empty();
}
final result = await ref.watch(
searchResultsProvider(profile, searchType, searchText, nextPage)
.future);
return result
.withResult((result) {
searchResult = reset ? result.data : searchResult.merge(result.data);
nextPage = result.next ?? genNextPageData();
})
.transform((_) => searchResult)
.execErrorCast();
}
PagingData genNextPageData() {
int offset = switch (searchType) {
SearchTypes.account => searchResult.accounts.length,
SearchTypes.statusesText => searchResult.statuses.length,
SearchTypes.directLink => 0,
SearchTypes.hashTag => searchResult.hashtags.length,
};
return PagingData(limit: limit, offset: offset);
}
}