Initial commit
This commit is contained in:
147
lib/config/themes.dart
Normal file
147
lib/config/themes.dart
Normal file
@@ -0,0 +1,147 @@
|
||||
// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
|
||||
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import 'package:tatchat/config/app_config.dart';
|
||||
import 'package:tatchat/config/tatu_palette.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:material_ui/material_ui.dart';
|
||||
|
||||
abstract class FluffyThemes {
|
||||
static const double columnWidth = 380.0;
|
||||
|
||||
static const double maxTimelineWidth = columnWidth * 2;
|
||||
|
||||
static const double navRailWidth = 80.0;
|
||||
|
||||
static bool isColumnModeByWidth(double width) =>
|
||||
width > columnWidth * 2 + navRailWidth;
|
||||
|
||||
static bool isColumnMode(BuildContext context) =>
|
||||
isColumnModeByWidth(MediaQuery.sizeOf(context).width);
|
||||
|
||||
static bool isThreeColumnMode(BuildContext context) =>
|
||||
MediaQuery.sizeOf(context).width > FluffyThemes.columnWidth * 3.5;
|
||||
|
||||
static LinearGradient backgroundGradient(BuildContext context, int alpha) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
return LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
colors: [
|
||||
colorScheme.primaryContainer.withAlpha(alpha),
|
||||
colorScheme.secondaryContainer.withAlpha(alpha),
|
||||
colorScheme.tertiaryContainer.withAlpha(alpha),
|
||||
colorScheme.primaryContainer.withAlpha(alpha),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
static const Duration animationDuration = Duration(milliseconds: 250);
|
||||
static const Curve animationCurve = Curves.easeInOut;
|
||||
|
||||
static ThemeData buildTheme(
|
||||
BuildContext context,
|
||||
Brightness brightness, [
|
||||
Color? seed,
|
||||
]) {
|
||||
final colorScheme = TatuPalette.scheme(brightness, seed);
|
||||
final isColumnMode = FluffyThemes.isColumnMode(context);
|
||||
final dividerColor = brightness == Brightness.dark
|
||||
? colorScheme.surfaceContainerHighest
|
||||
: colorScheme.surfaceContainer;
|
||||
return ThemeData(
|
||||
visualDensity: VisualDensity.standard,
|
||||
useMaterial3: true,
|
||||
brightness: brightness,
|
||||
colorScheme: colorScheme,
|
||||
dividerColor: dividerColor,
|
||||
segmentedButtonTheme: SegmentedButtonThemeData(
|
||||
style: SegmentedButton.styleFrom(
|
||||
iconColor: colorScheme.onSurface,
|
||||
disabledIconColor: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
textSelectionTheme: TextSelectionThemeData(
|
||||
selectionColor: colorScheme.onSurface.withAlpha(128),
|
||||
selectionHandleColor: colorScheme.secondary,
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2),
|
||||
),
|
||||
contentPadding: const EdgeInsets.all(12),
|
||||
),
|
||||
chipTheme: ChipThemeData(
|
||||
showCheckmark: false,
|
||||
backgroundColor: colorScheme.surfaceContainer,
|
||||
side: BorderSide.none,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
toolbarHeight: isColumnMode ? 72 : 56,
|
||||
surfaceTintColor: isColumnMode ? colorScheme.surface : null,
|
||||
backgroundColor: isColumnMode ? colorScheme.surface : null,
|
||||
actionsPadding: isColumnMode
|
||||
? const EdgeInsets.symmetric(horizontal: 16.0)
|
||||
: null,
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarIconBrightness: brightness.reversed,
|
||||
statusBarBrightness: brightness,
|
||||
systemNavigationBarIconBrightness: brightness.reversed,
|
||||
systemNavigationBarColor: colorScheme.surface,
|
||||
),
|
||||
),
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: BorderSide(width: 1, color: colorScheme.primary),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: colorScheme.primary),
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2),
|
||||
),
|
||||
),
|
||||
),
|
||||
progressIndicatorTheme: ProgressIndicatorThemeData(
|
||||
strokeCap: StrokeCap.round,
|
||||
color: colorScheme.primary,
|
||||
refreshBackgroundColor: colorScheme.primaryContainer,
|
||||
),
|
||||
snackBarTheme: isColumnMode
|
||||
? const SnackBarThemeData(
|
||||
showCloseIcon: true,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
width: FluffyThemes.columnWidth * 1.5,
|
||||
)
|
||||
: const SnackBarThemeData(behavior: SnackBarBehavior.floating),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: colorScheme.secondaryContainer,
|
||||
foregroundColor: colorScheme.onSecondaryContainer,
|
||||
elevation: 0,
|
||||
padding: const EdgeInsets.all(16),
|
||||
textStyle: const TextStyle(fontSize: 16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension on Brightness {
|
||||
Brightness get reversed =>
|
||||
this == Brightness.dark ? Brightness.light : Brightness.dark;
|
||||
}
|
||||
|
||||
extension BubbleColorTheme on ThemeData {
|
||||
Color get bubbleColor => brightness == Brightness.light
|
||||
? colorScheme.primary
|
||||
: colorScheme.primaryContainer;
|
||||
|
||||
Color get onBubbleColor => brightness == Brightness.light
|
||||
? colorScheme.onPrimary
|
||||
: colorScheme.onPrimaryContainer;
|
||||
|
||||
Color get secondaryBubbleColor => colorScheme.surfaceContainer;
|
||||
}
|
||||
Reference in New Issue
Block a user