Skip to content

Commit 6220680

Browse files
authored
feat: support system default font family on desktop (#5279)
* fix: add permission check before selecting image in image block * feat: use system default font on desktop * fix: set appbar icon size to 30 * feat: add default font family on desktop
1 parent b4279f8 commit 6220680

File tree

23 files changed

+233
-190
lines changed

23 files changed

+233
-190
lines changed

frontend/appflowy_flutter/integration_test/desktop/uncategorized/appearance_settings_test.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:appflowy/util/font_family_extension.dart';
12
import 'package:appflowy/workspace/application/appearance_defaults.dart';
23
import 'package:appflowy/workspace/application/settings/prelude.dart';
34
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/settings_appearance.dart';
@@ -82,8 +83,10 @@ void main() {
8283
await tester.openSettingsPage(SettingsPage.appearance);
8384

8485
expect(
85-
find.textContaining(DefaultAppearanceSettings.kDefaultFontFamily),
86-
findsOneWidget,
86+
find.textContaining(
87+
DefaultAppearanceSettings.kDefaultFontFamily.fontFamilyDisplayName,
88+
),
89+
findsNWidgets(2),
8790
);
8891
});
8992
});

frontend/appflowy_flutter/lib/mobile/application/page_style/document_page_style_bloc.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import 'dart:async';
22
import 'dart:convert';
33
import 'dart:math';
44

5-
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
65
import 'package:appflowy/workspace/application/view/view_ext.dart';
76
import 'package:appflowy/workspace/application/view/view_service.dart';
87
import 'package:appflowy_backend/log.dart';
@@ -179,8 +178,8 @@ class DocumentPageStyleBloc
179178
);
180179
}
181180

182-
String _getSelectedFontFamily(Map layoutObject) {
183-
return layoutObject[ViewExtKeys.fontKey] ?? builtInFontFamily();
181+
String? _getSelectedFontFamily(Map layoutObject) {
182+
return layoutObject[ViewExtKeys.fontKey];
184183
}
185184

186185
(PageStyleCoverImageType, String colorValue) _getSelectedCover(

frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,11 @@ class _MobileViewPageState extends State<MobileViewPage> {
216216
child: AppBarButton(
217217
padding: EdgeInsets.zero,
218218
onTap: (context) => context.pop(),
219-
child: _buildImmersiveAppBarIcon(FlowySvgs.m_app_bar_back_s),
219+
child: _buildImmersiveAppBarIcon(
220+
FlowySvgs.m_app_bar_back_s,
221+
30.0,
222+
iconPadding: 6.0,
223+
),
220224
),
221225
),
222226
actions: actions,
@@ -274,13 +278,13 @@ class _MobileViewPageState extends State<MobileViewPage> {
274278
),
275279
);
276280
},
277-
child: _buildImmersiveAppBarIcon(FlowySvgs.m_layout_s),
281+
child: _buildImmersiveAppBarIcon(FlowySvgs.m_layout_s, 30.0),
278282
);
279283
}
280284

281285
Widget _buildAppBarMoreButton(ViewPB view) {
282286
return AppBarButton(
283-
padding: const EdgeInsets.only(left: 8, right: 16, top: 2, bottom: 2),
287+
padding: const EdgeInsets.only(left: 8, right: 16),
284288
onTap: (context) {
285289
EditorNotification.exitEditing().post();
286290

@@ -292,49 +296,62 @@ class _MobileViewPageState extends State<MobileViewPage> {
292296
builder: (_) => _buildAppBarMoreBottomSheet(context),
293297
);
294298
},
295-
child: _buildImmersiveAppBarIcon(FlowySvgs.m_app_bar_more_s),
299+
child: _buildImmersiveAppBarIcon(FlowySvgs.m_app_bar_more_s, 30.0),
296300
);
297301
}
298302

