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/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:appflowy/mobile/presentation/setting/appearance/theme_setting.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -17,6 +18,7 @@ class AppearanceSettingGroup extends StatelessWidget {
|
|||||||
settingItemList: const [
|
settingItemList: const [
|
||||||
ThemeSetting(),
|
ThemeSetting(),
|
||||||
FontSetting(),
|
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/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.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/util/theme_mode_extension.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
@ -34,26 +35,43 @@ class ThemeSetting extends StatelessWidget {
|
|||||||
showMobileBottomSheet(
|
showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
showCloseButton: true,
|
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
|
showDivider: false,
|
||||||
|
showCloseButton: false,
|
||||||
title: LocaleKeys.settings_appearance_themeMode_label.tr(),
|
title: LocaleKeys.settings_appearance_themeMode_label.tr(),
|
||||||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 32),
|
padding: const EdgeInsets.fromLTRB(0, 8, 0, 48),
|
||||||
builder: (_) {
|
builder: (context) {
|
||||||
return Column(
|
final themeMode =
|
||||||
children: [
|
context.read<AppearanceSettingsCubit>().state.themeMode;
|
||||||
_ThemeModeRadioListTile(
|
return Padding(
|
||||||
title: LocaleKeys.settings_appearance_themeMode_system.tr(),
|
padding: const EdgeInsets.only(top: 10),
|
||||||
value: ThemeMode.system,
|
child: Column(
|
||||||
),
|
children: [
|
||||||
_ThemeModeRadioListTile(
|
FlowyOptionTile.checkbox(
|
||||||
title: LocaleKeys.settings_appearance_themeMode_light.tr(),
|
text: LocaleKeys.settings_appearance_themeMode_system.tr(),
|
||||||
value: ThemeMode.light,
|
isSelected: themeMode == ThemeMode.system,
|
||||||
),
|
onTap: () => context
|
||||||
_ThemeModeRadioListTile(
|
.read<AppearanceSettingsCubit>()
|
||||||
title: LocaleKeys.settings_appearance_themeMode_dark.tr(),
|
.setThemeMode(ThemeMode.system),
|
||||||
value: ThemeMode.dark,
|
),
|
||||||
),
|
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"
|
"rtl": "RTL"
|
||||||
},
|
},
|
||||||
"textDirection": {
|
"textDirection": {
|
||||||
"label": "Default text direction",
|
"label": "Default Text Direction",
|
||||||
"hint": "Specify whether text should start from left or right as the default.",
|
"hint": "Specify whether text should start from left or right as the default.",
|
||||||
"ltr": "LTR",
|
"ltr": "LTR",
|
||||||
"rtl": "RTL",
|
"rtl": "RTL",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user