provider lifecycle hardenings

This commit is contained in:
Fabian Freund
2026-05-06 18:32:45 +02:00
parent d5f977a3d2
commit fee15cb8d2
25 changed files with 246 additions and 94 deletions
@@ -39,6 +39,10 @@ class WebExtensionsState extends _$WebExtensionsState {
: _imageCache = LRUCache(50, onEvict: (image) => image.dispose());
void _onExtensionUpdate(ExtensionDataEvent event) {
if (!ref.mounted) {
return;
}
final ExtensionDataEvent(:extensionId, :data) = event;
if (data != null) {
@@ -81,6 +85,11 @@ class WebExtensionsState extends _$WebExtensionsState {
final image = await tryDecodeImage(bytes);
if (!ref.mounted) {
image?.dispose();
return;
}
if (image != null) {
// set() will evict the old entry via onEvict callback, which handles disposal
_imageCache.set(extensionId, image);
@@ -185,13 +194,13 @@ class WebExtensionsState extends _$WebExtensionsState {
},
);
ref.onDispose(() async {
ref.onDispose(() {
// Dispose all cached images
_imageCache.clear();
// Cancel all stream subscriptions
for (final sub in subscriptions) {
await sub.cancel();
unawaited(sub.cancel());
}
});
@@ -62,7 +62,7 @@ final class WebExtensionsStateProvider
}
String _$webExtensionsStateHash() =>
r'13cbbea409b5b643eb6766689f6b23a4d1701204';
r'e067323e9a0a466e46e0c4d529667950ee62d4ca';
final class WebExtensionsStateFamily extends $Family
with
@@ -784,8 +784,9 @@ class TabRepository extends _$TabRepository {
final containerSiteAssignementSub = eventSerivce.siteAssignementEvent.listen(
(event) async {
if (event.tabId != null) {
final tabState = ref.read(tabStatesProvider)[event.tabId];
final tabId = event.tabId;
if (tabId != null) {
final tabState = ref.read(tabStatesProvider)[tabId];
if (tabState != null) {
final uri = Uri.parse(event.url);
final originUri = event.originUrl.mapNotNull(Uri.parse);
@@ -793,52 +794,81 @@ class TabRepository extends _$TabRepository {
final targetContainerId = await ref
.read(containerRepositoryProvider.notifier)
.siteAssignedContainerId(Uri.parse(uri.origin));
if (!ref.mounted) {
return;
}
final containerData = await targetContainerId.mapNotNull(
(id) => ref
.read(containerRepositoryProvider.notifier)
.getContainerData(id),
);
if (!ref.mounted) {
return;
}
if (containerData != null) {
final currentTabState = ref.read(tabStatesProvider)[tabId];
if (currentTabState == null) {
logger.w('Could not get tab for assignement ${event.url}');
return;
}
final tabIsEmpty =
tabState.url == TabState.defaultUrl &&
tabState.historyState.items.isEmpty;
currentTabState.url == TabState.defaultUrl &&
currentTabState.historyState.items.isEmpty;
if (event.blocked || tabIsEmpty) {
await addTab(
url: uri,
tabMode: tabState.tabMode,
tabMode: currentTabState.tabMode,
containerSelection: TabContainerSelection.specific(
containerData,
),
parentId: tabState.id,
parentId: currentTabState.id,
selectTab: true,
);
if (tabState.historyState.items.isEmpty) {
await closeTab(tabState.id);
if (!ref.mounted) {
return;
}
if (currentTabState.historyState.items.isEmpty) {
await closeTab(currentTabState.id);
}
} else {
final tabContainerId = await ref
.read(tabDataRepositoryProvider.notifier)
.getTabContainerId(tabState.id);
.getTabContainerId(currentTabState.id);
if (!ref.mounted) {
return;
}
final latestTabState = ref.read(tabStatesProvider)[tabId];
if (latestTabState == null) {
logger.w('Could not get tab for assignement ${event.url}');
return;
}
if (targetContainerId != tabContainerId) {
if (originUri == null) {
await ref
.read(tabDataRepositoryProvider.notifier)
.assignContainer(tabState.id, containerData);
} else if (tabState.url == originUri) {
.assignContainer(latestTabState.id, containerData);
} else if (latestTabState.url == originUri) {
await ref
.read(tabDataRepositoryProvider.notifier)
.assignContainer(
tabState.id,
latestTabState.id,
containerData,
closeOldTab: false,
);
} else {
logger.w(
'Could not match origin url for assignment ${tabState.url} to request ${event.originUrl}',
'Could not match origin url for assignment ${latestTabState.url} to request ${event.originUrl}',
);
}
}
@@ -41,7 +41,7 @@ final class TabRepositoryProvider
}
}
String _$tabRepositoryHash() => r'a68941d373f348201e3d8b1cab26343acca3852f';
String _$tabRepositoryHash() => r'f458baaf9061143a668470dccd57f32664728951';
abstract class _$TabRepository extends $Notifier<void> {
void build();