chore: add workspace log (#5206)

This commit is contained in:
Lucas.Xu 2024-04-26 14:09:02 +08:00 committed by GitHub
parent cc66147bc0
commit d86afb03ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 163 additions and 83 deletions

View File

@ -77,7 +77,6 @@ class DocumentCollabAdapter {
final ops = diffNodes(editorState.document.root, document.root);
if (ops.isEmpty) {
Log.info('Doc diff, no changes');
return;
}

View File

@ -39,7 +39,12 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
final isCollabWorkspaceOn =
userProfile.authenticator == AuthenticatorPB.AppFlowyCloud &&
FeatureFlag.collaborativeWorkspace.isOn;
Log.info(
'init workspace, current workspace: ${currentWorkspace?.workspaceId}, '
'workspaces: ${workspaces.map((e) => e.workspaceId)}, isCollabWorkspaceOn: $isCollabWorkspaceOn',
);
if (currentWorkspace != null && result.$3 == true) {
Log.info('init open workspace: ${currentWorkspace.workspaceId}');
await _userService.openWorkspace(currentWorkspace.workspaceId);
}
emit(
@ -53,10 +58,17 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
},
fetchWorkspaces: () async {
final result = await _fetchWorkspaces();
final currentWorkspace = result.$1;
final workspaces = result.$2;
Log.info(
'fetch workspaces: current workspace: ${currentWorkspace?.workspaceId}, workspaces: ${workspaces.map((e) => e.workspaceId)}',
);
emit(
state.copyWith(
currentWorkspace: result.$1,
workspaces: result.$2,
currentWorkspace: currentWorkspace,
workspaces: workspaces,
),
);
},
@ -86,11 +98,17 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
),
);
// open the created workspace by default
result.onSuccess((s) {
add(OpenWorkspace(s.workspaceId));
});
result
..onSuccess((s) {
Log.info('create workspace success: $s');
add(OpenWorkspace(s.workspaceId));
})
..onFailure((f) {
Log.error('create workspace error: $f');
});
},
deleteWorkspace: (workspaceId) async {
Log.info('try to delete workspace: $workspaceId');
emit(
state.copyWith(
actionResult: const UserWorkspaceActionResult(
@ -106,6 +124,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
if (state.workspaces.length <= 1 || remoteWorkspaces.length <= 1) {
// do not allow to delete the last workspace, otherwise the user
// cannot do create workspace again
Log.error('cannot delete the only workspace');
final result = FlowyResult.failure(
FlowyError(
code: ErrorCode.Internal,
@ -132,12 +151,17 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
.toList(),
(e) => state.workspaces,
);
result.onSuccess((_) {
// if the current workspace is deleted, open the first workspace
if (state.currentWorkspace?.workspaceId == workspaceId) {
add(OpenWorkspace(workspaces.first.workspaceId));
}
});
result
..onSuccess((_) {
Log.info('delete workspace success: $workspaceId');
// if the current workspace is deleted, open the first workspace
if (state.currentWorkspace?.workspaceId == workspaceId) {
add(OpenWorkspace(workspaces.first.workspaceId));
}
})
..onFailure((f) {
Log.error('delete workspace error: $f');
});
emit(
state.copyWith(
workspaces: workspaces,
@ -166,6 +190,17 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
),
(e) => state.currentWorkspace,
);
result
..onSuccess((s) {
Log.info(
'open workspace success: $workspaceId, current workspace: ${currentWorkspace?.toProto3Json()}',
);
})
..onFailure((f) {
Log.error('open workspace error: $f');
});
emit(
state.copyWith(
currentWorkspace: currentWorkspace,
@ -197,6 +232,15 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
final currentWorkspace = workspaces.firstWhere(
(e) => e.workspaceId == state.currentWorkspace?.workspaceId,
);
Log.info(
'rename workspace: $workspaceId, name: $name',
);
result.onFailure((f) {
Log.error('rename workspace error: $f');
});
emit(
state.copyWith(
workspaces: workspaces,
@ -231,6 +275,15 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
final currentWorkspace = workspaces.firstWhere(
(e) => e.workspaceId == state.currentWorkspace?.workspaceId,
);
Log.info(
'update workspace icon: $workspaceId, icon: $icon',
);
result.onFailure((f) {
Log.error('update workspace icon error: $f');
});
emit(
state.copyWith(
workspaces: workspaces,
@ -251,12 +304,17 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
.toList(),
(e) => state.workspaces,
);
result.onSuccess((_) {
// if leaving the current workspace, open the first workspace
if (state.currentWorkspace?.workspaceId == workspaceId) {
add(OpenWorkspace(workspaces.first.workspaceId));
}
});
result
..onSuccess((_) {
Log.info('leave workspace success: $workspaceId');
// if leaving the current workspace, open the first workspace
if (state.currentWorkspace?.workspaceId == workspaceId) {
add(OpenWorkspace(workspaces.first.workspaceId));
}
})
..onFailure((f) {
Log.error('leave workspace error: $f');
});
emit(
state.copyWith(
workspaces: workspaces,

View File

@ -1,5 +1,3 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/widgets/loading.dart';
@ -16,6 +14,7 @@ import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SidebarWorkspace extends StatefulWidget {
@ -142,7 +141,6 @@ class _SidebarWorkspaceState extends State<SidebarWorkspace> {
}
if (message != null) {
Log.info('[Workspace] $message');
showSnackBarMessage(context, message);
}
}
@ -167,6 +165,7 @@ class SidebarSwitchWorkspaceButton extends StatelessWidget {
onOpen: () => context
.read<UserWorkspaceBloc>()
.add(const UserWorkspaceEvent.fetchWorkspaces()),
onClose: () => Log.info('close workspace menu'),
popupBuilder: (_) {
return BlocProvider<UserWorkspaceBloc>.value(
value: context.read<UserWorkspaceBloc>(),
@ -177,6 +176,7 @@ class SidebarSwitchWorkspaceButton extends StatelessWidget {
if (currentWorkspace == null) {
return const SizedBox.shrink();
}
Log.info('open workspace menu');
return WorkspacesMenu(
userProfile: userProfile,
currentWorkspace: currentWorkspace,

View File

@ -5,6 +5,7 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sid
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
@ -117,7 +118,6 @@ class WorkspaceMenuItem extends StatelessWidget {
..add(const WorkspaceMemberEvent.initial()),
child: BlocBuilder<WorkspaceMemberBloc, WorkspaceMemberState>(
builder: (context, state) {
final members = state.members;
// settings right icon inside the flowy button will
// cause the popover dismiss intermediately when click the right icon.
// so using the stack to put the right icon on the flowy button.
@ -126,70 +126,14 @@ class WorkspaceMenuItem extends StatelessWidget {
child: Stack(
alignment: Alignment.center,
children: [
FlowyButton(
onTap: () {
if (!isSelected) {
context.read<UserWorkspaceBloc>().add(
UserWorkspaceEvent.openWorkspace(
workspace.workspaceId,
),
);
PopoverContainer.of(context).closeAll();
}
},
margin: const EdgeInsets.symmetric(
vertical: 8,
horizontal: 12,
),
iconPadding: 10.0,
leftIconSize: const Size.square(32),
leftIcon: const SizedBox.square(
dimension: 32,
),
rightIcon: const HSpace(42.0),
text: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FlowyText.medium(
workspace.name,
fontSize: 14.0,
overflow: TextOverflow.ellipsis,
withTooltip: true,
),
FlowyText(
state.isLoading
? ''
: LocaleKeys
.settings_appearance_members_membersCount
.plural(
members.length,
),
fontSize: 10.0,
color: Theme.of(context).hintColor,
),
],
),
),
Positioned(
left: 8,
child: SizedBox.square(
dimension: 32,
child: FlowyTooltip(
message:
LocaleKeys.document_plugins_cover_changeIcon.tr(),
child: WorkspaceIcon(
workspace: workspace,
iconSize: 26,
enableEdit: true,
),
),
),
_WorkspaceInfo(
isSelected: isSelected,
workspace: workspace,
),
Positioned(left: 8, child: _buildLeftIcon(context)),
Positioned(
right: 12.0,
child: Align(
child: _buildRightIcon(context),
),
child: Align(child: _buildRightIcon(context)),
),
],
),
@ -199,6 +143,20 @@ class WorkspaceMenuItem extends StatelessWidget {
);
}
Widget _buildLeftIcon(BuildContext context) {
return SizedBox.square(
dimension: 32,
child: FlowyTooltip(
message: LocaleKeys.document_plugins_cover_changeIcon.tr(),
child: WorkspaceIcon(
workspace: workspace,
iconSize: 26,
enableEdit: true,
),
),
);
}
Widget _buildRightIcon(BuildContext context) {
// only the owner can update or delete workspace.
// only show the more action button when the workspace is selected.
@ -217,6 +175,68 @@ class WorkspaceMenuItem extends StatelessWidget {
}
}
class _WorkspaceInfo extends StatelessWidget {
const _WorkspaceInfo({
required this.isSelected,
required this.workspace,
});
final bool isSelected;
final UserWorkspacePB workspace;
@override
Widget build(BuildContext context) {
return BlocBuilder<WorkspaceMemberBloc, WorkspaceMemberState>(
builder: (context, state) {
final members = state.members;
return FlowyButton(
onTap: () => _openWorkspace(context),
iconPadding: 10.0,
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
leftIconSize: const Size.square(32),
leftIcon: const SizedBox.square(dimension: 32),
rightIcon: const HSpace(42.0),
text: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// workspace name
FlowyText.medium(
workspace.name,
fontSize: 14.0,
overflow: TextOverflow.ellipsis,
withTooltip: true,
),
// workspace members count
FlowyText(
state.isLoading
? ''
: LocaleKeys.settings_appearance_members_membersCount
.plural(
members.length,
),
fontSize: 10.0,
color: Theme.of(context).hintColor,
),
],
),
);
},
);
}
void _openWorkspace(BuildContext context) {
if (!isSelected) {
Log.info('open workspace: ${workspace.workspaceId}');
context.read<UserWorkspaceBloc>().add(
UserWorkspaceEvent.openWorkspace(
workspace.workspaceId,
),
);
PopoverContainer.of(context).closeAll();
}
}
}
class CreateWorkspaceDialog extends StatelessWidget {
const CreateWorkspaceDialog({
super.key,

View File

@ -52,6 +52,9 @@ pub fn create_log_filter(level: String, with_crates: Vec<String>, platform: Plat
filters.push(format!("flowy_notification={}", "info"));
filters.push(format!("lib_infra={}", level));
filters.push(format!("flowy_search={}", level));
// Enable the frontend logs. DO NOT DISABLE.
// These logs are essential for debugging and verifying frontend behavior.
filters.push(format!("dart_ffi={}", level));
// Most of the time, we don't need to see the logs from the following crates
// filters.push(format!("flowy_sqlite={}", "info"));