mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-24 22:57:12 -04:00
feat: Customize Font Size In AppFlowy #1479
This commit is contained in:
parent
37b119172b
commit
6d6e61956a
5 changed files with 91 additions and 34 deletions
|
@ -12,6 +12,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class DocumentPluginBuilder extends PluginBuilder {
|
class DocumentPluginBuilder extends PluginBuilder {
|
||||||
@override
|
@override
|
||||||
|
@ -37,7 +38,9 @@ class DocumentPluginBuilder extends PluginBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DocumentStyle with ChangeNotifier {
|
class DocumentStyle with ChangeNotifier {
|
||||||
DocumentStyle();
|
DocumentStyle() {
|
||||||
|
sync();
|
||||||
|
}
|
||||||
|
|
||||||
double _fontSize = 14.0;
|
double _fontSize = 14.0;
|
||||||
double get fontSize => _fontSize;
|
double get fontSize => _fontSize;
|
||||||
|
@ -45,6 +48,11 @@ class DocumentStyle with ChangeNotifier {
|
||||||
_fontSize = fontSize;
|
_fontSize = fontSize;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sync() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
fontSize = prefs.getDouble('kSelectFontSize') ?? _fontSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DocumentPlugin extends Plugin<int> {
|
class DocumentPlugin extends Plugin<int> {
|
||||||
|
|
|
@ -28,13 +28,13 @@ EditorStyle customEditorTheme(BuildContext context) {
|
||||||
|
|
||||||
Iterable<ThemeExtension<dynamic>> customPluginTheme(BuildContext context) {
|
Iterable<ThemeExtension<dynamic>> customPluginTheme(BuildContext context) {
|
||||||
final documentStyle = context.watch<DocumentStyle>();
|
final documentStyle = context.watch<DocumentStyle>();
|
||||||
|
final baseFontSize = documentStyle.fontSize;
|
||||||
const basePadding = 12.0;
|
const basePadding = 12.0;
|
||||||
var headingPluginStyle = Theme.of(context).brightness == Brightness.dark
|
var headingPluginStyle = Theme.of(context).brightness == Brightness.dark
|
||||||
? HeadingPluginStyle.dark
|
? HeadingPluginStyle.dark
|
||||||
: HeadingPluginStyle.light;
|
: HeadingPluginStyle.light;
|
||||||
headingPluginStyle = headingPluginStyle.copyWith(
|
headingPluginStyle = headingPluginStyle.copyWith(
|
||||||
textStyle: (EditorState editorState, Node node) {
|
textStyle: (EditorState editorState, Node node) {
|
||||||
final baseFontSize = documentStyle.fontSize;
|
|
||||||
final headingToFontSize = {
|
final headingToFontSize = {
|
||||||
'h1': baseFontSize + 12,
|
'h1': baseFontSize + 12,
|
||||||
'h2': baseFontSize + 8,
|
'h2': baseFontSize + 8,
|
||||||
|
@ -60,10 +60,28 @@ Iterable<ThemeExtension<dynamic>> customPluginTheme(BuildContext context) {
|
||||||
return EdgeInsets.only(bottom: padding);
|
return EdgeInsets.only(bottom: padding);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
var numberListPluginStyle = Theme.of(context).brightness == Brightness.dark
|
||||||
|
? NumberListPluginStyle.dark
|
||||||
|
: NumberListPluginStyle.light;
|
||||||
|
|
||||||
|
numberListPluginStyle = numberListPluginStyle.copyWith(
|
||||||
|
icon: (_, textNode) {
|
||||||
|
const iconPadding = EdgeInsets.only(left: 5.0, right: 5.0);
|
||||||
|
return Container(
|
||||||
|
padding: iconPadding,
|
||||||
|
child: Text(
|
||||||
|
'${textNode.attributes.number.toString()}.',
|
||||||
|
style: customEditorTheme(context).textStyle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
final pluginTheme = Theme.of(context).brightness == Brightness.dark
|
final pluginTheme = Theme.of(context).brightness == Brightness.dark
|
||||||
? darkPlguinStyleExtension
|
? darkPlguinStyleExtension
|
||||||
: lightPlguinStyleExtension;
|
: lightPlguinStyleExtension;
|
||||||
return pluginTheme.toList()
|
return pluginTheme.toList()
|
||||||
..removeWhere((element) => element is HeadingPluginStyle)
|
..removeWhere((element) =>
|
||||||
..add(headingPluginStyle);
|
element is HeadingPluginStyle || element is NumberListPluginStyle)
|
||||||
|
..add(headingPluginStyle)
|
||||||
|
..add(numberListPluginStyle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
class FontSizeSwitcher extends StatefulWidget {
|
class FontSizeSwitcher extends StatefulWidget {
|
||||||
const FontSizeSwitcher({
|
const FontSizeSwitcher({
|
||||||
|
@ -15,14 +16,29 @@ class FontSizeSwitcher extends StatefulWidget {
|
||||||
State<FontSizeSwitcher> createState() => _FontSizeSwitcherState();
|
State<FontSizeSwitcher> createState() => _FontSizeSwitcherState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const String _kSelectFontSize = 'kSelectFontSize';
|
||||||
|
|
||||||
class _FontSizeSwitcherState extends State<FontSizeSwitcher> {
|
class _FontSizeSwitcherState extends State<FontSizeSwitcher> {
|
||||||
final _selectedFontSizes = [false, true, false];
|
final List<bool> _selectedFontSizes = [false, true, false];
|
||||||
final List<Tuple2<String, double>> _fontSizes = [
|
final List<Tuple2<String, double>> _fontSizes = [
|
||||||
Tuple2(LocaleKeys.moreAction_small.tr(), 12.0),
|
Tuple2(LocaleKeys.moreAction_small.tr(), 12.0),
|
||||||
Tuple2(LocaleKeys.moreAction_medium.tr(), 14.0),
|
Tuple2(LocaleKeys.moreAction_medium.tr(), 14.0),
|
||||||
Tuple2(LocaleKeys.moreAction_large.tr(), 18.0),
|
Tuple2(LocaleKeys.moreAction_large.tr(), 18.0),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
SharedPreferences.getInstance().then((prefs) {
|
||||||
|
final index = _fontSizes.indexWhere(
|
||||||
|
(element) => element.item2 == prefs.getDouble(_kSelectFontSize));
|
||||||
|
if (index != -1) {
|
||||||
|
_updateSelectedFontSize(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Column(
|
||||||
|
@ -38,12 +54,7 @@ class _FontSizeSwitcherState extends State<FontSizeSwitcher> {
|
||||||
ToggleButtons(
|
ToggleButtons(
|
||||||
isSelected: _selectedFontSizes,
|
isSelected: _selectedFontSizes,
|
||||||
onPressed: (int index) {
|
onPressed: (int index) {
|
||||||
setState(() {
|
_updateSelectedFontSize(index);
|
||||||
for (int i = 0; i < _selectedFontSizes.length; i++) {
|
|
||||||
_selectedFontSizes[i] = i == index;
|
|
||||||
}
|
|
||||||
context.read<DocumentStyle>().fontSize = _fontSizes[index].item2;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
||||||
selectedBorderColor: Theme.of(context).colorScheme.primaryContainer,
|
selectedBorderColor: Theme.of(context).colorScheme.primaryContainer,
|
||||||
|
@ -54,22 +65,27 @@ class _FontSizeSwitcherState extends State<FontSizeSwitcher> {
|
||||||
minHeight: 40.0,
|
minHeight: 40.0,
|
||||||
minWidth: 80.0,
|
minWidth: 80.0,
|
||||||
),
|
),
|
||||||
children: const [
|
children: _fontSizes
|
||||||
Text(
|
.map((e) => Text(
|
||||||
'small',
|
e.item1,
|
||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: e.item2),
|
||||||
),
|
))
|
||||||
Text(
|
.toList(),
|
||||||
'medium',
|
),
|
||||||
style: TextStyle(fontSize: 14),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'large',
|
|
||||||
style: TextStyle(fontSize: 18),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _updateSelectedFontSize(int index) {
|
||||||
|
final fontSize = _fontSizes[index].item2;
|
||||||
|
context.read<DocumentStyle>().fontSize = fontSize;
|
||||||
|
SharedPreferences.getInstance().then(
|
||||||
|
(prefs) => prefs.setDouble(_kSelectFontSize, fontSize),
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
for (int i = 0; i < _selectedFontSizes.length; i++) {
|
||||||
|
_selectedFontSizes[i] = i == index;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,11 @@ class DocumentMoreButton extends StatelessWidget {
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
child: svgWithSize('editor/details', const Size(18, 18)),
|
child: svgWidget(
|
||||||
|
'editor/details',
|
||||||
|
size: const Size(18, 18),
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,26 @@
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
Widget svgWidget(String name, {Color? color}) {
|
|
||||||
final Widget svg = SvgPicture.asset('assets/images/$name.svg', color: color);
|
|
||||||
|
|
||||||
return svg;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget svgWithSize(String name, Size size) {
|
Widget svgWithSize(String name, Size size) {
|
||||||
return SizedBox.fromSize(
|
return SizedBox.fromSize(
|
||||||
size: size,
|
size: size,
|
||||||
child: svgWidget(name),
|
child: svgWidget(name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget svgWidget(String name, {Size? size, Color? color}) {
|
||||||
|
if (size != null) {
|
||||||
|
return SizedBox.fromSize(
|
||||||
|
size: size,
|
||||||
|
child: _svgWidget(name, color: color),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return _svgWidget(name, color: color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _svgWidget(String name, {Color? color}) {
|
||||||
|
final Widget svg = SvgPicture.asset('assets/images/$name.svg', color: color);
|
||||||
|
|
||||||
|
return svg;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue