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:
Yijing Huang 2023-04-24 21:20:10 -05:00 committed by GitHub
parent 49caf74ee1
commit fccd6135f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 108 additions and 84 deletions

View File

@ -242,6 +242,12 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
shadow: theme.shadow,
);
const Set<MaterialState> scrollbarInteractiveStates = <MaterialState>{
MaterialState.pressed,
MaterialState.hovered,
MaterialState.dragged,
};
return ThemeData(
brightness: brightness,
textTheme: _getTextTheme(fontFamily: fontFamily, fontColor: theme.text),
@ -264,15 +270,15 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
contentTextStyle: TextStyle(color: colorScheme.onSurface),
),
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) {
const Set<MaterialState> interactiveStates = <MaterialState>{
MaterialState.pressed,
MaterialState.hovered,
MaterialState.dragged,
};
if (states.any(interactiveStates.contains)) {
return 5.0;
if (states.any(scrollbarInteractiveStates.contains)) {
return 4;
}
return 3.0;
}),

View File

@ -77,8 +77,8 @@ class ThemeSetting extends StatelessWidget {
child: FlowyButton(
text: FlowyText.medium(theme),
rightIcon: currentTheme == theme
? svgWidget("grid/checkmark")
: const SizedBox(),
? const FlowySvg(name: 'grid/checkmark')
: null,
onTap: () {
if (currentTheme != theme) {
context.read<AppearanceSettingsCubit>().setTheme(theme);
@ -134,8 +134,8 @@ class ThemeModeSetting extends StatelessWidget {
child: FlowyButton(
text: FlowyText.medium(_themeModeLabelText(themeMode)),
rightIcon: currentThemeMode == themeMode
? svgWidget("grid/checkmark")
: const SizedBox(),
? const FlowySvg(name: 'grid/checkmark')
: null,
onTap: () {
if (currentThemeMode != themeMode) {
context.read<AppearanceSettingsCubit>().setThemeMode(themeMode);

View File

@ -1,7 +1,9 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/appearance.dart';
import 'package:appflowy_popover/appflowy_popover.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:flowy_infra/language.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -12,85 +14,101 @@ class SettingsLanguageView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
FlowyText.medium(LocaleKeys.settings_menu_language.tr()),
const LanguageSelectorDropdown(),
],
),
],
child: BlocBuilder<AppearanceSettingsCubit, AppearanceSettingsState>(
builder: (context, state) => Row(
children: [
Expanded(
child: FlowyText.medium(
LocaleKeys.settings_menu_language.tr(),
),
),
LanguageSelector(currentLocale: state.locale),
],
),
),
);
}
}
class LanguageSelectorDropdown extends StatefulWidget {
const LanguageSelectorDropdown({
Key? key,
}) : super(key: key);
@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;
});
}
class LanguageSelector extends StatelessWidget {
final Locale currentLocale;
const LanguageSelector({
super.key,
required this.currentLocale,
});
@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (_) => hoverEnterLanguage(),
onExit: (_) => hoverExitLanguage(),
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: currHoverColor,
),
child: DropdownButtonHideUnderline(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: DropdownButton<Locale>(
value: context.locale,
dropdownColor: Theme.of(context).cardColor,
onChanged: (locale) {
context
.read<AppearanceSettingsCubit>()
.setLocale(context, locale!);
},
autofocus: true,
borderRadius: BorderRadius.circular(8),
items:
EasyLocalization.of(context)!.supportedLocales.map((locale) {
return DropdownMenuItem<Locale>(
value: locale,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: FlowyText.medium(
languageFromLocale(locale),
color: Theme.of(context).colorScheme.tertiary,
),
),
);
}).toList(),
),
),
),
return AppFlowyPopover(
direction: PopoverDirection.bottomWithRightAligned,
child: FlowyTextButton(
languageFromLocale(currentLocale),
fontColor: Theme.of(context).colorScheme.onBackground,
fillColor: Colors.transparent,
onPressed: () {},
),
popupBuilder: (BuildContext context) {
final allLocales = EasyLocalization.of(context)!.supportedLocales;
return LanguageItemsListView(
allLocales: allLocales,
currentLocale: currentLocale,
);
},
);
}
}
class LanguageItemsListView extends StatelessWidget {
const LanguageItemsListView({
super.key,
required this.allLocales,
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),
),
rightIcon: currentLocale == locale
? const FlowySvg(name: 'grid/checkmark')
: null,
onTap: () {
if (currentLocale != locale) {
context.read<AppearanceSettingsCubit>().setLocale(context, locale);
}
},
),
);
}