fix: space issues (#5531)

* fix: display the space icon in breadcrumb and disable the space entry

* fix: the icon and the title are not aligned center in more menu

* fix: incorrect space icon corner radius

* fix: missed tooltip for add new page button

* fix: disable space migration for local user

* chore: use general as default space name

* fix: space name overflow

* fix: only show arrow button when hovering on page

* fix: sidebar tooltip font size

* fix: use space name as hint text

* feat: support adding a new space from space menu

* fix: filter the space view
This commit is contained in:
Lucas.Xu 2024-06-14 09:32:02 +08:00 committed by GitHub
parent e2ce274718
commit 785597f53e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 149 additions and 57 deletions

View File

@ -10,7 +10,19 @@ import 'package:collection/collection.dart';
class FavoriteService { class FavoriteService {
Future<FlowyResult<RepeatedFavoriteViewPB, FlowyError>> readFavorites() { Future<FlowyResult<RepeatedFavoriteViewPB, FlowyError>> readFavorites() {
return FolderEventReadFavorites().send(); final result = FolderEventReadFavorites().send();
return result.then((result) {
return result.fold(
(favoriteViews) {
return FlowyResult.success(
RepeatedFavoriteViewPB(
items: favoriteViews.items.where((e) => !e.item.isSpace),
),
);
},
(error) => FlowyResult.failure(error),
);
});
} }
Future<FlowyResult<void, FlowyError>> toggleFavorite( Future<FlowyResult<void, FlowyError>> toggleFavorite(

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/workspace/application/recent/recent_listener.dart'; import 'package:appflowy/workspace/application/recent/recent_listener.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
@ -65,8 +66,20 @@ class CachedRecentService {
).send(); ).send();
} }
Future<FlowyResult<RepeatedRecentViewPB, FlowyError>> _readRecentViews() => Future<FlowyResult<RepeatedRecentViewPB, FlowyError>>
FolderEventReadRecentViews().send(); _readRecentViews() async {
final result = await FolderEventReadRecentViews().send();
return result.fold(
(recentViews) {
return FlowyResult.success(
RepeatedRecentViewPB(
items: recentViews.items.where((e) => !e.item.isSpace),
),
);
},
(error) => FlowyResult.failure(error),
);
}
bool _isInitialized = false; bool _isInitialized = false;

View File

@ -69,6 +69,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
publicViews: publicViews, publicViews: publicViews,
privateViews: privateViews, privateViews: privateViews,
); );
final currentSpace = await _getLastOpenedSpace(spaces); final currentSpace = await _getLastOpenedSpace(spaces);
final isExpanded = await _getSpaceExpandStatus(currentSpace); final isExpanded = await _getSpaceExpandStatus(currentSpace);
emit( emit(
@ -79,6 +80,10 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
shouldShowUpgradeDialog: shouldShowUpgradeDialog, shouldShowUpgradeDialog: shouldShowUpgradeDialog,
), ),
); );
if (shouldShowUpgradeDialog) {
add(const SpaceEvent.migrate());
}
}, },
create: (name, icon, iconColor, permission) async { create: (name, icon, iconColor, permission) async {
final space = await _createSpace( final space = await _createSpace(
@ -391,6 +396,10 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
final isOwner = members.items final isOwner = members.items
.any((e) => e.role == AFRolePB.Owner && e.email == user.email); .any((e) => e.role == AFRolePB.Owner && e.email == user.email);
if (members.items.isEmpty) {
return true;
}
// only one member in the workspace, migrate it immediately // only one member in the workspace, migrate it immediately
// only the owner can migrate the public space // only the owner can migrate the public space
if (members.items.length == 1 || isOwner) { if (members.items.length == 1 || isOwner) {
@ -399,7 +408,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
final publicViews = final publicViews =
await _workspaceService.getPublicViews().getOrThrow(); await _workspaceService.getPublicViews().getOrThrow();
final publicSpace = await _createSpace( final publicSpace = await _createSpace(
name: 'shared', name: 'Shared',
icon: builtInSpaceIcons.first, icon: builtInSpaceIcons.first,
iconColor: builtInSpaceColors.first, iconColor: builtInSpaceColors.first,
permission: SpacePermission.publicToAll, permission: SpacePermission.publicToAll,
@ -422,7 +431,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
final privateViews = final privateViews =
await _workspaceService.getPrivateViews().getOrThrow(); await _workspaceService.getPrivateViews().getOrThrow();
final privateSpace = await _createSpace( final privateSpace = await _createSpace(
name: 'private', name: 'Private',
icon: builtInSpaceIcons.last, icon: builtInSpaceIcons.last,
iconColor: builtInSpaceColors.last, iconColor: builtInSpaceColors.last,
permission: SpacePermission.private, permission: SpacePermission.private,

View File

@ -18,6 +18,7 @@ class ViewTitleBloc extends Bloc<ViewTitleEvent, ViewTitleState> {
state.copyWith( state.copyWith(
name: view.name, name: view.name,
icon: view.icon.value, icon: view.icon.value,
view: view,
), ),
); );
@ -27,16 +28,18 @@ class ViewTitleBloc extends Bloc<ViewTitleEvent, ViewTitleState> {
ViewTitleEvent.updateNameOrIcon( ViewTitleEvent.updateNameOrIcon(
view.name, view.name,
view.icon.value, view.icon.value,
view,
), ),
); );
}, },
); );
}, },
updateNameOrIcon: (name, icon) async { updateNameOrIcon: (name, icon, view) async {
emit( emit(
state.copyWith( state.copyWith(
name: name, name: name,
icon: icon, icon: icon,
view: view,
), ),
); );
}, },
@ -58,8 +61,11 @@ class ViewTitleBloc extends Bloc<ViewTitleEvent, ViewTitleState> {
@freezed @freezed
class ViewTitleEvent with _$ViewTitleEvent { class ViewTitleEvent with _$ViewTitleEvent {
const factory ViewTitleEvent.initial() = Initial; const factory ViewTitleEvent.initial() = Initial;
const factory ViewTitleEvent.updateNameOrIcon(String name, String icon) = const factory ViewTitleEvent.updateNameOrIcon(
UpdateNameOrIcon; String name,
String icon,
ViewPB? view,
) = UpdateNameOrIcon;
} }
@freezed @freezed
@ -67,6 +73,7 @@ class ViewTitleState with _$ViewTitleState {
const factory ViewTitleState({ const factory ViewTitleState({
required String name, required String name,
required String icon, required String icon,
@Default(null) ViewPB? view,
}) = _ViewTitleState; }) = _ViewTitleState;
factory ViewTitleState.initial() => const ViewTitleState(name: '', icon: ''); factory ViewTitleState.initial() => const ViewTitleState(name: '', icon: '');

View File

@ -70,13 +70,14 @@ class SidebarTopMenu extends StatelessWidget {
children: [ children: [
TextSpan( TextSpan(
text: '${LocaleKeys.sideBar_closeSidebar.tr()}\n', text: '${LocaleKeys.sideBar_closeSidebar.tr()}\n',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: color), style:
Theme.of(context).tooltipTheme.textStyle!.copyWith(color: color),
), ),
TextSpan( TextSpan(
text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\', text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\',
style: Theme.of(context) style: Theme.of(context)
.textTheme .tooltipTheme
.bodyMedium! .textStyle!
.copyWith(color: Theme.of(context).hintColor), .copyWith(color: Theme.of(context).hintColor),
), ),
], ],
@ -91,6 +92,7 @@ class SidebarTopMenu extends StatelessWidget {
child: FlowyTooltip( child: FlowyTooltip(
richMessage: textSpan, richMessage: textSpan,
child: Listener( child: Listener(
behavior: HitTestBehavior.translucent,
onPointerDown: (_) => context onPointerDown: (_) => context
.read<HomeSettingBloc>() .read<HomeSettingBloc>()
.add(const HomeSettingEvent.collapseMenu()), .add(const HomeSettingEvent.collapseMenu()),

View File

@ -326,11 +326,12 @@ class _SidebarState extends State<_Sidebar> {
} }
Widget _renderFolderOrSpace(EdgeInsets menuHorizontalInset) { Widget _renderFolderOrSpace(EdgeInsets menuHorizontalInset) {
final spaceState = context.read<SpaceBloc>().state;
final workspaceState = context.read<UserWorkspaceBloc>().state;
// there's no space or the workspace is not collaborative, // there's no space or the workspace is not collaborative,
// show the folder section (Workspace, Private, Personal) // show the folder section (Workspace, Private, Personal)
// otherwise, show the space // otherwise, show the space
return context.watch<SpaceBloc>().state.spaces.isEmpty || return spaceState.spaces.isEmpty || !workspaceState.isCollabWorkspaceOn
!context.read<UserWorkspaceBloc>().state.isCollabWorkspaceOn
? Expanded( ? Expanded(
child: Padding( child: Padding(
padding: menuHorizontalInset - const EdgeInsets.only(right: 6), padding: menuHorizontalInset - const EdgeInsets.only(right: 6),
@ -362,7 +363,10 @@ class _SidebarState extends State<_Sidebar> {
} }
Widget _renderUpgradeSpaceButton(EdgeInsets menuHorizontalInset) { Widget _renderUpgradeSpaceButton(EdgeInsets menuHorizontalInset) {
return !context.watch<SpaceBloc>().state.shouldShowUpgradeDialog final spaceState = context.watch<SpaceBloc>().state;
final workspaceState = context.read<UserWorkspaceBloc>().state;
return !spaceState.shouldShowUpgradeDialog ||
!workspaceState.isCollabWorkspaceOn
? const SizedBox.shrink() ? const SizedBox.shrink()
: Container( : Container(
height: 40, height: 40,

View File

@ -15,9 +15,9 @@ class CreateSpacePopup extends StatefulWidget {
} }
class _CreateSpacePopupState extends State<CreateSpacePopup> { class _CreateSpacePopupState extends State<CreateSpacePopup> {
String spaceName = ''; String spaceName = LocaleKeys.space_defaultSpaceName.tr();
String spaceIcon = ''; String spaceIcon = builtInSpaceIcons.first;
String spaceIconColor = ''; String spaceIconColor = builtInSpaceColors.first;
SpacePermission spacePermission = SpacePermission.publicToAll; SpacePermission spacePermission = SpacePermission.publicToAll;
@override @override
@ -98,7 +98,7 @@ class _SpaceNameTextField extends StatelessWidget {
SizedBox( SizedBox(
height: 40, height: 40,
child: FlowyTextField( child: FlowyTextField(
hintText: 'Untitled space', text: LocaleKeys.space_defaultSpaceName.tr(),
onChanged: onChanged, onChanged: onChanged,
), ),
), ),

View File

@ -99,6 +99,7 @@ class _SpaceNameTextField extends StatelessWidget {
SizedBox.square( SizedBox.square(
dimension: 40, dimension: 40,
child: SpaceIconPopup( child: SpaceIconPopup(
cornerRadius: 12,
icon: space?.spaceIcon, icon: space?.spaceIcon,
iconColor: space?.spaceIconColor, iconColor: space?.spaceIconColor,
onIconChanged: onIconChanged, onIconChanged: onIconChanged,

View File

@ -10,6 +10,7 @@ import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/rename_view_dialog.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/rename_view_dialog.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/create_space_popup.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
@ -79,33 +80,47 @@ class _SpaceState extends State<_Space> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<SpaceBloc, SpaceState>( return BlocBuilder<SpaceBloc, SpaceState>(
builder: (context, state) { builder: (context, state) {
// final isCollaborativeWorkspace =
// context.read<UserWorkspaceBloc>().state.isCollabWorkspaceOn;
if (state.spaces.isEmpty) { if (state.spaces.isEmpty) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
final currentSpace = state.currentSpace ?? state.spaces.first; final currentSpace = state.currentSpace ?? state.spaces.first;
return MouseRegion( return Column(
onEnter: (_) => isHovered.value = true, children: [
onExit: (_) => isHovered.value = false, SidebarSpaceHeader(
child: Column( isExpanded: state.isExpanded,
children: [ space: currentSpace,
SidebarSpaceHeader( onAdded: () => _showCreatePagePopup(context, currentSpace),
isExpanded: state.isExpanded, onCreateNewSpace: () => _showCreateSpaceDialog(context),
space: currentSpace, ),
onAdded: () => _showCreatePagePopup(context, currentSpace), MouseRegion(
onPressed: () {}, onEnter: (_) => isHovered.value = true,
onTapMore: () {}, onExit: (_) => isHovered.value = false,
), child: _Pages(
_Pages(
key: ValueKey(currentSpace.id), key: ValueKey(currentSpace.id),
space: currentSpace, space: currentSpace,
isHovered: isHovered, isHovered: isHovered,
), ),
], ),
],
);
},
);
}
void _showCreateSpaceDialog(BuildContext context) {
final spaceBloc = context.read<SpaceBloc>();
showDialog(
context: context,
builder: (_) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: BlocProvider.value(
value: spaceBloc,
child: const CreateSpacePopup(),
), ),
); );
}, },

View File

@ -20,16 +20,14 @@ class SidebarSpaceHeader extends StatefulWidget {
const SidebarSpaceHeader({ const SidebarSpaceHeader({
super.key, super.key,
required this.space, required this.space,
required this.onPressed,
required this.onAdded, required this.onAdded,
required this.onTapMore, required this.onCreateNewSpace,
required this.isExpanded, required this.isExpanded,
}); });
final ViewPB space; final ViewPB space;
final VoidCallback onPressed;
final VoidCallback onAdded; final VoidCallback onAdded;
final VoidCallback onTapMore; final VoidCallback onCreateNewSpace;
final bool isExpanded; final bool isExpanded;
@override @override
@ -73,6 +71,7 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
// rightIcon: _buildRightIcon(), // rightIcon: _buildRightIcon(),
iconPadding: 10.0, iconPadding: 10.0,
text: _buildChild(), text: _buildChild(),
rightIcon: const HSpace(60.0),
), ),
), ),
Positioned( Positioned(
@ -95,10 +94,13 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
cornerRadius: 6.0, cornerRadius: 6.0,
), ),
const HSpace(10), const HSpace(10),
FlowyText.medium( Flexible(
widget.space.name, child: FlowyText.medium(
lineHeight: 1.15, widget.space.name,
fontSize: 14.0, lineHeight: 1.15,
fontSize: 14.0,
overflow: TextOverflow.ellipsis,
),
), ),
const HSpace(4.0), const HSpace(4.0),
FlowySvg( FlowySvg(
@ -127,6 +129,7 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
const HSpace(8.0), const HSpace(8.0),
FlowyIconButton( FlowyIconButton(
width: 24, width: 24,
tooltipText: LocaleKeys.sideBar_addAPage.tr(),
iconPadding: const EdgeInsets.all(4.0), iconPadding: const EdgeInsets.all(4.0),
icon: const FlowySvg(FlowySvgs.view_item_add_s), icon: const FlowySvg(FlowySvgs.view_item_add_s),
onPressed: widget.onAdded, onPressed: widget.onAdded,
@ -150,6 +153,7 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
_showManageSpaceDialog(context); _showManageSpaceDialog(context);
break; break;
case SpaceMoreActionType.addNewSpace: case SpaceMoreActionType.addNewSpace:
widget.onCreateNewSpace();
break; break;
case SpaceMoreActionType.collapseAllPages: case SpaceMoreActionType.collapseAllPages:
break; break;
@ -166,6 +170,7 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
title: LocaleKeys.space_rename.tr(), title: LocaleKeys.space_rename.tr(),
value: widget.space.name, value: widget.space.name,
autoSelectAllText: true, autoSelectAllText: true,
hintText: LocaleKeys.space_spaceName.tr(),
onConfirm: (name, _) { onConfirm: (name, _) {
context.read<SpaceBloc>().add(SpaceEvent.rename(widget.space, name)); context.read<SpaceBloc>().add(SpaceEvent.rename(widget.space, name));
}, },

View File

@ -29,12 +29,14 @@ class SpaceIconPopup extends StatefulWidget {
super.key, super.key,
this.icon, this.icon,
this.iconColor, this.iconColor,
this.cornerRadius = 16,
required this.onIconChanged, required this.onIconChanged,
}); });
final String? icon; final String? icon;
final String? iconColor; final String? iconColor;
final void Function(String icon, String color) onIconChanged; final void Function(String icon, String color) onIconChanged;
final double cornerRadius;
@override @override
State<SpaceIconPopup> createState() => _SpaceIconPopupState(); State<SpaceIconPopup> createState() => _SpaceIconPopupState();
@ -93,7 +95,7 @@ class _SpaceIconPopupState extends State<SpaceIconPopup> {
valueListenable: selectedIcon, valueListenable: selectedIcon,
builder: (_, icon, __) { builder: (_, icon, __) {
final child = ClipRRect( final child = ClipRRect(
borderRadius: BorderRadius.circular(16.0), borderRadius: BorderRadius.circular(widget.cornerRadius),
child: FlowySvg( child: FlowySvg(
FlowySvgData('assets/flowy_icons/16x/$icon.svg'), FlowySvgData('assets/flowy_icons/16x/$icon.svg'),
color: Color(int.parse(color)), color: Color(int.parse(color)),

View File

@ -40,6 +40,7 @@ class SpaceMorePopup extends StatelessWidget {
return FlowyIconButton( return FlowyIconButton(
width: 24, width: 24,
icon: const FlowySvg(FlowySvgs.workspace_three_dots_s), icon: const FlowySvg(FlowySvgs.workspace_three_dots_s),
tooltipText: LocaleKeys.space_manage.tr(),
onPressed: () { onPressed: () {
onEditing(true); onEditing(true);
popover.show(); popover.show();
@ -68,9 +69,8 @@ class SpaceMorePopup extends StatelessWidget {
SpaceMoreActionType.rename, SpaceMoreActionType.rename,
SpaceMoreActionType.changeIcon, SpaceMoreActionType.changeIcon,
SpaceMoreActionType.manage, SpaceMoreActionType.manage,
// SpaceMoreActionType.divider, SpaceMoreActionType.divider,
// SpaceMoreActionType.addNewSpace, SpaceMoreActionType.addNewSpace,
// SpaceMoreActionType.collapseAllPages,
SpaceMoreActionType.divider, SpaceMoreActionType.divider,
SpaceMoreActionType.delete, SpaceMoreActionType.delete,
]; ];
@ -163,7 +163,7 @@ class SpaceMoreActionTypeWrapper extends CustomActionCell {
rightIcon: inner.rightIcon, rightIcon: inner.rightIcon,
iconPadding: 10.0, iconPadding: 10.0,
text: SizedBox( text: SizedBox(
height: 18.0, // height: 16.0,
child: FlowyText.regular( child: FlowyText.regular(
inner.name, inner.name,
color: inner == SpaceMoreActionType.delete color: inner == SpaceMoreActionType.delete

View File

@ -72,15 +72,15 @@ class FlowyNavigation extends StatelessWidget {
TextSpan( TextSpan(
text: '${LocaleKeys.sideBar_openSidebar.tr()}\n', text: '${LocaleKeys.sideBar_openSidebar.tr()}\n',
style: Theme.of(context) style: Theme.of(context)
.textTheme .tooltipTheme
.bodyMedium! .textStyle!
.copyWith(color: color), .copyWith(color: color),
), ),
TextSpan( TextSpan(
text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\', text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\',
style: Theme.of(context) style: Theme.of(context)
.textTheme .tooltipTheme
.bodyMedium! .textStyle!
.copyWith(color: Theme.of(context).hintColor), .copyWith(color: Theme.of(context).hintColor),
), ),
], ],

View File

@ -3,6 +3,7 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/application/view_title/view_title_bar_bloc.dart'; import 'package:appflowy/workspace/application/view_title/view_title_bar_bloc.dart';
import 'package:appflowy/workspace/application/view_title/view_title_bloc.dart'; import 'package:appflowy/workspace/application/view_title/view_title_bloc.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon.dart';
import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart'; import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/appflowy_popover.dart';
@ -153,6 +154,8 @@ class _ViewTitleState extends State<_ViewTitle> {
const HSpace(4.0), const HSpace(4.0),
], ],
); );
} else if (widget.view.isSpace) {
return _buildSpaceTitle(context, state);
} else if (isEditable) { } else if (isEditable) {
return _buildEditableViewTitle(context, state); return _buildEditableViewTitle(context, state);
} else { } else {
@ -163,6 +166,14 @@ class _ViewTitleState extends State<_ViewTitle> {
); );
} }
Widget _buildSpaceTitle(BuildContext context, ViewTitleState state) {
return Container(
alignment: Alignment.center,
margin: const EdgeInsets.symmetric(horizontal: 6.0),
child: _buildIconAndName(state, false),
);
}
Widget _buildUnEditableViewTitle(BuildContext context, ViewTitleState state) { Widget _buildUnEditableViewTitle(BuildContext context, ViewTitleState state) {
return Listener( return Listener(
onPointerDown: (_) => context.read<TabsBloc>().openPlugin(widget.view), onPointerDown: (_) => context.read<TabsBloc>().openPlugin(widget.view),
@ -171,7 +182,6 @@ class _ViewTitleState extends State<_ViewTitle> {
child: FlowyButton( child: FlowyButton(
useIntrinsicWidth: true, useIntrinsicWidth: true,
margin: const EdgeInsets.symmetric(horizontal: 6.0), margin: const EdgeInsets.symmetric(horizontal: 6.0),
onTap: () {},
text: _buildIconAndName(state, false), text: _buildIconAndName(state, false),
), ),
), ),
@ -220,6 +230,15 @@ class _ViewTitleState extends State<_ViewTitle> {
), ),
const HSpace(4.0), const HSpace(4.0),
], ],
if (state.view?.isSpace == true &&
state.view?.spaceIconSvg != null) ...[
SpaceIcon(
dimension: 14,
space: state.view!,
cornerRadius: 4,
),
const HSpace(6.0),
],
Opacity( Opacity(
opacity: isEditable ? 1.0 : 0.5, opacity: isEditable ? 1.0 : 0.5,
child: FlowyText.regular( child: FlowyText.regular(

View File

@ -254,7 +254,7 @@
"clickToHideWorkspace": "Click to hide workspace\nPages you created here are visible to every member", "clickToHideWorkspace": "Click to hide workspace\nPages you created here are visible to every member",
"clickToHidePersonal": "Click to hide personal space", "clickToHidePersonal": "Click to hide personal space",
"clickToHideFavorites": "Click to hide favorite space", "clickToHideFavorites": "Click to hide favorite space",
"addAPage": "Add a page", "addAPage": "Add a new page",
"addAPageToPrivate": "Add a page to private space", "addAPageToPrivate": "Add a page to private space",
"addAPageToWorkspace": "Add a page to workspace", "addAPageToWorkspace": "Add a page to workspace",
"recent": "Recent", "recent": "Recent",
@ -1912,6 +1912,7 @@
"unableToDeleteLastSpace": "Cannot delete the last space", "unableToDeleteLastSpace": "Cannot delete the last space",
"unableToDeleteSpaceNotCreatedByYou": "Cannot delete a space created by others", "unableToDeleteSpaceNotCreatedByYou": "Cannot delete a space created by others",
"enableSpacesForYourWorkspace": "Enable spaces for your workspace", "enableSpacesForYourWorkspace": "Enable spaces for your workspace",
"title": "Spaces" "title": "Spaces",
"defaultSpaceName": "General"
} }
} }

View File

@ -1235,11 +1235,12 @@ pub(crate) fn get_workspace_public_view_pbs(workspace_id: &str, folder: &Folder)
.into_iter() .into_iter()
.map(|view| { .map(|view| {
// Get child views // Get child views
let child_views = folder let mut child_views: Vec<Arc<View>> = folder
.views .views
.get_views_belong_to(&view.id) .get_views_belong_to(&view.id)
.into_iter() .into_iter()
.collect(); .collect();
child_views.retain(|view| !trash_ids.contains(&view.id));
view_pb_with_child_views(view, child_views) view_pb_with_child_views(view, child_views)
}) })
.collect() .collect()
@ -1284,11 +1285,12 @@ pub(crate) fn get_workspace_private_view_pbs(workspace_id: &str, folder: &Folder
.into_iter() .into_iter()
.map(|view| { .map(|view| {
// Get child views // Get child views
let child_views = folder let mut child_views: Vec<Arc<View>> = folder
.views .views
.get_views_belong_to(&view.id) .get_views_belong_to(&view.id)
.into_iter() .into_iter()
.collect(); .collect();
child_views.retain(|view| !trash_ids.contains(&view.id));
view_pb_with_child_views(view, child_views) view_pb_with_child_views(view, child_views)
}) })
.collect() .collect()