mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
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:
parent
e2ce274718
commit
785597f53e
@ -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(
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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: '');
|
||||||
|
@ -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()),
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
|
||||||
onExit: (_) => isHovered.value = false,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
children: [
|
||||||
SidebarSpaceHeader(
|
SidebarSpaceHeader(
|
||||||
isExpanded: state.isExpanded,
|
isExpanded: state.isExpanded,
|
||||||
space: currentSpace,
|
space: currentSpace,
|
||||||
onAdded: () => _showCreatePagePopup(context, currentSpace),
|
onAdded: () => _showCreatePagePopup(context, currentSpace),
|
||||||
onPressed: () {},
|
onCreateNewSpace: () => _showCreateSpaceDialog(context),
|
||||||
onTapMore: () {},
|
|
||||||
),
|
),
|
||||||
_Pages(
|
MouseRegion(
|
||||||
|
onEnter: (_) => isHovered.value = true,
|
||||||
|
onExit: (_) => isHovered.value = false,
|
||||||
|
child: _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(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -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(
|
||||||
|
child: FlowyText.medium(
|
||||||
widget.space.name,
|
widget.space.name,
|
||||||
lineHeight: 1.15,
|
lineHeight: 1.15,
|
||||||
fontSize: 14.0,
|
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));
|
||||||
},
|
},
|
||||||
|
@ -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)),
|
||||||
|
@ -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
|
||||||
|
@ -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),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -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(
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user