mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-18 07:30:29 +03:00
chore: add workspace log (#5206)
This commit is contained in:
parent
cc66147bc0
commit
d86afb03ba
@ -77,7 +77,6 @@ class DocumentCollabAdapter {
|
||||
|
||||
final ops = diffNodes(editorState.document.root, document.root);
|
||||
if (ops.isEmpty) {
|
||||
Log.info('Doc diff, no changes');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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"));
|
||||
|
Loading…
Reference in New Issue
Block a user