consolidate icons

This commit is contained in:
Fabian Freund
2026-01-19 18:44:57 +01:00
parent 2f5260ac84
commit 21a7b85cfb
8 changed files with 100 additions and 83 deletions
@@ -29,6 +29,7 @@ import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
import 'package:weblibre/features/geckoview/features/browser/domain/entities/sheet.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/toolbar_button.dart';
import 'package:weblibre/presentation/widgets/uri_breadcrumb.dart';
class AppBarTitle extends HookConsumerWidget {
@@ -70,16 +71,14 @@ class AppBarTitle extends HookConsumerWidget {
return Row(
children: [
// Icon tap → opens site settings sheet
GestureDetector(
ToolbarButton(
onTap: () {
ref
.read(bottomSheetControllerProvider.notifier)
.show(SiteSettingsSheet(tabState: tabState));
},
child: TabIcon(tabState: tabState),
child: TabIcon(tabState: tabState, iconSize: 24),
),
const SizedBox(width: 8),
// Title/URL tap → opens search screen
Expanded(
child: GestureDetector(
@@ -45,6 +45,7 @@ import 'package:weblibre/features/geckoview/features/browser/presentation/widget
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_creation_menu.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_menu.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tabs_action_button.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/toolbar_button.dart';
import 'package:weblibre/features/geckoview/features/history/domain/repositories/history.dart';
import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
import 'package:weblibre/features/geckoview/features/readerview/presentation/widgets/reader_button.dart';
@@ -281,7 +282,7 @@ class BrowserTabBar extends HookConsumerWidget {
child: AppBar(
primary: false,
automaticallyImplyLeading: false,
titleSpacing: 8.0,
titleSpacing: 0.0,
toolbarHeight: kToolbarHeight,
backgroundColor:
(containerColor != null && displayedSheet is! ViewTabsSheet)
@@ -314,7 +315,7 @@ class BrowserTabBar extends HookConsumerWidget {
visible: tabBarReaderView || readerabilityStateActive,
child: ReaderButton(
buttonBuilder: (isLoading, readerActive, icon) =>
InkWell(
ToolbarButton(
onTap: isLoading
? null
: () async {
@@ -325,13 +326,7 @@ class BrowserTabBar extends HookConsumerWidget {
)
.toggleReaderView(!readerActive);
},
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 15.0,
horizontal: 8.0,
),
child: icon,
),
child: icon,
),
),
);
@@ -340,15 +335,15 @@ class BrowserTabBar extends HookConsumerWidget {
if (showExtensionShortcut)
ExtensionShortcutMenu(
controller: extensionMenuController,
child: IconButton(
onPressed: () {
child: ToolbarButton(
onTap: () {
if (extensionMenuController.isOpen) {
extensionMenuController.close();
} else {
extensionMenuController.open();
}
},
icon: const Icon(MdiIcons.puzzle),
child: const Icon(MdiIcons.puzzle),
),
),
if (selectedTabId != null)
@@ -356,7 +351,7 @@ class BrowserTabBar extends HookConsumerWidget {
controller: trippleDotMenuController,
selectedTabId: selectedTabId,
builder: (context, controller, child) {
return InkWell(
return ToolbarButton(
onTap: () {
if (controller.isOpen) {
controller.close();
@@ -364,13 +359,7 @@ class BrowserTabBar extends HookConsumerWidget {
controller.open();
}
},
child: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 15.0,
),
child: Icon(MdiIcons.dotsVertical),
),
child: const Icon(MdiIcons.dotsVertical),
);
},
),
@@ -31,7 +31,7 @@ class TabIcon extends HookConsumerWidget {
final double iconSize;
const TabIcon({super.key, required this.tabState, this.iconSize = 16});
const TabIcon({super.key, required this.tabState, required this.iconSize});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -175,7 +175,7 @@ class GridTabPreview extends HookConsumerWidget {
Row(
children: [
const SizedBox(width: 6.0),
TabIcon(tabState: tabState),
TabIcon(tabState: tabState, iconSize: 16.0),
const SizedBox(width: 6.0),
Expanded(
child: Text(
@@ -22,6 +22,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nullability/nullability.dart';
import 'package:skeletonizer/skeletonizer.dart';
import 'package:weblibre/core/logger.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/toolbar_button.dart';
import 'package:weblibre/features/geckoview/features/tabs/data/entities/container_filter.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/providers/selected_container.dart';
@@ -56,64 +57,61 @@ class TabsActionButton extends HookConsumerWidget {
selectedContainerDataProvider.select((value) => value.value?.color),
);
return InkWell(
return ToolbarButton(
onTap: onTap,
onDoubleTap: onDoubleTap,
onLongPress: onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 15.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: isActive
? theme.colorScheme.primary
: DefaultTextStyle.of(context).style.color!,
),
borderRadius: BorderRadius.circular(5.0),
color: containerColor.mapNotNull(ContainerColors.forAppBar),
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: isActive
? theme.colorScheme.primary
: DefaultTextStyle.of(context).style.color!,
),
constraints: const BoxConstraints(minWidth: 25.0),
child: Center(
child: tabCount.when(
skipLoadingOnReload: true,
data: (count) {
return Text(
count.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: isActive ? theme.colorScheme.primary : null,
),
);
},
loading: () => (tabCount.hasValue)
? Text(
tabCount.value.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: isActive ? theme.colorScheme.primary : null,
),
)
: const Skeletonizer(child: Text('00')),
error: (error, stackTrace) {
logger.e(
'Could not determine tab count',
error: error,
stackTrace: stackTrace,
);
borderRadius: BorderRadius.circular(5.0),
color: containerColor.mapNotNull(ContainerColors.forAppBar),
),
constraints: const BoxConstraints(minWidth: 25.0),
child: Center(
child: tabCount.when(
skipLoadingOnReload: true,
data: (count) {
return Text(
count.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: isActive ? theme.colorScheme.primary : null,
),
);
},
loading: () => (tabCount.hasValue)
? Text(
tabCount.value.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: isActive ? theme.colorScheme.primary : null,
),
)
: const Skeletonizer(child: Text('00')),
error: (error, stackTrace) {
logger.e(
'Could not determine tab count',
error: error,
stackTrace: stackTrace,
);
return Text(
'-1',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: isActive ? theme.colorScheme.primary : null,
),
);
},
),
return Text(
'-1',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: isActive ? theme.colorScheme.primary : null,
),
);
},
),
),
),
@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
class ToolbarButton extends StatelessWidget {
final Widget child;
final VoidCallback? onTap;
final VoidCallback? onDoubleTap;
final VoidCallback? onLongPress;
const ToolbarButton({
super.key,
required this.child,
this.onTap,
this.onDoubleTap,
this.onLongPress,
});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
onDoubleTap: onDoubleTap,
onLongPress: onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 15.0),
child: child,
),
);
}
}
@@ -330,7 +330,7 @@ class SearchScreen extends HookConsumerWidget {
label: (activeBang != null)
? const Text('Search')
: const Text('Address / Search'),
unfocusOnTapOutside: !isEditMode,
unfocusOnTapOutside: false,
onSubmitted: (value) async {
if (value.isNotEmpty) {
var newUrl = uri_parser.tryParseUrl(
@@ -284,7 +284,8 @@ class _BangChipsList extends HookConsumerWidget {
searchTextController.clear();
} else {
// Site tab - only clear if text is a valid URL
final hasSupportedScheme = uri_parser
final hasSupportedScheme =
uri_parser
.tryParseUrl(searchTextController.text)
.mapNotNull((uri) => uri.hasSupportedScheme) ??
false;
@@ -318,8 +319,9 @@ class _BangChipsList extends HookConsumerWidget {
WidgetRef ref,
BangData bang,
) async {
final currentSelection =
ref.read(selectedBangTriggerProvider(domain: domain));
final currentSelection = ref.read(
selectedBangTriggerProvider(domain: domain),
);
if (currentSelection == bang.toKey()) {
// Clear selection if the deleted bang is currently selected