show tunnel icon for affected tabs

This commit is contained in:
Fabian Freund
2025-11-09 08:53:44 +01:00
parent 107b2a9aa6
commit 6c57fe662d
3 changed files with 110 additions and 0 deletions
@@ -35,8 +35,12 @@ import 'package:weblibre/features/geckoview/domain/providers.dart';
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
import 'package:weblibre/features/geckoview/features/find_in_page/domain/repositories/find_in_page.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/gecko_inference.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
import 'package:weblibre/features/geckoview/utils/image_helper.dart';
import 'package:weblibre/features/user/data/models/tor_settings.dart';
import 'package:weblibre/features/user/domain/repositories/tor_settings.dart';
part 'tab_state.g.dart';
@@ -238,6 +242,37 @@ TabState? tabState(Ref ref, String? tabId) {
return ref.watch(tabStatesProvider.select((tabs) => tabs[tabId]));
}
@Riverpod()
Future<bool> isTabTunneled(Ref ref, String? tabId) async {
final tabState = ref.watch(tabStateProvider(tabId));
final torSettings = ref.watch(torSettingsWithDefaultsProvider);
if (tabState != null) {
if (tabState.isPrivate) {
return torSettings.proxyPrivateTabsTor;
} else {
switch (torSettings.proxyRegularTabsMode) {
case TorRegularTabProxyMode.container:
final containerId = await ref
.read(tabDataRepositoryProvider.notifier)
.getContainerTabId(tabState.id);
final containerData = await containerId.mapNotNull(
(containerId) => ref
.read(containerRepositoryProvider.notifier)
.getContainerData(containerId),
);
return containerData?.metadata.useProxy ?? false;
case TorRegularTabProxyMode.all:
return true;
}
}
}
return false;
}
@Riverpod()
TabState? selectedTabState(Ref ref) {
final tabId = ref.watch(selectedTabProvider);
@@ -139,6 +139,75 @@ final class TabStateFamily extends $Family
String toString() => r'tabStateProvider';
}
@ProviderFor(isTabTunneled)
const isTabTunneledProvider = IsTabTunneledFamily._();
final class IsTabTunneledProvider
extends $FunctionalProvider<AsyncValue<bool>, bool, FutureOr<bool>>
with $FutureModifier<bool>, $FutureProvider<bool> {
const IsTabTunneledProvider._({
required IsTabTunneledFamily super.from,
required String? super.argument,
}) : super(
retry: null,
name: r'isTabTunneledProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$isTabTunneledHash();
@override
String toString() {
return r'isTabTunneledProvider'
''
'($argument)';
}
@$internal
@override
$FutureProviderElement<bool> $createElement($ProviderPointer pointer) =>
$FutureProviderElement(pointer);
@override
FutureOr<bool> create(Ref ref) {
final argument = this.argument as String?;
return isTabTunneled(ref, argument);
}
@override
bool operator ==(Object other) {
return other is IsTabTunneledProvider && other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$isTabTunneledHash() => r'fd8ca366b0835eef8aea7ad64453e6a6f2e69e82';
final class IsTabTunneledFamily extends $Family
with $FunctionalFamilyOverride<FutureOr<bool>, String?> {
const IsTabTunneledFamily._()
: super(
retry: null,
name: r'isTabTunneledProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
IsTabTunneledProvider call(String? tabId) =>
IsTabTunneledProvider._(argument: tabId, from: this);
@override
String toString() => r'isTabTunneledProvider';
}
@ProviderFor(selectedTabState)
const selectedTabStateProvider = SelectedTabStateProvider._();
@@ -35,6 +35,7 @@ class AppBarTitle extends HookConsumerWidget {
final theme = Theme.of(context);
final tabState = ref.watch(selectedTabStateProvider);
final isTabTuneledAsync = ref.watch(isTabTunneledProvider(tabState?.id));
if (tabState == null) {
return const SizedBox.shrink();
@@ -98,6 +99,11 @@ class AppBarTitle extends HookConsumerWidget {
),
Row(
children: [
if (isTabTuneledAsync.hasValue &&
isTabTuneledAsync.value == true) ...[
const Icon(MdiIcons.tunnelOutline, size: 14),
const SizedBox(width: 4),
],
icon,
const SizedBox(width: 4),
Expanded(