mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: change the UI of language selector (#2317)
* feat: change the UI of language selector * chore: clean up code * chore: delete unnecessary code and clean up
This commit is contained in:
parent
49caf74ee1
commit
fccd6135f7
@ -242,6 +242,12 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
|
|||||||
shadow: theme.shadow,
|
shadow: theme.shadow,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const Set<MaterialState> scrollbarInteractiveStates = <MaterialState>{
|
||||||
|
MaterialState.pressed,
|
||||||
|
MaterialState.hovered,
|
||||||
|
MaterialState.dragged,
|
||||||
|
};
|
||||||
|
|
||||||
return ThemeData(
|
return ThemeData(
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
textTheme: _getTextTheme(fontFamily: fontFamily, fontColor: theme.text),
|
textTheme: _getTextTheme(fontFamily: fontFamily, fontColor: theme.text),
|
||||||
@ -264,15 +270,15 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
|
|||||||
contentTextStyle: TextStyle(color: colorScheme.onSurface),
|
contentTextStyle: TextStyle(color: colorScheme.onSurface),
|
||||||
),
|
),
|
||||||
scrollbarTheme: ScrollbarThemeData(
|
scrollbarTheme: ScrollbarThemeData(
|
||||||
thumbColor: MaterialStateProperty.all(theme.shader3),
|
thumbColor: MaterialStateProperty.resolveWith((states) {
|
||||||
|
if (states.any(scrollbarInteractiveStates.contains)) {
|
||||||
|
return theme.shader7;
|
||||||
|
}
|
||||||
|
return theme.shader5;
|
||||||
|
}),
|
||||||
thickness: MaterialStateProperty.resolveWith((states) {
|
thickness: MaterialStateProperty.resolveWith((states) {
|
||||||
const Set<MaterialState> interactiveStates = <MaterialState>{
|
if (states.any(scrollbarInteractiveStates.contains)) {
|
||||||
MaterialState.pressed,
|
return 4;
|
||||||
MaterialState.hovered,
|
|
||||||
MaterialState.dragged,
|
|
||||||
};
|
|
||||||
if (states.any(interactiveStates.contains)) {
|
|
||||||
return 5.0;
|
|
||||||
}
|
}
|
||||||
return 3.0;
|
return 3.0;
|
||||||
}),
|
}),
|
||||||
|
@ -77,8 +77,8 @@ class ThemeSetting extends StatelessWidget {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(theme),
|
text: FlowyText.medium(theme),
|
||||||
rightIcon: currentTheme == theme
|
rightIcon: currentTheme == theme
|
||||||
? svgWidget("grid/checkmark")
|
? const FlowySvg(name: 'grid/checkmark')
|
||||||
: const SizedBox(),
|
: null,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (currentTheme != theme) {
|
if (currentTheme != theme) {
|
||||||
context.read<AppearanceSettingsCubit>().setTheme(theme);
|
context.read<AppearanceSettingsCubit>().setTheme(theme);
|
||||||
@ -134,8 +134,8 @@ class ThemeModeSetting extends StatelessWidget {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(_themeModeLabelText(themeMode)),
|
text: FlowyText.medium(_themeModeLabelText(themeMode)),
|
||||||
rightIcon: currentThemeMode == themeMode
|
rightIcon: currentThemeMode == themeMode
|
||||||
? svgWidget("grid/checkmark")
|
? const FlowySvg(name: 'grid/checkmark')
|
||||||
: const SizedBox(),
|
: null,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (currentThemeMode != themeMode) {
|
if (currentThemeMode != themeMode) {
|
||||||
context.read<AppearanceSettingsCubit>().setThemeMode(themeMode);
|
context.read<AppearanceSettingsCubit>().setThemeMode(themeMode);
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/appearance.dart';
|
||||||
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flowy_infra/language.dart';
|
import 'package:flowy_infra/language.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -12,85 +14,101 @@ class SettingsLanguageView extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Column(
|
child: BlocBuilder<AppearanceSettingsCubit, AppearanceSettingsState>(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
builder: (context, state) => Row(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Expanded(
|
||||||
children: [
|
child: FlowyText.medium(
|
||||||
FlowyText.medium(LocaleKeys.settings_menu_language.tr()),
|
LocaleKeys.settings_menu_language.tr(),
|
||||||
const LanguageSelectorDropdown(),
|
),
|
||||||
|
),
|
||||||
|
LanguageSelector(currentLocale: state.locale),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LanguageSelectorDropdown extends StatefulWidget {
|
class LanguageSelector extends StatelessWidget {
|
||||||
const LanguageSelectorDropdown({
|
final Locale currentLocale;
|
||||||
Key? key,
|
const LanguageSelector({
|
||||||
}) : super(key: key);
|
super.key,
|
||||||
|
required this.currentLocale,
|
||||||
@override
|
|
||||||
State<LanguageSelectorDropdown> createState() =>
|
|
||||||
_LanguageSelectorDropdownState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _LanguageSelectorDropdownState extends State<LanguageSelectorDropdown> {
|
|
||||||
Color currHoverColor = Colors.white.withOpacity(0.0);
|
|
||||||
void hoverExitLanguage() {
|
|
||||||
setState(() {
|
|
||||||
currHoverColor = Colors.white.withOpacity(0.0);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
void hoverEnterLanguage() {
|
|
||||||
setState(() {
|
|
||||||
currHoverColor = Theme.of(context).colorScheme.secondaryContainer;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MouseRegion(
|
return AppFlowyPopover(
|
||||||
onEnter: (_) => hoverEnterLanguage(),
|
direction: PopoverDirection.bottomWithRightAligned,
|
||||||
onExit: (_) => hoverExitLanguage(),
|
child: FlowyTextButton(
|
||||||
child: Container(
|
languageFromLocale(currentLocale),
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 8),
|
fontColor: Theme.of(context).colorScheme.onBackground,
|
||||||
decoration: BoxDecoration(
|
fillColor: Colors.transparent,
|
||||||
borderRadius: BorderRadius.circular(8),
|
onPressed: () {},
|
||||||
color: currHoverColor,
|
|
||||||
),
|
),
|
||||||
child: DropdownButtonHideUnderline(
|
popupBuilder: (BuildContext context) {
|
||||||
child: Padding(
|
final allLocales = EasyLocalization.of(context)!.supportedLocales;
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
|
||||||
child: DropdownButton<Locale>(
|
return LanguageItemsListView(
|
||||||
value: context.locale,
|
allLocales: allLocales,
|
||||||
dropdownColor: Theme.of(context).cardColor,
|
currentLocale: currentLocale,
|
||||||
onChanged: (locale) {
|
);
|
||||||
context
|
|
||||||
.read<AppearanceSettingsCubit>()
|
|
||||||
.setLocale(context, locale!);
|
|
||||||
},
|
},
|
||||||
autofocus: true,
|
);
|
||||||
borderRadius: BorderRadius.circular(8),
|
}
|
||||||
items:
|
}
|
||||||
EasyLocalization.of(context)!.supportedLocales.map((locale) {
|
|
||||||
return DropdownMenuItem<Locale>(
|
class LanguageItemsListView extends StatelessWidget {
|
||||||
value: locale,
|
const LanguageItemsListView({
|
||||||
child: Padding(
|
super.key,
|
||||||
padding: const EdgeInsets.all(12.0),
|
required this.allLocales,
|
||||||
child: FlowyText.medium(
|
required this.currentLocale,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<Locale> allLocales;
|
||||||
|
final Locale currentLocale;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxHeight: 400),
|
||||||
|
child: ListView.builder(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final locale = allLocales[index];
|
||||||
|
return LanguageItem(locale: locale, currentLocale: currentLocale);
|
||||||
|
},
|
||||||
|
itemCount: allLocales.length,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LanguageItem extends StatelessWidget {
|
||||||
|
final Locale locale;
|
||||||
|
final Locale currentLocale;
|
||||||
|
const LanguageItem({
|
||||||
|
super.key,
|
||||||
|
required this.locale,
|
||||||
|
required this.currentLocale,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 32,
|
||||||
|
child: FlowyButton(
|
||||||
|
text: FlowyText.medium(
|
||||||
languageFromLocale(locale),
|
languageFromLocale(locale),
|
||||||
color: Theme.of(context).colorScheme.tertiary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
rightIcon: currentLocale == locale
|
||||||
|
? const FlowySvg(name: 'grid/checkmark')
|
||||||
|
: null,
|
||||||
|
onTap: () {
|
||||||
|
if (currentLocale != locale) {
|
||||||
|
context.read<AppearanceSettingsCubit>().setLocale(context, locale);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user