From 00bf76b0ba3e9b00f844b344958d7145826bac7e Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Fri, 27 Feb 2026 20:34:10 +0100 Subject: [PATCH] update icons and tab order --- app/assets/fonts/WebLibre.ttf | Bin 2076 -> 53 bytes app/lib/extensions/uri.dart | 3 +- .../browser_modules/app_bar_title.dart | 16 +++---- .../browser_modules/bottom_app_bar.dart | 2 +- .../widgets/tab_creation_menu.dart | 40 +++++++++-------- .../presentation/widgets/tab_menu.dart | 8 ++-- .../widgets/tab_view/tab_preview.dart | 4 +- .../widgets/tab_view/tab_view_header.dart | 2 +- .../dialogs/open_shared_content.dart | 5 ++- .../widgets/animated_tab_type_switcher.dart | 41 +++++++++--------- .../screens/tabs_behavior_settings.dart | 34 ++++++++++----- app/lib/utils/uri_policy.dart | 4 +- 12 files changed, 89 insertions(+), 70 deletions(-) mode change 100644 => 120000 app/assets/fonts/WebLibre.ttf diff --git a/app/assets/fonts/WebLibre.ttf b/app/assets/fonts/WebLibre.ttf deleted file mode 100644 index 89261e910eebc1db8f55a0c96defe91fa5837789..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2076 zcmd^A%}-oa6hHU9H}4HIQ|5#D09s+@J(xj?^94g|qolS9#L!s#1{#e92Y3UN`EqzA zP!rRY8=KY`U6C|)p%@o#y3xegE{rbKqziY}g^3{s6B83d0{FX^M=aR?zQJ8f@_;Gm}4SObkK40sW2HYN_%5_||98|3-Uz zzOq(c{os{9h~(=;(%A*8G?#u-eh0n}(S{d5XrIcz1Am3qvrx5HwI6_pan4t%&z9%` zi(~vMba%D1+F;$Z4tqQFc&${m;ve1$6S?kV{%E7VY`^v0I`*Rd1p9fy-sRtb4*GkX zIaFl9fc^f(smiqfnZL-pKjPPqf5tjQ2U5N#FF|#a2NkgWZb@=0lp3*BpN`&Uf7g~iRdC&K5_sO z5rbE#NBAh5-<0-{gH6VJ==)J%ZpNedzZaiKK%bKaWMz|QjAv71j%N>8oCGAl`{I6y z+b5GoJ_=BnIw+2e_u&MxRG_EnS$d9MrWv|P)HYZ!B4~xdg03=vUbI-j2uE2Wk|+!% zW$2veGRSd$Sa=IE#tlhT3r7d@r$*RNDw#_5sv2q}9F2h-E~HsZPo-HZscWrFQw=?p zEDVjX!F&u3v1tC(Ft3C8E*1%EYQM>gk!2T5bN4RCSvk0Smwl8qK=@2^qlhA{8(EmR z!zab!Yn^@S;E7Y7J%ncQS=D&SUpnxrU_+pD;P zea2)igC_{*MdF!5*5T2M+d9lJ#GeXboPK6 zvuakeWLtCbnYH-x%6#6o%kgrvUX72|YqnLX)Z>k2{faefrx$FyaVC=~JA8V!UZu-q z;d`2(Mf6SJOK9_Sl`2$%e$;wYpMrOjmNB|cHGHc%O5-*h^%{d$O?Z~bhMa@v46UJG zrWLG~2WwLqdKt6TsR}eIX5`)#)H;}kuw4N&3-2^7h*1qXLmAZa5&ty2_)P!4G5kO4 faYbellbJ%^MsslmiJZ1eGhVdmdc#Jpmoerakv}Qx diff --git a/app/assets/fonts/WebLibre.ttf b/app/assets/fonts/WebLibre.ttf new file mode 120000 index 00000000..cca22d83 --- /dev/null +++ b/app/assets/fonts/WebLibre.ttf @@ -0,0 +1 @@ +../../../font/src/assets/generated-icons/WebLibre.ttf \ No newline at end of file diff --git a/app/lib/extensions/uri.dart b/app/lib/extensions/uri.dart index e1c969e6..8308f37b 100644 --- a/app/lib/extensions/uri.dart +++ b/app/lib/extensions/uri.dart @@ -23,7 +23,8 @@ import 'package:weblibre/utils/uri_policy.dart'; extension UriX on Uri { Uri get base => Uri.parse('$scheme://$authority'); - bool get hasSupportedScheme => allSupportedSchemes.any((s) => s.name == scheme); + bool get hasSupportedScheme => + allSupportedSchemes.any((s) => s.name == scheme); bool get isHttp => isScheme('http'); bool get isHttps => isScheme('https'); diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/app_bar_title.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/app_bar_title.dart index f7e61231..c483bc4f 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/app_bar_title.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/app_bar_title.dart @@ -152,13 +152,6 @@ 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), if (tabState.tabMode is PrivateTabMode) ...[ Icon( MdiIcons.dominoMask, @@ -168,12 +161,19 @@ class AppBarTitle extends HookConsumerWidget { const SizedBox(width: 4), ] else if (tabState.tabMode is IsolatedTabMode) ...[ Icon( - MdiIcons.shieldLock, + MdiIcons.snowflake, color: appColors.isolatedTabTeal, size: 14, ), const SizedBox(width: 4), ], + if (isTabTuneledAsync.hasValue && + isTabTuneledAsync.value == true) ...[ + const Icon(MdiIcons.tunnelOutline, size: 14), + const SizedBox(width: 4), + ], + icon, + const SizedBox(width: 4), Expanded( child: UriBreadcrumb( uri: tabState.url, diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart index e40d2920..a2907414 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart @@ -553,7 +553,7 @@ class QuickTabSwitcher extends HookConsumerWidget { Padding( padding: const EdgeInsets.only(left: 8.0), child: Icon( - MdiIcons.shieldLock, + MdiIcons.snowflake, color: appColors.isolatedTabTeal, size: 20, ), diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_creation_menu.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_creation_menu.dart index 0c8d7d9a..dacb6ca1 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_creation_menu.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_creation_menu.dart @@ -23,7 +23,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:weblibre/core/design/app_colors.dart'; import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/features/user/domain/repositories/general_settings.dart'; -import 'package:weblibre/presentation/icons/weblibre_icons.dart'; class TabCreationMenu extends HookConsumerWidget { final Widget child; @@ -61,24 +60,6 @@ class TabCreationMenu extends HookConsumerWidget { leadingIcon: const Icon(MdiIcons.tab), child: const Text('Add Regular Tab'), ), - MenuItemButton( - onPressed: () async { - await const SearchRoute(tabType: TabType.private).push(context); - }, - leadingIcon: const Icon(WebLibreIcons.privateTab), - child: const Text('Add Private Tab'), - ), - if (showIsolatedTabUi) - MenuItemButton( - onPressed: () async { - await const SearchRoute(tabType: TabType.isolated).push(context); - }, - leadingIcon: Icon( - MdiIcons.shieldLock, - color: AppColors.of(context).isolatedTabTeal, - ), - child: const Text('Add Isolated Tab'), - ), if (createChildTabsOption) MenuItemButton( onPressed: () async { @@ -87,6 +68,27 @@ class TabCreationMenu extends HookConsumerWidget { leadingIcon: const Icon(MdiIcons.fileTree), child: const Text('Add Child Tab'), ), + MenuItemButton( + onPressed: () async { + await const SearchRoute(tabType: TabType.private).push(context); + }, + leadingIcon: Icon( + MdiIcons.dominoMask, + color: AppColors.of(context).privateTabPurple, + ), + child: const Text('Add Private Tab'), + ), + if (showIsolatedTabUi) + MenuItemButton( + onPressed: () async { + await const SearchRoute(tabType: TabType.isolated).push(context); + }, + leadingIcon: Icon( + MdiIcons.snowflake, + color: AppColors.of(context).isolatedTabTeal, + ), + child: const Text('Add Isolated Tab'), + ), ], child: child, ); diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_menu.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_menu.dart index fa5e8cff..6289d226 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_menu.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_menu.dart @@ -50,7 +50,6 @@ import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/co import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart'; import 'package:weblibre/features/user/domain/repositories/general_settings.dart'; import 'package:weblibre/presentation/hooks/menu_controller.dart'; -import 'package:weblibre/presentation/icons/weblibre_icons.dart'; import 'package:weblibre/presentation/widgets/website_feed_menu_button.dart'; import 'package:weblibre/utils/ui_helper.dart' as ui_helper; @@ -273,7 +272,10 @@ class TabMenu extends HookConsumerWidget { }, ), MenuItemButton( - leadingIcon: const Icon(WebLibreIcons.privateTab), + leadingIcon: Icon( + MdiIcons.dominoMask, + color: AppColors.of(context).privateTabPurple, + ), child: const Text('Private'), onPressed: () async { final tabState = ref.read(tabStateProvider(selectedTabId))!; @@ -318,7 +320,7 @@ class TabMenu extends HookConsumerWidget { if (settings.showIsolatedTabUi) MenuItemButton( leadingIcon: Icon( - MdiIcons.shieldLock, + MdiIcons.snowflake, color: AppColors.of(context).isolatedTabTeal, ), child: const Text('Isolated'), diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_preview.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_preview.dart index b2358e22..f1b5b91b 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_preview.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_preview.dart @@ -233,7 +233,7 @@ class GridTabPreview extends HookConsumerWidget { top: -4, child: Icon( tabState.tabMode is IsolatedTabMode - ? MdiIcons.shieldLock + ? MdiIcons.snowflake : MdiIcons.dominoMask, color: tabState.tabMode is IsolatedTabMode ? appColors.isolatedTabTeal @@ -337,7 +337,7 @@ class ListTabPreview extends HookConsumerWidget { }; final (modeBadgeIcon, modeBadgeColor) = switch (tabState.tabMode) { PrivateTabMode() => (MdiIcons.dominoMask, appColors.privateTabPurple), - IsolatedTabMode() => (MdiIcons.shieldLock, appColors.isolatedTabTeal), + IsolatedTabMode() => (MdiIcons.snowflake, appColors.isolatedTabTeal), RegularTabMode() => (null, null), }; diff --git a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_header.dart b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_header.dart index 35e9710f..56f78762 100644 --- a/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_header.dart +++ b/app/lib/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_header.dart @@ -516,7 +516,7 @@ class TabViewHeader extends HookConsumerWidget { if (showIsolatedTabUi) MenuItemButton( leadingIcon: Icon( - MdiIcons.shieldLock, + MdiIcons.snowflake, color: AppColors.of(context).isolatedTabTeal, ), onPressed: isSyncedScope diff --git a/app/lib/features/geckoview/features/open_link_tools/presentation/dialogs/open_shared_content.dart b/app/lib/features/geckoview/features/open_link_tools/presentation/dialogs/open_shared_content.dart index bcc872e7..2a8838ec 100644 --- a/app/lib/features/geckoview/features/open_link_tools/presentation/dialogs/open_shared_content.dart +++ b/app/lib/features/geckoview/features/open_link_tools/presentation/dialogs/open_shared_content.dart @@ -42,6 +42,7 @@ import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/c import 'package:weblibre/features/user/domain/repositories/general_settings.dart'; import 'package:weblibre/presentation/hooks/cached_future.dart'; import 'package:weblibre/presentation/hooks/debouncer.dart'; +import 'package:weblibre/presentation/icons/weblibre_icons.dart'; import 'package:weblibre/utils/form_validators.dart'; import 'package:weblibre/utils/ui_helper.dart'; @@ -381,7 +382,7 @@ class OpenSharedContent extends HookConsumerWidget { subtitle: 'Add to your browser tabs', icon: MdiIcons.tab, trailing: PopupMenuButton( - icon: const Icon(MdiIcons.tabUnselected, size: 24), + icon: const Icon(WebLibreIcons.tabType, size: 24), tooltip: settings.showIsolatedTabUi ? 'Private / Isolated' : 'Private', @@ -407,7 +408,7 @@ class OpenSharedContent extends HookConsumerWidget { child: Row( children: [ Icon( - MdiIcons.shieldLock, + MdiIcons.snowflake, color: appColors.isolatedTabTeal, size: 20, ), diff --git a/app/lib/features/geckoview/features/search/presentation/widgets/animated_tab_type_switcher.dart b/app/lib/features/geckoview/features/search/presentation/widgets/animated_tab_type_switcher.dart index 655c7f5e..23182da7 100644 --- a/app/lib/features/geckoview/features/search/presentation/widgets/animated_tab_type_switcher.dart +++ b/app/lib/features/geckoview/features/search/presentation/widgets/animated_tab_type_switcher.dart @@ -20,7 +20,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; import 'package:weblibre/core/routing/routes.dart'; -import 'package:weblibre/presentation/icons/weblibre_icons.dart'; /// An animated tab type switcher that only shows the label for the currently /// active option. Inactive options collapse to show only their icon. @@ -65,26 +64,6 @@ class AnimatedTabTypeSwitcher extends StatelessWidget { selectedBackgroundColor: selectedBackgroundColor, onTap: () => onChanged(TabType.regular), ), - _divider(borderColor), - _Segment( - tabType: TabType.private, - icon: WebLibreIcons.privateTab, - label: 'Private', - isSelected: selected == TabType.private, - selectedBackgroundColor: selectedBackgroundColor, - onTap: () => onChanged(TabType.private), - ), - if (showIsolatedOption) ...[ - _divider(borderColor), - _Segment( - tabType: TabType.isolated, - icon: MdiIcons.shieldLock, - label: 'Isolated', - isSelected: selected == TabType.isolated, - selectedBackgroundColor: selectedBackgroundColor, - onTap: () => onChanged(TabType.isolated), - ), - ], if (showChildOption) ...[ _divider(borderColor), _Segment( @@ -96,6 +75,26 @@ class AnimatedTabTypeSwitcher extends StatelessWidget { onTap: () => onChanged(TabType.child), ), ], + _divider(borderColor), + _Segment( + tabType: TabType.private, + icon: MdiIcons.dominoMask, + label: 'Private', + isSelected: selected == TabType.private, + selectedBackgroundColor: selectedBackgroundColor, + onTap: () => onChanged(TabType.private), + ), + if (showIsolatedOption) ...[ + _divider(borderColor), + _Segment( + tabType: TabType.isolated, + icon: MdiIcons.snowflake, + label: 'Isolated', + isSelected: selected == TabType.isolated, + selectedBackgroundColor: selectedBackgroundColor, + onTap: () => onChanged(TabType.isolated), + ), + ], ], ), ), diff --git a/app/lib/features/settings/presentation/screens/tabs_behavior_settings.dart b/app/lib/features/settings/presentation/screens/tabs_behavior_settings.dart index 115a6360..d8a6977d 100644 --- a/app/lib/features/settings/presentation/screens/tabs_behavior_settings.dart +++ b/app/lib/features/settings/presentation/screens/tabs_behavior_settings.dart @@ -30,7 +30,6 @@ import 'package:weblibre/features/settings/presentation/controllers/save_setting import 'package:weblibre/features/settings/presentation/widgets/sections.dart'; import 'package:weblibre/features/user/data/models/general_settings.dart'; import 'package:weblibre/features/user/domain/repositories/general_settings.dart'; -import 'package:weblibre/presentation/icons/weblibre_icons.dart'; class TabsBehaviorSettingsScreen extends StatelessWidget { const TabsBehaviorSettingsScreen({super.key}); @@ -137,17 +136,22 @@ class _NewTabDefaultSection extends HookConsumerWidget { label: Text('Regular'), icon: Icon(MdiIcons.tab), ), - const ButtonSegment( + ButtonSegment( value: TabType.private, - label: Text('Private'), - icon: Icon(WebLibreIcons.privateTab), + label: const Text('Private'), + icon: Icon( + MdiIcons.dominoMask, + color: defaultCreateTabType == TabType.private + ? null + : appColors.privateTabPurple, + ), ), if (settings.showIsolatedTabUi) ButtonSegment( value: TabType.isolated, label: const Text('Isolated'), icon: Icon( - MdiIcons.shieldLock, + MdiIcons.snowflake, color: defaultCreateTabType == TabType.isolated ? null : appColors.isolatedTabTeal, @@ -206,21 +210,26 @@ class _ExternalLinkHandlingSection extends HookConsumerWidget { Center( child: SegmentedButton( showSelectedIcon: false, - segments: const [ - ButtonSegment( + segments: [ + const ButtonSegment( value: TabIntentOpenSetting.ask, label: Text('Prompt'), icon: Icon(MdiIcons.messageQuestion), ), - ButtonSegment( + const ButtonSegment( value: TabIntentOpenSetting.regular, label: Text('Regular'), icon: Icon(MdiIcons.tab), ), ButtonSegment( value: TabIntentOpenSetting.private, - label: Text('Private'), - icon: Icon(WebLibreIcons.privateTab), + label: const Text('Private'), + icon: Icon( + MdiIcons.dominoMask, + color: tabIntentOpenSetting == TabIntentOpenSetting.private + ? null + : appColors.privateTabPurple, + ), ), ], selected: {tabIntentOpenSetting}, @@ -326,7 +335,10 @@ class _ShowIsolatedTabUiTile extends HookConsumerWidget { return SwitchListTile.adaptive( title: const Text('Show Isolated Tab UI'), subtitle: const Text('Show isolated-tab creation options in the UI'), - secondary: const Icon(MdiIcons.shieldLock), + secondary: Icon( + MdiIcons.snowflake, + color: AppColors.of(context).isolatedTabTeal, + ), value: showIsolatedTabUi, onChanged: (value) async { await ref.read(saveGeneralSettingsControllerProvider.notifier).save(( diff --git a/app/lib/utils/uri_policy.dart b/app/lib/utils/uri_policy.dart index 296bb9e6..42aa759d 100644 --- a/app/lib/utils/uri_policy.dart +++ b/app/lib/utils/uri_policy.dart @@ -45,7 +45,9 @@ const allSupportedSchemes = [ const httpOnlySchemes = [kSchemeHttp, kSchemeHttps]; bool schemeRequiresAuthority(String scheme) { - return allSupportedSchemes.any((s) => s.name == scheme && s.requiresAuthority); + return allSupportedSchemes.any( + (s) => s.name == scheme && s.requiresAuthority, + ); } enum SchemePolicy {