feat: support RTL layout on mobile (#4335)

* feat: revamp theme mode settings

* feat: support RTL layout on mobile
This commit is contained in:
Lucas.Xu 2024-01-09 09:12:54 +07:00 committed by GitHub
parent 332a677d20
commit dcb070909c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 122 additions and 50 deletions

View File

@ -1,4 +1,5 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/setting/appearance/rtl_setting.dart';
import 'package:appflowy/mobile/presentation/setting/appearance/theme_setting.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -17,6 +18,7 @@ class AppearanceSettingGroup extends StatelessWidget {
settingItemList: const [
ThemeSetting(),
FontSetting(),
RTLSetting(),
],
);
}

View File

@ -0,0 +1,83 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../setting.dart';
class RTLSetting extends StatelessWidget {
const RTLSetting({
super.key,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final layoutDirection =
context.watch<AppearanceSettingsCubit>().state.layoutDirection;
return MobileSettingItem(
name: LocaleKeys.settings_appearance_textDirection_label.tr(),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
FlowyText(
_textDirectionLabelText(layoutDirection),
color: theme.colorScheme.onSurface,
),
const Icon(Icons.chevron_right),
],
),
onTap: () {
showMobileBottomSheet(
context,
showHeader: true,
showDragHandle: true,
showDivider: false,
showCloseButton: false,
title: LocaleKeys.settings_appearance_textDirection_label.tr(),
padding: const EdgeInsets.fromLTRB(0, 8, 0, 48),
builder: (context) {
final layoutDirection =
context.watch<AppearanceSettingsCubit>().state.layoutDirection;
return Padding(
padding: const EdgeInsets.only(top: 10),
child: Column(
children: [
FlowyOptionTile.checkbox(
text: LocaleKeys.settings_appearance_textDirection_ltr.tr(),
isSelected: layoutDirection == LayoutDirection.ltrLayout,
onTap: () => context
.read<AppearanceSettingsCubit>()
.setLayoutDirection(LayoutDirection.ltrLayout),
),
FlowyOptionTile.checkbox(
showTopBorder: false,
text: LocaleKeys.settings_appearance_textDirection_rtl.tr(),
isSelected: layoutDirection == LayoutDirection.rtlLayout,
onTap: () => context
.read<AppearanceSettingsCubit>()
.setLayoutDirection(LayoutDirection.rtlLayout),
),
],
),
);
},
);
},
);
}
String _textDirectionLabelText(LayoutDirection? textDirection) {
switch (textDirection) {
case LayoutDirection.rtlLayout:
return LocaleKeys.settings_appearance_textDirection_rtl.tr();
case LayoutDirection.ltrLayout:
default:
return LocaleKeys.settings_appearance_textDirection_ltr.tr();
}
}
}

View File

@ -1,5 +1,6 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
import 'package:appflowy/util/theme_mode_extension.dart';
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
import 'package:easy_localization/easy_localization.dart';
@ -34,26 +35,43 @@ class ThemeSetting extends StatelessWidget {
showMobileBottomSheet(
context,
showHeader: true,
showCloseButton: true,
showDragHandle: true,
showDivider: false,
showCloseButton: false,
title: LocaleKeys.settings_appearance_themeMode_label.tr(),
padding: const EdgeInsets.fromLTRB(16, 0, 16, 32),
builder: (_) {
return Column(
children: [
_ThemeModeRadioListTile(
title: LocaleKeys.settings_appearance_themeMode_system.tr(),
value: ThemeMode.system,
),
_ThemeModeRadioListTile(
title: LocaleKeys.settings_appearance_themeMode_light.tr(),
value: ThemeMode.light,
),
_ThemeModeRadioListTile(
title: LocaleKeys.settings_appearance_themeMode_dark.tr(),
value: ThemeMode.dark,
),
],
padding: const EdgeInsets.fromLTRB(0, 8, 0, 48),
builder: (context) {
final themeMode =
context.read<AppearanceSettingsCubit>().state.themeMode;
return Padding(
padding: const EdgeInsets.only(top: 10),
child: Column(
children: [
FlowyOptionTile.checkbox(
text: LocaleKeys.settings_appearance_themeMode_system.tr(),
isSelected: themeMode == ThemeMode.system,
onTap: () => context
.read<AppearanceSettingsCubit>()
.setThemeMode(ThemeMode.system),
),
FlowyOptionTile.checkbox(
showTopBorder: false,
text: LocaleKeys.settings_appearance_themeMode_light.tr(),
isSelected: themeMode == ThemeMode.light,
onTap: () => context
.read<AppearanceSettingsCubit>()
.setThemeMode(ThemeMode.light),
),
FlowyOptionTile.checkbox(
showTopBorder: false,
text: LocaleKeys.settings_appearance_themeMode_dark.tr(),
isSelected: themeMode == ThemeMode.dark,
onTap: () => context
.read<AppearanceSettingsCubit>()
.setThemeMode(ThemeMode.dark),
),
],
),
);
},
);
@ -61,34 +79,3 @@ class ThemeSetting extends StatelessWidget {
);
}
}
class _ThemeModeRadioListTile extends StatelessWidget {
const _ThemeModeRadioListTile({
required this.title,
required this.value,
});
final String title;
final ThemeMode value;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return RadioListTile<ThemeMode>(
dense: true,
contentPadding: const EdgeInsets.fromLTRB(0, 0, 4, 0),
controlAffinity: ListTileControlAffinity.trailing,
title: Text(
title,
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurface,
),
),
groupValue: context.read<AppearanceSettingsCubit>().state.themeMode,
value: value,
onChanged: (selectedThemeMode) {
if (selectedThemeMode == null) return;
context.read<AppearanceSettingsCubit>().setThemeMode(selectedThemeMode);
},
);
}
}

View File

@ -343,7 +343,7 @@
"rtl": "RTL"
},
"textDirection": {
"label": "Default text direction",
"label": "Default Text Direction",
"hint": "Specify whether text should start from left or right as the default.",
"ltr": "LTR",
"rtl": "RTL",