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(); } final Map _idCache = {}; final Map _cache = {}; Future> listAccount(Iterable id) async { final out = List.generate(id.length, (e) => null); final plannedQuery = {}; 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().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 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, ); _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]; } }