properly organize custom colors

This commit is contained in:
Fabian Freund
2026-01-01 09:07:53 +01:00
parent 7a85176fb2
commit d448087122
14 changed files with 63 additions and 34 deletions
+21
View File
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
class AppColors {
AppColors._();
static const Color seedColor = Color(0xFF167C80);
static const Color privateTabPurple = Color(0xFF8000D7);
static const Color privateTabBackground = Color(0xFF25003E);
static const Color privateSelectionOverlay = Color(0x648000D7);
static const Color torPurple = Color(0xFF7D4698);
static const Color torActiveGreen = Color(0xFF68B030);
static const Color torBackgroundGrey = Color(0xFF333A41);
static const Color dialogOverlay = Color(0x44000000);
}
+3 -2
View File
@@ -19,14 +19,15 @@
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:weblibre/core/design/app_colors.dart';
part 'defaults.g.dart'; part 'defaults.g.dart';
@Riverpod(keepAlive: true) @Riverpod(keepAlive: true)
Color lightSeedColorFallback(Ref ref) => const Color(0xFF167C80); Color lightSeedColorFallback(Ref ref) => AppColors.seedColor;
@Riverpod(keepAlive: true) @Riverpod(keepAlive: true)
Color darkSeedColorFallback(Ref ref) => const Color(0xFF167C80); Color darkSeedColorFallback(Ref ref) => AppColors.seedColor;
@Riverpod(keepAlive: true) @Riverpod(keepAlive: true)
Uri docsUri(Ref ref) => Uri.parse('https://docs.weblibre.eu/'); Uri docsUri(Ref ref) => Uri.parse('https://docs.weblibre.eu/');
+2 -2
View File
@@ -49,7 +49,7 @@ final class LightSeedColorFallbackProvider
} }
String _$lightSeedColorFallbackHash() => String _$lightSeedColorFallbackHash() =>
r'af151d3293d372f5df451aa8c3a75136377b6ce1'; r'd5fb3ead5795c1cadd6c3a5f91ef84c3cbdaa3c1';
@ProviderFor(darkSeedColorFallback) @ProviderFor(darkSeedColorFallback)
const darkSeedColorFallbackProvider = DarkSeedColorFallbackProvider._(); const darkSeedColorFallbackProvider = DarkSeedColorFallbackProvider._();
@@ -91,7 +91,7 @@ final class DarkSeedColorFallbackProvider
} }
String _$darkSeedColorFallbackHash() => String _$darkSeedColorFallbackHash() =>
r'9418cf71e3d80c8a2142e0d3a8820989b29bff86'; r'a383dbf6edf4fee54a8215bc52a98f26354e4645';
@ProviderFor(docsUri) @ProviderFor(docsUri)
const docsUriProvider = DocsUriProvider._(); const docsUriProvider = DocsUriProvider._();
@@ -27,6 +27,7 @@ import 'package:graphview/GraphView.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nullability/nullability.dart'; import 'package:nullability/nullability.dart';
import 'package:skeletonizer/skeletonizer.dart'; import 'package:skeletonizer/skeletonizer.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart'; import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart';
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart'; import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
@@ -82,7 +83,7 @@ class TabTreeDialog extends HookConsumerWidget {
return Dialog.fullscreen( return Dialog.fullscreen(
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
backgroundColor: const Color(0x44000000), backgroundColor: AppColors.dialogOverlay,
elevation: 0, elevation: 0,
leading: const CloseButton(), leading: const CloseButton(),
), ),
@@ -23,6 +23,7 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:skeletonizer/skeletonizer.dart'; import 'package:skeletonizer/skeletonizer.dart';
import 'package:text_scroll/text_scroll.dart'; import 'package:text_scroll/text_scroll.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart'; import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
import 'package:weblibre/presentation/widgets/uri_breadcrumb.dart'; import 'package:weblibre/presentation/widgets/uri_breadcrumb.dart';
@@ -109,7 +110,7 @@ class AppBarTitle extends HookConsumerWidget {
if (tabState.isPrivate) ...[ if (tabState.isPrivate) ...[
const Icon( const Icon(
MdiIcons.dominoMask, MdiIcons.dominoMask,
color: Color(0xFF8000D7), color: AppColors.privateTabPurple,
size: 14, size: 14,
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
@@ -25,6 +25,7 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart'; import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; 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/core/routing/routes.dart';
import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart'; import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart';
import 'package:weblibre/features/geckoview/domain/entities/states/readerable.dart'; import 'package:weblibre/features/geckoview/domain/entities/states/readerable.dart';
@@ -475,7 +476,7 @@ class QuickTabSwitcher extends HookConsumerWidget {
padding: EdgeInsets.only(left: 8.0), padding: EdgeInsets.only(left: 8.0),
child: Icon( child: Icon(
MdiIcons.dominoMask, MdiIcons.dominoMask,
color: Color(0xFF8000D7), color: AppColors.privateTabPurple,
size: 20, size: 20,
), ),
), ),
@@ -777,7 +778,7 @@ class NavigationMenuButton extends HookConsumerWidget {
return Badge( return Badge(
isLabelVisible: torConnected, isLabelVisible: torConnected,
backgroundColor: const Color(0xFF68B030), backgroundColor: AppColors.torActiveGreen,
child: child, child: child,
); );
}, },
@@ -24,6 +24,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nullability/nullability.dart'; import 'package:nullability/nullability.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/features/geckoview/domain/entities/states/tab.dart'; import 'package:weblibre/features/geckoview/domain/entities/states/tab.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart'; import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart'; import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
@@ -61,7 +62,7 @@ class GridTabItemContainer extends StatelessWidget {
), ),
child: Material( child: Material(
color: isPrivate color: isPrivate
? const Color(0xFF25003E) ? AppColors.privateTabBackground
: colorScheme.surfaceContainerHighest, : colorScheme.surfaceContainerHighest,
borderRadius: const BorderRadius.all(Radius.circular(14.0)), borderRadius: const BorderRadius.all(Radius.circular(14.0)),
child: child, child: child,
@@ -193,7 +194,7 @@ class GridTabPreview extends HookConsumerWidget {
top: -4, top: -4,
child: Icon( child: Icon(
MdiIcons.dominoMask, MdiIcons.dominoMask,
color: Color(0xFF8000D7), color: AppColors.privateTabPurple,
), ),
), ),
], ],
@@ -271,7 +272,7 @@ class ListTabPreview extends HookConsumerWidget {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: tabState.isPrivate ? const Color(0xFF25003E) : null, color: tabState.isPrivate ? AppColors.privateTabBackground : null,
border: isActive ? Border.all(color: colorScheme.primary) : null, border: isActive ? Border.all(color: colorScheme.primary) : null,
borderRadius: const BorderRadius.all(Radius.circular(4.0)), borderRadius: const BorderRadius.all(Radius.circular(4.0)),
), ),
@@ -304,7 +305,7 @@ class ListTabPreview extends HookConsumerWidget {
if (tabState.isPrivate) ...[ if (tabState.isPrivate) ...[
const Icon( const Icon(
MdiIcons.dominoMask, MdiIcons.dominoMask,
color: Color(0xFF8000D7), color: AppColors.privateTabPurple,
size: 14, size: 14,
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
@@ -22,6 +22,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; 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/core/routing/routes.dart';
import 'package:weblibre/features/bangs/data/models/bang_data.dart'; import 'package:weblibre/features/bangs/data/models/bang_data.dart';
import 'package:weblibre/features/bangs/domain/providers/bangs.dart'; import 'package:weblibre/features/bangs/domain/providers/bangs.dart';
@@ -172,14 +173,12 @@ class SearchScreen extends HookConsumerWidget {
style: switch (selectedTabType.value) { style: switch (selectedTabType.value) {
TabType.regular => null, TabType.regular => null,
TabType.private => SegmentedButton.styleFrom( TabType.private => SegmentedButton.styleFrom(
selectedBackgroundColor: const Color(0x648000D7), selectedBackgroundColor: AppColors.privateSelectionOverlay,
), ),
TabType.child => TabType.child =>
(currentTabTabType == TabType.private) (currentTabTabType == TabType.private)
? SegmentedButton.styleFrom( ? SegmentedButton.styleFrom(
selectedBackgroundColor: const Color( selectedBackgroundColor: AppColors.privateSelectionOverlay,
0x648000D7,
),
) )
: null, : null,
}, },
@@ -132,7 +132,7 @@ class _MaterialPickerState extends State<MaterialPicker> {
setState(() => _currentColorType = colors); setState(() => _currentColorType = colors);
}, },
child: Container( child: Container(
color: const Color(0x00000000), color: Colors.transparent,
padding: isPortrait padding: isPortrait
? const EdgeInsets.fromLTRB(0, 7, 0, 7) ? const EdgeInsets.fromLTRB(0, 7, 0, 7)
: const EdgeInsets.fromLTRB(7, 0, 7, 0), : const EdgeInsets.fromLTRB(7, 0, 7, 0),
@@ -217,7 +217,7 @@ class _MaterialPickerState extends State<MaterialPicker> {
widget.onColorChanged(color); widget.onColorChanged(color);
}, },
child: Container( child: Container(
color: const Color(0x00000000), color: Colors.transparent,
margin: isPortrait margin: isPortrait
? const EdgeInsets.only(right: 10) ? const EdgeInsets.only(right: 10)
: const EdgeInsets.only(bottom: 10), : const EdgeInsets.only(bottom: 10),
@@ -118,7 +118,7 @@ List<Map<Color, String>> shadingTypes(List<Color> colors) {
].map((int shade) => {colorType[shade]!: shade.toString()}).toList(), ].map((int shade) => {colorType[shade]!: shade.toString()}).toList(),
); );
} else { } else {
result.add({const Color(0x00000000): ''}); result.add({Colors.transparent: ''});
} }
} }
@@ -23,6 +23,7 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nullability/nullability.dart'; import 'package:nullability/nullability.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/search/domain/entities/abstract/i_search_suggestion_provider.dart'; import 'package:weblibre/features/search/domain/entities/abstract/i_search_suggestion_provider.dart';
import 'package:weblibre/features/settings/presentation/controllers/save_settings.dart'; import 'package:weblibre/features/settings/presentation/controllers/save_settings.dart';
@@ -144,7 +145,7 @@ class GeneralSettingsScreen extends HookConsumerWidget {
style: switch (generalSettings.defaultCreateTabType) { style: switch (generalSettings.defaultCreateTabType) {
TabType.regular => null, TabType.regular => null,
TabType.private => SegmentedButton.styleFrom( TabType.private => SegmentedButton.styleFrom(
selectedBackgroundColor: const Color(0x648000D7), selectedBackgroundColor: AppColors.privateSelectionOverlay,
), ),
TabType.child => null, TabType.child => null,
}, },
@@ -205,7 +206,7 @@ class GeneralSettingsScreen extends HookConsumerWidget {
TabIntentOpenSetting.regular => null, TabIntentOpenSetting.regular => null,
TabIntentOpenSetting.private => TabIntentOpenSetting.private =>
SegmentedButton.styleFrom( SegmentedButton.styleFrom(
selectedBackgroundColor: const Color(0x648000D7), selectedBackgroundColor: AppColors.privateSelectionOverlay,
), ),
TabIntentOpenSetting.ask => null, TabIntentOpenSetting.ask => null,
}, },
@@ -21,6 +21,7 @@ import 'package:fading_scroll/fading_scroll.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/features/settings/presentation/controllers/save_settings.dart'; import 'package:weblibre/features/settings/presentation/controllers/save_settings.dart';
import 'package:weblibre/features/tor/domain/services/tor_proxy.dart'; import 'package:weblibre/features/tor/domain/services/tor_proxy.dart';
import 'package:weblibre/features/user/data/models/tor_settings.dart'; import 'package:weblibre/features/user/data/models/tor_settings.dart';
@@ -60,7 +61,7 @@ class TorProxyScreen extends HookConsumerWidget {
Set<WidgetState> states, Set<WidgetState> states,
) { ) {
if (states.isEmpty) { if (states.isEmpty) {
return const Color(0xFF333A41); return AppColors.torBackgroundGrey;
} }
return null; // Use the default color. return null; // Use the default color.
}), }),
@@ -86,7 +87,7 @@ class TorProxyScreen extends HookConsumerWidget {
), ),
child: SafeArea( child: SafeArea(
child: ColoredBox( child: ColoredBox(
color: const Color(0xFF7D4698), color: AppColors.torPurple,
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 16), const SizedBox(height: 16),
@@ -100,7 +101,7 @@ class TorProxyScreen extends HookConsumerWidget {
), ),
child: SwitchListTile.adaptive( child: SwitchListTile.adaptive(
inactiveThumbColor: Colors.white, inactiveThumbColor: Colors.white,
activeThumbColor: const Color(0xFF68B030), activeThumbColor: AppColors.torActiveGreen,
thumbIcon: WidgetStateProperty.resolveWith<Icon?>(( thumbIcon: WidgetStateProperty.resolveWith<Icon?>((
Set<WidgetState> states, Set<WidgetState> states,
) { ) {
@@ -189,7 +190,7 @@ class TorProxyScreen extends HookConsumerWidget {
SwitchListTile.adaptive( SwitchListTile.adaptive(
inactiveThumbColor: Colors.white, inactiveThumbColor: Colors.white,
activeThumbColor: const Color(0xFF68B030), activeThumbColor: AppColors.torActiveGreen,
thumbIcon: thumbIcon:
WidgetStateProperty.resolveWith<Icon?>(( WidgetStateProperty.resolveWith<Icon?>((
Set<WidgetState> states, Set<WidgetState> states,
@@ -234,7 +235,7 @@ class TorProxyScreen extends HookConsumerWidget {
), ),
SwitchListTile.adaptive( SwitchListTile.adaptive(
inactiveThumbColor: Colors.white, inactiveThumbColor: Colors.white,
activeThumbColor: const Color(0xFF68B030), activeThumbColor: AppColors.torActiveGreen,
thumbIcon: thumbIcon:
WidgetStateProperty.resolveWith<Icon?>(( WidgetStateProperty.resolveWith<Icon?>((
Set<WidgetState> states, Set<WidgetState> states,
@@ -284,7 +285,7 @@ class TorProxyScreen extends HookConsumerWidget {
TorConnectionConfig.auto) ...[ TorConnectionConfig.auto) ...[
SwitchListTile.adaptive( SwitchListTile.adaptive(
inactiveThumbColor: Colors.white, inactiveThumbColor: Colors.white,
activeThumbColor: const Color(0xFF68B030), activeThumbColor: AppColors.torActiveGreen,
value: torSettings.requireBridge, value: torSettings.requireBridge,
contentPadding: const EdgeInsets.only( contentPadding: const EdgeInsets.only(
left: 56, left: 56,
@@ -418,8 +419,8 @@ class TorProxyScreen extends HookConsumerWidget {
children: [ children: [
SizedBox(height: 8), SizedBox(height: 8),
LinearProgressIndicator( LinearProgressIndicator(
backgroundColor: Color(0xFF333A41), backgroundColor: AppColors.torBackgroundGrey,
color: Color(0xFF68B030), color: AppColors.torActiveGreen,
), ),
SizedBox(height: 8), SizedBox(height: 8),
Text( Text(
@@ -436,14 +437,14 @@ class TorProxyScreen extends HookConsumerWidget {
children: [ children: [
const Icon( const Icon(
MdiIcons.shieldLockOutline, MdiIcons.shieldLockOutline,
color: Color(0xFF68B030), color: AppColors.torActiveGreen,
size: 32, size: 32,
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
Text( Text(
'Connected to the Tor Network', 'Connected to the Tor Network',
style: Theme.of(context).textTheme.titleMedium style: Theme.of(context).textTheme.titleMedium
?.copyWith(color: const Color(0xFF68B030)), ?.copyWith(color: AppColors.torActiveGreen),
), ),
], ],
), ),
@@ -19,13 +19,14 @@
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/presentation/icons/tor_icons.dart'; import 'package:weblibre/presentation/icons/tor_icons.dart';
class TorDialog extends StatelessWidget { class TorDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
icon: const Icon(TorIcons.onionAlt, color: Color(0xFF7D4698)), icon: const Icon(TorIcons.onionAlt, color: AppColors.torPurple),
title: const Text('Tor™ Proxy'), title: const Text('Tor™ Proxy'),
content: const Text( content: const Text(
'This container requires a Tor proxy for secure connections, which is not currently running.', 'This container requires a Tor proxy for secure connections, which is not currently running.',
@@ -19,6 +19,7 @@
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/features/geckoview/domain/controllers/overlay.dart'; import 'package:weblibre/features/geckoview/domain/controllers/overlay.dart';
import 'package:weblibre/features/tor/domain/services/tor_proxy.dart'; import 'package:weblibre/features/tor/domain/services/tor_proxy.dart';
import 'package:weblibre/presentation/icons/tor_icons.dart'; import 'package:weblibre/presentation/icons/tor_icons.dart';
@@ -35,7 +36,7 @@ class TorNotification extends HookConsumerWidget {
return SafeArea( return SafeArea(
child: ColoredBox( child: ColoredBox(
color: const Color(0xFF7D4698), color: AppColors.torPurple,
child: SizedBox( child: SizedBox(
height: 56, height: 56,
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
@@ -47,7 +48,7 @@ class TorNotification extends HookConsumerWidget {
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
primaryEnd: Alignment.bottomLeft, primaryEnd: Alignment.bottomLeft,
secondaryEnd: Alignment.topRight, secondaryEnd: Alignment.topRight,
primaryColors: const [Color(0xFF68B030), Color(0xFF68B030)], primaryColors: const [AppColors.torActiveGreen, AppColors.torActiveGreen],
secondaryColors: const [Colors.white, Colors.white], secondaryColors: const [Colors.white, Colors.white],
child: const Padding( child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 12), padding: EdgeInsets.symmetric(horizontal: 12),