feat: optimize the workspace menu loading speed (#6758)

* feat: optimize the workspace menu loading speed

* chore: add workspace menu animation

* feat: optimize workspace menu loading speed on mobile

* test: workspace member count test

* fix: rust ci
This commit is contained in:
Lucas 2024-11-13 20:36:15 +08:00 committed by GitHub
parent 57933736ea
commit cd3be696dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 87 additions and 61 deletions

View File

@ -43,6 +43,7 @@ jobs:
cp deploy.env .env cp deploy.env .env
sed -i '' 's|RUST_LOG=.*|RUST_LOG=trace|' .env sed -i '' 's|RUST_LOG=.*|RUST_LOG=trace|' .env
sed -i '' 's|API_EXTERNAL_URL=.*|API_EXTERNAL_URL=http://localhost|' .env sed -i '' 's|API_EXTERNAL_URL=.*|API_EXTERNAL_URL=http://localhost|' .env
sed -i '' 's|APPFLOWY_AI_OPENAI_API_KEY=.*|APPFLOWY_AI_OPENAI_API_KEY=${{ secrets.CI_OPENAI_API_KEY }}|' .env
- name: Ensure AppFlowy-Cloud is Running with Correct Version - name: Ensure AppFlowy-Cloud is Running with Correct Version
working-directory: AppFlowy-Cloud working-directory: AppFlowy-Cloud

View File

@ -74,5 +74,32 @@ void main() {
}, },
); );
}); });
testWidgets('check the member count immediately after creating a workspace',
(tester) async {
// only run the test when the feature flag is on
if (!FeatureFlag.collaborativeWorkspace.isOn) {
return;
}
await tester.initializeAppFlowy(
cloudType: AuthenticatorType.appflowyCloudSelfHost,
);
await tester.tapGoogleLoginInButton();
await tester.expectToSeeHomePageWithGetStartedPage();
const name = 'AppFlowy.IO';
// the workspace will be opened after created
await tester.createCollaborativeWorkspace(name);
final loading = find.byType(Loading);
await tester.pumpUntilNotFound(loading);
await tester.openCollaborativeWorkspaceMenu();
// expect to see the member count
final memberCount = find.text('1 member');
expect(memberCount, findsNWidgets(2));
});
}); });
} }

View File

@ -234,6 +234,7 @@ class _WorkspaceMenuItemContent extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final memberCount = workspace.memberCount.toInt();
return Padding( return Padding(
padding: const EdgeInsets.only(left: 12), padding: const EdgeInsets.only(left: 12),
child: Column( child: Column(
@ -247,10 +248,10 @@ class _WorkspaceMenuItemContent extends StatelessWidget {
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
FlowyText( FlowyText(
context.read<WorkspaceMemberBloc>().state.isLoading memberCount == 0
? '' ? ''
: LocaleKeys.settings_appearance_members_membersCount.plural( : LocaleKeys.settings_appearance_members_membersCount.plural(
context.read<WorkspaceMemberBloc>().state.members.length, memberCount,
), ),
fontSize: 10.0, fontSize: 10.0,
color: Theme.of(context).hintColor, color: Theme.of(context).hintColor,

View File

@ -170,7 +170,7 @@ class _WorkspaceMoreActionWrapper extends CustomActionCell {
switch (inner) { switch (inner) {
case WorkspaceMoreAction.delete: case WorkspaceMoreAction.delete:
return FlowySvg( return FlowySvg(
FlowySvgs.delete_s, FlowySvgs.trash_s,
color: onHover ? Theme.of(context).colorScheme.error : null, color: onHover ? Theme.of(context).colorScheme.error : null,
); );
case WorkspaceMoreAction.rename: case WorkspaceMoreAction.rename:

View File

@ -196,13 +196,10 @@ class _WorkspaceMenuItemState extends State<WorkspaceMenuItem> {
} }
Widget _buildRightIcon(BuildContext context, ValueNotifier<bool> isHovered) { Widget _buildRightIcon(BuildContext context, ValueNotifier<bool> isHovered) {
// only the owner can update or delete workspace.
if (context.read<WorkspaceMemberBloc>().state.isLoading) {
return const SizedBox.shrink();
}
return Row( return Row(
children: [ children: [
// only the owner can update or delete workspace.
if (!context.read<WorkspaceMemberBloc>().state.isLoading)
ValueListenableBuilder( ValueListenableBuilder(
valueListenable: isHovered, valueListenable: isHovered,
builder: (context, value, child) { builder: (context, value, child) {
@ -244,9 +241,7 @@ class _WorkspaceInfo extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<WorkspaceMemberBloc, WorkspaceMemberState>( final memberCount = workspace.memberCount.toInt();
builder: (context, state) {
final members = state.members;
return FlowyButton( return FlowyButton(
onTap: () => _openWorkspace(context), onTap: () => _openWorkspace(context),
iconPadding: 10.0, iconPadding: 10.0,
@ -267,11 +262,10 @@ class _WorkspaceInfo extends StatelessWidget {
), ),
// workspace members count // workspace members count
FlowyText.regular( FlowyText.regular(
state.isLoading memberCount == 0
? '' ? ''
: LocaleKeys.settings_appearance_members_membersCount : LocaleKeys.settings_appearance_members_membersCount.plural(
.plural( memberCount,
members.length,
), ),
fontSize: 10.0, fontSize: 10.0,
figmaLineHeight: 12.0, figmaLineHeight: 12.0,
@ -280,8 +274,6 @@ class _WorkspaceInfo extends StatelessWidget {
], ],
), ),
); );
},
);
} }
void _openWorkspace(BuildContext context) { void _openWorkspace(BuildContext context) {

View File

@ -204,9 +204,12 @@ class _SidebarSwitchWorkspaceButtonState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AppFlowyPopover( return AppFlowyPopover(
direction: PopoverDirection.bottomWithLeftAligned, direction: PopoverDirection.bottomWithCenterAligned,
offset: const Offset(0, 5), offset: const Offset(0, 5),
constraints: const BoxConstraints(maxWidth: 300, maxHeight: 600), constraints: const BoxConstraints(maxWidth: 300, maxHeight: 600),
animationDuration: Durations.short3,
beginScaleFactor: 1.0,
beginOpacity: 0.8,
controller: _popoverController, controller: _popoverController,
triggerActions: PopoverTriggerFlags.none, triggerActions: PopoverTriggerFlags.none,
onOpen: () { onOpen: () {

View File

@ -679,6 +679,7 @@ pub fn save_user_workspace(
user_workspace_table::created_at.eq(&user_workspace.created_at), user_workspace_table::created_at.eq(&user_workspace.created_at),
user_workspace_table::database_storage_id.eq(&user_workspace.database_storage_id), user_workspace_table::database_storage_id.eq(&user_workspace.database_storage_id),
user_workspace_table::icon.eq(&user_workspace.icon), user_workspace_table::icon.eq(&user_workspace.icon),
user_workspace_table::member_count.eq(&user_workspace.member_count),
)) ))
.execute(conn)?; .execute(conn)?;
@ -729,6 +730,7 @@ pub fn save_all_user_workspaces(
user_workspace_table::created_at.eq(&user_workspace.created_at), user_workspace_table::created_at.eq(&user_workspace.created_at),
user_workspace_table::database_storage_id.eq(&user_workspace.database_storage_id), user_workspace_table::database_storage_id.eq(&user_workspace.database_storage_id),
user_workspace_table::icon.eq(&user_workspace.icon), user_workspace_table::icon.eq(&user_workspace.icon),
user_workspace_table::member_count.eq(&user_workspace.member_count),
)) ))
.execute(conn)?; .execute(conn)?;