mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-19 12:24:53 -04:00
chore: don't use theme extension
This commit is contained in:
parent
74caa39655
commit
8b303b7e9d
6 changed files with 199 additions and 88 deletions
|
@ -19,6 +19,7 @@ import 'package:appflowy/workspace/application/view/view_ext.dart';
|
|||
import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
|
@ -233,22 +234,34 @@ class _ApplicationWidgetState extends State<ApplicationWidget> {
|
|||
supportedLocales: context.supportedLocales,
|
||||
locale: state.locale,
|
||||
routerConfig: routerConfig,
|
||||
builder: (context, child) => MediaQuery(
|
||||
// use the 1.0 as the textScaleFactor to avoid the text size
|
||||
// affected by the system setting.
|
||||
data: MediaQuery.of(context).copyWith(
|
||||
textScaler: TextScaler.linear(state.textScaleFactor),
|
||||
),
|
||||
child: overlayManagerBuilder(
|
||||
context,
|
||||
!UniversalPlatform.isMobile && FeatureFlag.search.isOn
|
||||
? CommandPalette(
|
||||
notifier: _commandPaletteNotifier,
|
||||
child: child,
|
||||
)
|
||||
: child,
|
||||
),
|
||||
),
|
||||
builder: (context, child) {
|
||||
final themeBuilder = AppFlowyDefaultTheme();
|
||||
final brightness = Theme.of(context).brightness;
|
||||
|
||||
return AppFlowyTheme(
|
||||
data: brightness == Brightness.light
|
||||
? themeBuilder.light()
|
||||
: themeBuilder.dark(),
|
||||
child: MediaQuery(
|
||||
// use the 1.0 as the textScaleFactor to avoid the text size
|
||||
// affected by the system setting.
|
||||
data: MediaQuery.of(context).copyWith(
|
||||
textScaler:
|
||||
TextScaler.linear(state.textScaleFactor),
|
||||
),
|
||||
child: overlayManagerBuilder(
|
||||
context,
|
||||
!UniversalPlatform.isMobile &&
|
||||
FeatureFlag.search.isOn
|
||||
? CommandPalette(
|
||||
notifier: _commandPaletteNotifier,
|
||||
child: child,
|
||||
)
|
||||
: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
|
@ -46,8 +45,6 @@ class DesktopAppearance extends BaseAppearance {
|
|||
shadow: theme.shadow,
|
||||
);
|
||||
|
||||
final newThemeBuilder = AppFlowyDefaultTheme();
|
||||
|
||||
// Due to Desktop version has multiple themes, it relies on the current theme to build the ThemeData
|
||||
return ThemeData(
|
||||
visualDensity: VisualDensity.standard,
|
||||
|
@ -154,9 +151,6 @@ class DesktopAppearance extends BaseAppearance {
|
|||
lightIconColor: theme.lightIconColor,
|
||||
toolbarHoverColor: theme.toolbarHoverColor,
|
||||
),
|
||||
AppFlowyTheme(
|
||||
themeData: isLight ? newThemeBuilder.light() : newThemeBuilder.dark(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// ThemeData in mobile
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
|
@ -75,8 +74,6 @@ class MobileAppearance extends BaseAppearance {
|
|||
final onBackground = isLight ? _onBackgroundColor : Colors.white;
|
||||
final background = isLight ? Colors.white : const Color(0xff121212);
|
||||
|
||||
final newThemeBuilder = AppFlowyDefaultTheme();
|
||||
|
||||
return ThemeData(
|
||||
useMaterial3: false,
|
||||
primaryColor: colorTheme.primary, //primary 100
|
||||
|
@ -281,9 +278,6 @@ class MobileAppearance extends BaseAppearance {
|
|||
toolbarHoverColor: theme.toolbarHoverColor,
|
||||
),
|
||||
ToolbarColorExtension.fromBrightness(brightness),
|
||||
AppFlowyTheme(
|
||||
themeData: isLight ? newThemeBuilder.light() : newThemeBuilder.dark(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,25 +27,22 @@ class MyApp extends StatelessWidget {
|
|||
valueListenable: themeMode,
|
||||
builder: (context, themeMode, child) {
|
||||
final themeBuilder = AppFlowyDefaultTheme();
|
||||
ThemeData themeData =
|
||||
final themeData =
|
||||
themeMode == ThemeMode.light ? ThemeData.light() : ThemeData.dark();
|
||||
themeData = themeData.copyWith(
|
||||
visualDensity: VisualDensity.standard,
|
||||
extensions: [
|
||||
AppFlowyTheme(
|
||||
themeData: themeMode == ThemeMode.light
|
||||
? themeBuilder.light()
|
||||
: themeBuilder.dark(),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'AppFlowy UI Example',
|
||||
theme: themeData,
|
||||
home: const MyHomePage(
|
||||
title: 'AppFlowy UI',
|
||||
return AppFlowyTheme(
|
||||
data: themeMode == ThemeMode.light
|
||||
? themeBuilder.light()
|
||||
: themeBuilder.dark(),
|
||||
child: MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'AppFlowy UI Example',
|
||||
theme: themeData.copyWith(
|
||||
visualDensity: VisualDensity.standard,
|
||||
),
|
||||
home: const MyHomePage(
|
||||
title: 'AppFlowy UI',
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,42 +1,153 @@
|
|||
import 'package:appflowy_ui/src/theme/theme.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// [AppFlowyTheme] relies on the Material library's [ThemeData] extensions to
|
||||
/// handle dependency injection into the widget tree.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// - [AppFlowyThemeData], which contains the actual theme data
|
||||
class AppFlowyTheme extends ThemeExtension<AppFlowyTheme> {
|
||||
const AppFlowyTheme({required this.themeData});
|
||||
class AppFlowyTheme extends StatelessWidget {
|
||||
const AppFlowyTheme({
|
||||
super.key,
|
||||
required this.data,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
static AppFlowyThemeData of(BuildContext context) =>
|
||||
Theme.of(context).extension<AppFlowyTheme>()!.themeData;
|
||||
final AppFlowyThemeData data;
|
||||
final Widget child;
|
||||
|
||||
static AppFlowyThemeData? maybeOf(BuildContext context) =>
|
||||
Theme.of(context).extension<AppFlowyTheme>()?.themeData;
|
||||
static AppFlowyThemeData of(BuildContext context, {bool listen = true}) {
|
||||
final provider = maybeOf(context, listen: listen);
|
||||
if (provider == null) {
|
||||
throw FlutterError(
|
||||
'''
|
||||
AppFlowyTheme.of() called with a context that does not contain a AppFlowyTheme.\n
|
||||
No AppFlowyTheme ancestor could be found starting from the context that was passed to AppFlowyTheme.of().
|
||||
This can happen because you do not have a AppFlowyTheme widget (which introduces a AppFlowyTheme),
|
||||
or it can happen if the context you use comes from a widget above this widget.\n
|
||||
The context used was: $context''',
|
||||
);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
final AppFlowyThemeData themeData;
|
||||
|
||||
@override
|
||||
ThemeExtension<AppFlowyTheme> copyWith({
|
||||
AppFlowyThemeData? themeData,
|
||||
static AppFlowyThemeData? maybeOf(
|
||||
BuildContext context, {
|
||||
bool listen = true,
|
||||
}) {
|
||||
return AppFlowyTheme(
|
||||
themeData: themeData ?? this.themeData,
|
||||
);
|
||||
if (listen) {
|
||||
return context
|
||||
.dependOnInheritedWidgetOfExactType<AppFlowyInheritedTheme>()
|
||||
?.theme
|
||||
.data;
|
||||
}
|
||||
final provider = context
|
||||
.getElementForInheritedWidgetOfExactType<AppFlowyInheritedTheme>()
|
||||
?.widget;
|
||||
|
||||
return (provider as AppFlowyInheritedTheme?)?.theme.data;
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<AppFlowyTheme> lerp(
|
||||
covariant ThemeExtension<AppFlowyTheme>? other,
|
||||
double t,
|
||||
) {
|
||||
if (other is! AppFlowyTheme) {
|
||||
return this;
|
||||
}
|
||||
return AppFlowyTheme(
|
||||
themeData: themeData.lerp(other.themeData, t),
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyInheritedTheme(
|
||||
theme: this,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppFlowyInheritedTheme extends InheritedTheme {
|
||||
const AppFlowyInheritedTheme({
|
||||
super.key,
|
||||
required this.theme,
|
||||
required super.child,
|
||||
});
|
||||
|
||||
final AppFlowyTheme theme;
|
||||
|
||||
@override
|
||||
Widget wrap(BuildContext context, Widget child) {
|
||||
return AppFlowyTheme(data: theme.data, child: child);
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(AppFlowyInheritedTheme oldWidget) =>
|
||||
theme.data != oldWidget.theme.data;
|
||||
}
|
||||
|
||||
/// An interpolation between two [ThemeData]s.
|
||||
///
|
||||
/// This class specializes the interpolation of [Tween<ThemeData>] to call the
|
||||
/// [ThemeData.lerp] method.
|
||||
///
|
||||
/// See [Tween] for a discussion on how to use interpolation objects.
|
||||
class AppFlowyThemeDataTween extends Tween<AppFlowyThemeData> {
|
||||
/// Creates a [AppFlowyThemeData] tween.
|
||||
///
|
||||
/// The [begin] and [end] properties must be non-null before the tween is
|
||||
/// first used, but the arguments can be null if the values are going to be
|
||||
/// filled in later.
|
||||
AppFlowyThemeDataTween({super.begin, super.end});
|
||||
|
||||
@override
|
||||
AppFlowyThemeData lerp(double t) => AppFlowyThemeData.lerp(begin!, end!, t);
|
||||
}
|
||||
|
||||
class AnimatedAppFlowyTheme extends ImplicitlyAnimatedWidget {
|
||||
/// Creates an animated theme.
|
||||
///
|
||||
/// By default, the theme transition uses a linear curve.
|
||||
const AnimatedAppFlowyTheme({
|
||||
super.key,
|
||||
required this.data,
|
||||
super.curve,
|
||||
super.duration = kThemeAnimationDuration,
|
||||
super.onEnd,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
/// Specifies the color and typography values for descendant widgets.
|
||||
final AppFlowyThemeData data;
|
||||
|
||||
/// The widget below this widget in the tree.
|
||||
///
|
||||
/// {@macro flutter.widgets.ProxyWidget.child}
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
AnimatedWidgetBaseState<AnimatedAppFlowyTheme> createState() =>
|
||||
_AnimatedThemeState();
|
||||
}
|
||||
|
||||
class _AnimatedThemeState
|
||||
extends AnimatedWidgetBaseState<AnimatedAppFlowyTheme> {
|
||||
AppFlowyThemeDataTween? data;
|
||||
|
||||
@override
|
||||
void forEachTween(TweenVisitor<dynamic> visitor) {
|
||||
data = visitor(
|
||||
data,
|
||||
widget.data,
|
||||
(dynamic value) =>
|
||||
AppFlowyThemeDataTween(begin: value as AppFlowyThemeData),
|
||||
)! as AppFlowyThemeDataTween;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyTheme(
|
||||
data: data!.evaluate(animation),
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder description) {
|
||||
super.debugFillProperties(description);
|
||||
description.add(
|
||||
DiagnosticsProperty<AppFlowyThemeDataTween>(
|
||||
'data',
|
||||
data,
|
||||
showName: false,
|
||||
defaultValue: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,25 +46,27 @@ class AppFlowyThemeData {
|
|||
|
||||
final AppFlowyOtherColorsColorScheme otherColorsColorScheme;
|
||||
|
||||
AppFlowyThemeData lerp(
|
||||
AppFlowyThemeData other,
|
||||
static AppFlowyThemeData lerp(
|
||||
AppFlowyThemeData begin,
|
||||
AppFlowyThemeData end,
|
||||
double t,
|
||||
) {
|
||||
return AppFlowyThemeData(
|
||||
textColorScheme: textColorScheme.lerp(other.textColorScheme, t),
|
||||
textStyle: other.textStyle,
|
||||
iconColorScheme: iconColorScheme.lerp(other.iconColorScheme, t),
|
||||
borderColorScheme: borderColorScheme.lerp(other.borderColorScheme, t),
|
||||
textColorScheme: begin.textColorScheme.lerp(end.textColorScheme, t),
|
||||
textStyle: end.textStyle,
|
||||
iconColorScheme: begin.iconColorScheme.lerp(end.iconColorScheme, t),
|
||||
borderColorScheme: begin.borderColorScheme.lerp(end.borderColorScheme, t),
|
||||
backgroundColorScheme:
|
||||
backgroundColorScheme.lerp(other.backgroundColorScheme, t),
|
||||
fillColorScheme: fillColorScheme.lerp(other.fillColorScheme, t),
|
||||
surfaceColorScheme: surfaceColorScheme.lerp(other.surfaceColorScheme, t),
|
||||
borderRadius: other.borderRadius,
|
||||
spacing: other.spacing,
|
||||
shadow: other.shadow,
|
||||
brandColorScheme: brandColorScheme.lerp(other.brandColorScheme, t),
|
||||
begin.backgroundColorScheme.lerp(end.backgroundColorScheme, t),
|
||||
fillColorScheme: begin.fillColorScheme.lerp(end.fillColorScheme, t),
|
||||
surfaceColorScheme:
|
||||
begin.surfaceColorScheme.lerp(end.surfaceColorScheme, t),
|
||||
borderRadius: end.borderRadius,
|
||||
spacing: end.spacing,
|
||||
shadow: end.shadow,
|
||||
brandColorScheme: begin.brandColorScheme.lerp(end.brandColorScheme, t),
|
||||
otherColorsColorScheme:
|
||||
otherColorsColorScheme.lerp(other.otherColorsColorScheme, t),
|
||||
begin.otherColorsColorScheme.lerp(end.otherColorsColorScheme, t),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue