new setting to hide tab bar title
This commit is contained in:
+135
@@ -35,6 +35,141 @@ import 'package:weblibre/features/geckoview/features/browser/presentation/widget
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
|
||||
import 'package:weblibre/presentation/widgets/uri_breadcrumb.dart';
|
||||
|
||||
class CompactAppBarTitle extends HookConsumerWidget {
|
||||
const CompactAppBarTitle({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = Theme.of(context);
|
||||
final appColors = AppColors.of(context);
|
||||
|
||||
final tabState = ref.watch(selectedTabStateProvider);
|
||||
final isTabTuneledAsync = ref.watch(isTabTunneledProvider(tabState?.id));
|
||||
final showSiteSettingsBadge = ref.watch(
|
||||
showSiteSettingsBadgeProvider.select((value) => value.value == true),
|
||||
);
|
||||
|
||||
if (tabState == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final icon = useMemoized(() {
|
||||
if (tabState.url.isHttp) {
|
||||
return Icon(
|
||||
MdiIcons.lockOff,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
size: 16,
|
||||
);
|
||||
} else if (tabState.readerableState.active) {
|
||||
return const Icon(MdiIcons.lockMinus, size: 16);
|
||||
} else if (!tabState.securityInfoState.secure) {
|
||||
return Icon(
|
||||
MdiIcons.lockAlert,
|
||||
color: Theme.of(context).colorScheme.errorContainer,
|
||||
size: 16,
|
||||
);
|
||||
} else if (!tabState.isLoading) {
|
||||
return const Icon(MdiIcons.lock, size: 16);
|
||||
} else {
|
||||
return const Icon(MdiIcons.timerSand, size: 16);
|
||||
}
|
||||
}, [tabState]);
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
ToolbarButton(
|
||||
onTap: () {
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.show(SiteSettingsSheet(tabState: tabState));
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 4.0),
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
TabIcon(tabState: tabState, iconSize: 24),
|
||||
Positioned(
|
||||
top: -4,
|
||||
right: -4,
|
||||
child: Icon(
|
||||
MdiIcons.shieldHalfFull,
|
||||
size: 10,
|
||||
color: showSiteSettingsBadge
|
||||
? appColors.warningAmber
|
||||
: Colors.green,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final searchText = tabState.url.scheme == 'about'
|
||||
? ''
|
||||
: tabState.url.toString();
|
||||
|
||||
await SearchRoute(
|
||||
tabId: tabState.id,
|
||||
searchText: searchText.isEmpty
|
||||
? SearchRoute.emptySearchText
|
||||
: searchText,
|
||||
tabType: tabState.tabMode.toTabType(),
|
||||
).push(context);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (tabState.tabMode is PrivateTabMode) ...[
|
||||
Icon(
|
||||
MdiIcons.dominoMask,
|
||||
color: appColors.privateTabPurple,
|
||||
size: 16,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
] else if (tabState.tabMode is IsolatedTabMode) ...[
|
||||
Icon(
|
||||
MdiIcons.snowflake,
|
||||
color: appColors.isolatedTabTeal,
|
||||
size: 16,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
if (isTabTuneledAsync.hasValue &&
|
||||
isTabTuneledAsync.value == true) ...[
|
||||
const Icon(MdiIcons.tunnelOutline, size: 16),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
icon,
|
||||
const SizedBox(width: 6),
|
||||
Flexible(
|
||||
child: UriBreadcrumb(
|
||||
uri: tabState.url,
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8.0),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppBarTitle extends HookConsumerWidget {
|
||||
const AppBarTitle({super.key});
|
||||
|
||||
|
||||
+3
-1
@@ -291,7 +291,9 @@ class BrowserTabBar extends HookConsumerWidget {
|
||||
: null,
|
||||
title:
|
||||
(selectedTabId != null && displayedSheet is! ViewTabsSheet)
|
||||
? const AppBarTitle()
|
||||
? settings.tabBarLayout == TabBarLayout.compact
|
||||
? const CompactAppBarTitle()
|
||||
: const AppBarTitle()
|
||||
: null,
|
||||
actions: [
|
||||
if (selectedTabId != null && displayedSheet is! ViewTabsSheet)
|
||||
|
||||
@@ -76,6 +76,7 @@ class _TabBarLayoutSection extends StatelessWidget {
|
||||
children: [
|
||||
SettingSection(name: 'Tab Bar Layout'),
|
||||
_TabBarPositionSection(),
|
||||
_TabBarLayoutModeSection(),
|
||||
_ShowContextualTabBarTile(),
|
||||
_AutoHideTabBarTile(),
|
||||
_BottomSheetTabViewTile(),
|
||||
@@ -287,6 +288,59 @@ class _TabBarPositionSection extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _TabBarLayoutModeSection extends HookConsumerWidget {
|
||||
const _TabBarLayoutModeSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final tabBarLayout = ref.watch(
|
||||
generalSettingsWithDefaultsProvider.select((s) => s.tabBarLayout),
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const ListTile(
|
||||
title: Text('Tab Bar Style'),
|
||||
leading: Icon(MdiIcons.tabUnselected),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
RadioGroup(
|
||||
groupValue: tabBarLayout,
|
||||
onChanged: (value) async {
|
||||
if (value != null) {
|
||||
await ref
|
||||
.read(saveGeneralSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) =>
|
||||
currentSettings.copyWith.tabBarLayout(value),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: const Column(
|
||||
children: [
|
||||
RadioListTile.adaptive(
|
||||
value: TabBarLayout.withTitle,
|
||||
title: Text('With Title'),
|
||||
subtitle: Text('Shows page title and URL breadcrumb'),
|
||||
),
|
||||
RadioListTile.adaptive(
|
||||
value: TabBarLayout.compact,
|
||||
title: Text('Compact'),
|
||||
subtitle: Text('Centered URL pill without page title'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ShowContextualTabBarTile extends HookConsumerWidget {
|
||||
const _ShowContextualTabBarTile();
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ enum TabIntentOpenSetting { regular, private, ask }
|
||||
|
||||
enum TabBarPosition { top, bottom }
|
||||
|
||||
enum TabBarLayout { withTitle, compact }
|
||||
|
||||
enum DeleteBrowsingDataType {
|
||||
tabs('Open tabs'),
|
||||
history('Browsing history'),
|
||||
@@ -82,6 +84,7 @@ class GeneralSettings with FastEquatable {
|
||||
final bool tabBarShowContextualBar;
|
||||
final bool tabBarShowQuickTabSwitcherBar;
|
||||
final TabBarPosition tabBarPosition;
|
||||
final TabBarLayout tabBarLayout;
|
||||
final QuickTabSwitcherMode quickTabSwitcherMode;
|
||||
final bool pullToRefreshEnabled;
|
||||
final bool useExternalDownloadManager;
|
||||
@@ -127,6 +130,7 @@ class GeneralSettings with FastEquatable {
|
||||
required this.tabBarShowContextualBar,
|
||||
required this.tabBarShowQuickTabSwitcherBar,
|
||||
required this.tabBarPosition,
|
||||
required this.tabBarLayout,
|
||||
required this.quickTabSwitcherMode,
|
||||
required this.pullToRefreshEnabled,
|
||||
required this.useExternalDownloadManager,
|
||||
@@ -173,6 +177,7 @@ class GeneralSettings with FastEquatable {
|
||||
bool? tabBarShowContextualBar,
|
||||
bool? tabBarShowQuickTabSwitcherBar,
|
||||
TabBarPosition? tabBarPosition,
|
||||
TabBarLayout? tabBarLayout,
|
||||
QuickTabSwitcherMode? quickTabSwitcherMode,
|
||||
bool? pullToRefreshEnabled,
|
||||
bool? useExternalDownloadManager,
|
||||
@@ -219,6 +224,7 @@ class GeneralSettings with FastEquatable {
|
||||
tabBarShowContextualBar = tabBarShowContextualBar ?? true,
|
||||
tabBarShowQuickTabSwitcherBar = tabBarShowQuickTabSwitcherBar ?? true,
|
||||
tabBarPosition = tabBarPosition ?? TabBarPosition.bottom,
|
||||
tabBarLayout = tabBarLayout ?? TabBarLayout.withTitle,
|
||||
quickTabSwitcherMode =
|
||||
quickTabSwitcherMode ?? QuickTabSwitcherMode.lastUsedTabs,
|
||||
pullToRefreshEnabled = pullToRefreshEnabled ?? true,
|
||||
@@ -292,6 +298,7 @@ class GeneralSettings with FastEquatable {
|
||||
tabBarShowContextualBar,
|
||||
tabBarShowQuickTabSwitcherBar,
|
||||
tabBarPosition,
|
||||
tabBarLayout,
|
||||
quickTabSwitcherMode,
|
||||
pullToRefreshEnabled,
|
||||
useExternalDownloadManager,
|
||||
|
||||
@@ -59,6 +59,8 @@ abstract class _$GeneralSettingsCWProxy {
|
||||
|
||||
GeneralSettings tabBarPosition(TabBarPosition tabBarPosition);
|
||||
|
||||
GeneralSettings tabBarLayout(TabBarLayout tabBarLayout);
|
||||
|
||||
GeneralSettings quickTabSwitcherMode(
|
||||
QuickTabSwitcherMode quickTabSwitcherMode,
|
||||
);
|
||||
@@ -140,6 +142,7 @@ abstract class _$GeneralSettingsCWProxy {
|
||||
bool tabBarShowContextualBar,
|
||||
bool tabBarShowQuickTabSwitcherBar,
|
||||
TabBarPosition tabBarPosition,
|
||||
TabBarLayout tabBarLayout,
|
||||
QuickTabSwitcherMode quickTabSwitcherMode,
|
||||
bool pullToRefreshEnabled,
|
||||
bool useExternalDownloadManager,
|
||||
@@ -260,6 +263,10 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
||||
GeneralSettings tabBarPosition(TabBarPosition tabBarPosition) =>
|
||||
call(tabBarPosition: tabBarPosition);
|
||||
|
||||
@override
|
||||
GeneralSettings tabBarLayout(TabBarLayout tabBarLayout) =>
|
||||
call(tabBarLayout: tabBarLayout);
|
||||
|
||||
@override
|
||||
GeneralSettings quickTabSwitcherMode(
|
||||
QuickTabSwitcherMode quickTabSwitcherMode,
|
||||
@@ -386,6 +393,7 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
||||
Object? tabBarShowContextualBar = const $CopyWithPlaceholder(),
|
||||
Object? tabBarShowQuickTabSwitcherBar = const $CopyWithPlaceholder(),
|
||||
Object? tabBarPosition = const $CopyWithPlaceholder(),
|
||||
Object? tabBarLayout = const $CopyWithPlaceholder(),
|
||||
Object? quickTabSwitcherMode = const $CopyWithPlaceholder(),
|
||||
Object? pullToRefreshEnabled = const $CopyWithPlaceholder(),
|
||||
Object? useExternalDownloadManager = const $CopyWithPlaceholder(),
|
||||
@@ -533,6 +541,11 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
||||
? _value.tabBarPosition
|
||||
// ignore: cast_nullable_to_non_nullable
|
||||
: tabBarPosition as TabBarPosition,
|
||||
tabBarLayout:
|
||||
tabBarLayout == const $CopyWithPlaceholder() || tabBarLayout == null
|
||||
? _value.tabBarLayout
|
||||
// ignore: cast_nullable_to_non_nullable
|
||||
: tabBarLayout as TabBarLayout,
|
||||
quickTabSwitcherMode:
|
||||
quickTabSwitcherMode == const $CopyWithPlaceholder() ||
|
||||
quickTabSwitcherMode == null
|
||||
@@ -727,6 +740,10 @@ GeneralSettings _$GeneralSettingsFromJson(
|
||||
_$TabBarPositionEnumMap,
|
||||
json['tabBarPosition'],
|
||||
),
|
||||
tabBarLayout: $enumDecodeNullable(
|
||||
_$TabBarLayoutEnumMap,
|
||||
json['tabBarLayout'],
|
||||
),
|
||||
quickTabSwitcherMode: $enumDecodeNullable(
|
||||
_$QuickTabSwitcherModeEnumMap,
|
||||
json['quickTabSwitcherMode'],
|
||||
@@ -795,6 +812,7 @@ Map<String, dynamic> _$GeneralSettingsToJson(
|
||||
'tabBarShowContextualBar': instance.tabBarShowContextualBar,
|
||||
'tabBarShowQuickTabSwitcherBar': instance.tabBarShowQuickTabSwitcherBar,
|
||||
'tabBarPosition': _$TabBarPositionEnumMap[instance.tabBarPosition]!,
|
||||
'tabBarLayout': _$TabBarLayoutEnumMap[instance.tabBarLayout]!,
|
||||
'quickTabSwitcherMode':
|
||||
_$QuickTabSwitcherModeEnumMap[instance.quickTabSwitcherMode]!,
|
||||
'pullToRefreshEnabled': instance.pullToRefreshEnabled,
|
||||
@@ -868,6 +886,11 @@ const _$TabBarPositionEnumMap = {
|
||||
TabBarPosition.bottom: 'bottom',
|
||||
};
|
||||
|
||||
const _$TabBarLayoutEnumMap = {
|
||||
TabBarLayout.withTitle: 'withTitle',
|
||||
TabBarLayout.compact: 'compact',
|
||||
};
|
||||
|
||||
const _$QuickTabSwitcherModeEnumMap = {
|
||||
QuickTabSwitcherMode.lastUsedTabs: 'lastUsedTabs',
|
||||
QuickTabSwitcherMode.containerTabs: 'containerTabs',
|
||||
|
||||
@@ -126,6 +126,10 @@ class GeneralSettingsRepository extends _$GeneralSettingsRepository {
|
||||
DriftSqlType.string,
|
||||
db.typeMapping,
|
||||
),
|
||||
'tabBarLayout': settings['tabBarLayout']?.readAs(
|
||||
DriftSqlType.string,
|
||||
db.typeMapping,
|
||||
),
|
||||
'quickTabSwitcherMode': settings['quickTabSwitcherMode']?.readAs(
|
||||
DriftSqlType.string,
|
||||
db.typeMapping,
|
||||
|
||||
@@ -35,7 +35,7 @@ final class GeneralSettingsRepositoryProvider
|
||||
}
|
||||
|
||||
String _$generalSettingsRepositoryHash() =>
|
||||
r'2e987b58279ea638157324a03403dfac8437b888';
|
||||
r'23b15af79f0f41771c20f7c0f7e94f93659ee1e8';
|
||||
|
||||
abstract class _$GeneralSettingsRepository
|
||||
extends $StreamNotifier<GeneralSettings> {
|
||||
|
||||
Reference in New Issue
Block a user