299-
Widget _buildImmersiveAppBarIcon(FlowySvgData icon) {
300-
return ValueListenableBuilder(
301-
valueListenable: _isImmersiveMode,
302-
builder: (context, isImmersiveMode, child) {
303-
return ValueListenableBuilder(
304-
valueListenable: _appBarOpacity,
305-
builder: (context, appBarOpacity, child) {
306-
Color? color;
303+
Widget _buildImmersiveAppBarIcon(
304+
FlowySvgData icon,
305+
double dimension, {
306+
double iconPadding = 5.0,
307+
}) {
308+
assert(
309+
dimension > 0.0 && dimension <= kToolbarHeight,
310+
'dimension must be greater than 0, and less than or equal to kToolbarHeight',
311+
);
312+
return UnconstrainedBox(
313+
child: SizedBox.square(
314+
dimension: dimension,
315+
child: ValueListenableBuilder(
316+
valueListenable: _isImmersiveMode,
317+
builder: (context, isImmersiveMode, child) {
318+
return ValueListenableBuilder(
319+
valueListenable: _appBarOpacity,
320+
builder: (context, appBarOpacity, child) {
321+
Color? color;
307322

308-
// if there's no cover or the cover is not immersive,
309-
// make sure the app bar is always visible
310-
if (!isImmersiveMode) {
311-
color = null;
312-
} else if (appBarOpacity < 0.99) {
313-
color = Colors.white;
314-
}
323+
// if there's no cover or the cover is not immersive,
324+
// make sure the app bar is always visible
325+
if (!isImmersiveMode) {
326+
color = null;
327+
} else if (appBarOpacity < 0.99) {
328+
color = Colors.white;
329+
}
315330

316-
Widget child = Container(
317-
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
318-
child: FlowySvg(
319-
icon,
320-
color: color,
321-
),
322-
);
331+
Widget child = Container(
332+
margin: EdgeInsets.all(iconPadding),
333+
child: FlowySvg(
334+
icon,
335+
color: color,
336+
),
337+
);
323338

324-
if (isImmersiveMode && appBarOpacity <= 0.99) {
325-
child = DecoratedBox(
326-
decoration: BoxDecoration(
327-
borderRadius: BorderRadius.circular(22),
328-
color: Colors.black.withOpacity(0.2),
329-
),
330-
child: child,
331-
);
332-
}
339+
if (isImmersiveMode && appBarOpacity <= 0.99) {
340+
child = DecoratedBox(
341+
decoration: BoxDecoration(
342+
borderRadius: BorderRadius.circular(dimension / 2.0),
343+
color: Colors.black.withOpacity(0.2),
344+
),
345+
child: child,
346+
);
347+
}
333348

334-
return child;
349+
return child;
350+
},
351+
);
335352
},
336-
);
337-
},
353+
),
354+
),
338355
);
339356
}
340357

frontend/appflowy_flutter/lib/mobile/presentation/setting/font/font_picker_screen.dart

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'package:appflowy/mobile/presentation/base/app_bar/app_bar.dart';
33
import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_search_text_field.dart';
44
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
55
import 'package:appflowy/shared/google_fonts_extension.dart';
6-
import 'package:appflowy/util/google_font_family_extension.dart';
6+
import 'package:appflowy/util/font_family_extension.dart';
77
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
88
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
99
import 'package:easy_localization/easy_localization.dart';
@@ -13,7 +13,7 @@ import 'package:go_router/go_router.dart';
1313
import 'package:google_fonts/google_fonts.dart';
1414

1515
final List<String> _availableFonts = [
16-
builtInFontFamily(),
16+
defaultFontFamily,
1717
...GoogleFonts.asMap().keys,
1818
];
1919

@@ -106,16 +106,12 @@ class _FontSelectorState extends State<FontSelector> {
106106
}
107107

108108
final fontFamilyName = availableFonts[index - 1];
109-
final usingDefaultFontFamily = fontFamilyName == builtInFontFamily();
109+
final usingDefaultFontFamily = fontFamilyName == defaultFontFamily;
110110
final fontFamily = !usingDefaultFontFamily
111111
? getGoogleFontSafely(fontFamilyName).fontFamily
112-
: TextStyle(fontFamily: builtInFontFamily()).fontFamily;
112+
: defaultFontFamily;
113113
return FlowyOptionTile.checkbox(
114-
// display the default font name if the font family name is empty
115-
// or using the default font family
116-
text: fontFamilyName.isNotEmpty && !usingDefaultFontFamily
117-
? fontFamilyName.parseFontFamilyName()
118-
: LocaleKeys.settings_appearance_fontFamily_defaultFont.tr(),
114+
text: fontFamilyName.fontFamilyDisplayName,
119115
isSelected: widget.selectedFontFamilyName == fontFamilyName,
120116
showTopBorder: false,
121117
onTap: () => widget.onFontFamilySelected(fontFamilyName),

frontend/appflowy_flutter/lib/mobile/presentation/setting/font/font_setting.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import 'dart:async';
33
import 'package:appflowy/generated/locale_keys.g.dart';
44
import 'package:appflowy/mobile/presentation/setting/font/font_picker_screen.dart';
55
import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart';
6+
import 'package:appflowy/util/font_family_extension.dart';
67
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
7-
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
88
import 'package:easy_localization/easy_localization.dart';
99
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
1010
import 'package:flutter/material.dart';
@@ -22,9 +22,7 @@ class FontSetting extends StatelessWidget {
2222
Widget build(BuildContext context) {
2323
final theme = Theme.of(context);
2424
final selectedFont = context.watch<AppearanceSettingsCubit>().state.font;
25-
final name = selectedFont == builtInFontFamily()
26-
? LocaleKeys.settings_appearance_fontFamily_defaultFont.tr()
27-
: selectedFont;
25+
final name = selectedFont.fontFamilyDisplayName;
2826
return MobileSettingItem(
2927
name: LocaleKeys.settings_appearance_fontFamily_label.tr(),
3028
trailing: Row(

frontend/appflowy_flutter/lib/plugins/document/application/document_appearance_cubit.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ class DocumentAppearance {
5757
class DocumentAppearanceCubit extends Cubit<DocumentAppearance> {
5858
DocumentAppearanceCubit()
5959
: super(
60-
DocumentAppearance(
60+
const DocumentAppearance(
6161
fontSize: 16.0,
62-
fontFamily: builtInFontFamily(),
62+
fontFamily: defaultFontFamily,
6363
codeFontFamily: builtInCodeFontFamily,
6464
),
6565
);
@@ -69,7 +69,7 @@ class DocumentAppearanceCubit extends Cubit<DocumentAppearance> {
6969
final fontSize =
7070
prefs.getDouble(KVKeys.kDocumentAppearanceFontSize) ?? 16.0;
7171
final fontFamily = prefs.getString(KVKeys.kDocumentAppearanceFontFamily) ??
72-
builtInFontFamily();
72+
defaultFontFamily;
7373
final defaultTextDirection =
7474
prefs.getString(KVKeys.kDocumentAppearanceDefaultTextDirection);
7575

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/cover/document_immersive_cover.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class _DocumentImmersiveCoverState extends State<DocumentImmersiveCover> {
127127
BuildContext context,
128128
DocumentImmersiveCoverState state,
129129
) {
130-
String? fontFamily = builtInFontFamily();
130+
String? fontFamily = defaultFontFamily;
131131
final documentFontFamily =
132132
context.read<DocumentPageStyleBloc>().state.fontFamily;
133133
if (documentFontFamily != null && fontFamily != documentFontFamily) {

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/upload_image_file_widget.dart

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import 'package:appflowy/generated/locale_keys.g.dart';
2+
import 'package:appflowy/shared/permission/permission_checker.dart';
23
import 'package:appflowy/startup/startup.dart';
3-
import 'package:appflowy_editor/appflowy_editor.dart';
4+
import 'package:appflowy_backend/log.dart';
5+
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
46
import 'package:easy_localization/easy_localization.dart';
57
import 'package:flowy_infra/file_picker/file_picker_service.dart';
68
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@@ -20,22 +22,28 @@ class UploadImageFileWidget extends StatelessWidget {
2022

2123
@override
2224
Widget build(BuildContext context) {
23-
return FlowyHover(
24-
child: FlowyButton(
25-
showDefaultBoxDecorationOnMobile: true,
26-
text: Container(
27-
margin: const EdgeInsets.all(4.0),
28-
alignment: Alignment.center,
29-
child: FlowyText(
30-
LocaleKeys.document_imageBlock_upload_placeholder.tr(),
31-
),
25+
final child = FlowyButton(
26+
showDefaultBoxDecorationOnMobile: true,
27+
text: Container(
28+
margin: const EdgeInsets.all(4.0),
29+
alignment: Alignment.center,
30+
child: FlowyText(
31+
LocaleKeys.document_imageBlock_upload_placeholder.tr(),
3232
),
33-
onTap: _uploadImage,
3433
),
34+
onTap: () => _uploadImage(context),
3535
);
36+
37+
if (PlatformExtension.isDesktopOrWeb) {
38+
return FlowyHover(
39+
child: child,
40+
);
41+
}
42+
43+
return child;
3644
}
3745

38-
Future<void> _uploadImage() async {
46+
Future<void> _uploadImage(BuildContext context) async {
3947
if (PlatformExtension.isDesktopOrWeb) {
4048
// on desktop, the users can pick a image file from folder
4149
final result = await getIt<FilePickerService>().pickFiles(
@@ -45,6 +53,12 @@ class UploadImageFileWidget extends StatelessWidget {
4553
);
4654
onPickFile(result?.files.firstOrNull?.path);
4755
} else {
56+
final photoPermission =
57+
await PermissionChecker.checkPhotoPermission(context);
58+
if (!photoPermission) {
59+
Log.error('Has no permission to access the photo library');
60+
return;
61+
}
4862
// on mobile, the users can pick a image file from camera or image library
4963
final result = await ImagePicker().pickImage(source: ImageSource.gallery);
5064
onPickFile(result?.path);

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_font_item.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'package:appflowy/plugins/document/application/document_appearance_cubit.
55
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart';
66
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
77
import 'package:appflowy/shared/google_fonts_extension.dart';
8-
import 'package:appflowy/util/google_font_family_extension.dart';
8+
import 'package:appflowy/util/font_family_extension.dart';
99
import 'package:appflowy_editor/appflowy_editor.dart';
1010
import 'package:flutter/material.dart';
1111
import 'package:go_router/go_router.dart';

0 commit comments

Comments
 (0)