mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: support RTL layout on mobile (#4335)
* feat: revamp theme mode settings * feat: support RTL layout on mobile
This commit is contained in:
parent
332a677d20
commit
dcb070909c
@ -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(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user