Surface/lib/providers/user_directory.dart
LittleSheep e8ded55055 🐛 Fix some listing non offset bugs
 Optimize user listing speed
2025-02-18 00:07:48 +08:00

74 lines
2.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/types/account.dart';
class UserDirectoryProvider {
late final SnNetworkProvider _sn;
UserDirectoryProvider(BuildContext context) {
_sn = context.read<SnNetworkProvider>();
}
final Map<String, int> _idCache = {};
final Map<int, SnAccount> _cache = {};
Future<List<SnAccount?>> listAccount(Iterable<dynamic> id) async {
final out = List<SnAccount?>.generate(id.length, (e) => null);
final plannedQuery = <int>{};
for (var idx = 0; idx < out.length; idx++) {
var item = id.elementAt(idx);
if (item is String && _idCache.containsKey(item)) {
item = _idCache[item];
}
if (_cache.containsKey(item)) {
out[idx] = _cache[item];
} else {
plannedQuery.add(item);
}
}
final resp = await _sn.client.get('/cgi/id/users', queryParameters: {'id': plannedQuery.join(',')});
final respDecoded = resp.data.map((e) => SnAccount.fromJson(e)).cast<SnAccount>().toList();
var sideIdx = 0;
for (var idx = 0; idx < out.length; idx++) {
if (out[idx] != null) continue;
if (respDecoded.length <= sideIdx) {
break;
}
out[idx] = respDecoded[sideIdx];
_cache[respDecoded[sideIdx].id] = out[idx]!;
_idCache[respDecoded[sideIdx].name] = respDecoded[sideIdx].id;
sideIdx++;
}
return out;
}
Future<SnAccount?> getAccount(dynamic id) async {
if (id is String && _idCache.containsKey(id)) {
id = _idCache[id];
}
if (_cache.containsKey(id)) {
return _cache[id];
}
try {
final resp = await _sn.client.get('/cgi/id/users/$id');
final account = SnAccount.fromJson(
resp.data as Map<String, dynamic>,
);
_cache[account.id] = account;
if (id is String) _idCache[id] = account.id;
return account;
} catch (err) {
return null;
}
}
SnAccount? getAccountFromCache(dynamic id) {
if (id is String && _idCache.containsKey(id)) {
id = _idCache[id];
}
return _cache[id];
}
}