mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-10-01 11:21:20 +00:00
feat: display joined at and user avatar in members page (#7809)
* feat: new settings page design * feat: support display member join at and avatar * chore: bump version 0.9.0 * chore: update translations
This commit is contained in:
parent
4626c18ced
commit
1977cf6637
@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
APPFLOWY_VERSION = "0.8.9"
|
||||
APPFLOWY_VERSION = "0.9.0"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||
|
@ -27,6 +27,7 @@ import 'package:appflowy/workspace/presentation/settings/widgets/web_url_hint_wi
|
||||
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_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -60,6 +61,7 @@ class SettingsDialog extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final width = MediaQuery.of(context).size.width * 0.6;
|
||||
final theme = AppFlowyTheme.of(context);
|
||||
return BlocProvider<SettingsDialogBloc>(
|
||||
create: (context) => SettingsDialogBloc(
|
||||
user,
|
||||
@ -72,12 +74,12 @@ class SettingsDialog extends StatelessWidget {
|
||||
constraints: const BoxConstraints(minWidth: 564),
|
||||
child: ScaffoldMessenger(
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: theme.backgroundColorScheme.primary,
|
||||
body: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 200,
|
||||
width: 204,
|
||||
child: SettingsMenu(
|
||||
userProfile: user,
|
||||
changeSelectedPage: (index) => context
|
||||
@ -88,6 +90,10 @@ class SettingsDialog extends StatelessWidget {
|
||||
isBillingEnabled: state.isBillingEnabled,
|
||||
),
|
||||
),
|
||||
AFDivider(
|
||||
axis: Axis.vertical,
|
||||
color: theme.borderColorScheme.primary,
|
||||
),
|
||||
Expanded(
|
||||
child: getSettingsView(
|
||||
context
|
||||
|
@ -88,17 +88,18 @@ class _Description extends StatelessWidget {
|
||||
await showConfirmDialog(
|
||||
context: context,
|
||||
style: ConfirmPopupStyle.cancelAndOk,
|
||||
title: 'Reset the invite link?',
|
||||
description:
|
||||
'Resetting will deactivate the current link for all space members and generate a new one. The old link will no longer be available.',
|
||||
confirmLabel: 'Reset',
|
||||
title: LocaleKeys.settings_appearance_members_resetInviteLink.tr(),
|
||||
description: LocaleKeys
|
||||
.settings_appearance_members_resetInviteLinkDescription
|
||||
.tr(),
|
||||
confirmLabel: LocaleKeys.settings_appearance_members_reset.tr(),
|
||||
onConfirm: () {
|
||||
context.read<WorkspaceMemberBloc>().add(
|
||||
const WorkspaceMemberEvent.generateInviteLink(),
|
||||
);
|
||||
},
|
||||
confirmButtonBuilder: (_) => AFFilledTextButton.destructive(
|
||||
text: 'Reset',
|
||||
text: LocaleKeys.settings_appearance_members_reset.tr(),
|
||||
onTap: () {
|
||||
context.read<WorkspaceMemberBloc>().add(
|
||||
const WorkspaceMemberEvent.generateInviteLink(),
|
||||
@ -145,7 +146,8 @@ class _CopyLinkButton extends StatelessWidget {
|
||||
);
|
||||
} else {
|
||||
showToastNotification(
|
||||
message: LocaleKeys.shareAction_copyLinkFailed.tr(),
|
||||
message: 'You haven\'t generated an invite link yet.',
|
||||
type: ToastificationType.error,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
@ -10,6 +10,7 @@ import 'package:appflowy/workspace/presentation/settings/widgets/members/inivita
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/user_avatar.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
@ -318,6 +319,7 @@ class _MemberListHeader extends StatelessWidget {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Text(
|
||||
LocaleKeys.settings_appearance_members_user.tr(),
|
||||
style: theme.textStyle.body.standard(
|
||||
@ -326,6 +328,7 @@ class _MemberListHeader extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
LocaleKeys.settings_appearance_members_role.tr(),
|
||||
style: theme.textStyle.body.standard(
|
||||
@ -334,6 +337,7 @@ class _MemberListHeader extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
LocaleKeys.settings_accountPage_email_title.tr(),
|
||||
style: theme.textStyle.body.standard(
|
||||
@ -364,14 +368,39 @@ class _MemberItem extends StatelessWidget {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
member.name,
|
||||
style: theme.textStyle.body.enhanced(
|
||||
color: theme.textColorScheme.primary,
|
||||
),
|
||||
flex: 4,
|
||||
child: Row(
|
||||
children: [
|
||||
UserAvatar(
|
||||
iconUrl: member.avatarUrl,
|
||||
name: member.name,
|
||||
size: 24,
|
||||
fontSize: 12,
|
||||
emojiFontSize: 20,
|
||||
),
|
||||
HSpace(8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
member.name,
|
||||
style: theme.textStyle.body.enhanced(
|
||||
color: theme.textColorScheme.primary,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
_formatJoinedDate(member.joinedAt.toInt()),
|
||||
style: theme.textStyle.caption.standard(
|
||||
color: theme.textColorScheme.secondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: member.role.isOwner || !myRole.canUpdate
|
||||
? Text(
|
||||
member.role.description,
|
||||
@ -384,6 +413,7 @@ class _MemberItem extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: FlowyTooltip(
|
||||
message: member.email,
|
||||
child: Text(
|
||||
@ -403,6 +433,11 @@ class _MemberItem extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
String _formatJoinedDate(int joinedAt) {
|
||||
final date = DateTime.fromMillisecondsSinceEpoch(joinedAt * 1000);
|
||||
return 'Joined on ${DateFormat('MMM d, y').format(date)}';
|
||||
}
|
||||
}
|
||||
|
||||
enum _MemberMoreAction {
|
||||
@ -428,7 +463,7 @@ class _MemberMoreActionList extends StatelessWidget {
|
||||
return FlowyButton(
|
||||
useIntrinsicWidth: true,
|
||||
text: const FlowySvg(
|
||||
FlowySvgs.three_dots_vertical_s,
|
||||
FlowySvgs.three_dots_s,
|
||||
),
|
||||
onTap: () {
|
||||
controller.show();
|
||||
|
@ -4,6 +4,7 @@ import 'package:appflowy/shared/feature_flags.dart';
|
||||
import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu_element.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -25,28 +26,27 @@ class SettingsMenu extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = AppFlowyTheme.of(context);
|
||||
// Column > Expanded for full size no matter the content
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8) +
|
||||
const EdgeInsets.only(left: 8, right: 4),
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
color: theme.backgroundColorScheme.secondary,
|
||||
borderRadius: const BorderRadiusDirectional.only(
|
||||
topStart: Radius.circular(8),
|
||||
bottomStart: Radius.circular(8),
|
||||
),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
// Right padding is added to make the scrollbar centered
|
||||
// in the space between the menu and the content
|
||||
padding: const EdgeInsets.only(right: 4) +
|
||||
const EdgeInsets.symmetric(vertical: 16),
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 24,
|
||||
horizontal: theme.spacing.l,
|
||||
),
|
||||
physics: const ClampingScrollPhysics(),
|
||||
child: SeparatedColumn(
|
||||
separatorBuilder: () => const VSpace(16),
|
||||
separatorBuilder: () => VSpace(theme.spacing.xs),
|
||||
children: [
|
||||
SettingsMenuElement(
|
||||
page: SettingsPage.account,
|
||||
|
@ -1,8 +1,6 @@
|
||||
import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SettingsMenuElement extends StatelessWidget {
|
||||
@ -23,42 +21,67 @@ class SettingsMenuElement extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FlowyHover(
|
||||
isSelected: () => page == selectedPage,
|
||||
resetHoverOnRebuild: false,
|
||||
style: HoverStyle(
|
||||
hoverColor: AFThemeExtension.of(context).greyHover,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
builder: (_, isHovering) => ListTile(
|
||||
dense: true,
|
||||
leading: iconWidget(
|
||||
isHovering || page == selectedPage
|
||||
? Theme.of(context).colorScheme.onSurface
|
||||
: AFThemeExtension.of(context).textColor,
|
||||
),
|
||||
onTap: () => changeSelectedPage(page),
|
||||
selected: page == selectedPage,
|
||||
selectedColor: Theme.of(context).colorScheme.onSurface,
|
||||
selectedTileColor: Theme.of(context).colorScheme.primary,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
minLeadingWidth: 0,
|
||||
title: FlowyText.medium(
|
||||
label,
|
||||
fontSize: FontSizes.s14,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: page == selectedPage
|
||||
? Theme.of(context).colorScheme.onSurface
|
||||
: null,
|
||||
),
|
||||
),
|
||||
final theme = AppFlowyTheme.of(context);
|
||||
return AFBaseButton(
|
||||
onTap: () => changeSelectedPage(page),
|
||||
padding: EdgeInsets.all(theme.spacing.m),
|
||||
borderRadius: theme.borderRadius.m,
|
||||
borderColor: (_, __, ___, ____) => theme.fillColorScheme.transparent,
|
||||
backgroundColor: (_, isHovering, __) {
|
||||
if (isHovering) {
|
||||
return theme.fillColorScheme.primaryAlpha5;
|
||||
} else if (page == selectedPage) {
|
||||
return theme.fillColorScheme.themeSelect;
|
||||
}
|
||||
return theme.fillColorScheme.transparent;
|
||||
},
|
||||
builder: (_, __, ___) {
|
||||
return Row(
|
||||
children: [
|
||||
icon,
|
||||
HSpace(theme.spacing.m),
|
||||
Text(
|
||||
label,
|
||||
style: theme.textStyle.body.standard(
|
||||
color: theme.textColorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget iconWidget(Color color) => IconTheme(
|
||||
data: IconThemeData(color: color),
|
||||
child: icon,
|
||||
);
|
||||
// return FlowyHover(
|
||||
// isSelected: () => page == selectedPage,
|
||||
// resetHoverOnRebuild: false,
|
||||
// style: HoverStyle(
|
||||
// hoverColor: AFThemeExtension.of(context).greyHover,
|
||||
// borderRadius: BorderRadius.circular(4),
|
||||
// ),
|
||||
// builder: (_, isHovering) => ListTile(
|
||||
// dense: true,
|
||||
// leading: iconWidget(
|
||||
// isHovering || page == selectedPage
|
||||
// ? Theme.of(context).colorScheme.onSurface
|
||||
// : AFThemeExtension.of(context).textColor,
|
||||
// ),
|
||||
// onTap: () => changeSelectedPage(page),
|
||||
// selected: page == selectedPage,
|
||||
// selectedColor: Theme.of(context).colorScheme.onSurface,
|
||||
// selectedTileColor: Theme.of(context).colorScheme.primary,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(5),
|
||||
// ),
|
||||
// minLeadingWidth: 0,
|
||||
// title: FlowyText.medium(
|
||||
// label,
|
||||
// fontSize: FontSizes.s14,
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// color: page == selectedPage
|
||||
// ? Theme.of(context).colorScheme.onSurface
|
||||
// : null,
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
}
|
||||
|
@ -17,12 +17,14 @@ class UserAvatar extends StatelessWidget {
|
||||
required this.fontSize,
|
||||
this.isHovering = false,
|
||||
this.decoration,
|
||||
this.emojiFontSize,
|
||||
});
|
||||
|
||||
final String iconUrl;
|
||||
final String name;
|
||||
final double size;
|
||||
final double fontSize;
|
||||
final double? emojiFontSize;
|
||||
final Decoration? decoration;
|
||||
|
||||
// If true, a border will be applied on top of the avatar
|
||||
@ -127,7 +129,10 @@ class UserAvatar extends StatelessWidget {
|
||||
FlowySvgData('emoji/$iconUrl'),
|
||||
blendMode: null,
|
||||
)
|
||||
: FlowyText.emoji(iconUrl, fontSize: fontSize),
|
||||
: FlowyText.emoji(
|
||||
iconUrl,
|
||||
fontSize: emojiFontSize ?? fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -4,7 +4,7 @@ description: Bring projects, wikis, and teams together with AI. AppFlowy is an
|
||||
your data. The best open source alternative to Notion.
|
||||
publish_to: "none"
|
||||
|
||||
version: 0.8.9
|
||||
version: 0.9.0
|
||||
|
||||
environment:
|
||||
flutter: ">=3.27.4"
|
||||
|
@ -1353,7 +1353,7 @@
|
||||
"generateANewLink": "generate a new link",
|
||||
"inviteMemberByEmail": "Invite member by email",
|
||||
"inviteMemberHintText": "Invite by email",
|
||||
"resetInviteLink": "Reset the invite link",
|
||||
"resetInviteLink": "Reset the invite link?",
|
||||
"resetInviteLinkDescription": "Resetting will deactivate the current link for all space members and generate a new one. The previous link can only be managed through the",
|
||||
"adminPanel": "Admin Panel",
|
||||
"reset": "Reset",
|
||||
|
24
frontend/rust-lib/Cargo.lock
generated
24
frontend/rust-lib/Cargo.lock
generated
@ -493,7 +493,7 @@ checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -513,7 +513,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "appflowy-ai-client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -1159,7 +1159,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@ -1214,7 +1214,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"collab-entity",
|
||||
"collab-rt-entity",
|
||||
@ -1227,7 +1227,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@ -1499,7 +1499,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -1521,7 +1521,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1969,7 +1969,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bytes",
|
||||
@ -3426,7 +3426,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"getrandom 0.2.10",
|
||||
@ -3441,7 +3441,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"app-error",
|
||||
"jsonwebtoken",
|
||||
@ -4065,7 +4065,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -6643,7 +6643,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6c6f1c5cc3ce2161c247f63f6132361da8dc0a32#6c6f1c5cc3ce2161c247f63f6132361da8dc0a32"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=954c323#954c32332487f5e17a7fb5be0bc339db1cb00e17"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
|
@ -108,8 +108,8 @@ af-local-ai = { version = "0.1" }
|
||||
# Run the script.add_workspace_members:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6c6f1c5cc3ce2161c247f63f6132361da8dc0a32" }
|
||||
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6c6f1c5cc3ce2161c247f63f6132361da8dc0a32" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "954c323" }
|
||||
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "954c323" }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
|
@ -71,6 +71,7 @@ pub fn from_af_workspace_member(member: AFWorkspaceMember) -> WorkspaceMember {
|
||||
role: from_af_role(member.role),
|
||||
name: member.name,
|
||||
avatar_url: member.avatar_url,
|
||||
joined_at: member.joined_at.map(|dt| dt.timestamp()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,6 +248,7 @@ impl UserCloudService for LocalServerUserServiceImpl {
|
||||
uid,
|
||||
workspace_id: workspace_id.to_string(),
|
||||
updated_at: chrono::Utc::now().naive_utc(),
|
||||
joined_at: None,
|
||||
};
|
||||
|
||||
let member = WorkspaceMember::from(row.clone());
|
||||
|
@ -0,0 +1,3 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
ALTER TABLE workspace_members_table
|
||||
DROP COLUMN joined_at;
|
@ -0,0 +1,3 @@
|
||||
-- Your SQL goes here
|
||||
ALTER TABLE workspace_members_table
|
||||
ADD COLUMN joined_at BIGINT DEFAULT NULL;
|
@ -120,6 +120,7 @@ diesel::table! {
|
||||
uid -> BigInt,
|
||||
workspace_id -> Text,
|
||||
updated_at -> Timestamp,
|
||||
joined_at -> Nullable<BigInt>,
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,16 +133,16 @@ diesel::table! {
|
||||
}
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
af_collab_metadata,
|
||||
chat_local_setting_table,
|
||||
chat_message_table,
|
||||
chat_table,
|
||||
collab_snapshot,
|
||||
upload_file_part,
|
||||
upload_file_table,
|
||||
user_data_migration_records,
|
||||
user_table,
|
||||
user_workspace_table,
|
||||
workspace_members_table,
|
||||
workspace_setting_table,
|
||||
af_collab_metadata,
|
||||
chat_local_setting_table,
|
||||
chat_message_table,
|
||||
chat_table,
|
||||
collab_snapshot,
|
||||
upload_file_part,
|
||||
upload_file_table,
|
||||
user_data_migration_records,
|
||||
user_table,
|
||||
user_workspace_table,
|
||||
workspace_members_table,
|
||||
workspace_setting_table,
|
||||
);
|
||||
|
@ -370,6 +370,7 @@ pub struct WorkspaceMember {
|
||||
pub role: Role,
|
||||
pub name: String,
|
||||
pub avatar_url: Option<String>,
|
||||
pub joined_at: Option<i64>,
|
||||
}
|
||||
|
||||
/// represent the user awareness object id for the workspace.
|
||||
|
@ -16,6 +16,7 @@ pub struct WorkspaceMemberTable {
|
||||
pub uid: i64,
|
||||
pub workspace_id: String,
|
||||
pub updated_at: chrono::NaiveDateTime,
|
||||
pub joined_at: Option<i64>,
|
||||
}
|
||||
|
||||
impl From<WorkspaceMemberTable> for WorkspaceMember {
|
||||
@ -25,6 +26,7 @@ impl From<WorkspaceMemberTable> for WorkspaceMember {
|
||||
role: Role::from(value.role),
|
||||
name: value.name,
|
||||
avatar_url: value.avatar_url,
|
||||
joined_at: value.joined_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ pub fn insert_local_workspace(
|
||||
uid,
|
||||
workspace_id: workspace_id.to_string(),
|
||||
updated_at: chrono::Utc::now().naive_utc(),
|
||||
joined_at: None,
|
||||
};
|
||||
|
||||
upsert_user_workspace(uid, AuthType::Local, user_workspace.clone(), conn)?;
|
||||
|
@ -24,6 +24,9 @@ pub struct WorkspaceMemberPB {
|
||||
|
||||
#[pb(index = 4, one_of)]
|
||||
pub avatar_url: Option<String>,
|
||||
|
||||
#[pb(index = 5, one_of)]
|
||||
pub joined_at: Option<i64>,
|
||||
}
|
||||
|
||||
impl From<WorkspaceMember> for WorkspaceMemberPB {
|
||||
@ -33,6 +36,7 @@ impl From<WorkspaceMember> for WorkspaceMemberPB {
|
||||
name: value.name,
|
||||
role: value.role.into(),
|
||||
avatar_url: value.avatar_url,
|
||||
joined_at: value.joined_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -673,6 +673,7 @@ impl UserManager {
|
||||
role: member_record.role.into(),
|
||||
name: member_record.name,
|
||||
avatar_url: member_record.avatar_url,
|
||||
joined_at: member_record.joined_at,
|
||||
});
|
||||
}
|
||||
|
||||
@ -703,6 +704,7 @@ impl UserManager {
|
||||
uid,
|
||||
workspace_id: workspace_id.to_string(),
|
||||
updated_at: Utc::now().naive_utc(),
|
||||
joined_at: member.joined_at,
|
||||
};
|
||||
|
||||
let mut db = self.authenticate_user.get_sqlite_connection(uid)?;
|
||||
|
Loading…
x
Reference in New Issue
Block a user