mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-02-03 11:50:01 -05:00
fix refresh, error
This commit is contained in:
parent
56d8f81cf2
commit
0cf2b947be
@ -26,8 +26,8 @@ class ContactInvitationDisplayDialog extends StatefulWidget {
|
||||
final String message;
|
||||
|
||||
@override
|
||||
ContactInvitationDisplayDialogState createState() =>
|
||||
ContactInvitationDisplayDialogState();
|
||||
State<ContactInvitationDisplayDialog> createState() =>
|
||||
_ContactInvitationDisplayDialogState();
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
@ -36,7 +36,7 @@ class ContactInvitationDisplayDialog extends StatefulWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class ContactInvitationDisplayDialogState
|
||||
class _ContactInvitationDisplayDialogState
|
||||
extends State<ContactInvitationDisplayDialog> {
|
||||
final focusNode = FocusNode();
|
||||
final formKey = GlobalKey<FormState>();
|
||||
@ -123,12 +123,8 @@ class ContactInvitationDisplayDialogState
|
||||
},
|
||||
).paddingAll(16),
|
||||
])),
|
||||
error: (e, s) {
|
||||
Navigator.of(context).pop();
|
||||
showErrorToast(context,
|
||||
translate('send_invite_dialog.failed_to_generate'));
|
||||
return const Text('');
|
||||
})));
|
||||
error: (e, s) =>
|
||||
Text(translate('send_invite_dialog.failed_to_generate')))));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -212,17 +212,54 @@ class DHTShortArray {
|
||||
return record!.get(subkey: recordSubkey, forceRefresh: forceRefresh);
|
||||
}
|
||||
|
||||
Future<List<Uint8List>?> getAllItems({bool forceRefresh = false}) async {
|
||||
await _refreshHead(forceRefresh: forceRefresh, onlyUpdates: true);
|
||||
|
||||
final out = <Uint8List>[];
|
||||
|
||||
for (var pos = 0; pos < _head.index.length; pos++) {
|
||||
final index = _head.index[pos];
|
||||
final recordNumber = index ~/ _stride;
|
||||
final record = _getLinkedRecord(recordNumber);
|
||||
if (record == null) {
|
||||
assert(record != null, 'Record does not exist');
|
||||
return null;
|
||||
}
|
||||
|
||||
final recordSubkey = (index % _stride) + ((recordNumber == 0) ? 1 : 0);
|
||||
final elem =
|
||||
await record.get(subkey: recordSubkey, forceRefresh: forceRefresh);
|
||||
if (elem == null) {
|
||||
return null;
|
||||
}
|
||||
out.add(elem);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Future<T?> getItemJson<T>(T Function(dynamic) fromJson, int pos,
|
||||
{bool forceRefresh = false}) =>
|
||||
getItem(pos, forceRefresh: forceRefresh)
|
||||
.then((out) => jsonDecodeOptBytes(fromJson, out));
|
||||
|
||||
Future<List<T>?> getAllItemsJson<T>(T Function(dynamic) fromJson,
|
||||
{bool forceRefresh = false}) =>
|
||||
getAllItems(forceRefresh: forceRefresh)
|
||||
.then((out) => out?.map(fromJson).toList());
|
||||
|
||||
Future<T?> getItemProtobuf<T extends GeneratedMessage>(
|
||||
T Function(List<int>) fromBuffer, int pos,
|
||||
{bool forceRefresh = false}) =>
|
||||
getItem(pos, forceRefresh: forceRefresh)
|
||||
.then((out) => (out == null) ? null : fromBuffer(out));
|
||||
|
||||
Future<List<T>?> getAllItemsProtobuf<T extends GeneratedMessage>(
|
||||
T Function(List<int>) fromBuffer,
|
||||
{bool forceRefresh = false}) =>
|
||||
getAllItems(forceRefresh: forceRefresh)
|
||||
.then((out) => out?.map(fromBuffer).toList());
|
||||
|
||||
Future<bool> tryAddItem(Uint8List value) async {
|
||||
await _refreshHead(onlyUpdates: true);
|
||||
|
||||
|
@ -18,13 +18,13 @@ class DHTShortArrayCubit<T> extends Cubit<DHTShortArrayBusyState<T>>
|
||||
required T Function(List<int> data) decodeElement,
|
||||
}) : _decodeElement = decodeElement,
|
||||
super(const BlocBusyState(AsyncValue.loading())) {
|
||||
Future.delayed(Duration.zero, () async {
|
||||
_initFuture = Future(() async {
|
||||
// Open DHT record
|
||||
_shortArray = await open();
|
||||
_wantsCloseRecord = true;
|
||||
|
||||
// Make initial state update
|
||||
_update();
|
||||
await _refreshNoWait();
|
||||
_subscription = await _shortArray.listen(_update);
|
||||
});
|
||||
}
|
||||
@ -35,57 +35,53 @@ class DHTShortArrayCubit<T> extends Cubit<DHTShortArrayBusyState<T>>
|
||||
}) : _shortArray = shortArray,
|
||||
_decodeElement = decodeElement,
|
||||
super(const BlocBusyState(AsyncValue.loading())) {
|
||||
_initFuture = Future(() async {
|
||||
// Make initial state update
|
||||
_update();
|
||||
Future.delayed(Duration.zero, () async {
|
||||
await _refreshNoWait();
|
||||
_subscription = await shortArray.listen(_update);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> refresh({bool forceRefresh = false}) async => busy((emit) async {
|
||||
var out = IList<T>();
|
||||
// xxx could be parallelized but we need to watch out for rate limits
|
||||
for (var i = 0; i < _shortArray.length; i++) {
|
||||
final cir = await _shortArray.getItem(i, forceRefresh: forceRefresh);
|
||||
if (cir == null) {
|
||||
throw Exception('Failed to get short array element');
|
||||
Future<void> refresh({bool forceRefresh = false}) async {
|
||||
await _initFuture;
|
||||
await _refreshNoWait(forceRefresh: forceRefresh);
|
||||
}
|
||||
out = out.add(_decodeElement(cir));
|
||||
}
|
||||
emit(AsyncValue.data(out));
|
||||
|
||||
Future<void> _refreshNoWait({bool forceRefresh = false}) async =>
|
||||
busy((emit) async {
|
||||
await _refreshInner(emit, forceRefresh: forceRefresh);
|
||||
});
|
||||
|
||||
Future<void> _refreshInner(void Function(AsyncValue<IList<T>>) emit,
|
||||
{bool forceRefresh = false}) async {
|
||||
try {
|
||||
final newState =
|
||||
(await _shortArray.getAllItems(forceRefresh: forceRefresh))
|
||||
?.map(_decodeElement)
|
||||
.toIList();
|
||||
if (newState == null) {
|
||||
emit(const AsyncValue.loading());
|
||||
} else {
|
||||
emit(AsyncValue.data(newState));
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
emit(AsyncValue.error(e));
|
||||
}
|
||||
}
|
||||
|
||||
void _update() {
|
||||
// Run at most one background update process
|
||||
// Because this is async, we could get an update while we're
|
||||
// still processing the last one
|
||||
// still processing the last one. Only called after init future has run
|
||||
// so we dont have to wait for that here.
|
||||
_sspUpdate.busyUpdate<T, AsyncValue<IList<T>>>(busy, (emit) async {
|
||||
try {
|
||||
final initialState = await _getElementsInner();
|
||||
emit(AsyncValue.data(initialState));
|
||||
} on Exception catch (e) {
|
||||
emit(AsyncValue.error(e));
|
||||
}
|
||||
await _refreshInner(emit);
|
||||
});
|
||||
}
|
||||
|
||||
// Get and decode the entire short array
|
||||
Future<IList<T>> _getElementsInner() async {
|
||||
assert(isBusy, 'should only be called from a busy state');
|
||||
var out = IList<T>();
|
||||
for (var i = 0; i < _shortArray.length; i++) {
|
||||
// Get the element bytes (throw if fails, array state is invalid)
|
||||
final bytes = (await _shortArray.getItem(i))!;
|
||||
// Decode the element
|
||||
final elem = _decodeElement(bytes);
|
||||
// Append to the output list
|
||||
out = out.add(elem);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _initFuture;
|
||||
await _subscription?.cancel();
|
||||
_subscription = null;
|
||||
if (_wantsCloseRecord) {
|
||||
@ -94,10 +90,13 @@ class DHTShortArrayCubit<T> extends Cubit<DHTShortArrayBusyState<T>>
|
||||
await super.close();
|
||||
}
|
||||
|
||||
Future<R> operate<R>(Future<R> Function(DHTShortArray) closure) async =>
|
||||
_operateMutex.protect(() async => closure(_shortArray));
|
||||
Future<R> operate<R>(Future<R> Function(DHTShortArray) closure) async {
|
||||
await _initFuture;
|
||||
return _operateMutex.protect(() async => closure(_shortArray));
|
||||
}
|
||||
|
||||
final _operateMutex = Mutex();
|
||||
late final Future<void> _initFuture;
|
||||
late final DHTShortArray _shortArray;
|
||||
final T Function(List<int> data) _decodeElement;
|
||||
StreamSubscription<void>? _subscription;
|
||||
|
16
pubspec.lock
16
pubspec.lock
@ -251,10 +251,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: change_case
|
||||
sha256: f4e08feaa845e75e4f5ad2b0e15f24813d7ea6c27e7b78252f0c17f752cf1157
|
||||
sha256: "47c48c36f95f20c6d0ba03efabceff261d05026cca322cc2c4c01c343371b5bb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "2.0.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -423,14 +423,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
file_utils:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_utils
|
||||
sha256: d1e64389a22649095c8405c9e177272caf05139255931c9ff30d53b5c9bcaa34
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
fixnum:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1342,10 +1334,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: system_info2
|
||||
sha256: af2f948e3f31a3367a049932a8ad59faf0063ecf836a020d975b9f41566d8bc9
|
||||
sha256: "65206bbef475217008b5827374767550a5420ce70a04d2d7e94d1d2253f3efc9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
version: "4.0.0"
|
||||
system_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -20,7 +20,7 @@ dependencies:
|
||||
bloc_tools:
|
||||
path: packages/bloc_tools
|
||||
blurry_modal_progress_hud: ^1.1.1
|
||||
change_case: ^1.1.0
|
||||
change_case: ^2.0.1
|
||||
charcode: ^1.3.1
|
||||
circular_profile_avatar: ^2.0.5
|
||||
circular_reveal_animation: ^2.0.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user