reorganize app colors

This commit is contained in:
Fabian Freund
2026-01-11 19:05:18 +01:00
parent edbc157c46
commit 01d145bd72
17 changed files with 152 additions and 62 deletions
+76 -12
View File
@@ -1,21 +1,85 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AppColors { @immutable
AppColors._(); class AppColors extends ThemeExtension<AppColors> {
const AppColors._({
this.seedColor = const Color(0xFF167C80),
this.privateTabPurple = const Color(0xFF8000D7),
this.privateTabBackground = const Color(0xFF25003E),
this.privateSelectionOverlay = const Color(0x648000D7),
this.torPurple = const Color(0xFF7D4698),
this.torActiveGreen = const Color(0xFF68B030),
this.torBackgroundGrey = const Color(0xFF333A41),
});
static const Color seedColor = Color(0xFF167C80); final Color seedColor;
final Color privateTabPurple;
final Color privateTabBackground;
final Color privateSelectionOverlay;
final Color torPurple;
final Color torActiveGreen;
final Color torBackgroundGrey;
static const Color privateTabPurple = Color(0xFF8000D7); static const light = AppColors._();
static const dark = AppColors._();
static const Color privateTabBackground = Color(0xFF25003E); @override
AppColors copyWith({
Color? seedColor,
Color? privateTabPurple,
Color? privateTabBackground,
Color? privateSelectionOverlay,
Color? torPurple,
Color? torActiveGreen,
Color? torBackgroundGrey,
}) {
return AppColors._(
seedColor: seedColor ?? this.seedColor,
privateTabPurple: privateTabPurple ?? this.privateTabPurple,
privateTabBackground: privateTabBackground ?? this.privateTabBackground,
privateSelectionOverlay:
privateSelectionOverlay ?? this.privateSelectionOverlay,
torPurple: torPurple ?? this.torPurple,
torActiveGreen: torActiveGreen ?? this.torActiveGreen,
torBackgroundGrey: torBackgroundGrey ?? this.torBackgroundGrey,
);
}
static const Color privateSelectionOverlay = Color(0x648000D7); @override
AppColors lerp(covariant ThemeExtension<AppColors>? other, double t) {
if (other is! AppColors) {
return this;
}
static const Color torPurple = Color(0xFF7D4698); return AppColors._(
seedColor: Color.lerp(seedColor, other.seedColor, t)!,
privateTabPurple: Color.lerp(
privateTabPurple,
other.privateTabPurple,
t,
)!,
privateTabBackground: Color.lerp(
privateTabBackground,
other.privateTabBackground,
t,
)!,
privateSelectionOverlay: Color.lerp(
privateSelectionOverlay,
other.privateSelectionOverlay,
t,
)!,
torPurple: Color.lerp(torPurple, other.torPurple, t)!,
torActiveGreen: Color.lerp(torActiveGreen, other.torActiveGreen, t)!,
torBackgroundGrey: Color.lerp(
torBackgroundGrey,
other.torBackgroundGrey,
t,
)!,
);
}
static const Color torActiveGreen = Color(0xFF68B030); /// Get AppColors from the current theme
static AppColors of(BuildContext context) {
static const Color torBackgroundGrey = Color(0xFF333A41); return Theme.of(context).extension<AppColors>() ?? light;
}
static const Color dialogOverlay = Color(0x44000000);
} }
+2 -2
View File
@@ -24,10 +24,10 @@ 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) => AppColors.seedColor; Color lightSeedColorFallback(Ref ref) => AppColors.light.seedColor;
@Riverpod(keepAlive: true) @Riverpod(keepAlive: true)
Color darkSeedColorFallback(Ref ref) => AppColors.seedColor; Color darkSeedColorFallback(Ref ref) => AppColors.dark.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'd5fb3ead5795c1cadd6c3a5f91ef84c3cbdaa3c1'; r'851efdcb11e4367ea2e54f1884a73fd4cd841d4a';
@ProviderFor(darkSeedColorFallback) @ProviderFor(darkSeedColorFallback)
final darkSeedColorFallbackProvider = DarkSeedColorFallbackProvider._(); final darkSeedColorFallbackProvider = DarkSeedColorFallbackProvider._();
@@ -91,7 +91,7 @@ final class DarkSeedColorFallbackProvider
} }
String _$darkSeedColorFallbackHash() => String _$darkSeedColorFallbackHash() =>
r'a383dbf6edf4fee54a8215bc52a98f26354e4645'; r'161a8c4318108c31d5c300441bc3332d08c24496';
@ProviderFor(docsUri) @ProviderFor(docsUri)
final docsUriProvider = DocsUriProvider._(); final docsUriProvider = DocsUriProvider._();
@@ -21,6 +21,7 @@ import 'package:flutter/material.dart';
import 'package:pretty_qr_code/pretty_qr_code.dart'; import 'package:pretty_qr_code/pretty_qr_code.dart';
Future<void> showQrCode(BuildContext context, String data) { Future<void> showQrCode(BuildContext context, String data) {
final colorScheme = Theme.of(context).colorScheme;
return showDialog( return showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
@@ -39,9 +40,9 @@ Future<void> showQrCode(BuildContext context, String data) {
Container( Container(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: colorScheme.surface,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey.shade300), border: Border.all(color: colorScheme.outline),
), ),
child: PrettyQrView.data( child: PrettyQrView.data(
data: data, data: data,
@@ -27,7 +27,6 @@ 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';
@@ -83,7 +82,7 @@ class TabTreeDialog extends HookConsumerWidget {
return Dialog.fullscreen( return Dialog.fullscreen(
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
backgroundColor: AppColors.dialogOverlay, backgroundColor: Theme.of(context).colorScheme.surface,
elevation: 0, elevation: 0,
leading: const CloseButton(), leading: const CloseButton(),
), ),
@@ -44,8 +44,8 @@ import 'package:weblibre/features/geckoview/features/browser/presentation/contro
import 'package:weblibre/features/geckoview/features/browser/presentation/controllers/tab_view_controllers.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/controllers/tab_view_controllers.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/browser_fab.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/browser_fab.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/draggable_fab.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/browser_view.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/browser_view.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/draggable_fab.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/sheets/view_tab.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/sheets/view_tab.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_grid_view.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_grid_view.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_list_view.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_list_view.dart';
@@ -183,8 +183,9 @@ class _TabBar extends HookConsumerWidget {
useOnStreamChange( useOnStreamChange(
pointerMoveEvents, pointerMoveEvents,
onData: (event) { onData: (event) {
if (!ref.read(generalSettingsWithDefaultsProvider).autoHideTabBar) if (!ref.read(generalSettingsWithDefaultsProvider).autoHideTabBar) {
return; return;
}
final diff = event.dy; final diff = event.dy;
if (diff < 0) { if (diff < 0) {
if (diffAcc.value > 0) { if (diffAcc.value > 0) {
@@ -502,6 +503,7 @@ class _SheetContainer extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final colorScheme = Theme.of(context).colorScheme;
// Memoize maxChildSize to prevent keyboard from affecting sheet size // Memoize maxChildSize to prevent keyboard from affecting sheet size
final stableMaxChildSize = useMemoized(() => relativeSafeArea, []); final stableMaxChildSize = useMemoized(() => relativeSafeArea, []);
@@ -520,7 +522,7 @@ class _SheetContainer extends HookConsumerWidget {
ref.read(bottomSheetControllerProvider.notifier).requestDismiss(); ref.read(bottomSheetControllerProvider.notifier).requestDismiss();
}, },
child: ColoredBox( child: ColoredBox(
color: Colors.black54, // Scrim color: colorScheme.scrim,
child: GestureDetector( child: GestureDetector(
onTap: () {}, // Prevent tap from propagating to parent onTap: () {}, // Prevent tap from propagating to parent
child: Align( child: Align(
@@ -34,6 +34,7 @@ class AppBarTitle extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context); final theme = Theme.of(context);
final appColors = AppColors.of(context);
final tabState = ref.watch(selectedTabStateProvider); final tabState = ref.watch(selectedTabStateProvider);
final isTabTuneledAsync = ref.watch(isTabTunneledProvider(tabState?.id)); final isTabTuneledAsync = ref.watch(isTabTunneledProvider(tabState?.id));
@@ -108,9 +109,9 @@ class AppBarTitle extends HookConsumerWidget {
icon, icon,
const SizedBox(width: 4), const SizedBox(width: 4),
if (tabState.isPrivate) ...[ if (tabState.isPrivate) ...[
const Icon( Icon(
MdiIcons.dominoMask, MdiIcons.dominoMask,
color: AppColors.privateTabPurple, color: appColors.privateTabPurple,
size: 14, size: 14,
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
@@ -482,6 +482,7 @@ class QuickTabSwitcher extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final appColors = AppColors.of(context);
final selectedTabId = ref.watch(selectedTabProvider); final selectedTabId = ref.watch(selectedTabProvider);
final tabStates = (switch (quickTabSwitcherMode) { final tabStates = (switch (quickTabSwitcherMode) {
@@ -521,11 +522,11 @@ class QuickTabSwitcher extends HookConsumerWidget {
child: Text(item.title), child: Text(item.title),
), ),
if (item.isPrivate) if (item.isPrivate)
const Padding( Padding(
padding: EdgeInsets.only(left: 8.0), padding: const EdgeInsets.only(left: 8.0),
child: Icon( child: Icon(
MdiIcons.dominoMask, MdiIcons.dominoMask,
color: AppColors.privateTabPurple, color: appColors.privateTabPurple,
size: 20, size: 20,
), ),
), ),
@@ -834,7 +835,7 @@ class NavigationMenuButton extends HookConsumerWidget {
return Badge( return Badge(
isLabelVisible: torConnected, isLabelVisible: torConnected,
backgroundColor: AppColors.torActiveGreen, backgroundColor: AppColors.of(context).torActiveGreen,
child: child, child: child,
); );
}, },
@@ -97,6 +97,7 @@ class _BrowserViewState extends ConsumerState<BrowserView>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final initializationCompleter = useMemoized(() => Completer()); final initializationCompleter = useMemoized(() => Completer());
useOnInitialization(() async { useOnInitialization(() async {
@@ -313,7 +314,9 @@ class _BrowserViewState extends ConsumerState<BrowserView>
), ),
if (!hasTab) if (!hasTab)
Positioned.fill( Positioned.fill(
child: SizedBox.expand(child: Container(color: Colors.grey[800])), child: SizedBox.expand(
child: Container(color: colorScheme.surfaceContainerHighest),
),
), ),
], ],
), ),
@@ -41,6 +41,7 @@ class _TabDraggable extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final colorScheme = Theme.of(context).colorScheme;
final activeTab = ref.watch(selectedTabProvider); final activeTab = ref.watch(selectedTabProvider);
final dragData = ref.watch( final dragData = ref.watch(
@@ -102,7 +103,7 @@ class _TabDraggable extends HookConsumerWidget {
DeleteDropData() => Opacity( DeleteDropData() => Opacity(
opacity: 0.3, opacity: 0.3,
child: ColorFiltered( child: ColorFiltered(
colorFilter: const ColorFilter.mode(Colors.red, BlendMode.modulate), colorFilter: ColorFilter.mode(colorScheme.error, BlendMode.modulate),
child: tab, child: tab,
), ),
), ),
@@ -51,6 +51,7 @@ class GridTabItemContainer extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final appColors = AppColors.of(context);
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -62,7 +63,7 @@ class GridTabItemContainer extends StatelessWidget {
), ),
child: Material( child: Material(
color: isPrivate color: isPrivate
? AppColors.privateTabBackground ? 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,
@@ -97,6 +98,9 @@ class GridTabPreview extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final colorScheme = Theme.of(context).colorScheme;
final appColors = AppColors.of(context);
final tabState = final tabState =
ref.watch( ref.watch(
tabStateWithFallbackProvider( tabStateWithFallbackProvider(
@@ -127,7 +131,7 @@ class GridTabPreview extends HookConsumerWidget {
tabState.titleOrAuthority, tabState.titleOrAuthority,
maxLines: 2, maxLines: 2,
style: tabState.isPrivate style: tabState.isPrivate
? const TextStyle(color: Colors.white) ? TextStyle(color: colorScheme.onSurface)
: null, : null,
), ),
), ),
@@ -178,13 +182,13 @@ class GridTabPreview extends HookConsumerWidget {
child: Text( child: Text(
tabState.url.authority, tabState.url.authority,
style: Theme.of(context).textTheme.bodySmall?.copyWith( style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: tabState.isPrivate ? Colors.white : null, color: tabState.isPrivate ? colorScheme.onSurface : null,
), ),
), ),
), ),
if (tabState.isPrivate) ...[ if (tabState.isPrivate) ...[
const SizedBox(width: 6.0), const SizedBox(width: 6.0),
const SizedBox( SizedBox(
height: 16, height: 16,
width: 24, width: 24,
child: Stack( child: Stack(
@@ -194,7 +198,7 @@ class GridTabPreview extends HookConsumerWidget {
top: -4, top: -4,
child: Icon( child: Icon(
MdiIcons.dominoMask, MdiIcons.dominoMask,
color: AppColors.privateTabPurple, color: appColors.privateTabPurple,
), ),
), ),
], ],
@@ -259,6 +263,7 @@ class ListTabPreview extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final appColors = AppColors.of(context);
final tabState = final tabState =
ref.watch( ref.watch(
@@ -272,7 +277,7 @@ class ListTabPreview extends HookConsumerWidget {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: tabState.isPrivate ? AppColors.privateTabBackground : 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)),
), ),
@@ -297,15 +302,15 @@ class ListTabPreview extends HookConsumerWidget {
tabState.titleOrAuthority, tabState.titleOrAuthority,
maxLines: 2, maxLines: 2,
style: tabState.isPrivate style: tabState.isPrivate
? const TextStyle(color: Colors.white) ? TextStyle(color: colorScheme.onSurface)
: null, : null,
), ),
subtitle: Row( subtitle: Row(
children: [ children: [
if (tabState.isPrivate) ...[ if (tabState.isPrivate) ...[
const Icon( Icon(
MdiIcons.dominoMask, MdiIcons.dominoMask,
color: AppColors.privateTabPurple, color: appColors.privateTabPurple,
size: 14, size: 14,
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
@@ -314,7 +319,7 @@ class ListTabPreview extends HookConsumerWidget {
child: UriBreadcrumb( child: UriBreadcrumb(
uri: tabState.url, uri: tabState.url,
style: Theme.of(context).textTheme.bodySmall?.copyWith( style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: tabState.isPrivate ? Colors.white : null, color: tabState.isPrivate ? colorScheme.onSurface : null,
), ),
), ),
), ),
@@ -55,6 +55,7 @@ class SearchScreen extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final appColors = AppColors.of(context);
final formKey = useMemoized(() => GlobalKey<FormState>()); final formKey = useMemoized(() => GlobalKey<FormState>());
final createChildTabsOption = ref.watch( final createChildTabsOption = ref.watch(
@@ -190,13 +191,13 @@ class SearchScreen extends HookConsumerWidget {
TabType.regular => null, TabType.regular => null,
TabType.private => SegmentedButton.styleFrom( TabType.private => SegmentedButton.styleFrom(
selectedBackgroundColor: selectedBackgroundColor:
AppColors.privateSelectionOverlay, appColors.privateSelectionOverlay,
), ),
TabType.child => TabType.child =>
(currentTabTabType == TabType.private) (currentTabTabType == TabType.private)
? SegmentedButton.styleFrom( ? SegmentedButton.styleFrom(
selectedBackgroundColor: selectedBackgroundColor:
AppColors.privateSelectionOverlay, appColors.privateSelectionOverlay,
) )
: null, : null,
}, },
@@ -143,6 +143,7 @@ class _NewTabDefaultSection extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final appColors = AppColors.of(context);
final defaultCreateTabType = ref.watch( final defaultCreateTabType = ref.watch(
generalSettingsWithDefaultsProvider.select((s) => s.defaultCreateTabType), generalSettingsWithDefaultsProvider.select((s) => s.defaultCreateTabType),
); );
@@ -193,7 +194,7 @@ class _NewTabDefaultSection extends HookConsumerWidget {
style: switch (defaultCreateTabType) { style: switch (defaultCreateTabType) {
TabType.regular => null, TabType.regular => null,
TabType.private => SegmentedButton.styleFrom( TabType.private => SegmentedButton.styleFrom(
selectedBackgroundColor: AppColors.privateSelectionOverlay, selectedBackgroundColor: appColors.privateSelectionOverlay,
), ),
TabType.child => null, TabType.child => null,
}, },
@@ -210,6 +211,7 @@ class _ExternalLinkHandlingSection extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final appColors = AppColors.of(context);
final tabIntentOpenSetting = ref.watch( final tabIntentOpenSetting = ref.watch(
generalSettingsWithDefaultsProvider.select((s) => s.tabIntentOpenSetting), generalSettingsWithDefaultsProvider.select((s) => s.tabIntentOpenSetting),
); );
@@ -265,7 +267,7 @@ class _ExternalLinkHandlingSection extends HookConsumerWidget {
style: switch (tabIntentOpenSetting) { style: switch (tabIntentOpenSetting) {
TabIntentOpenSetting.regular => null, TabIntentOpenSetting.regular => null,
TabIntentOpenSetting.private => SegmentedButton.styleFrom( TabIntentOpenSetting.private => SegmentedButton.styleFrom(
selectedBackgroundColor: AppColors.privateSelectionOverlay, selectedBackgroundColor: appColors.privateSelectionOverlay,
), ),
TabIntentOpenSetting.ask => null, TabIntentOpenSetting.ask => null,
}, },
@@ -37,6 +37,7 @@ class TorProxyScreen extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final appColors = AppColors.of(context);
final bootstrapProgress = ref.watch( final bootstrapProgress = ref.watch(
torProxyServiceProvider.select( torProxyServiceProvider.select(
(value) => value.value?.bootstrapProgress ?? 0, (value) => value.value?.bootstrapProgress ?? 0,
@@ -125,7 +126,7 @@ class TorProxyScreen extends HookConsumerWidget {
Set<WidgetState> states, Set<WidgetState> states,
) { ) {
if (states.isEmpty) { if (states.isEmpty) {
return AppColors.torBackgroundGrey; return appColors.torBackgroundGrey;
} }
return null; // Use the default color. return null; // Use the default color.
}), }),
@@ -147,20 +148,20 @@ class TorProxyScreen extends HookConsumerWidget {
fillColor: WidgetStateColor.resolveWith((states) { fillColor: WidgetStateColor.resolveWith((states) {
return Colors.white; return Colors.white;
}), }),
checkColor: WidgetStateProperty.all(AppColors.torPurple), checkColor: WidgetStateProperty.all(appColors.torPurple),
), ),
iconTheme: const IconThemeData(color: Colors.white), iconTheme: const IconThemeData(color: Colors.white),
), ),
child: SafeArea( child: SafeArea(
child: ColoredBox( child: ColoredBox(
color: AppColors.torPurple, color: appColors.torPurple,
child: CustomScrollView( child: CustomScrollView(
slivers: [ slivers: [
SliverAppBar( SliverAppBar(
pinned: true, pinned: true,
title: SwitchListTile.adaptive( title: SwitchListTile.adaptive(
inactiveThumbColor: Colors.white, inactiveThumbColor: Colors.white,
activeThumbColor: AppColors.torActiveGreen, activeThumbColor: appColors.torActiveGreen,
thumbIcon: WidgetStateProperty.resolveWith<Icon?>(( thumbIcon: WidgetStateProperty.resolveWith<Icon?>((
Set<WidgetState> states, Set<WidgetState> states,
) { ) {
@@ -199,8 +200,8 @@ class TorProxyScreen extends HookConsumerWidget {
children: [ children: [
if (torPendingRequest.value != false && torIsBusy) if (torPendingRequest.value != false && torIsBusy)
LinearProgressIndicator( LinearProgressIndicator(
backgroundColor: AppColors.torBackgroundGrey, backgroundColor: appColors.torBackgroundGrey,
color: AppColors.torActiveGreen, color: appColors.torActiveGreen,
value: bootstrapProgress / 100, value: bootstrapProgress / 100,
), ),
Padding( Padding(
@@ -289,7 +290,7 @@ class TorProxyScreen extends HookConsumerWidget {
SwitchListTile.adaptive( SwitchListTile.adaptive(
inactiveThumbColor: Colors.white, inactiveThumbColor: Colors.white,
activeThumbColor: AppColors.torActiveGreen, activeThumbColor: appColors.torActiveGreen,
thumbIcon: WidgetStateProperty.resolveWith<Icon?>(( thumbIcon: WidgetStateProperty.resolveWith<Icon?>((
Set<WidgetState> states, Set<WidgetState> states,
) { ) {
@@ -327,7 +328,7 @@ class TorProxyScreen extends HookConsumerWidget {
), ),
SwitchListTile.adaptive( SwitchListTile.adaptive(
inactiveThumbColor: Colors.white, inactiveThumbColor: Colors.white,
activeThumbColor: AppColors.torActiveGreen, activeThumbColor: appColors.torActiveGreen,
thumbIcon: WidgetStateProperty.resolveWith<Icon?>(( thumbIcon: WidgetStateProperty.resolveWith<Icon?>((
Set<WidgetState> states, Set<WidgetState> states,
) { ) {
@@ -362,7 +363,7 @@ class TorProxyScreen extends HookConsumerWidget {
if (torSettings.config == TorConnectionConfig.auto) ...[ if (torSettings.config == TorConnectionConfig.auto) ...[
SwitchListTile.adaptive( SwitchListTile.adaptive(
inactiveThumbColor: Colors.white, inactiveThumbColor: Colors.white,
activeThumbColor: AppColors.torActiveGreen, activeThumbColor: appColors.torActiveGreen,
value: torSettings.requireBridge, value: torSettings.requireBridge,
contentPadding: const EdgeInsets.only( contentPadding: const EdgeInsets.only(
left: 56, left: 56,
@@ -27,8 +27,9 @@ class TorDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final appColors = AppColors.of(context);
return AlertDialog( return AlertDialog(
icon: const Icon(TorIcons.onionAlt, color: AppColors.torPurple), icon: 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.',
@@ -28,6 +28,8 @@ import 'package:weblibre/presentation/widgets/animate_gradient_shader.dart';
class TorNotification extends HookConsumerWidget { class TorNotification extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final appColors = AppColors.of(context);
ref.listen(torProxyServiceProvider, (previous, next) { ref.listen(torProxyServiceProvider, (previous, next) {
if (next.hasValue & next.requireValue.isRunning && if (next.hasValue & next.requireValue.isRunning &&
next.requireValue.bootstrapProgress == 100) { next.requireValue.bootstrapProgress == 100) {
@@ -37,7 +39,7 @@ class TorNotification extends HookConsumerWidget {
return SafeArea( return SafeArea(
child: ColoredBox( child: ColoredBox(
color: AppColors.torPurple, color: appColors.torPurple,
child: SizedBox( child: SizedBox(
height: 56 + 12, height: 56 + 12,
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
@@ -52,9 +54,9 @@ 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 [ primaryColors: [
AppColors.torActiveGreen, appColors.torActiveGreen,
AppColors.torActiveGreen, appColors.torActiveGreen,
], ],
secondaryColors: const [Colors.white, Colors.white], secondaryColors: const [Colors.white, Colors.white],
child: const Padding( child: const Padding(
@@ -87,8 +89,8 @@ class TorNotification extends HookConsumerWidget {
); );
return LinearProgressIndicator( return LinearProgressIndicator(
backgroundColor: AppColors.torBackgroundGrey, backgroundColor: AppColors.of(context).torBackgroundGrey,
color: AppColors.torActiveGreen, color: AppColors.of(context).torActiveGreen,
value: bootstrapProgress / 100, value: bootstrapProgress / 100,
); );
}, },
+7 -1
View File
@@ -30,6 +30,7 @@ import 'package:flutter_mozilla_components/flutter_mozilla_components.dart'
import 'package:home_widget/home_widget.dart'; import 'package:home_widget/home_widget.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/core/error_observer.dart'; import 'package:weblibre/core/error_observer.dart';
import 'package:weblibre/core/filesystem.dart'; import 'package:weblibre/core/filesystem.dart';
import 'package:weblibre/core/logger.dart'; import 'package:weblibre/core/logger.dart';
@@ -141,10 +142,15 @@ class _MainWidget extends HookConsumerWidget {
return MainApp( return MainApp(
key: rootKey, key: rootKey,
theme: ThemeData(useMaterial3: true, colorScheme: lightColorScheme), theme: ThemeData(
useMaterial3: true,
colorScheme: lightColorScheme,
extensions: const <ThemeExtension<dynamic>>[AppColors.light],
),
darkTheme: ThemeData( darkTheme: ThemeData(
useMaterial3: true, useMaterial3: true,
colorScheme: darkColorScheme, colorScheme: darkColorScheme,
extensions: const <ThemeExtension<dynamic>>[AppColors.dark],
), ),
themeMode: themeMode, themeMode: themeMode,
); );