chore: update translations (#6124)

* chore: update translations

* fix: close popup menu when tapping navigation bar item

* chore: update toolbar divider color and popup menu background color

* chore: update translations and icon

* chore: update frontend/appflowy_flutter/lib/shared/popup_menu/appflowy_popup_menu.dart

Co-authored-by: Mathias Mogensen <42929161+Xazin@users.noreply.github.com>

---------

Co-authored-by: Mathias Mogensen <42929161+Xazin@users.noreply.github.com>
This commit is contained in:
Lucas.Xu 2024-08-30 19:19:41 +08:00 committed by GitHub
parent 78c2e756d6
commit 928da2a223
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 178 additions and 69 deletions

View File

@ -64,11 +64,7 @@ class MobileHomeTrashPage extends StatelessWidget {
],
),
body: state.objects.isEmpty
? FlowyMobileStateContainer.info(
emoji: '🗑️',
title: LocaleKeys.trash_mobile_empty.tr(),
description: LocaleKeys.trash_mobile_emptyDescription.tr(),
)
? const _EmptyTrashBin()
: _DeletedFilesListView(state),
);
},
@ -82,6 +78,41 @@ enum _TrashActionType {
deleteAll,
}
class _EmptyTrashBin extends StatelessWidget {
const _EmptyTrashBin();
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const FlowySvg(
FlowySvgs.m_empty_trash_xl,
size: Size.square(46),
),
const VSpace(16.0),
FlowyText.medium(
LocaleKeys.trash_mobile_empty.tr(),
fontSize: 18.0,
textAlign: TextAlign.center,
),
const VSpace(8.0),
FlowyText.regular(
LocaleKeys.trash_mobile_emptyDescription.tr(),
fontSize: 17.0,
maxLines: 10,
textAlign: TextAlign.center,
lineHeight: 1.3,
color: Theme.of(context).hintColor,
),
const VSpace(kBottomNavigationBarHeight + 36.0),
],
),
);
}
}
class _TrashActionAllButton extends StatelessWidget {
/// Switch between 'delete all' and 'restore all' feature
const _TrashActionAllButton({

View File

@ -22,6 +22,7 @@ class HomePageSettingsPopupMenu extends StatelessWidget {
@override
Widget build(BuildContext context) {
return PopupMenuButton<_MobileSettingsPopupMenuItem>(
offset: const Offset(0, 36),
padding: EdgeInsets.zero,
@ -32,13 +33,7 @@ class HomePageSettingsPopupMenu extends StatelessWidget {
),
shadowColor: const Color(0x68000000),
elevation: 10,
color: Theme.of(context).colorScheme.surface,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: FlowySvg(
FlowySvgs.m_settings_more_s,
),
),
color: context.popupMenuBackgroundColor,
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<_MobileSettingsPopupMenuItem>>[
_buildItem(
@ -81,6 +76,12 @@ class HomePageSettingsPopupMenu extends StatelessWidget {
break;
}
},
child: const Padding(
padding: EdgeInsets.all(8.0),
child: FlowySvg(
FlowySvgs.m_settings_more_s,
),
),
);
}

View File

@ -6,7 +6,10 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
class EmptySpacePlaceholder extends StatelessWidget {
const EmptySpacePlaceholder({super.key, required this.type});
const EmptySpacePlaceholder({
super.key,
required this.type,
});
final MobilePageCardType type;

View File

@ -1,9 +1,11 @@
import 'dart:io';
import 'dart:ui';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/notifications/mobile_notifications_screen.dart';
import 'package:appflowy/mobile/presentation/widgets/navigation_bar_button.dart';
import 'package:appflowy/shared/popup_menu/appflowy_popup_menu.dart';
import 'package:appflowy/shared/red_dot.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
@ -193,25 +195,44 @@ class _HomePageNavigationBar extends StatelessWidget {
border: context.border,
color: context.backgroundColor,
),
child: BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
enableFeedback: false,
type: BottomNavigationBarType.fixed,
elevation: 0,
items: _items,
backgroundColor: Colors.transparent,
currentIndex: navigationShell.currentIndex,
onTap: (int bottomBarIndex) => _onTap(context, bottomBarIndex),
child: Theme(
data: _getThemeData(context),
child: BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
enableFeedback: false,
type: BottomNavigationBarType.fixed,
elevation: 0,
items: _items,
backgroundColor: Colors.transparent,
currentIndex: navigationShell.currentIndex,
onTap: (int bottomBarIndex) => _onTap(context, bottomBarIndex),
),
),
),
),
);
}
ThemeData _getThemeData(BuildContext context) {
if (Platform.isAndroid) {
return Theme.of(context);
}
// hide the splash effect for iOS
return Theme.of(context).copyWith(
splashFactory: NoSplash.splashFactory,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
);
}
/// Navigate to the current location of the branch at the provided index when
/// tapping an item in the BottomNavigationBar.
void _onTap(BuildContext context, int bottomBarIndex) {
// close the popup menu
closePopupMenu();
final label = _items[bottomBarIndex].label;
if (label == _addLabel) {
// show an add dialog

View File

@ -36,12 +36,7 @@ class NotificationSettingsPopupMenu extends StatelessWidget {
// todo: replace it with shadows
shadowColor: const Color(0x68000000),
elevation: 10,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: FlowySvg(
FlowySvgs.m_settings_more_s,
),
),
color: context.popupMenuBackgroundColor,
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<_NotificationSettingsPopupMenuItem>>[
_buildItem(
@ -87,6 +82,12 @@ class NotificationSettingsPopupMenu extends StatelessWidget {
break;
}
},
child: const Padding(
padding: EdgeInsets.all(8.0),
child: FlowySvg(
FlowySvgs.m_settings_more_s,
),
),
);
}

View File

@ -245,12 +245,12 @@ class _MobileToolbarState extends State<_MobileToolbar>
children: [
const Divider(
height: 0.5,
color: Color(0xFFEDEDED),
color: Color(0x7FEDEDED),
),
_buildToolbar(context),
const Divider(
height: 0.5,
color: Color(0xFFEDEDED),
color: Color(0x7FEDEDED),
),
_buildMenuOrSpacer(context),
],

View File

@ -264,7 +264,13 @@ final referencedDocSlashMenuItem = SelectionMenuItem(
isSelected: isSelected,
style: style,
),
keywords: ['page', 'notes', 'referenced page', 'referenced document'],
keywords: [
'page',
'notes',
'referenced page',
'referenced document',
'link to page',
],
handler: (editorState, menuService, context) => showLinkToPageMenu(
editorState,
menuService,

View File

@ -33,6 +33,12 @@ const double _kMenuVerticalPadding = 8.0;
const double _kMenuWidthStep = 56.0;
const double _kMenuScreenPadding = 8.0;
GlobalKey<_PopupMenuState>? _kPopupMenuKey;
void closePopupMenu() {
_kPopupMenuKey?.currentState?.dismiss();
_kPopupMenuKey = null;
}
/// A base class for entries in a Material Design popup menu.
///
/// The popup menu widget uses this interface to interact with the menu items.
@ -569,7 +575,7 @@ class _CheckedPopupMenuItemState<T>
}
}
class _PopupMenu<T> extends StatelessWidget {
class _PopupMenu<T> extends StatefulWidget {
const _PopupMenu({
super.key,
required this.itemKeys,
@ -585,10 +591,15 @@ class _PopupMenu<T> extends StatelessWidget {
final BoxConstraints? constraints;
final Clip clipBehavior;
@override
State<_PopupMenu<T>> createState() => _PopupMenuState<T>();
}
class _PopupMenuState<T> extends State<_PopupMenu<T>> {
@override
Widget build(BuildContext context) {
final double unit = 1.0 /
(route.items.length +
(widget.route.items.length +
1.5); // 1.0 for the width and 0.5 for the last item's fade.
final List<Widget> children = <Widget>[];
final ThemeData theme = Theme.of(context);
@ -597,16 +608,16 @@ class _PopupMenu<T> extends StatelessWidget {
? _PopupMenuDefaultsM3(context)
: _PopupMenuDefaultsM2(context);
for (int i = 0; i < route.items.length; i += 1) {
for (int i = 0; i < widget.route.items.length; i += 1) {
final double start = (i + 1) * unit;
final double end = clampDouble(start + 1.5 * unit, 0.0, 1.0);
final CurvedAnimation opacity = CurvedAnimation(
parent: route.animation!,
parent: widget.route.animation!,
curve: Interval(start, end),
);
Widget item = route.items[i];
if (route.initialValue != null &&
route.items[i].represents(route.initialValue)) {
Widget item = widget.route.items[i];
if (widget.route.initialValue != null &&
widget.route.items[i].represents(widget.route.initialValue)) {
item = ColoredBox(
color: Theme.of(context).highlightColor,
child: item,
@ -615,10 +626,10 @@ class _PopupMenu<T> extends StatelessWidget {
children.add(
_MenuItem(
onLayout: (Size size) {
route.itemSizes[i] = size;
widget.route.itemSizes[i] = size;
},
child: FadeTransition(
key: itemKeys[i],
key: widget.itemKeys[i],
opacity: opacity,
child: item,
),
@ -630,10 +641,10 @@ class _PopupMenu<T> extends StatelessWidget {
CurveTween(curve: const Interval(0.0, 1.0 / 3.0));
final CurveTween width = CurveTween(curve: Interval(0.0, unit));
final CurveTween height =
CurveTween(curve: Interval(0.0, unit * route.items.length));
CurveTween(curve: Interval(0.0, unit * widget.route.items.length));
final Widget child = ConstrainedBox(
constraints: constraints ??
constraints: widget.constraints ??
const BoxConstraints(
minWidth: _kMenuMinWidth,
maxWidth: _kMenuMaxWidth,
@ -644,7 +655,7 @@ class _PopupMenu<T> extends StatelessWidget {
scopesRoute: true,
namesRoute: true,
explicitChildNodes: true,
label: semanticLabel,
label: widget.semanticLabel,
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(
vertical: _kMenuVerticalPadding,
@ -656,28 +667,28 @@ class _PopupMenu<T> extends StatelessWidget {
);
return AnimatedBuilder(
animation: route.animation!,
animation: widget.route.animation!,
builder: (BuildContext context, Widget? child) {
return FadeTransition(
opacity: opacity.animate(route.animation!),
opacity: opacity.animate(widget.route.animation!),
child: Material(
shape: route.shape ?? popupMenuTheme.shape ?? defaults.shape,
color: route.color ?? popupMenuTheme.color ?? defaults.color,
clipBehavior: clipBehavior,
shape: widget.route.shape ?? popupMenuTheme.shape ?? defaults.shape,
color: widget.route.color ?? popupMenuTheme.color ?? defaults.color,
clipBehavior: widget.clipBehavior,
type: MaterialType.card,
elevation: route.elevation ??
elevation: widget.route.elevation ??
popupMenuTheme.elevation ??
defaults.elevation!,
shadowColor: route.shadowColor ??
shadowColor: widget.route.shadowColor ??
popupMenuTheme.shadowColor ??
defaults.shadowColor,
surfaceTintColor: route.surfaceTintColor ??
surfaceTintColor: widget.route.surfaceTintColor ??
popupMenuTheme.surfaceTintColor ??
defaults.surfaceTintColor,
child: Align(
alignment: AlignmentDirectional.topEnd,
widthFactor: width.evaluate(route.animation!),
heightFactor: height.evaluate(route.animation!),
widthFactor: width.evaluate(widget.route.animation!),
heightFactor: height.evaluate(widget.route.animation!),
child: child,
),
),
@ -686,6 +697,21 @@ class _PopupMenu<T> extends StatelessWidget {
child: child,
);
}
@override
void dispose() {
_kPopupMenuKey = null;
super.dispose();
}
void dismiss() {
if (_kPopupMenuKey == null) {
return;
}
Navigator.of(context).pop();
_kPopupMenuKey = null;
}
}
// Positioning of the menu on the screen.
@ -937,7 +963,9 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
scrollTo(selectedItemIndex);
}
_kPopupMenuKey ??= GlobalKey<_PopupMenuState>();
final Widget menu = _PopupMenu<T>(
key: _kPopupMenuKey,
route: this,
itemKeys: itemKeys,
semanticLabel: semanticLabel,
@ -1526,7 +1554,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
if (widget.child != null) {
return AnimatedGestureDetector(
scaleFactor: 0.99,
scaleFactor: 0.95,
onTapUp: widget.enabled ? showButtonMenu : null,
child: widget.child!,
);
@ -1607,3 +1635,12 @@ class _PopupMenuDefaultsM3 extends PopupMenuThemeData {
const EdgeInsets.symmetric(horizontal: 12.0);
}
// END GENERATED TOKEN PROPERTIES - PopupMenu
extension PopupMenuColors on BuildContext {
Color get popupMenuBackgroundColor {
if (Theme.of(this).brightness == Brightness.light) {
return Theme.of(this).colorScheme.surface;
}
return const Color(0xFF23262B);
}
}

View File

@ -0,0 +1,9 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.6">
<path d="M49 10.5517C40.1201 9.7597 31.1865 9.35171 22.2799 9.35171C16.9999 9.35171 11.7199 9.5917 6.44 10.0717L1 10.5517" stroke="#171717" stroke-width="1.83" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15.6652 8.12783L16.2518 4.98388C16.6785 2.70395 16.9985 1 21.5051 1H28.4918C32.9984 1 33.3451 2.79995 33.7451 5.00788L34.3317 8.12783" stroke="#171717" stroke-width="1.83" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M43.2662 18.137L41.5329 42.3042C41.2396 46.0721 40.9996 49 33.5596 49H16.4397C8.99973 49 8.75973 46.0721 8.46635 42.3042L6.73303 18.137" stroke="#171717" stroke-width="1.83" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M20.5466 35.799H29.4266" stroke="#171717" stroke-width="1.83" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.3333 26.1992H31.6666" stroke="#171717" stroke-width="1.83" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -49,7 +49,7 @@
"syncPromptMessage": "Syncing the data might take a while. Please don't close this page",
"or": "OR",
"signInWithGoogle": "Continue with Google",
"signInWithGithub": "Continue with Github",
"signInWithGithub": "Continue with GitHub",
"signInWithDiscord": "Continue with Discord",
"signInWithApple": "Continue with Apple",
"continueAnotherWay": "Continue another way",
@ -144,8 +144,8 @@
"rename": "Rename",
"delete": "Delete",
"duplicate": "Duplicate",
"unfavorite": "Remove from favorites",
"favorite": "Add to favorites",
"unfavorite": "Remove from Favorites",
"favorite": "Add to Favorites",
"openNewTab": "Open in a new tab",
"moveTo": "Move to",
"addToFavorites": "Add to Favorites",
@ -204,8 +204,8 @@
},
"mobile": {
"actions": "Trash Actions",
"empty": "Trash Bin is Empty",
"emptyDescription": "You don't have any deleted file",
"empty": "No pages or spaces in Trash",
"emptyDescription": "Move things you don't need to the Trash.",
"isDeleted": "is deleted",
"isRestored": "is restored"
},
@ -347,9 +347,9 @@
"putback": "Put Back",
"update": "Update",
"share": "Share",
"removeFromFavorites": "Remove from favorites",
"removeFromRecent": "Remove from recent",
"addToFavorites": "Add to favorites",
"removeFromFavorites": "Remove from Favorites",
"removeFromRecent": "Remove from Recent",
"addToFavorites": "Add to Favorites",
"favoriteSuccessfully": "Favorited success",
"unfavoriteSuccessfully": "Unfavorited success",
"duplicateSuccessfully": "Duplicated successfully",
@ -368,7 +368,7 @@
"deleteAccount": "Delete account",
"back": "Back",
"signInGoogle": "Continue with Google",
"signInGithub": "Continue with Github",
"signInGithub": "Continue with GitHub",
"signInDiscord": "Continue with Discord",
"more": "More",
"create": "Create",
@ -997,16 +997,16 @@
"archiveAll": "Archive all"
},
"emptyInbox": {
"title": "No notifications yet",
"description": "You'll be notified here for @mentions"
"title": "Inbox Zero!",
"description": "Set reminders to receive notifications here."
},
"emptyUnread": {
"title": "No unread notifications",
"description": "You're all caught up!"
},
"emptyArchived": {
"title": "No archived notifications",
"description": "You haven't archived any notifications yet"
"title": "No archived",
"description": "Archived notifications will appear here."
},
"tabs": {
"inbox": "Inbox",
@ -2505,4 +2505,4 @@
"uploadFailedDescription": "The file upload failed",
"uploadingDescription": "The file is being uploaded"
}
}
}