mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: code cleanup according to unintroduced lints (#4488)
* chore: remove redundant arguments * chore: remove unused constructor params * chore: reorganize constructors * chore: remove unnecessary awaits in returns * chore: remove unnecessary paranthesis * chore: add lints * chore: clean up after merge * chore: add sort constructors first * chore: organize constructors in blocs * chore: use sizedbox.shrink over empty container
This commit is contained in:
@ -2,14 +2,15 @@ import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class EditPanelContext extends Equatable {
|
||||
const EditPanelContext({
|
||||
required this.identifier,
|
||||
required this.title,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
final String identifier;
|
||||
final String title;
|
||||
final Widget child;
|
||||
const EditPanelContext({
|
||||
required this.child,
|
||||
required this.identifier,
|
||||
required this.title,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [identifier];
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:appflowy/workspace/application/edit_panel/edit_context.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'edit_panel_bloc.freezed.dart';
|
||||
|
||||
|
@ -11,10 +11,20 @@ import 'favorite_listener.dart';
|
||||
part 'favorite_bloc.freezed.dart';
|
||||
|
||||
class FavoriteBloc extends Bloc<FavoriteEvent, FavoriteState> {
|
||||
FavoriteBloc() : super(FavoriteState.initial()) {
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final _service = FavoriteService();
|
||||
final _listener = FavoriteListener();
|
||||
|
||||
FavoriteBloc() : super(FavoriteState.initial()) {
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<FavoriteEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -58,12 +68,6 @@ class FavoriteBloc extends Bloc<FavoriteEvent, FavoriteState> {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _onFavoritesUpdated(
|
||||
Either<FlowyError, RepeatedViewPB> favoriteOrFailed,
|
||||
bool didFavorite,
|
||||
|
@ -1,22 +1,29 @@
|
||||
import 'package:appflowy/user/application/user_listener.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'
|
||||
show WorkspaceSettingPB;
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'home_bloc.freezed.dart';
|
||||
|
||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
HomeBloc(WorkspaceSettingPB workspaceSetting)
|
||||
: _workspaceListener = UserWorkspaceListener(),
|
||||
super(HomeState.initial(workspaceSetting)) {
|
||||
_dispatch(workspaceSetting);
|
||||
}
|
||||
|
||||
final UserWorkspaceListener _workspaceListener;
|
||||
|
||||
HomeBloc(
|
||||
UserProfilePB userProfile,
|
||||
WorkspaceSettingPB workspaceSetting,
|
||||
) : _workspaceListener = UserWorkspaceListener(userProfile: userProfile),
|
||||
super(HomeState.initial(workspaceSetting)) {
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _workspaceListener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch(WorkspaceSettingPB workspaceSetting) {
|
||||
on<HomeEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -56,12 +63,6 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _workspaceListener.stop();
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
enum MenuResizeType {
|
||||
@ -100,6 +101,5 @@ class HomeState with _$HomeState {
|
||||
factory HomeState.initial(WorkspaceSettingPB workspaceSetting) => HomeState(
|
||||
isLoading: false,
|
||||
workspaceSetting: workspaceSetting,
|
||||
latestView: null,
|
||||
);
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
import 'package:appflowy/user/application/user_listener.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||
import 'package:appflowy/workspace/application/edit_panel/edit_context.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'
|
||||
show WorkspaceSettingPB;
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
@ -13,15 +12,11 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'home_setting_bloc.freezed.dart';
|
||||
|
||||
class HomeSettingBloc extends Bloc<HomeSettingEvent, HomeSettingState> {
|
||||
final UserWorkspaceListener _listener;
|
||||
final AppearanceSettingsCubit _appearanceSettingsCubit;
|
||||
|
||||
HomeSettingBloc(
|
||||
UserProfilePB user,
|
||||
WorkspaceSettingPB workspaceSetting,
|
||||
AppearanceSettingsCubit appearanceSettingsCubit,
|
||||
double screenWidthPx,
|
||||
) : _listener = UserWorkspaceListener(userProfile: user),
|
||||
) : _listener = UserWorkspaceListener(),
|
||||
_appearanceSettingsCubit = appearanceSettingsCubit,
|
||||
super(
|
||||
HomeSettingState.initial(
|
||||
@ -30,6 +25,19 @@ class HomeSettingBloc extends Bloc<HomeSettingEvent, HomeSettingState> {
|
||||
screenWidthPx,
|
||||
),
|
||||
) {
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final UserWorkspaceListener _listener;
|
||||
final AppearanceSettingsCubit _appearanceSettingsCubit;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<HomeSettingEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -92,12 +100,6 @@ class HomeSettingBloc extends Bloc<HomeSettingEvent, HomeSettingState> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
enum MenuResizeType {
|
||||
|
@ -13,73 +13,77 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'menu_bloc.freezed.dart';
|
||||
|
||||
class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
||||
final WorkspaceService _workspaceService;
|
||||
final WorkspaceListener _listener;
|
||||
final UserProfilePB user;
|
||||
final String workspaceId;
|
||||
|
||||
MenuBloc({
|
||||
required this.user,
|
||||
required this.workspaceId,
|
||||
}) : _workspaceService = WorkspaceService(workspaceId: workspaceId),
|
||||
MenuBloc({required this.user, required this.workspaceId})
|
||||
: _workspaceService = WorkspaceService(workspaceId: workspaceId),
|
||||
_listener = WorkspaceListener(
|
||||
user: user,
|
||||
workspaceId: workspaceId,
|
||||
),
|
||||
super(MenuState.initial()) {
|
||||
on<MenuEvent>((event, emit) async {
|
||||
await event.map(
|
||||
initial: (e) async {
|
||||
_listener.start(appsChanged: _handleAppsOrFail);
|
||||
await _fetchApps(emit);
|
||||
},
|
||||
createApp: (_CreateApp event) async {
|
||||
final result = await _workspaceService.createApp(
|
||||
name: event.name,
|
||||
desc: event.desc,
|
||||
index: event.index,
|
||||
);
|
||||
result.fold(
|
||||
(app) => emit(state.copyWith(lastCreatedView: app)),
|
||||
(error) {
|
||||
Log.error(error);
|
||||
emit(state.copyWith(successOrFailure: right(error)));
|
||||
},
|
||||
);
|
||||
},
|
||||
didReceiveApps: (e) async {
|
||||
emit(
|
||||
e.appsOrFail.fold(
|
||||
(views) =>
|
||||
state.copyWith(views: views, successOrFailure: left(unit)),
|
||||
(err) => state.copyWith(successOrFailure: right(err)),
|
||||
),
|
||||
);
|
||||
},
|
||||
moveApp: (_MoveApp value) {
|
||||
if (state.views.length > value.fromIndex) {
|
||||
final view = state.views[value.fromIndex];
|
||||
_workspaceService.moveApp(
|
||||
appId: view.id,
|
||||
fromIndex: value.fromIndex,
|
||||
toIndex: value.toIndex,
|
||||
);
|
||||
final apps = List<ViewPB>.from(state.views);
|
||||
|
||||
apps.insert(value.toIndex, apps.removeAt(value.fromIndex));
|
||||
emit(state.copyWith(views: apps));
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final WorkspaceService _workspaceService;
|
||||
final WorkspaceListener _listener;
|
||||
final UserProfilePB user;
|
||||
final String workspaceId;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<MenuEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
initial: (e) async {
|
||||
_listener.start(appsChanged: _handleAppsOrFail);
|
||||
await _fetchApps(emit);
|
||||
},
|
||||
createApp: (_CreateApp event) async {
|
||||
final result = await _workspaceService.createApp(
|
||||
name: event.name,
|
||||
desc: event.desc,
|
||||
index: event.index,
|
||||
);
|
||||
result.fold(
|
||||
(app) => emit(state.copyWith(lastCreatedView: app)),
|
||||
(error) {
|
||||
Log.error(error);
|
||||
emit(state.copyWith(successOrFailure: right(error)));
|
||||
},
|
||||
);
|
||||
},
|
||||
didReceiveApps: (e) async {
|
||||
emit(
|
||||
e.appsOrFail.fold(
|
||||
(views) =>
|
||||
state.copyWith(views: views, successOrFailure: left(unit)),
|
||||
(err) => state.copyWith(successOrFailure: right(err)),
|
||||
),
|
||||
);
|
||||
},
|
||||
moveApp: (_MoveApp value) {
|
||||
if (state.views.length > value.fromIndex) {
|
||||
final view = state.views[value.fromIndex];
|
||||
_workspaceService.moveApp(
|
||||
appId: view.id,
|
||||
fromIndex: value.fromIndex,
|
||||
toIndex: value.toIndex,
|
||||
);
|
||||
final apps = List<ViewPB>.from(state.views);
|
||||
|
||||
apps.insert(value.toIndex, apps.removeAt(value.fromIndex));
|
||||
emit(state.copyWith(views: apps));
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
Future<void> _fetchApps(Emitter<MenuState> emit) async {
|
||||
final viewsOrError = await _workspaceService.getViews();
|
||||
@ -124,6 +128,5 @@ class MenuState with _$MenuState {
|
||||
factory MenuState.initial() => MenuState(
|
||||
views: [],
|
||||
successOrFailure: left(unit),
|
||||
lastCreatedView: null,
|
||||
);
|
||||
}
|
||||
|
@ -1,51 +1,29 @@
|
||||
import 'package:appflowy/user/application/user_listener.dart';
|
||||
import 'package:appflowy/user/application/user_service.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
part 'menu_user_bloc.freezed.dart';
|
||||
|
||||
class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
|
||||
MenuUserBloc(this.userProfile)
|
||||
: _userListener = UserListener(userProfile: userProfile),
|
||||
_userWorkspaceListener = UserWorkspaceListener(),
|
||||
_userService = UserBackendService(userId: userProfile.id),
|
||||
super(MenuUserState.initial(userProfile)) {
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final UserBackendService _userService;
|
||||
final UserListener _userListener;
|
||||
final UserWorkspaceListener _userWorkspaceListener;
|
||||
final UserProfilePB userProfile;
|
||||
|
||||
MenuUserBloc(this.userProfile)
|
||||
: _userListener = UserListener(userProfile: userProfile),
|
||||
_userWorkspaceListener =
|
||||
UserWorkspaceListener(userProfile: userProfile),
|
||||
_userService = UserBackendService(userId: userProfile.id),
|
||||
super(MenuUserState.initial(userProfile)) {
|
||||
on<MenuUserEvent>((event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_userListener.start(onProfileUpdated: _profileUpdated);
|
||||
await _initUser();
|
||||
},
|
||||
fetchWorkspaces: () async {
|
||||
//
|
||||
},
|
||||
didReceiveUserProfile: (UserProfilePB newUserProfile) {
|
||||
emit(state.copyWith(userProfile: newUserProfile));
|
||||
},
|
||||
updateUserName: (String name) {
|
||||
_userService.updateUserProfile(name: name).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _userListener.stop();
|
||||
@ -53,6 +31,33 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
|
||||
super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<MenuUserEvent>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_userListener.start(onProfileUpdated: _profileUpdated);
|
||||
await _initUser();
|
||||
},
|
||||
fetchWorkspaces: () async {
|
||||
//
|
||||
},
|
||||
didReceiveUserProfile: (UserProfilePB newUserProfile) {
|
||||
emit(state.copyWith(userProfile: newUserProfile));
|
||||
},
|
||||
updateUserName: (String name) {
|
||||
_userService.updateUserProfile(name: name).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _initUser() async {
|
||||
final result = await _userService.initUser();
|
||||
result.fold((l) => null, (error) => Log.error(error));
|
||||
|
@ -38,6 +38,10 @@ class NotificationActionEvent with _$NotificationActionEvent {
|
||||
}
|
||||
|
||||
class NotificationActionState {
|
||||
const NotificationActionState.initial()
|
||||
: action = null,
|
||||
nextActions = const [];
|
||||
|
||||
const NotificationActionState({
|
||||
required this.action,
|
||||
this.nextActions = const [],
|
||||
@ -46,10 +50,6 @@ class NotificationActionState {
|
||||
final NotificationAction? action;
|
||||
final List<NotificationAction> nextActions;
|
||||
|
||||
const NotificationActionState.initial()
|
||||
: action = null,
|
||||
nextActions = const [];
|
||||
|
||||
NotificationActionState copyWith({
|
||||
NotificationAction? action,
|
||||
List<NotificationAction>? nextActions,
|
||||
|
@ -14,7 +14,6 @@ class NotificationService {
|
||||
static Future<void> initialize() async {
|
||||
await localNotifier.setup(
|
||||
appName: _appName,
|
||||
shortcutPolicy: ShortcutPolicy.requireCreate, // Windows Specific
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,20 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'recent_views_bloc.freezed.dart';
|
||||
|
||||
class RecentViewsBloc extends Bloc<RecentViewsEvent, RecentViewsState> {
|
||||
RecentViewsBloc() : super(RecentViewsState.initial()) {
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final _service = RecentService();
|
||||
final _listener = RecentViewsListener();
|
||||
|
||||
RecentViewsBloc() : super(RecentViewsState.initial()) {
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<RecentViewsEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -43,12 +53,6 @@ class RecentViewsBloc extends Bloc<RecentViewsEvent, RecentViewsState> {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _onRecentViewsUpdated(
|
||||
Either<FlowyError, RepeatedViewIdPB> result,
|
||||
) {
|
||||
|
@ -26,9 +26,6 @@ part 'appearance_cubit.freezed.dart';
|
||||
/// - [UserTimeFormatPB]
|
||||
///
|
||||
class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
||||
final AppearanceSettingsPB _appearanceSettings;
|
||||
final DateTimeSettingsPB _dateTimeSettings;
|
||||
|
||||
AppearanceSettingsCubit(
|
||||
AppearanceSettingsPB appearanceSettings,
|
||||
DateTimeSettingsPB dateTimeSettings,
|
||||
@ -52,9 +49,7 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
||||
appearanceSettings.documentSetting.cursorColor.isEmpty
|
||||
? null
|
||||
: Color(
|
||||
int.parse(
|
||||
appearanceSettings.documentSetting.cursorColor,
|
||||
),
|
||||
int.parse(appearanceSettings.documentSetting.cursorColor),
|
||||
),
|
||||
appearanceSettings.documentSetting.selectionColor.isEmpty
|
||||
? null
|
||||
@ -66,6 +61,9 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
||||
),
|
||||
);
|
||||
|
||||
final AppearanceSettingsPB _appearanceSettings;
|
||||
final DateTimeSettingsPB _dateTimeSettings;
|
||||
|
||||
/// Update selected theme in the user's settings and emit an updated state
|
||||
/// with the AppTheme named [themeName].
|
||||
Future<void> setTheme(String themeName) async {
|
||||
|
@ -3,55 +3,62 @@ import 'package:appflowy/workspace/application/settings/cloud_setting_listener.d
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
part 'appflowy_cloud_setting_bloc.freezed.dart';
|
||||
|
||||
class AppFlowyCloudSettingBloc
|
||||
extends Bloc<AppFlowyCloudSettingEvent, AppFlowyCloudSettingState> {
|
||||
final UserCloudConfigListener _listener;
|
||||
AppFlowyCloudSettingBloc(CloudSettingPB setting)
|
||||
: _listener = UserCloudConfigListener(),
|
||||
super(AppFlowyCloudSettingState.initial(setting)) {
|
||||
on<AppFlowyCloudSettingEvent>((event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_listener.start(
|
||||
onSettingChanged: (result) {
|
||||
if (isClosed) {
|
||||
return;
|
||||
}
|
||||
result.fold(
|
||||
(setting) =>
|
||||
add(AppFlowyCloudSettingEvent.didReceiveSetting(setting)),
|
||||
(error) => Log.error(error),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
enableSync: (isEnable) async {
|
||||
final config = UpdateCloudConfigPB.create()..enableSync = isEnable;
|
||||
await UserEventSetCloudConfig(config).send();
|
||||
},
|
||||
didReceiveSetting: (CloudSettingPB setting) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
setting: setting,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final UserCloudConfigListener _listener;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
_listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<AppFlowyCloudSettingEvent>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_listener.start(
|
||||
onSettingChanged: (result) {
|
||||
if (isClosed) {
|
||||
return;
|
||||
}
|
||||
result.fold(
|
||||
(setting) =>
|
||||
add(AppFlowyCloudSettingEvent.didReceiveSetting(setting)),
|
||||
(error) => Log.error(error),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
enableSync: (isEnable) async {
|
||||
final config = UpdateCloudConfigPB.create()..enableSync = isEnable;
|
||||
await UserEventSetCloudConfig(config).send();
|
||||
},
|
||||
didReceiveSetting: (CloudSettingPB setting) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
setting: setting,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -2,10 +2,10 @@ import 'package:appflowy/env/backend_env.dart';
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
part 'appflowy_cloud_urls_bloc.freezed.dart';
|
||||
|
||||
|
@ -10,11 +10,11 @@ import 'package:dartz/dartz.dart';
|
||||
import '../../../core/notification/user_notification.dart';
|
||||
|
||||
class UserCloudConfigListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
void Function(Either<CloudSettingPB, FlowyError>)? _onSettingChanged;
|
||||
UserCloudConfigListener();
|
||||
|
||||
UserNotificationParser? _userParser;
|
||||
UserCloudConfigListener();
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
void Function(Either<CloudSettingPB, FlowyError>)? _onSettingChanged;
|
||||
|
||||
void start({
|
||||
void Function(Either<CloudSettingPB, FlowyError>)? onSettingChanged,
|
||||
|
@ -9,10 +9,6 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'notification_settings_cubit.freezed.dart';
|
||||
|
||||
class NotificationSettingsCubit extends Cubit<NotificationSettingsState> {
|
||||
final Completer<void> _initCompleter = Completer();
|
||||
|
||||
late final NotificationSettingsPB _notificationSettings;
|
||||
|
||||
NotificationSettingsCubit() : super(NotificationSettingsState.initial()) {
|
||||
UserSettingsBackendService()
|
||||
.getNotificationSettings()
|
||||
@ -27,6 +23,10 @@ class NotificationSettingsCubit extends Cubit<NotificationSettingsState> {
|
||||
});
|
||||
}
|
||||
|
||||
final Completer<void> _initCompleter = Completer();
|
||||
|
||||
late final NotificationSettingsPB _notificationSettings;
|
||||
|
||||
Future<void> toggleNotificationsEnabled() async {
|
||||
await _initCompleter.future;
|
||||
|
||||
|
@ -2,9 +2,9 @@ import 'package:appflowy/user/application/user_listener.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
part 'settings_dialog_bloc.freezed.dart';
|
||||
|
||||
@ -20,33 +20,39 @@ enum SettingsPage {
|
||||
|
||||
class SettingsDialogBloc
|
||||
extends Bloc<SettingsDialogEvent, SettingsDialogState> {
|
||||
final UserListener _userListener;
|
||||
final UserProfilePB userProfile;
|
||||
|
||||
SettingsDialogBloc(this.userProfile)
|
||||
: _userListener = UserListener(userProfile: userProfile),
|
||||
super(SettingsDialogState.initial(userProfile)) {
|
||||
on<SettingsDialogEvent>((event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_userListener.start(onProfileUpdated: _profileUpdated);
|
||||
},
|
||||
didReceiveUserProfile: (UserProfilePB newUserProfile) {
|
||||
emit(state.copyWith(userProfile: newUserProfile));
|
||||
},
|
||||
setSelectedPage: (SettingsPage page) {
|
||||
emit(state.copyWith(page: page));
|
||||
},
|
||||
);
|
||||
});
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final UserProfilePB userProfile;
|
||||
final UserListener _userListener;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _userListener.stop();
|
||||
super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<SettingsDialogEvent>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_userListener.start(onProfileUpdated: _profileUpdated);
|
||||
},
|
||||
didReceiveUserProfile: (UserProfilePB newUserProfile) {
|
||||
emit(state.copyWith(userProfile: newUserProfile));
|
||||
},
|
||||
setSelectedPage: (SettingsPage page) {
|
||||
emit(state.copyWith(page: page));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _profileUpdated(Either<UserProfilePB, FlowyError> userProfileOrFailed) {
|
||||
userProfileOrFailed.fold(
|
||||
(newUserProfile) =>
|
||||
|
@ -17,7 +17,7 @@ class ImportBackendService {
|
||||
..viewLayout = importType.toLayout()
|
||||
..name = name
|
||||
..importType = importType;
|
||||
return await FolderEventImportData(payload).send();
|
||||
return FolderEventImportData(payload).send();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ class SettingsShortcutService {
|
||||
) async {
|
||||
for (final shortcut in customizeShortcuts) {
|
||||
final shortcutEvent = commandShortcuts.firstWhereOrNull(
|
||||
(s) => (s.key == shortcut.key && s.command != shortcut.command),
|
||||
(s) => s.key == shortcut.key && s.command != shortcut.command,
|
||||
);
|
||||
shortcutEvent?.updateCommand(command: shortcut.command);
|
||||
}
|
||||
|
@ -1,21 +1,17 @@
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
class EditorShortcuts {
|
||||
EditorShortcuts({
|
||||
required this.commandShortcuts,
|
||||
});
|
||||
|
||||
final List<CommandShortcutModel> commandShortcuts;
|
||||
|
||||
factory EditorShortcuts.fromJson(Map<String, dynamic> json) =>
|
||||
EditorShortcuts(
|
||||
commandShortcuts: List<CommandShortcutModel>.from(
|
||||
json["commandShortcuts"].map(
|
||||
(x) => CommandShortcutModel.fromJson(x),
|
||||
),
|
||||
json["commandShortcuts"].map((x) => CommandShortcutModel.fromJson(x)),
|
||||
),
|
||||
);
|
||||
|
||||
EditorShortcuts({required this.commandShortcuts});
|
||||
|
||||
final List<CommandShortcutModel> commandShortcuts;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"commandShortcuts":
|
||||
List<dynamic>.from(commandShortcuts.map((x) => x.toJson())),
|
||||
@ -23,20 +19,6 @@ class EditorShortcuts {
|
||||
}
|
||||
|
||||
class CommandShortcutModel {
|
||||
const CommandShortcutModel({
|
||||
required this.key,
|
||||
required this.command,
|
||||
});
|
||||
|
||||
final String key;
|
||||
final String command;
|
||||
|
||||
factory CommandShortcutModel.fromJson(Map<String, dynamic> json) =>
|
||||
CommandShortcutModel(
|
||||
key: json["key"],
|
||||
command: (json["command"] ?? ''),
|
||||
);
|
||||
|
||||
factory CommandShortcutModel.fromCommandEvent(
|
||||
CommandShortcutEvent commandShortcutEvent,
|
||||
) =>
|
||||
@ -45,10 +27,18 @@ class CommandShortcutModel {
|
||||
command: commandShortcutEvent.command,
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"key": key,
|
||||
"command": command,
|
||||
};
|
||||
factory CommandShortcutModel.fromJson(Map<String, dynamic> json) =>
|
||||
CommandShortcutModel(
|
||||
key: json["key"],
|
||||
command: json["command"] ?? '',
|
||||
);
|
||||
|
||||
const CommandShortcutModel({required this.key, required this.command});
|
||||
|
||||
final String key;
|
||||
final String command;
|
||||
|
||||
Map<String, dynamic> toJson() => {"key": key, "command": command};
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
|
@ -5,9 +5,9 @@ import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
import 'cloud_setting_listener.dart';
|
||||
|
||||
@ -15,58 +15,64 @@ part 'supabase_cloud_setting_bloc.freezed.dart';
|
||||
|
||||
class SupabaseCloudSettingBloc
|
||||
extends Bloc<SupabaseCloudSettingEvent, SupabaseCloudSettingState> {
|
||||
final UserCloudConfigListener _listener;
|
||||
|
||||
SupabaseCloudSettingBloc({
|
||||
required CloudSettingPB setting,
|
||||
}) : _listener = UserCloudConfigListener(),
|
||||
super(SupabaseCloudSettingState.initial(setting)) {
|
||||
on<SupabaseCloudSettingEvent>((event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_listener.start(
|
||||
onSettingChanged: (result) {
|
||||
if (isClosed) {
|
||||
return;
|
||||
}
|
||||
result.fold(
|
||||
(setting) =>
|
||||
add(SupabaseCloudSettingEvent.didReceiveSetting(setting)),
|
||||
(error) => Log.error(error),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
enableSync: (bool enable) async {
|
||||
final update = UpdateCloudConfigPB.create()..enableSync = enable;
|
||||
updateCloudConfig(update);
|
||||
},
|
||||
didReceiveSetting: (CloudSettingPB setting) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
setting: setting,
|
||||
loadingState: LoadingState.finish(left(unit)),
|
||||
),
|
||||
);
|
||||
},
|
||||
enableEncrypt: (bool enable) {
|
||||
final update = UpdateCloudConfigPB.create()..enableEncrypt = enable;
|
||||
updateCloudConfig(update);
|
||||
emit(state.copyWith(loadingState: const LoadingState.loading()));
|
||||
},
|
||||
);
|
||||
});
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
Future<void> updateCloudConfig(UpdateCloudConfigPB setting) async {
|
||||
await UserEventSetCloudConfig(setting).send();
|
||||
}
|
||||
final UserCloudConfigListener _listener;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
_listener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<SupabaseCloudSettingEvent>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_listener.start(
|
||||
onSettingChanged: (result) {
|
||||
if (isClosed) {
|
||||
return;
|
||||
}
|
||||
result.fold(
|
||||
(setting) =>
|
||||
add(SupabaseCloudSettingEvent.didReceiveSetting(setting)),
|
||||
(error) => Log.error(error),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
enableSync: (bool enable) async {
|
||||
final update = UpdateCloudConfigPB.create()..enableSync = enable;
|
||||
updateCloudConfig(update);
|
||||
},
|
||||
didReceiveSetting: (CloudSettingPB setting) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
setting: setting,
|
||||
loadingState: LoadingState.finish(left(unit)),
|
||||
),
|
||||
);
|
||||
},
|
||||
enableEncrypt: (bool enable) {
|
||||
final update = UpdateCloudConfigPB.create()..enableEncrypt = enable;
|
||||
updateCloudConfig(update);
|
||||
emit(state.copyWith(loadingState: const LoadingState.loading()));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> updateCloudConfig(UpdateCloudConfigPB setting) async {
|
||||
await UserEventSetCloudConfig(setting).send();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -4,10 +4,10 @@ import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
import 'appflowy_cloud_setting_bloc.dart';
|
||||
|
||||
|
@ -15,40 +15,45 @@ part 'tabs_state.dart';
|
||||
part 'tabs_bloc.freezed.dart';
|
||||
|
||||
class TabsBloc extends Bloc<TabsEvent, TabsState> {
|
||||
late final MenuSharedState menuSharedState;
|
||||
|
||||
TabsBloc() : super(TabsState()) {
|
||||
menuSharedState = getIt<MenuSharedState>();
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
on<TabsEvent>((event, emit) async {
|
||||
event.when(
|
||||
selectTab: (int index) {
|
||||
if (index != state.currentIndex &&
|
||||
index >= 0 &&
|
||||
index < state.pages) {
|
||||
emit(state.copyWith(newIndex: index));
|
||||
late final MenuSharedState menuSharedState;
|
||||
|
||||
void _dispatch() {
|
||||
on<TabsEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
selectTab: (int index) {
|
||||
if (index != state.currentIndex &&
|
||||
index >= 0 &&
|
||||
index < state.pages) {
|
||||
emit(state.copyWith(newIndex: index));
|
||||
_setLatestOpenView();
|
||||
}
|
||||
},
|
||||
moveTab: () {},
|
||||
closeTab: (String pluginId) {
|
||||
emit(state.closeView(pluginId));
|
||||
_setLatestOpenView();
|
||||
}
|
||||
},
|
||||
moveTab: () {},
|
||||
closeTab: (String pluginId) {
|
||||
emit(state.closeView(pluginId));
|
||||
_setLatestOpenView();
|
||||
},
|
||||
closeCurrentTab: () {
|
||||
emit(state.closeView(state.currentPageManager.plugin.id));
|
||||
_setLatestOpenView();
|
||||
},
|
||||
openTab: (Plugin plugin, ViewPB view) {
|
||||
emit(state.openView(plugin, view));
|
||||
_setLatestOpenView(view);
|
||||
},
|
||||
openPlugin: (Plugin plugin, ViewPB? view) {
|
||||
emit(state.openPlugin(plugin: plugin));
|
||||
_setLatestOpenView(view);
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
closeCurrentTab: () {
|
||||
emit(state.closeView(state.currentPageManager.plugin.id));
|
||||
_setLatestOpenView();
|
||||
},
|
||||
openTab: (Plugin plugin, ViewPB view) {
|
||||
emit(state.openView(plugin, view));
|
||||
_setLatestOpenView(view);
|
||||
},
|
||||
openPlugin: (Plugin plugin, ViewPB? view) {
|
||||
emit(state.openPlugin(plugin: plugin));
|
||||
_setLatestOpenView(view);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _setLatestOpenView([ViewPB? view]) {
|
||||
|
@ -1,18 +1,17 @@
|
||||
part of 'tabs_bloc.dart';
|
||||
|
||||
class TabsState {
|
||||
final int currentIndex;
|
||||
|
||||
final List<PageManager> _pageManagers;
|
||||
int get pages => _pageManagers.length;
|
||||
PageManager get currentPageManager => _pageManagers[currentIndex];
|
||||
List<PageManager> get pageManagers => _pageManagers;
|
||||
|
||||
TabsState({
|
||||
this.currentIndex = 0,
|
||||
List<PageManager>? pageManagers,
|
||||
}) : _pageManagers = pageManagers ?? [PageManager()];
|
||||
|
||||
final int currentIndex;
|
||||
final List<PageManager> _pageManagers;
|
||||
int get pages => _pageManagers.length;
|
||||
PageManager get currentPageManager => _pageManagers[currentIndex];
|
||||
List<PageManager> get pageManagers => _pageManagers;
|
||||
|
||||
/// This opens a new tab given a [Plugin] and a [View].
|
||||
///
|
||||
/// If the [Plugin.id] is already associated with an open tab,
|
||||
|
@ -10,84 +10,90 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'settings_user_bloc.freezed.dart';
|
||||
|
||||
class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
|
||||
final UserBackendService _userService;
|
||||
final UserListener _userListener;
|
||||
final UserProfilePB userProfile;
|
||||
|
||||
SettingsUserViewBloc(this.userProfile)
|
||||
: _userListener = UserListener(userProfile: userProfile),
|
||||
_userService = UserBackendService(userId: userProfile.id),
|
||||
super(SettingsUserState.initial(userProfile)) {
|
||||
on<SettingsUserEvent>((event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_loadUserProfile();
|
||||
_userListener.start(onProfileUpdated: _profileUpdated);
|
||||
},
|
||||
didReceiveUserProfile: (UserProfilePB newUserProfile) {
|
||||
emit(state.copyWith(userProfile: newUserProfile));
|
||||
},
|
||||
updateUserName: (String name) {
|
||||
_userService.updateUserProfile(name: name).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
updateUserIcon: (String iconUrl) {
|
||||
_userService.updateUserProfile(iconUrl: iconUrl).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
removeUserIcon: () {
|
||||
// Empty Icon URL = No icon
|
||||
_userService.updateUserProfile(iconUrl: "").then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
updateUserOpenAIKey: (openAIKey) {
|
||||
_userService.updateUserProfile(openAIKey: openAIKey).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
updateUserStabilityAIKey: (stabilityAIKey) {
|
||||
_userService
|
||||
.updateUserProfile(stabilityAiKey: stabilityAIKey)
|
||||
.then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
updateUserEmail: (String email) {
|
||||
_userService.updateUserProfile(email: email).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final UserBackendService _userService;
|
||||
final UserListener _userListener;
|
||||
final UserProfilePB userProfile;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _userListener.stop();
|
||||
super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<SettingsUserEvent>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
initial: () async {
|
||||
_loadUserProfile();
|
||||
_userListener.start(onProfileUpdated: _profileUpdated);
|
||||
},
|
||||
didReceiveUserProfile: (UserProfilePB newUserProfile) {
|
||||
emit(state.copyWith(userProfile: newUserProfile));
|
||||
},
|
||||
updateUserName: (String name) {
|
||||
_userService.updateUserProfile(name: name).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
updateUserIcon: (String iconUrl) {
|
||||
_userService.updateUserProfile(iconUrl: iconUrl).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
removeUserIcon: () {
|
||||
// Empty Icon URL = No icon
|
||||
_userService.updateUserProfile(iconUrl: "").then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
updateUserOpenAIKey: (openAIKey) {
|
||||
_userService.updateUserProfile(openAIKey: openAIKey).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
updateUserStabilityAIKey: (stabilityAIKey) {
|
||||
_userService
|
||||
.updateUserProfile(stabilityAiKey: stabilityAIKey)
|
||||
.then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
updateUserEmail: (String email) {
|
||||
_userService.updateUserProfile(email: email).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _loadUserProfile() {
|
||||
UserBackendService.getCurrentUserProfile().then((result) {
|
||||
if (isClosed) {
|
||||
|
@ -18,167 +18,19 @@ import 'package:protobuf/protobuf.dart';
|
||||
part 'view_bloc.freezed.dart';
|
||||
|
||||
class ViewBloc extends Bloc<ViewEvent, ViewState> {
|
||||
final ViewBackendService viewBackendSvc;
|
||||
final ViewListener listener;
|
||||
final FavoriteListener favoriteListener;
|
||||
final ViewPB view;
|
||||
|
||||
ViewBloc({
|
||||
required this.view,
|
||||
}) : viewBackendSvc = ViewBackendService(),
|
||||
ViewBloc({required this.view})
|
||||
: viewBackendSvc = ViewBackendService(),
|
||||
listener = ViewListener(viewId: view.id),
|
||||
favoriteListener = FavoriteListener(),
|
||||
super(ViewState.init(view)) {
|
||||
on<ViewEvent>((event, emit) async {
|
||||
await event.map(
|
||||
initial: (e) async {
|
||||
listener.start(
|
||||
onViewUpdated: (result) {
|
||||
add(ViewEvent.viewDidUpdate(left(result)));
|
||||
},
|
||||
onViewChildViewsUpdated: (result) async {
|
||||
final view = await _updateChildViews(result);
|
||||
if (!isClosed && view != null) {
|
||||
add(ViewEvent.viewUpdateChildView(view));
|
||||
}
|
||||
},
|
||||
);
|
||||
favoriteListener.start(
|
||||
favoritesUpdated: (result, isFavorite) {
|
||||
result.fold((error) {}, (result) {
|
||||
final current =
|
||||
result.items.firstWhereOrNull((v) => v.id == state.view.id);
|
||||
if (current != null) {
|
||||
add(ViewEvent.viewDidUpdate(left(current)));
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
final isExpanded = await _getViewIsExpanded(view);
|
||||
emit(state.copyWith(isExpanded: isExpanded));
|
||||
await _loadViewsWhenExpanded(emit, isExpanded);
|
||||
},
|
||||
setIsEditing: (e) {
|
||||
emit(state.copyWith(isEditing: e.isEditing));
|
||||
},
|
||||
setIsExpanded: (e) async {
|
||||
if (e.isExpanded && !state.isExpanded) {
|
||||
await _loadViewsWhenExpanded(emit, true);
|
||||
} else {
|
||||
emit(state.copyWith(isExpanded: e.isExpanded));
|
||||
}
|
||||
await _setViewIsExpanded(view, e.isExpanded);
|
||||
},
|
||||
viewDidUpdate: (e) async {
|
||||
final result = await ViewBackendService.getView(
|
||||
view.id,
|
||||
);
|
||||
final view_ = result.fold((l) => l, (r) => null);
|
||||
e.result.fold(
|
||||
(view) async {
|
||||
// ignore child view changes because it only contains one level
|
||||
// children data.
|
||||
if (_isSameViewIgnoreChildren(view, state.view)) {
|
||||
// do nothing.
|
||||
}
|
||||
emit(
|
||||
state.copyWith(
|
||||
view: view_ ?? view,
|
||||
successOrFailure: left(unit),
|
||||
),
|
||||
);
|
||||
},
|
||||
(error) => emit(
|
||||
state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
rename: (e) async {
|
||||
final result = await ViewBackendService.updateView(
|
||||
viewId: view.id,
|
||||
name: e.newName,
|
||||
);
|
||||
emit(
|
||||
result.fold(
|
||||
(l) {
|
||||
final view = state.view;
|
||||
view.freeze();
|
||||
final newView = view.rebuild(
|
||||
(b) => b.name = e.newName,
|
||||
);
|
||||
return state.copyWith(
|
||||
successOrFailure: left(unit),
|
||||
view: newView,
|
||||
);
|
||||
},
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
delete: (e) async {
|
||||
final result = await ViewBackendService.delete(viewId: view.id);
|
||||
emit(
|
||||
result.fold(
|
||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
RecentService().updateRecentViews([view.id], false);
|
||||
},
|
||||
duplicate: (e) async {
|
||||
final result = await ViewBackendService.duplicate(view: view);
|
||||
emit(
|
||||
result.fold(
|
||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
move: (value) async {
|
||||
final result = await ViewBackendService.moveViewV2(
|
||||
viewId: value.from.id,
|
||||
newParentId: value.newParentId,
|
||||
prevViewId: value.prevId,
|
||||
);
|
||||
emit(
|
||||
result.fold(
|
||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
createView: (e) async {
|
||||
final result = await ViewBackendService.createView(
|
||||
parentViewId: view.id,
|
||||
name: e.name,
|
||||
desc: '',
|
||||
layoutType: e.layoutType,
|
||||
initialDataBytes: null,
|
||||
ext: {},
|
||||
openAfterCreate: e.openAfterCreated,
|
||||
);
|
||||
|
||||
emit(
|
||||
result.fold(
|
||||
(view) => state.copyWith(
|
||||
lastCreatedView: view,
|
||||
successOrFailure: left(unit),
|
||||
),
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
viewUpdateChildView: (e) async {
|
||||
emit(
|
||||
state.copyWith(
|
||||
view: e.result,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final ViewPB view;
|
||||
final ViewBackendService viewBackendSvc;
|
||||
final ViewListener listener;
|
||||
final FavoriteListener favoriteListener;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await listener.stop();
|
||||
@ -186,6 +38,158 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<ViewEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
initial: (e) async {
|
||||
listener.start(
|
||||
onViewUpdated: (result) {
|
||||
add(ViewEvent.viewDidUpdate(left(result)));
|
||||
},
|
||||
onViewChildViewsUpdated: (result) async {
|
||||
final view = await _updateChildViews(result);
|
||||
if (!isClosed && view != null) {
|
||||
add(ViewEvent.viewUpdateChildView(view));
|
||||
}
|
||||
},
|
||||
);
|
||||
favoriteListener.start(
|
||||
favoritesUpdated: (result, isFavorite) {
|
||||
result.fold((error) {}, (result) {
|
||||
final current = result.items
|
||||
.firstWhereOrNull((v) => v.id == state.view.id);
|
||||
if (current != null) {
|
||||
add(ViewEvent.viewDidUpdate(left(current)));
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
final isExpanded = await _getViewIsExpanded(view);
|
||||
emit(state.copyWith(isExpanded: isExpanded));
|
||||
await _loadViewsWhenExpanded(emit, isExpanded);
|
||||
},
|
||||
setIsEditing: (e) {
|
||||
emit(state.copyWith(isEditing: e.isEditing));
|
||||
},
|
||||
setIsExpanded: (e) async {
|
||||
if (e.isExpanded && !state.isExpanded) {
|
||||
await _loadViewsWhenExpanded(emit, true);
|
||||
} else {
|
||||
emit(state.copyWith(isExpanded: e.isExpanded));
|
||||
}
|
||||
await _setViewIsExpanded(view, e.isExpanded);
|
||||
},
|
||||
viewDidUpdate: (e) async {
|
||||
final result = await ViewBackendService.getView(
|
||||
view.id,
|
||||
);
|
||||
final view_ = result.fold((l) => l, (r) => null);
|
||||
e.result.fold(
|
||||
(view) async {
|
||||
// ignore child view changes because it only contains one level
|
||||
// children data.
|
||||
if (_isSameViewIgnoreChildren(view, state.view)) {
|
||||
// do nothing.
|
||||
}
|
||||
emit(
|
||||
state.copyWith(
|
||||
view: view_ ?? view,
|
||||
successOrFailure: left(unit),
|
||||
),
|
||||
);
|
||||
},
|
||||
(error) => emit(
|
||||
state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
rename: (e) async {
|
||||
final result = await ViewBackendService.updateView(
|
||||
viewId: view.id,
|
||||
name: e.newName,
|
||||
);
|
||||
emit(
|
||||
result.fold(
|
||||
(l) {
|
||||
final view = state.view;
|
||||
view.freeze();
|
||||
final newView = view.rebuild(
|
||||
(b) => b.name = e.newName,
|
||||
);
|
||||
return state.copyWith(
|
||||
successOrFailure: left(unit),
|
||||
view: newView,
|
||||
);
|
||||
},
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
delete: (e) async {
|
||||
final result = await ViewBackendService.delete(viewId: view.id);
|
||||
emit(
|
||||
result.fold(
|
||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
RecentService().updateRecentViews([view.id], false);
|
||||
},
|
||||
duplicate: (e) async {
|
||||
final result = await ViewBackendService.duplicate(view: view);
|
||||
emit(
|
||||
result.fold(
|
||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
move: (value) async {
|
||||
final result = await ViewBackendService.moveViewV2(
|
||||
viewId: value.from.id,
|
||||
newParentId: value.newParentId,
|
||||
prevViewId: value.prevId,
|
||||
);
|
||||
emit(
|
||||
result.fold(
|
||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
createView: (e) async {
|
||||
final result = await ViewBackendService.createView(
|
||||
parentViewId: view.id,
|
||||
name: e.name,
|
||||
desc: '',
|
||||
layoutType: e.layoutType,
|
||||
ext: {},
|
||||
openAfterCreate: e.openAfterCreated,
|
||||
);
|
||||
|
||||
emit(
|
||||
result.fold(
|
||||
(view) => state.copyWith(
|
||||
lastCreatedView: view,
|
||||
successOrFailure: left(unit),
|
||||
),
|
||||
(error) => state.copyWith(successOrFailure: right(error)),
|
||||
),
|
||||
);
|
||||
},
|
||||
viewUpdateChildView: (e) async {
|
||||
emit(
|
||||
state.copyWith(
|
||||
view: e.result,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _loadViewsWhenExpanded(
|
||||
Emitter<ViewState> emit,
|
||||
bool isExpanded,
|
||||
@ -355,7 +359,5 @@ class ViewState with _$ViewState {
|
||||
isExpanded: false,
|
||||
isEditing: false,
|
||||
successOrFailure: left(unit),
|
||||
lastCreatedView: null,
|
||||
isLoading: true,
|
||||
);
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ extension ViewExtension on ViewPB {
|
||||
};
|
||||
|
||||
Plugin plugin({
|
||||
bool listenOnViewChanged = false,
|
||||
Map<String, dynamic> arguments = const {},
|
||||
}) {
|
||||
switch (layout) {
|
||||
@ -65,7 +64,6 @@ extension ViewExtension on ViewPB {
|
||||
return DocumentPlugin(
|
||||
view: this,
|
||||
pluginType: pluginType,
|
||||
listenOnViewChanged: listenOnViewChanged,
|
||||
initialSelection: initialSelection,
|
||||
);
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ typedef RestoreViewNotifiedValue = Either<ViewPB, FlowyError>;
|
||||
typedef MoveToTrashNotifiedValue = Either<DeletedViewPB, FlowyError>;
|
||||
|
||||
class ViewListener {
|
||||
ViewListener({required this.viewId});
|
||||
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
void Function(UpdateViewNotifiedValue)? _updatedViewNotifier;
|
||||
void Function(ChildViewUpdatePB)? _updateViewChildViewsNotifier;
|
||||
@ -30,10 +32,6 @@ class ViewListener {
|
||||
FolderNotificationParser? _parser;
|
||||
final String viewId;
|
||||
|
||||
ViewListener({
|
||||
required this.viewId,
|
||||
});
|
||||
|
||||
void start({
|
||||
void Function(UpdateViewNotifiedValue)? onViewUpdated,
|
||||
void Function(ChildViewUpdatePB)? onViewChildViewsUpdated,
|
||||
|
@ -94,7 +94,6 @@ class ViewBackendService {
|
||||
layoutType: layoutType,
|
||||
parentViewId: parentViewId,
|
||||
name: name,
|
||||
openAfterCreate: false,
|
||||
ext: {
|
||||
'database_id': databaseId,
|
||||
},
|
||||
@ -236,7 +235,7 @@ class ViewBackendService {
|
||||
if (childViews != null && childViews.isNotEmpty) {
|
||||
result.addAll(childViews);
|
||||
final views = await Future.wait(
|
||||
childViews.map((e) async => await getAllViews(e)),
|
||||
childViews.map((e) async => getAllViews(e)),
|
||||
);
|
||||
result.addAll(views.expand((element) => element));
|
||||
}
|
||||
|
@ -1,18 +1,21 @@
|
||||
import 'package:appflowy/user/application/user_service.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'workspace_bloc.freezed.dart';
|
||||
|
||||
class WorkspaceBloc extends Bloc<WorkspaceEvent, WorkspaceState> {
|
||||
WorkspaceBloc({required this.userService}) : super(WorkspaceState.initial()) {
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final UserBackendService userService;
|
||||
WorkspaceBloc({
|
||||
required this.userService,
|
||||
}) : super(WorkspaceState.initial()) {
|
||||
|
||||
void _dispatch() {
|
||||
on<WorkspaceEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
|
@ -14,18 +14,16 @@ typedef AppListNotifyValue = Either<List<ViewPB>, FlowyError>;
|
||||
typedef WorkspaceNotifyValue = Either<WorkspacePB, FlowyError>;
|
||||
|
||||
class WorkspaceListener {
|
||||
WorkspaceListener({required this.user, required this.workspaceId});
|
||||
|
||||
final UserProfilePB user;
|
||||
final String workspaceId;
|
||||
|
||||
PublishNotifier<AppListNotifyValue>? _appsChangedNotifier = PublishNotifier();
|
||||
PublishNotifier<WorkspaceNotifyValue>? _workspaceUpdatedNotifier =
|
||||
PublishNotifier();
|
||||
|
||||
FolderNotificationListener? _listener;
|
||||
final UserProfilePB user;
|
||||
final String workspaceId;
|
||||
|
||||
WorkspaceListener({
|
||||
required this.user,
|
||||
required this.workspaceId,
|
||||
});
|
||||
|
||||
void start({
|
||||
void Function(AppListNotifyValue)? appsChanged,
|
||||
|
@ -8,10 +8,9 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
|
||||
|
||||
class WorkspaceService {
|
||||
WorkspaceService({required this.workspaceId});
|
||||
|
||||
final String workspaceId;
|
||||
WorkspaceService({
|
||||
required this.workspaceId,
|
||||
});
|
||||
|
||||
Future<Either<ViewPB, FlowyError>> createApp({
|
||||
required String name,
|
||||
|
Reference in New Issue
Block a user