mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge pull request #585 from AppFlowy-IO/feat/update_user_profile
chore: update user name with UserService
This commit is contained in:
commit
1f47221fc9
39
frontend/app_flowy/lib/core/folder_notification.dart
Normal file
39
frontend/app_flowy/lib/core/folder_notification.dart
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||||
|
import 'package:flowy_sdk/rust_stream.dart';
|
||||||
|
|
||||||
|
import 'notification_helper.dart';
|
||||||
|
|
||||||
|
// Folder
|
||||||
|
typedef FolderNotificationCallback = void Function(FolderNotification, Either<Uint8List, FlowyError>);
|
||||||
|
|
||||||
|
class FolderNotificationParser extends NotificationParser<FolderNotification, FlowyError> {
|
||||||
|
FolderNotificationParser({String? id, required FolderNotificationCallback callback})
|
||||||
|
: super(
|
||||||
|
id: id,
|
||||||
|
callback: callback,
|
||||||
|
tyParser: (ty) => FolderNotification.valueOf(ty),
|
||||||
|
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef FolderNotificationHandler = Function(FolderNotification ty, Either<Uint8List, FlowyError> result);
|
||||||
|
|
||||||
|
class FolderNotificationListener {
|
||||||
|
StreamSubscription<SubscribeObject>? _subscription;
|
||||||
|
FolderNotificationParser? _parser;
|
||||||
|
|
||||||
|
FolderNotificationListener({required String objectId, required FolderNotificationHandler handler})
|
||||||
|
: _parser = FolderNotificationParser(id: objectId, callback: handler) {
|
||||||
|
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stop() async {
|
||||||
|
_parser = null;
|
||||||
|
await _subscription?.cancel();
|
||||||
|
}
|
||||||
|
}
|
39
frontend/app_flowy/lib/core/grid_notification.dart
Normal file
39
frontend/app_flowy/lib/core/grid_notification.dart
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||||
|
import 'package:flowy_sdk/rust_stream.dart';
|
||||||
|
|
||||||
|
import 'notification_helper.dart';
|
||||||
|
|
||||||
|
// Grid
|
||||||
|
typedef GridNotificationCallback = void Function(GridNotification, Either<Uint8List, FlowyError>);
|
||||||
|
|
||||||
|
class GridNotificationParser extends NotificationParser<GridNotification, FlowyError> {
|
||||||
|
GridNotificationParser({String? id, required GridNotificationCallback callback})
|
||||||
|
: super(
|
||||||
|
id: id,
|
||||||
|
callback: callback,
|
||||||
|
tyParser: (ty) => GridNotification.valueOf(ty),
|
||||||
|
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef GridNotificationHandler = Function(GridNotification ty, Either<Uint8List, FlowyError> result);
|
||||||
|
|
||||||
|
class GridNotificationListener {
|
||||||
|
StreamSubscription<SubscribeObject>? _subscription;
|
||||||
|
GridNotificationParser? _parser;
|
||||||
|
|
||||||
|
GridNotificationListener({required String objectId, required GridNotificationHandler handler})
|
||||||
|
: _parser = GridNotificationParser(id: objectId, callback: handler) {
|
||||||
|
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stop() async {
|
||||||
|
_parser = null;
|
||||||
|
await _subscription?.cancel();
|
||||||
|
}
|
||||||
|
}
|
@ -1,68 +1,6 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
|
||||||
import 'package:flowy_sdk/rust_stream.dart';
|
|
||||||
|
|
||||||
// User
|
|
||||||
typedef UserNotificationCallback = void Function(UserNotification, Either<Uint8List, FlowyError>);
|
|
||||||
|
|
||||||
class UserNotificationParser extends NotificationParser<UserNotification, FlowyError> {
|
|
||||||
UserNotificationParser({required String id, required UserNotificationCallback callback})
|
|
||||||
: super(
|
|
||||||
id: id,
|
|
||||||
callback: callback,
|
|
||||||
tyParser: (ty) => UserNotification.valueOf(ty),
|
|
||||||
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Folder
|
|
||||||
typedef FolderNotificationCallback = void Function(FolderNotification, Either<Uint8List, FlowyError>);
|
|
||||||
|
|
||||||
class FolderNotificationParser extends NotificationParser<FolderNotification, FlowyError> {
|
|
||||||
FolderNotificationParser({String? id, required FolderNotificationCallback callback})
|
|
||||||
: super(
|
|
||||||
id: id,
|
|
||||||
callback: callback,
|
|
||||||
tyParser: (ty) => FolderNotification.valueOf(ty),
|
|
||||||
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grid
|
|
||||||
typedef GridNotificationCallback = void Function(GridNotification, Either<Uint8List, FlowyError>);
|
|
||||||
|
|
||||||
class GridNotificationParser extends NotificationParser<GridNotification, FlowyError> {
|
|
||||||
GridNotificationParser({String? id, required GridNotificationCallback callback})
|
|
||||||
: super(
|
|
||||||
id: id,
|
|
||||||
callback: callback,
|
|
||||||
tyParser: (ty) => GridNotification.valueOf(ty),
|
|
||||||
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef GridNotificationHandler = Function(GridNotification ty, Either<Uint8List, FlowyError> result);
|
|
||||||
|
|
||||||
class GridNotificationListener {
|
|
||||||
StreamSubscription<SubscribeObject>? _subscription;
|
|
||||||
GridNotificationParser? _parser;
|
|
||||||
|
|
||||||
GridNotificationListener({required String objectId, required GridNotificationHandler handler})
|
|
||||||
: _parser = GridNotificationParser(id: objectId, callback: handler) {
|
|
||||||
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> stop() async {
|
|
||||||
_parser = null;
|
|
||||||
await _subscription?.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NotificationParser<T, E> {
|
class NotificationParser<T, E> {
|
||||||
String? id;
|
String? id;
|
||||||
|
39
frontend/app_flowy/lib/core/user_notification.dart
Normal file
39
frontend/app_flowy/lib/core/user_notification.dart
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/rust_stream.dart';
|
||||||
|
|
||||||
|
import 'notification_helper.dart';
|
||||||
|
|
||||||
|
// User
|
||||||
|
typedef UserNotificationCallback = void Function(UserNotification, Either<Uint8List, FlowyError>);
|
||||||
|
|
||||||
|
class UserNotificationParser extends NotificationParser<UserNotification, FlowyError> {
|
||||||
|
UserNotificationParser({required String id, required UserNotificationCallback callback})
|
||||||
|
: super(
|
||||||
|
id: id,
|
||||||
|
callback: callback,
|
||||||
|
tyParser: (ty) => UserNotification.valueOf(ty),
|
||||||
|
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef UserNotificationHandler = Function(UserNotification ty, Either<Uint8List, FlowyError> result);
|
||||||
|
|
||||||
|
class UserNotificationListener {
|
||||||
|
StreamSubscription<SubscribeObject>? _subscription;
|
||||||
|
UserNotificationParser? _parser;
|
||||||
|
|
||||||
|
UserNotificationListener({required String objectId, required UserNotificationHandler handler})
|
||||||
|
: _parser = UserNotificationParser(id: objectId, callback: handler) {
|
||||||
|
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stop() async {
|
||||||
|
_parser = null;
|
||||||
|
await _subscription?.cancel();
|
||||||
|
}
|
||||||
|
}
|
@ -52,7 +52,7 @@ void _resolveHomeDeps(GetIt getIt) {
|
|||||||
getIt.registerSingleton(MenuSharedState());
|
getIt.registerSingleton(MenuSharedState());
|
||||||
|
|
||||||
getIt.registerFactoryParam<UserListener, UserProfile, void>(
|
getIt.registerFactoryParam<UserListener, UserProfile, void>(
|
||||||
(user, _) => UserListener(user: user),
|
(user, _) => UserListener(userProfile: user),
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -60,8 +60,8 @@ void _resolveHomeDeps(GetIt getIt) {
|
|||||||
|
|
||||||
getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
|
getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
|
||||||
(user, _) => WelcomeBloc(
|
(user, _) => WelcomeBloc(
|
||||||
userService: UserService(),
|
userService: UserService(userId: user.id),
|
||||||
userListener: getIt<UserListener>(param1: user),
|
userWorkspaceListener: UserWorkspaceListener(userProfile: user),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -73,8 +73,8 @@ void _resolveHomeDeps(GetIt getIt) {
|
|||||||
|
|
||||||
void _resolveFolderDeps(GetIt getIt) {
|
void _resolveFolderDeps(GetIt getIt) {
|
||||||
//workspace
|
//workspace
|
||||||
getIt.registerFactoryParam<WorkspaceListener, UserProfile, String>((user, workspaceId) =>
|
getIt.registerFactoryParam<WorkspaceListener, UserProfile, String>(
|
||||||
WorkspaceListener(service: WorkspaceListenerService(user: user, workspaceId: workspaceId)));
|
(user, workspaceId) => WorkspaceListener(user: user, workspaceId: workspaceId));
|
||||||
|
|
||||||
// View
|
// View
|
||||||
getIt.registerFactoryParam<ViewListener, View, void>(
|
getIt.registerFactoryParam<ViewListener, View, void>(
|
||||||
@ -98,11 +98,7 @@ void _resolveFolderDeps(GetIt getIt) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
|
getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
|
||||||
(user, _) => MenuUserBloc(
|
(user, _) => MenuUserBloc(user),
|
||||||
user,
|
|
||||||
UserService(),
|
|
||||||
getIt<UserListener>(param1: user),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// App
|
// App
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:app_flowy/core/folder_notification.dart';
|
||||||
|
import 'package:app_flowy/core/user_notification.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
import 'package:flowy_infra/notifier.dart';
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||||
@ -14,104 +15,58 @@ import 'package:flowy_sdk/rust_stream.dart';
|
|||||||
|
|
||||||
typedef UserProfileNotifyValue = Either<UserProfile, FlowyError>;
|
typedef UserProfileNotifyValue = Either<UserProfile, FlowyError>;
|
||||||
typedef AuthNotifyValue = Either<Unit, FlowyError>;
|
typedef AuthNotifyValue = Either<Unit, FlowyError>;
|
||||||
typedef WorkspaceListNotifyValue = Either<List<Workspace>, FlowyError>;
|
|
||||||
typedef WorkspaceSettingNotifyValue = Either<CurrentWorkspaceSetting, FlowyError>;
|
|
||||||
|
|
||||||
class UserListener {
|
class UserListener {
|
||||||
StreamSubscription<SubscribeObject>? _subscription;
|
StreamSubscription<SubscribeObject>? _subscription;
|
||||||
final _profileNotifier = PublishNotifier<UserProfileNotifyValue>();
|
PublishNotifier<AuthNotifyValue>? _authNotifier = PublishNotifier();
|
||||||
final _authNotifier = PublishNotifier<AuthNotifyValue>();
|
PublishNotifier<UserProfileNotifyValue>? _profileNotifier = PublishNotifier();
|
||||||
final _workspaceListNotifier = PublishNotifier<WorkspaceListNotifyValue>();
|
|
||||||
final _workSettingNotifier = PublishNotifier<WorkspaceSettingNotifyValue>();
|
|
||||||
|
|
||||||
FolderNotificationParser? _workspaceParser;
|
|
||||||
UserNotificationParser? _userParser;
|
UserNotificationParser? _userParser;
|
||||||
final UserProfile _user;
|
final UserProfile _userProfile;
|
||||||
UserListener({
|
UserListener({
|
||||||
required UserProfile user,
|
required UserProfile userProfile,
|
||||||
}) : _user = user;
|
}) : _userProfile = userProfile;
|
||||||
|
|
||||||
void start({
|
void start({
|
||||||
void Function(AuthNotifyValue)? onAuthChanged,
|
void Function(AuthNotifyValue)? onAuthChanged,
|
||||||
void Function(UserProfileNotifyValue)? onProfileUpdated,
|
void Function(UserProfileNotifyValue)? onProfileUpdated,
|
||||||
void Function(WorkspaceListNotifyValue)? onWorkspaceListUpdated,
|
|
||||||
void Function(WorkspaceSettingNotifyValue)? onWorkspaceSettingUpdated,
|
|
||||||
}) {
|
}) {
|
||||||
if (onAuthChanged != null) {
|
|
||||||
_authNotifier.addListener(() {
|
|
||||||
onAuthChanged(_authNotifier.currentValue!);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onProfileUpdated != null) {
|
if (onProfileUpdated != null) {
|
||||||
_profileNotifier.addListener(() {
|
_profileNotifier?.addPublishListener(onProfileUpdated);
|
||||||
onProfileUpdated(_profileNotifier.currentValue!);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onWorkspaceListUpdated != null) {
|
if (onAuthChanged != null) {
|
||||||
_workspaceListNotifier.addListener(() {
|
_authNotifier?.addPublishListener(onAuthChanged);
|
||||||
onWorkspaceListUpdated(_workspaceListNotifier.currentValue!);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onWorkspaceSettingUpdated != null) {
|
_userParser = UserNotificationParser(id: _userProfile.token, callback: _userNotificationCallback);
|
||||||
_workSettingNotifier.addListener(() {
|
|
||||||
onWorkspaceSettingUpdated(_workSettingNotifier.currentValue!);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_workspaceParser = FolderNotificationParser(id: _user.token, callback: _notificationCallback);
|
|
||||||
_userParser = UserNotificationParser(id: _user.token, callback: _userNotificationCallback);
|
|
||||||
_subscription = RustStreamReceiver.listen((observable) {
|
_subscription = RustStreamReceiver.listen((observable) {
|
||||||
_workspaceParser?.parse(observable);
|
|
||||||
_userParser?.parse(observable);
|
_userParser?.parse(observable);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> stop() async {
|
Future<void> stop() async {
|
||||||
_workspaceParser = null;
|
|
||||||
_userParser = null;
|
_userParser = null;
|
||||||
await _subscription?.cancel();
|
await _subscription?.cancel();
|
||||||
_profileNotifier.dispose();
|
_profileNotifier?.dispose();
|
||||||
_authNotifier.dispose();
|
_profileNotifier = null;
|
||||||
_workspaceListNotifier.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _notificationCallback(FolderNotification ty, Either<Uint8List, FlowyError> result) {
|
_authNotifier?.dispose();
|
||||||
switch (ty) {
|
_authNotifier = null;
|
||||||
case FolderNotification.UserCreateWorkspace:
|
|
||||||
case FolderNotification.UserDeleteWorkspace:
|
|
||||||
case FolderNotification.WorkspaceListUpdated:
|
|
||||||
result.fold(
|
|
||||||
(payload) => _workspaceListNotifier.value = left(RepeatedWorkspace.fromBuffer(payload).items),
|
|
||||||
(error) => _workspaceListNotifier.value = right(error),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case FolderNotification.WorkspaceSetting:
|
|
||||||
result.fold(
|
|
||||||
(payload) => _workSettingNotifier.value = left(CurrentWorkspaceSetting.fromBuffer(payload)),
|
|
||||||
(error) => _workSettingNotifier.value = right(error),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case FolderNotification.UserUnauthorized:
|
|
||||||
result.fold(
|
|
||||||
(_) {},
|
|
||||||
(error) => _authNotifier.value = right(FlowyError.create()..code = ErrorCode.UserUnauthorized.value),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _userNotificationCallback(user.UserNotification ty, Either<Uint8List, FlowyError> result) {
|
void _userNotificationCallback(user.UserNotification ty, Either<Uint8List, FlowyError> result) {
|
||||||
switch (ty) {
|
switch (ty) {
|
||||||
case user.UserNotification.UserUnauthorized:
|
case user.UserNotification.UserUnauthorized:
|
||||||
result.fold(
|
result.fold(
|
||||||
(payload) => _profileNotifier.value = left(UserProfile.fromBuffer(payload)),
|
(_) {},
|
||||||
(error) => _profileNotifier.value = right(error),
|
(error) => _authNotifier?.value = right(error),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case user.UserNotification.UserProfileUpdated:
|
||||||
|
result.fold(
|
||||||
|
(payload) => _profileNotifier?.value = left(UserProfile.fromBuffer(payload)),
|
||||||
|
(error) => _profileNotifier?.value = right(error),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -119,3 +74,81 @@ class UserListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef WorkspaceListNotifyValue = Either<List<Workspace>, FlowyError>;
|
||||||
|
typedef WorkspaceSettingNotifyValue = Either<CurrentWorkspaceSetting, FlowyError>;
|
||||||
|
|
||||||
|
class UserWorkspaceListener {
|
||||||
|
PublishNotifier<AuthNotifyValue>? _authNotifier = PublishNotifier();
|
||||||
|
PublishNotifier<WorkspaceListNotifyValue>? _workspacesChangedNotifier = PublishNotifier();
|
||||||
|
PublishNotifier<WorkspaceSettingNotifyValue>? _settingChangedNotifier = PublishNotifier();
|
||||||
|
|
||||||
|
FolderNotificationListener? _listener;
|
||||||
|
final UserProfile _userProfile;
|
||||||
|
|
||||||
|
UserWorkspaceListener({
|
||||||
|
required UserProfile userProfile,
|
||||||
|
}) : _userProfile = userProfile;
|
||||||
|
|
||||||
|
void start({
|
||||||
|
void Function(AuthNotifyValue)? onAuthChanged,
|
||||||
|
void Function(WorkspaceListNotifyValue)? onWorkspacesUpdated,
|
||||||
|
void Function(WorkspaceSettingNotifyValue)? onSettingUpdated,
|
||||||
|
}) {
|
||||||
|
if (onAuthChanged != null) {
|
||||||
|
_authNotifier?.addPublishListener(onAuthChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onWorkspacesUpdated != null) {
|
||||||
|
_workspacesChangedNotifier?.addPublishListener(onWorkspacesUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onSettingUpdated != null) {
|
||||||
|
_settingChangedNotifier?.addPublishListener(onSettingUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
_listener = FolderNotificationListener(
|
||||||
|
objectId: _userProfile.token,
|
||||||
|
handler: _handleObservableType,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleObservableType(FolderNotification ty, Either<Uint8List, FlowyError> result) {
|
||||||
|
switch (ty) {
|
||||||
|
case FolderNotification.UserCreateWorkspace:
|
||||||
|
case FolderNotification.UserDeleteWorkspace:
|
||||||
|
case FolderNotification.WorkspaceListUpdated:
|
||||||
|
result.fold(
|
||||||
|
(payload) => _workspacesChangedNotifier?.value = left(RepeatedWorkspace.fromBuffer(payload).items),
|
||||||
|
(error) => _workspacesChangedNotifier?.value = right(error),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case FolderNotification.WorkspaceSetting:
|
||||||
|
result.fold(
|
||||||
|
(payload) => _settingChangedNotifier?.value = left(CurrentWorkspaceSetting.fromBuffer(payload)),
|
||||||
|
(error) => _settingChangedNotifier?.value = right(error),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case FolderNotification.UserUnauthorized:
|
||||||
|
result.fold(
|
||||||
|
(_) {},
|
||||||
|
(error) => _authNotifier?.value = right(FlowyError.create()..code = ErrorCode.UserUnauthorized.value),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stop() async {
|
||||||
|
await _listener?.stop();
|
||||||
|
_workspacesChangedNotifier?.dispose();
|
||||||
|
_workspacesChangedNotifier = null;
|
||||||
|
|
||||||
|
_settingChangedNotifier?.dispose();
|
||||||
|
_settingChangedNotifier = null;
|
||||||
|
|
||||||
|
_authNotifier?.dispose();
|
||||||
|
_authNotifier = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,15 +1,42 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
|
||||||
|
|
||||||
class UserService {
|
class UserService {
|
||||||
Future<Either<UserProfile, FlowyError>> fetchUserProfile({required String userId}) {
|
final String userId;
|
||||||
|
UserService({
|
||||||
|
required this.userId,
|
||||||
|
});
|
||||||
|
Future<Either<UserProfile, FlowyError>> getUserProfile({required String userId}) {
|
||||||
return UserEventGetUserProfile().send();
|
return UserEventGetUserProfile().send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Either<Unit, FlowyError>> updateUserProfile({
|
||||||
|
String? name,
|
||||||
|
String? password,
|
||||||
|
String? email,
|
||||||
|
}) {
|
||||||
|
var payload = UpdateUserProfilePayload.create()..id = userId;
|
||||||
|
|
||||||
|
if (name != null) {
|
||||||
|
payload.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password != null) {
|
||||||
|
payload.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (email != null) {
|
||||||
|
payload.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UserEventUpdateUserProfile(payload).send();
|
||||||
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> deleteWorkspace({required String workspaceId}) {
|
Future<Either<Unit, FlowyError>> deleteWorkspace({required String workspaceId}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:app_flowy/user/application/auth_service.dart';
|
import 'package:app_flowy/user/application/auth_service.dart';
|
||||||
import 'package:app_flowy/user/application/user_listener.dart';
|
|
||||||
import 'package:app_flowy/user/presentation/router.dart';
|
import 'package:app_flowy/user/presentation/router.dart';
|
||||||
import 'package:app_flowy/user/presentation/widgets/background.dart';
|
import 'package:app_flowy/user/presentation/widgets/background.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
@ -34,8 +33,6 @@ class SkipLogInScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
||||||
UserListener? userListener;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'package:app_flowy/core/folder_notification.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
|
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'package:app_flowy/core/grid_notification.dart';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_infra/notifier.dart';
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
import 'package:app_flowy/core/grid_notification.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||||
import 'package:flowy_infra/notifier.dart';
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
|
|
||||||
typedef UpdateFieldNotifiedValue = Either<Unit, FlowyError>;
|
typedef UpdateFieldNotifiedValue = Either<Unit, FlowyError>;
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
import 'package:app_flowy/core/grid_notification.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||||
import 'package:flowy_infra/notifier.dart';
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
|
|
||||||
typedef UpdateFieldNotifiedValue = Either<Field, FlowyError>;
|
typedef UpdateFieldNotifiedValue = Either<Field, FlowyError>;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
import 'package:app_flowy/core/grid_notification.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||||
import 'package:flowy_infra/notifier.dart';
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
|
|
||||||
typedef UpdateFieldNotifiedValue = Either<GridFieldChangeset, FlowyError>;
|
typedef UpdateFieldNotifiedValue = Either<GridFieldChangeset, FlowyError>;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
import 'package:app_flowy/core/grid_notification.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||||
import 'package:flowy_infra/notifier.dart';
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
|
|
||||||
|
@ -11,19 +11,17 @@ import 'package:dartz/dartz.dart';
|
|||||||
part 'home_bloc.freezed.dart';
|
part 'home_bloc.freezed.dart';
|
||||||
|
|
||||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||||
final UserListener _listener;
|
final UserWorkspaceListener _listener;
|
||||||
|
|
||||||
HomeBloc(UserProfile user, CurrentWorkspaceSetting workspaceSetting)
|
HomeBloc(UserProfile user, CurrentWorkspaceSetting workspaceSetting)
|
||||||
: _listener = UserListener(user: user),
|
: _listener = UserWorkspaceListener(userProfile: user),
|
||||||
super(HomeState.initial(workspaceSetting)) {
|
super(HomeState.initial(workspaceSetting)) {
|
||||||
on<HomeEvent>((event, emit) async {
|
on<HomeEvent>((event, emit) async {
|
||||||
await event.map(
|
await event.map(
|
||||||
initial: (_Initial value) {
|
initial: (_Initial value) {
|
||||||
_listener.start(
|
_listener.start(
|
||||||
onAuthChanged: (result) {
|
onAuthChanged: (result) => _authDidChanged(result),
|
||||||
_authDidChanged(result);
|
onSettingUpdated: (result) {
|
||||||
},
|
|
||||||
onWorkspaceSettingUpdated: (result) {
|
|
||||||
result.fold(
|
result.fold(
|
||||||
(setting) => add(HomeEvent.didReceiveWorkspaceSetting(setting)),
|
(setting) => add(HomeEvent.didReceiveWorkspaceSetting(setting)),
|
||||||
(r) => Log.error(r),
|
(r) => Log.error(r),
|
||||||
|
@ -22,7 +22,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
|||||||
on<MenuEvent>((event, emit) async {
|
on<MenuEvent>((event, emit) async {
|
||||||
await event.map(
|
await event.map(
|
||||||
initial: (e) async {
|
initial: (e) async {
|
||||||
listener.start(addAppCallback: _handleAppsOrFail);
|
listener.start(appsChanged: _handleAppsOrFail);
|
||||||
await _fetchApps(emit);
|
await _fetchApps(emit);
|
||||||
},
|
},
|
||||||
openPage: (e) async {
|
openPage: (e) async {
|
||||||
|
@ -11,49 +11,62 @@ import 'package:dartz/dartz.dart';
|
|||||||
part 'menu_user_bloc.freezed.dart';
|
part 'menu_user_bloc.freezed.dart';
|
||||||
|
|
||||||
class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
|
class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
|
||||||
final UserService userService;
|
final UserService _userService;
|
||||||
final UserListener userListener;
|
final UserListener _userListener;
|
||||||
|
final UserWorkspaceListener _userWorkspaceListener;
|
||||||
final UserProfile userProfile;
|
final UserProfile userProfile;
|
||||||
|
|
||||||
MenuUserBloc(this.userProfile, this.userService, this.userListener) : super(MenuUserState.initial(userProfile)) {
|
MenuUserBloc(this.userProfile)
|
||||||
|
: _userListener = UserListener(userProfile: userProfile),
|
||||||
|
_userWorkspaceListener = UserWorkspaceListener(userProfile: userProfile),
|
||||||
|
_userService = UserService(userId: userProfile.id),
|
||||||
|
super(MenuUserState.initial(userProfile)) {
|
||||||
on<MenuUserEvent>((event, emit) async {
|
on<MenuUserEvent>((event, emit) async {
|
||||||
await event.map(
|
await event.when(
|
||||||
initial: (_) async {
|
initial: () async {
|
||||||
userListener.start(
|
_userListener.start(onProfileUpdated: _profileUpdated);
|
||||||
onProfileUpdated: _profileUpdated,
|
_userWorkspaceListener.start(onWorkspacesUpdated: _workspaceListUpdated);
|
||||||
onWorkspaceListUpdated: _workspaceListUpdated,
|
|
||||||
);
|
|
||||||
await _initUser();
|
await _initUser();
|
||||||
},
|
},
|
||||||
fetchWorkspaces: (_FetchWorkspaces value) async {},
|
fetchWorkspaces: () async {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
didReceiveUserProfile: (UserProfile newUserProfile) {
|
||||||
|
emit(state.copyWith(userProfile: newUserProfile));
|
||||||
|
},
|
||||||
|
updateUserName: (String name) {
|
||||||
|
_userService.updateUserProfile(name: name).then((result) {
|
||||||
|
result.fold(
|
||||||
|
(l) => null,
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await userListener.stop();
|
await _userListener.stop();
|
||||||
|
await _userWorkspaceListener.stop();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _initUser() async {
|
Future<void> _initUser() async {
|
||||||
final result = await userService.initUser();
|
final result = await _userService.initUser();
|
||||||
result.fold((l) => null, (error) => Log.error(error));
|
result.fold((l) => null, (error) => Log.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _profileUpdated(Either<UserProfile, FlowyError> userOrFailed) {}
|
void _profileUpdated(Either<UserProfile, FlowyError> userProfileOrFailed) {
|
||||||
|
userProfileOrFailed.fold(
|
||||||
|
(newUserProfile) => add(MenuUserEvent.didReceiveUserProfile(newUserProfile)),
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void _workspaceListUpdated(Either<List<Workspace>, FlowyError> workspacesOrFailed) {
|
void _workspaceListUpdated(Either<List<Workspace>, FlowyError> workspacesOrFailed) {
|
||||||
// fetch workspaces
|
// Do nothing by now
|
||||||
// iUserImpl.fetchWorkspaces().then((result) {
|
|
||||||
// result.fold(
|
|
||||||
// (workspaces) async* {
|
|
||||||
// yield state.copyWith(workspaces: some(workspaces));
|
|
||||||
// },
|
|
||||||
// (error) async* {
|
|
||||||
// yield state.copyWith(successOrFailure: right(error.msg));
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,18 +74,20 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
|
|||||||
class MenuUserEvent with _$MenuUserEvent {
|
class MenuUserEvent with _$MenuUserEvent {
|
||||||
const factory MenuUserEvent.initial() = _Initial;
|
const factory MenuUserEvent.initial() = _Initial;
|
||||||
const factory MenuUserEvent.fetchWorkspaces() = _FetchWorkspaces;
|
const factory MenuUserEvent.fetchWorkspaces() = _FetchWorkspaces;
|
||||||
|
const factory MenuUserEvent.updateUserName(String name) = _UpdateUserName;
|
||||||
|
const factory MenuUserEvent.didReceiveUserProfile(UserProfile newUserProfile) = _DidReceiveUserProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class MenuUserState with _$MenuUserState {
|
class MenuUserState with _$MenuUserState {
|
||||||
const factory MenuUserState({
|
const factory MenuUserState({
|
||||||
required UserProfile user,
|
required UserProfile userProfile,
|
||||||
required Option<List<Workspace>> workspaces,
|
required Option<List<Workspace>> workspaces,
|
||||||
required Either<Unit, String> successOrFailure,
|
required Either<Unit, String> successOrFailure,
|
||||||
}) = _MenuUserState;
|
}) = _MenuUserState;
|
||||||
|
|
||||||
factory MenuUserState.initial(UserProfile user) => MenuUserState(
|
factory MenuUserState.initial(UserProfile userProfile) => MenuUserState(
|
||||||
user: user,
|
userProfile: userProfile,
|
||||||
workspaces: none(),
|
workspaces: none(),
|
||||||
successOrFailure: left(unit),
|
successOrFailure: left(unit),
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'package:app_flowy/core/folder_notification.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
|
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
import 'package:app_flowy/core/folder_notification.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
|
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||||
|
@ -11,13 +11,13 @@ part 'welcome_bloc.freezed.dart';
|
|||||||
|
|
||||||
class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
||||||
final UserService userService;
|
final UserService userService;
|
||||||
final UserListener userListener;
|
final UserWorkspaceListener userWorkspaceListener;
|
||||||
WelcomeBloc({required this.userService, required this.userListener}) : super(WelcomeState.initial()) {
|
WelcomeBloc({required this.userService, required this.userWorkspaceListener}) : super(WelcomeState.initial()) {
|
||||||
on<WelcomeEvent>(
|
on<WelcomeEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.map(initial: (e) async {
|
await event.map(initial: (e) async {
|
||||||
userListener.start(
|
userWorkspaceListener.start(
|
||||||
onWorkspaceListUpdated: (result) => add(WelcomeEvent.workspacesReveived(result)),
|
onWorkspacesUpdated: (result) => add(WelcomeEvent.workspacesReveived(result)),
|
||||||
);
|
);
|
||||||
//
|
//
|
||||||
await _fetchWorkspaces(emit);
|
await _fetchWorkspaces(emit);
|
||||||
@ -37,7 +37,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await userListener.stop();
|
await userWorkspaceListener.stop();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,97 +1,73 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'package:app_flowy/core/folder_notification.dart';
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_infra/notifier.dart';
|
||||||
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
|
import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||||
import 'package:flowy_sdk/rust_stream.dart';
|
|
||||||
|
|
||||||
typedef WorkspaceAppsChangedCallback = void Function(Either<List<App>, FlowyError> appsOrFail);
|
typedef AppListNotifyValue = Either<List<App>, FlowyError>;
|
||||||
typedef WorkspaceUpdatedCallback = void Function(String name, String desc);
|
typedef WorkspaceNotifyValue = Either<Workspace, FlowyError>;
|
||||||
|
|
||||||
class WorkspaceListener {
|
class WorkspaceListener {
|
||||||
WorkspaceListenerService service;
|
PublishNotifier<AppListNotifyValue>? _appsChangedNotifier = PublishNotifier();
|
||||||
WorkspaceListener({
|
PublishNotifier<WorkspaceNotifyValue>? _workspaceUpdatedNotifier = PublishNotifier();
|
||||||
required this.service,
|
|
||||||
});
|
|
||||||
|
|
||||||
void start({WorkspaceAppsChangedCallback? addAppCallback, WorkspaceUpdatedCallback? updatedCallback}) {
|
FolderNotificationListener? _listener;
|
||||||
service.startListening(appsChanged: addAppCallback, update: updatedCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> stop() async {
|
|
||||||
await service.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WorkspaceListenerService {
|
|
||||||
StreamSubscription<SubscribeObject>? _subscription;
|
|
||||||
WorkspaceAppsChangedCallback? _appsChanged;
|
|
||||||
WorkspaceUpdatedCallback? _update;
|
|
||||||
FolderNotificationParser? _parser;
|
|
||||||
final UserProfile user;
|
final UserProfile user;
|
||||||
final String workspaceId;
|
final String workspaceId;
|
||||||
|
|
||||||
WorkspaceListenerService({
|
WorkspaceListener({
|
||||||
required this.user,
|
required this.user,
|
||||||
required this.workspaceId,
|
required this.workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
void startListening({
|
void start({
|
||||||
WorkspaceAppsChangedCallback? appsChanged,
|
void Function(AppListNotifyValue)? appsChanged,
|
||||||
WorkspaceUpdatedCallback? update,
|
void Function(WorkspaceNotifyValue)? onWorkspaceUpdated,
|
||||||
}) {
|
}) {
|
||||||
_appsChanged = appsChanged;
|
if (appsChanged != null) {
|
||||||
_update = update;
|
_appsChangedNotifier?.addPublishListener(appsChanged);
|
||||||
|
}
|
||||||
|
|
||||||
_parser = FolderNotificationParser(
|
if (onWorkspaceUpdated != null) {
|
||||||
id: workspaceId,
|
_workspaceUpdatedNotifier?.addPublishListener(onWorkspaceUpdated);
|
||||||
callback: (ty, result) {
|
}
|
||||||
_handleObservableType(ty, result);
|
|
||||||
},
|
_listener = FolderNotificationListener(
|
||||||
|
objectId: workspaceId,
|
||||||
|
handler: _handleObservableType,
|
||||||
);
|
);
|
||||||
|
|
||||||
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleObservableType(FolderNotification ty, Either<Uint8List, FlowyError> result) {
|
void _handleObservableType(FolderNotification ty, Either<Uint8List, FlowyError> result) {
|
||||||
switch (ty) {
|
switch (ty) {
|
||||||
case FolderNotification.WorkspaceUpdated:
|
case FolderNotification.WorkspaceUpdated:
|
||||||
if (_update != null) {
|
|
||||||
result.fold(
|
result.fold(
|
||||||
(payload) {
|
(payload) => _workspaceUpdatedNotifier?.value = left(Workspace.fromBuffer(payload)),
|
||||||
final workspace = Workspace.fromBuffer(payload);
|
(error) => _workspaceUpdatedNotifier?.value = right(error),
|
||||||
_update!(workspace.name, workspace.desc);
|
|
||||||
},
|
|
||||||
(error) => Log.error(error),
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case FolderNotification.WorkspaceAppsChanged:
|
case FolderNotification.WorkspaceAppsChanged:
|
||||||
if (_appsChanged != null) {
|
|
||||||
result.fold(
|
result.fold(
|
||||||
(payload) => _appsChanged!(
|
(payload) => _appsChangedNotifier?.value = left(RepeatedApp.fromBuffer(payload).items),
|
||||||
left(RepeatedApp.fromBuffer(payload).items),
|
(error) => _appsChangedNotifier?.value = right(error),
|
||||||
),
|
|
||||||
(error) => _appsChanged!(right(error)),
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> close() async {
|
Future<void> stop() async {
|
||||||
_parser = null;
|
await _listener?.stop();
|
||||||
await _subscription?.cancel();
|
_appsChangedNotifier?.dispose();
|
||||||
// _appsChanged = null;
|
_appsChangedNotifier = null;
|
||||||
// _update = null;
|
|
||||||
|
_workspaceUpdatedNotifier?.dispose();
|
||||||
|
_workspaceUpdatedNotifier = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,9 @@ class MenuUser extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderUserName(BuildContext context) {
|
Widget _renderUserName(BuildContext context) {
|
||||||
String name = context.read<MenuUserBloc>().state.user.name;
|
String name = context.read<MenuUserBloc>().state.userProfile.name;
|
||||||
if (name.isEmpty) {
|
if (name.isEmpty) {
|
||||||
name = context.read<MenuUserBloc>().state.user.email;
|
name = context.read<MenuUserBloc>().state.userProfile.email;
|
||||||
}
|
}
|
||||||
return FlowyText(name, fontSize: 12);
|
return FlowyText(name, fontSize: 12);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use crate::{configuration::*, request::HttpRequestBuilder};
|
|||||||
use flowy_error::FlowyError;
|
use flowy_error::FlowyError;
|
||||||
use flowy_user::event_map::UserCloudService;
|
use flowy_user::event_map::UserCloudService;
|
||||||
use flowy_user_data_model::entities::{
|
use flowy_user_data_model::entities::{
|
||||||
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile,
|
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserProfileParams, UserProfile,
|
||||||
};
|
};
|
||||||
use http_flowy::errors::ServerError;
|
use http_flowy::errors::ServerError;
|
||||||
use lib_infra::future::FutureResult;
|
use lib_infra::future::FutureResult;
|
||||||
@ -42,7 +42,7 @@ impl UserCloudService for UserHttpCloudService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_user(&self, token: &str, params: UpdateUserParams) -> FutureResult<(), FlowyError> {
|
fn update_user(&self, token: &str, params: UpdateUserProfileParams) -> FutureResult<(), FlowyError> {
|
||||||
let token = token.to_owned();
|
let token = token.to_owned();
|
||||||
let url = self.config.user_profile_url();
|
let url = self.config.user_profile_url();
|
||||||
FutureResult::new(async move {
|
FutureResult::new(async move {
|
||||||
@ -101,7 +101,11 @@ pub async fn get_user_profile_request(token: &str, url: &str) -> Result<UserProf
|
|||||||
Ok(user_profile)
|
Ok(user_profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_user_profile_request(token: &str, params: UpdateUserParams, url: &str) -> Result<(), ServerError> {
|
pub async fn update_user_profile_request(
|
||||||
|
token: &str,
|
||||||
|
params: UpdateUserProfileParams,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<(), ServerError> {
|
||||||
let _ = request_builder()
|
let _ = request_builder()
|
||||||
.patch(&url.to_owned())
|
.patch(&url.to_owned())
|
||||||
.header(HEADER_TOKEN, token)
|
.header(HEADER_TOKEN, token)
|
||||||
|
@ -264,7 +264,7 @@ use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision
|
|||||||
use flowy_text_block::BlockCloudService;
|
use flowy_text_block::BlockCloudService;
|
||||||
use flowy_user::event_map::UserCloudService;
|
use flowy_user::event_map::UserCloudService;
|
||||||
use flowy_user_data_model::entities::{
|
use flowy_user_data_model::entities::{
|
||||||
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile,
|
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserProfileParams, UserProfile,
|
||||||
};
|
};
|
||||||
use lib_infra::{future::FutureResult, util::timestamp};
|
use lib_infra::{future::FutureResult, util::timestamp};
|
||||||
|
|
||||||
@ -401,7 +401,7 @@ impl UserCloudService for LocalServer {
|
|||||||
FutureResult::new(async { Ok(()) })
|
FutureResult::new(async { Ok(()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_user(&self, _token: &str, _params: UpdateUserParams) -> FutureResult<(), FlowyError> {
|
fn update_user(&self, _token: &str, _params: UpdateUserProfileParams) -> FutureResult<(), FlowyError> {
|
||||||
FutureResult::new(async { Ok(()) })
|
FutureResult::new(async { Ok(()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{errors::FlowyError, handlers::*, services::UserSession};
|
use crate::{errors::FlowyError, handlers::*, services::UserSession};
|
||||||
use flowy_user_data_model::entities::{
|
use flowy_user_data_model::entities::{
|
||||||
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile,
|
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserProfileParams, UserProfile,
|
||||||
};
|
};
|
||||||
use lib_dispatch::prelude::*;
|
use lib_dispatch::prelude::*;
|
||||||
use lib_infra::future::FutureResult;
|
use lib_infra::future::FutureResult;
|
||||||
@ -15,7 +15,7 @@ pub fn create(user_session: Arc<UserSession>) -> Module {
|
|||||||
.event(UserEvent::InitUser, init_user_handler)
|
.event(UserEvent::InitUser, init_user_handler)
|
||||||
.event(UserEvent::GetUserProfile, get_user_profile_handler)
|
.event(UserEvent::GetUserProfile, get_user_profile_handler)
|
||||||
.event(UserEvent::SignOut, sign_out)
|
.event(UserEvent::SignOut, sign_out)
|
||||||
.event(UserEvent::UpdateUser, update_user_handler)
|
.event(UserEvent::UpdateUserProfile, update_user_profile_handler)
|
||||||
.event(UserEvent::CheckUser, check_user_handler)
|
.event(UserEvent::CheckUser, check_user_handler)
|
||||||
.event(UserEvent::SetAppearanceSetting, set_appearance_setting)
|
.event(UserEvent::SetAppearanceSetting, set_appearance_setting)
|
||||||
.event(UserEvent::GetAppearanceSetting, get_appearance_setting)
|
.event(UserEvent::GetAppearanceSetting, get_appearance_setting)
|
||||||
@ -25,7 +25,7 @@ pub trait UserCloudService: Send + Sync {
|
|||||||
fn sign_up(&self, params: SignUpParams) -> FutureResult<SignUpResponse, FlowyError>;
|
fn sign_up(&self, params: SignUpParams) -> FutureResult<SignUpResponse, FlowyError>;
|
||||||
fn sign_in(&self, params: SignInParams) -> FutureResult<SignInResponse, FlowyError>;
|
fn sign_in(&self, params: SignInParams) -> FutureResult<SignInResponse, FlowyError>;
|
||||||
fn sign_out(&self, token: &str) -> FutureResult<(), FlowyError>;
|
fn sign_out(&self, token: &str) -> FutureResult<(), FlowyError>;
|
||||||
fn update_user(&self, token: &str, params: UpdateUserParams) -> FutureResult<(), FlowyError>;
|
fn update_user(&self, token: &str, params: UpdateUserProfileParams) -> FutureResult<(), FlowyError>;
|
||||||
fn get_user(&self, token: &str) -> FutureResult<UserProfile, FlowyError>;
|
fn get_user(&self, token: &str) -> FutureResult<UserProfile, FlowyError>;
|
||||||
fn ws_addr(&self) -> String;
|
fn ws_addr(&self) -> String;
|
||||||
}
|
}
|
||||||
@ -48,8 +48,8 @@ pub enum UserEvent {
|
|||||||
#[event(passthrough)]
|
#[event(passthrough)]
|
||||||
SignOut = 3,
|
SignOut = 3,
|
||||||
|
|
||||||
#[event(input = "UpdateUserPayload")]
|
#[event(input = "UpdateUserProfilePayload")]
|
||||||
UpdateUser = 4,
|
UpdateUserProfile = 4,
|
||||||
|
|
||||||
#[event(output = "UserProfile")]
|
#[event(output = "UserProfile")]
|
||||||
GetUserProfile = 5,
|
GetUserProfile = 5,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{errors::FlowyError, services::UserSession};
|
use crate::{errors::FlowyError, services::UserSession};
|
||||||
use flowy_database::kv::KV;
|
use flowy_database::kv::KV;
|
||||||
use flowy_user_data_model::entities::{
|
use flowy_user_data_model::entities::{
|
||||||
AppearanceSettings, UpdateUserParams, UpdateUserPayload, UserProfile, APPEARANCE_DEFAULT_THEME,
|
AppearanceSettings, UpdateUserProfileParams, UpdateUserProfilePayload, UserProfile, APPEARANCE_DEFAULT_THEME,
|
||||||
};
|
};
|
||||||
use lib_dispatch::prelude::*;
|
use lib_dispatch::prelude::*;
|
||||||
use std::{convert::TryInto, sync::Arc};
|
use std::{convert::TryInto, sync::Arc};
|
||||||
@ -20,7 +20,7 @@ pub async fn check_user_handler(session: AppData<Arc<UserSession>>) -> DataResul
|
|||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip(session))]
|
#[tracing::instrument(level = "debug", skip(session))]
|
||||||
pub async fn get_user_profile_handler(session: AppData<Arc<UserSession>>) -> DataResult<UserProfile, FlowyError> {
|
pub async fn get_user_profile_handler(session: AppData<Arc<UserSession>>) -> DataResult<UserProfile, FlowyError> {
|
||||||
let user_profile = session.user_profile().await?;
|
let user_profile = session.get_user_profile().await?;
|
||||||
data_result(user_profile)
|
data_result(user_profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,13 +30,13 @@ pub async fn sign_out(session: AppData<Arc<UserSession>>) -> Result<(), FlowyErr
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", name = "update_user", skip(data, session))]
|
#[tracing::instrument(level = "debug", skip(data, session))]
|
||||||
pub async fn update_user_handler(
|
pub async fn update_user_profile_handler(
|
||||||
data: Data<UpdateUserPayload>,
|
data: Data<UpdateUserProfilePayload>,
|
||||||
session: AppData<Arc<UserSession>>,
|
session: AppData<Arc<UserSession>>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let params: UpdateUserParams = data.into_inner().try_into()?;
|
let params: UpdateUserProfileParams = data.into_inner().try_into()?;
|
||||||
session.update_user(params).await?;
|
session.update_user_profile(params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use flowy_database::ConnectionPool;
|
use flowy_database::ConnectionPool;
|
||||||
use flowy_database::{schema::user_table, DBConnection, Database};
|
use flowy_database::{schema::user_table, DBConnection, Database};
|
||||||
use flowy_error::{ErrorCode, FlowyError};
|
use flowy_error::{ErrorCode, FlowyError};
|
||||||
use flowy_user_data_model::entities::{SignInResponse, SignUpResponse, UpdateUserParams, UserProfile};
|
use flowy_user_data_model::entities::{SignInResponse, SignUpResponse, UpdateUserProfileParams, UserProfile};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||||
@ -134,7 +134,7 @@ pub struct UserTableChangeset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UserTableChangeset {
|
impl UserTableChangeset {
|
||||||
pub fn new(params: UpdateUserParams) -> Self {
|
pub fn new(params: UpdateUserProfileParams) -> Self {
|
||||||
UserTableChangeset {
|
UserTableChangeset {
|
||||||
id: params.id,
|
id: params.id,
|
||||||
workspace: None,
|
workspace: None,
|
||||||
|
@ -15,7 +15,7 @@ use flowy_database::{
|
|||||||
DBConnection, ExpressionMethods, UserDatabaseConnection,
|
DBConnection, ExpressionMethods, UserDatabaseConnection,
|
||||||
};
|
};
|
||||||
use flowy_user_data_model::entities::{
|
use flowy_user_data_model::entities::{
|
||||||
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile,
|
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserProfileParams, UserProfile,
|
||||||
};
|
};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -82,7 +82,7 @@ impl UserSession {
|
|||||||
#[tracing::instrument(level = "debug", skip(self))]
|
#[tracing::instrument(level = "debug", skip(self))]
|
||||||
pub async fn sign_in(&self, params: SignInParams) -> Result<UserProfile, FlowyError> {
|
pub async fn sign_in(&self, params: SignInParams) -> Result<UserProfile, FlowyError> {
|
||||||
if self.is_user_login(¶ms.email) {
|
if self.is_user_login(¶ms.email) {
|
||||||
self.user_profile().await
|
self.get_user_profile().await
|
||||||
} else {
|
} else {
|
||||||
let resp = self.cloud_service.sign_in(params).await?;
|
let resp = self.cloud_service.sign_in(params).await?;
|
||||||
let session: Session = resp.clone().into();
|
let session: Session = resp.clone().into();
|
||||||
@ -97,7 +97,7 @@ impl UserSession {
|
|||||||
#[tracing::instrument(level = "debug", skip(self))]
|
#[tracing::instrument(level = "debug", skip(self))]
|
||||||
pub async fn sign_up(&self, params: SignUpParams) -> Result<UserProfile, FlowyError> {
|
pub async fn sign_up(&self, params: SignUpParams) -> Result<UserProfile, FlowyError> {
|
||||||
if self.is_user_login(¶ms.email) {
|
if self.is_user_login(¶ms.email) {
|
||||||
self.user_profile().await
|
self.get_user_profile().await
|
||||||
} else {
|
} else {
|
||||||
let resp = self.cloud_service.sign_up(params).await?;
|
let resp = self.cloud_service.sign_up(params).await?;
|
||||||
let session: Session = resp.clone().into();
|
let session: Session = resp.clone().into();
|
||||||
@ -126,11 +126,15 @@ impl UserSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip(self))]
|
#[tracing::instrument(level = "debug", skip(self))]
|
||||||
pub async fn update_user(&self, params: UpdateUserParams) -> Result<(), FlowyError> {
|
pub async fn update_user_profile(&self, params: UpdateUserProfileParams) -> Result<(), FlowyError> {
|
||||||
let session = self.get_session()?;
|
let session = self.get_session()?;
|
||||||
let changeset = UserTableChangeset::new(params.clone());
|
let changeset = UserTableChangeset::new(params.clone());
|
||||||
diesel_update_table!(user_table, changeset, &*self.db_connection()?);
|
diesel_update_table!(user_table, changeset, &*self.db_connection()?);
|
||||||
|
|
||||||
|
let user_profile = self.get_user_profile().await?;
|
||||||
|
dart_notify(&session.token, UserNotification::UserProfileUpdated)
|
||||||
|
.payload(user_profile)
|
||||||
|
.send();
|
||||||
let _ = self.update_user_on_server(&session.token, params).await?;
|
let _ = self.update_user_on_server(&session.token, params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -150,7 +154,7 @@ impl UserSession {
|
|||||||
Ok(user.into())
|
Ok(user.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn user_profile(&self) -> Result<UserProfile, FlowyError> {
|
pub async fn get_user_profile(&self) -> Result<UserProfile, FlowyError> {
|
||||||
let (user_id, token) = self.get_session()?.into_part();
|
let (user_id, token) = self.get_session()?.into_part();
|
||||||
let user = dsl::user_table
|
let user = dsl::user_table
|
||||||
.filter(user_table::id.eq(&user_id))
|
.filter(user_table::id.eq(&user_id))
|
||||||
@ -179,27 +183,27 @@ impl UserSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UserSession {
|
impl UserSession {
|
||||||
fn read_user_profile_on_server(&self, token: &str) -> Result<(), FlowyError> {
|
fn read_user_profile_on_server(&self, _token: &str) -> Result<(), FlowyError> {
|
||||||
let server = self.cloud_service.clone();
|
// let server = self.cloud_service.clone();
|
||||||
let token = token.to_owned();
|
// let token = token.to_owned();
|
||||||
tokio::spawn(async move {
|
// tokio::spawn(async move {
|
||||||
match server.get_user(&token).await {
|
// match server.get_user(&token).await {
|
||||||
Ok(profile) => {
|
// Ok(profile) => {
|
||||||
dart_notify(&token, UserNotification::UserProfileUpdated)
|
// dart_notify(&token, UserNotification::UserProfileUpdated)
|
||||||
.payload(profile)
|
// .payload(profile)
|
||||||
.send();
|
// .send();
|
||||||
}
|
// }
|
||||||
Err(e) => {
|
// Err(e) => {
|
||||||
dart_notify(&token, UserNotification::UserProfileUpdated)
|
// dart_notify(&token, UserNotification::UserProfileUpdated)
|
||||||
.error(e)
|
// .error(e)
|
||||||
.send();
|
// .send();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_user_on_server(&self, token: &str, params: UpdateUserParams) -> Result<(), FlowyError> {
|
async fn update_user_on_server(&self, token: &str, params: UpdateUserProfileParams) -> Result<(), FlowyError> {
|
||||||
let server = self.cloud_service.clone();
|
let server = self.cloud_service.clone();
|
||||||
let token = token.to_owned();
|
let token = token.to_owned();
|
||||||
let _ = tokio::spawn(async move {
|
let _ = tokio::spawn(async move {
|
||||||
@ -275,7 +279,7 @@ impl UserSession {
|
|||||||
pub async fn update_user(
|
pub async fn update_user(
|
||||||
_cloud_service: Arc<dyn UserCloudService>,
|
_cloud_service: Arc<dyn UserCloudService>,
|
||||||
pool: Arc<ConnectionPool>,
|
pool: Arc<ConnectionPool>,
|
||||||
params: UpdateUserParams,
|
params: UpdateUserProfileParams,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let changeset = UserTableChangeset::new(params);
|
let changeset = UserTableChangeset::new(params);
|
||||||
let conn = pool.get()?;
|
let conn = pool.get()?;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::helper::*;
|
use crate::helper::*;
|
||||||
use flowy_test::{event_builder::UserModuleEventBuilder, FlowySDKTest};
|
use flowy_test::{event_builder::UserModuleEventBuilder, FlowySDKTest};
|
||||||
use flowy_user::{errors::ErrorCode, event_map::UserEvent::*};
|
use flowy_user::{errors::ErrorCode, event_map::UserEvent::*};
|
||||||
use flowy_user_data_model::entities::{UpdateUserPayload, UserProfile};
|
use flowy_user_data_model::entities::{UpdateUserProfilePayload, UserProfile};
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
|
|
||||||
// use serial_test::*;
|
// use serial_test::*;
|
||||||
@ -33,9 +33,9 @@ async fn user_update_with_name() {
|
|||||||
let sdk = FlowySDKTest::default();
|
let sdk = FlowySDKTest::default();
|
||||||
let user = sdk.init_user().await;
|
let user = sdk.init_user().await;
|
||||||
let new_name = "hello_world".to_owned();
|
let new_name = "hello_world".to_owned();
|
||||||
let request = UpdateUserPayload::new(&user.id).name(&new_name);
|
let request = UpdateUserProfilePayload::new(&user.id).name(&new_name);
|
||||||
let _ = UserModuleEventBuilder::new(sdk.clone())
|
let _ = UserModuleEventBuilder::new(sdk.clone())
|
||||||
.event(UpdateUser)
|
.event(UpdateUserProfile)
|
||||||
.payload(request)
|
.payload(request)
|
||||||
.sync_send();
|
.sync_send();
|
||||||
|
|
||||||
@ -53,9 +53,9 @@ async fn user_update_with_email() {
|
|||||||
let sdk = FlowySDKTest::default();
|
let sdk = FlowySDKTest::default();
|
||||||
let user = sdk.init_user().await;
|
let user = sdk.init_user().await;
|
||||||
let new_email = format!("{}@gmail.com", nanoid!(6));
|
let new_email = format!("{}@gmail.com", nanoid!(6));
|
||||||
let request = UpdateUserPayload::new(&user.id).email(&new_email);
|
let request = UpdateUserProfilePayload::new(&user.id).email(&new_email);
|
||||||
let _ = UserModuleEventBuilder::new(sdk.clone())
|
let _ = UserModuleEventBuilder::new(sdk.clone())
|
||||||
.event(UpdateUser)
|
.event(UpdateUserProfile)
|
||||||
.payload(request)
|
.payload(request)
|
||||||
.sync_send();
|
.sync_send();
|
||||||
let user_profile = UserModuleEventBuilder::new(sdk.clone())
|
let user_profile = UserModuleEventBuilder::new(sdk.clone())
|
||||||
@ -72,10 +72,10 @@ async fn user_update_with_password() {
|
|||||||
let sdk = FlowySDKTest::default();
|
let sdk = FlowySDKTest::default();
|
||||||
let user = sdk.init_user().await;
|
let user = sdk.init_user().await;
|
||||||
let new_password = "H123world!".to_owned();
|
let new_password = "H123world!".to_owned();
|
||||||
let request = UpdateUserPayload::new(&user.id).password(&new_password);
|
let request = UpdateUserProfilePayload::new(&user.id).password(&new_password);
|
||||||
|
|
||||||
let _ = UserModuleEventBuilder::new(sdk.clone())
|
let _ = UserModuleEventBuilder::new(sdk.clone())
|
||||||
.event(UpdateUser)
|
.event(UpdateUserProfile)
|
||||||
.payload(request)
|
.payload(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.assert_success();
|
.assert_success();
|
||||||
@ -86,10 +86,10 @@ async fn user_update_with_invalid_email() {
|
|||||||
let test = FlowySDKTest::default();
|
let test = FlowySDKTest::default();
|
||||||
let user = test.init_user().await;
|
let user = test.init_user().await;
|
||||||
for email in invalid_email_test_case() {
|
for email in invalid_email_test_case() {
|
||||||
let request = UpdateUserPayload::new(&user.id).email(&email);
|
let request = UpdateUserProfilePayload::new(&user.id).email(&email);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
UserModuleEventBuilder::new(test.clone())
|
UserModuleEventBuilder::new(test.clone())
|
||||||
.event(UpdateUser)
|
.event(UpdateUserProfile)
|
||||||
.payload(request)
|
.payload(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.error()
|
.error()
|
||||||
@ -104,10 +104,10 @@ async fn user_update_with_invalid_password() {
|
|||||||
let test = FlowySDKTest::default();
|
let test = FlowySDKTest::default();
|
||||||
let user = test.init_user().await;
|
let user = test.init_user().await;
|
||||||
for password in invalid_password_test_case() {
|
for password in invalid_password_test_case() {
|
||||||
let request = UpdateUserPayload::new(&user.id).password(&password);
|
let request = UpdateUserProfilePayload::new(&user.id).password(&password);
|
||||||
|
|
||||||
UserModuleEventBuilder::new(test.clone())
|
UserModuleEventBuilder::new(test.clone())
|
||||||
.event(UpdateUser)
|
.event(UpdateUserProfile)
|
||||||
.payload(request)
|
.payload(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.assert_error();
|
.assert_error();
|
||||||
@ -118,9 +118,9 @@ async fn user_update_with_invalid_password() {
|
|||||||
async fn user_update_with_invalid_name() {
|
async fn user_update_with_invalid_name() {
|
||||||
let test = FlowySDKTest::default();
|
let test = FlowySDKTest::default();
|
||||||
let user = test.init_user().await;
|
let user = test.init_user().await;
|
||||||
let request = UpdateUserPayload::new(&user.id).name("");
|
let request = UpdateUserProfilePayload::new(&user.id).name("");
|
||||||
UserModuleEventBuilder::new(test.clone())
|
UserModuleEventBuilder::new(test.clone())
|
||||||
.event(UpdateUser)
|
.event(UpdateUserProfile)
|
||||||
.payload(request)
|
.payload(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.assert_error();
|
.assert_error();
|
||||||
|
@ -28,7 +28,7 @@ pub struct UserProfile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ProtoBuf, Default)]
|
#[derive(ProtoBuf, Default)]
|
||||||
pub struct UpdateUserPayload {
|
pub struct UpdateUserProfilePayload {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ pub struct UpdateUserPayload {
|
|||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UpdateUserPayload {
|
impl UpdateUserProfilePayload {
|
||||||
pub fn new(id: &str) -> Self {
|
pub fn new(id: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: id.to_owned(),
|
id: id.to_owned(),
|
||||||
@ -67,7 +67,7 @@ impl UpdateUserPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ProtoBuf, Default, Clone, Debug)]
|
#[derive(ProtoBuf, Default, Clone, Debug)]
|
||||||
pub struct UpdateUserParams {
|
pub struct UpdateUserProfileParams {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ pub struct UpdateUserParams {
|
|||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UpdateUserParams {
|
impl UpdateUserProfileParams {
|
||||||
pub fn new(user_id: &str) -> Self {
|
pub fn new(user_id: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: user_id.to_owned(),
|
id: user_id.to_owned(),
|
||||||
@ -105,10 +105,10 @@ impl UpdateUserParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<UpdateUserParams> for UpdateUserPayload {
|
impl TryInto<UpdateUserProfileParams> for UpdateUserProfilePayload {
|
||||||
type Error = ErrorCode;
|
type Error = ErrorCode;
|
||||||
|
|
||||||
fn try_into(self) -> Result<UpdateUserParams, Self::Error> {
|
fn try_into(self) -> Result<UpdateUserProfileParams, Self::Error> {
|
||||||
let id = UserId::parse(self.id)?.0;
|
let id = UserId::parse(self.id)?.0;
|
||||||
|
|
||||||
let name = match self.name {
|
let name = match self.name {
|
||||||
@ -126,7 +126,7 @@ impl TryInto<UpdateUserParams> for UpdateUserPayload {
|
|||||||
Some(password) => Some(UserPassword::parse(password)?.0),
|
Some(password) => Some(UserPassword::parse(password)?.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(UpdateUserParams {
|
Ok(UpdateUserProfileParams {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
email,
|
email,
|
||||||
|
Loading…
Reference in New Issue
Block a user