mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
config menu user bloc
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
|
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_infra/time/duration.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/route/animation.dart';
|
import 'package:flowy_infra_ui/widget/route/animation.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||||
import 'package:app_flowy/user/domain/i_auth.dart';
|
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||||
|
@ -13,7 +13,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
|||||||
Stream<WelcomeState> mapEventToState(WelcomeEvent event) async* {
|
Stream<WelcomeState> mapEventToState(WelcomeEvent event) async* {
|
||||||
yield* event.map(
|
yield* event.map(
|
||||||
getUser: (val) async* {
|
getUser: (val) async* {
|
||||||
final authState = await authImpl.currentUserState();
|
final authState = await authImpl.currentUserDetail();
|
||||||
yield state.copyWith(auth: authState);
|
yield state.copyWith(auth: authState);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'auth_state.dart';
|
import 'auth_state.dart';
|
||||||
|
|
||||||
abstract class IWelcomeAuth {
|
abstract class IWelcomeAuth {
|
||||||
Future<AuthState> currentUserState();
|
Future<AuthState> currentUserDetail();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IWelcomeRoute {
|
abstract class IWelcomeRoute {
|
||||||
|
@ -13,7 +13,7 @@ export 'package:app_flowy/welcome/domain/i_welcome.dart';
|
|||||||
|
|
||||||
class WelcomeAuthImpl implements IWelcomeAuth {
|
class WelcomeAuthImpl implements IWelcomeAuth {
|
||||||
@override
|
@override
|
||||||
Future<AuthState> currentUserState() {
|
Future<AuthState> currentUserDetail() {
|
||||||
final result = UserEventGetStatus().send();
|
final result = UserEventGetStatus().send();
|
||||||
return result.then((result) {
|
return result.then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
|
14
app_flowy/lib/workspace/domain/i_user.dart
Normal file
14
app_flowy/lib/workspace/domain/i_user.dart
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
|
|
||||||
|
export 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||||
|
export 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
export 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
|
|
||||||
|
abstract class IUser {
|
||||||
|
Future<Either<Unit, WorkspaceError>> deleteWorkspace(String workspaceId);
|
||||||
|
Future<Either<UserDetail, UserError>> fetchUserDetail(String userId);
|
||||||
|
Future<Either<Unit, UserError>> signOut();
|
||||||
|
}
|
@ -16,8 +16,10 @@ import 'package:app_flowy/workspace/infrastructure/repos/doc_repo.dart';
|
|||||||
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
|
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
|
||||||
import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
|
import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
|
||||||
import 'package:flowy_editor/flowy_editor.dart';
|
import 'package:flowy_editor/flowy_editor.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
|
|
||||||
|
import 'i_user_impl.dart';
|
||||||
import 'i_view_impl.dart';
|
import 'i_view_impl.dart';
|
||||||
|
|
||||||
class HomeDepsResolver {
|
class HomeDepsResolver {
|
||||||
@ -32,10 +34,10 @@ class HomeDepsResolver {
|
|||||||
(appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId)));
|
(appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId)));
|
||||||
|
|
||||||
//workspace
|
//workspace
|
||||||
getIt.registerFactoryParam<IWorkspace, String, void>((workspaceId, _) =>
|
getIt.registerFactoryParam<IWorkspace, UserDetail, void>(
|
||||||
IWorkspaceImpl(repo: WorkspaceRepo(workspaceId: workspaceId)));
|
(user, _) => IWorkspaceImpl(repo: WorkspaceRepo(user: user)));
|
||||||
getIt.registerFactoryParam<IWorkspaceWatch, String, void>((workspacId, _) =>
|
getIt.registerFactoryParam<IWorkspaceWatch, UserDetail, void>(
|
||||||
IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(workspaceId: workspacId)));
|
(user, _) => IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(user: user)));
|
||||||
|
|
||||||
// View
|
// View
|
||||||
getIt.registerFactoryParam<IView, String, void>(
|
getIt.registerFactoryParam<IView, String, void>(
|
||||||
@ -47,11 +49,15 @@ class HomeDepsResolver {
|
|||||||
getIt.registerFactoryParam<IDoc, String, void>(
|
getIt.registerFactoryParam<IDoc, String, void>(
|
||||||
(docId, _) => IDocImpl(repo: DocRepository(docId: docId)));
|
(docId, _) => IDocImpl(repo: DocRepository(docId: docId)));
|
||||||
|
|
||||||
|
// User
|
||||||
|
getIt.registerFactoryParam<IUser, UserDetail, void>(
|
||||||
|
(user, _) => IUserImpl(repo: UserRepo(user: user)));
|
||||||
|
|
||||||
//Bloc
|
//Bloc
|
||||||
getIt.registerFactoryParam<MenuBloc, String, void>(
|
getIt.registerFactoryParam<MenuBloc, UserDetail, void>(
|
||||||
(workspaceId, _) => MenuBloc(getIt<IWorkspace>(param1: workspaceId)));
|
(user, _) => MenuBloc(getIt<IWorkspace>(param1: user)));
|
||||||
getIt.registerFactoryParam<MenuWatchBloc, String, void>((workspaceId, _) =>
|
getIt.registerFactoryParam<MenuWatchBloc, UserDetail, void>(
|
||||||
MenuWatchBloc(getIt<IWorkspaceWatch>(param1: workspaceId)));
|
(user, _) => MenuWatchBloc(getIt<IWorkspaceWatch>(param1: user)));
|
||||||
|
|
||||||
getIt.registerFactoryParam<AppBloc, String, void>(
|
getIt.registerFactoryParam<AppBloc, String, void>(
|
||||||
(appId, _) => AppBloc(getIt<IApp>(param1: appId)));
|
(appId, _) => AppBloc(getIt<IApp>(param1: appId)));
|
||||||
|
30
app_flowy/lib/workspace/infrastructure/i_user_impl.dart
Normal file
30
app_flowy/lib/workspace/infrastructure/i_user_impl.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
|
import 'package:app_flowy/workspace/domain/i_user.dart';
|
||||||
|
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
|
||||||
|
export 'package:app_flowy/workspace/domain/i_user.dart';
|
||||||
|
export 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
|
||||||
|
|
||||||
|
class IUserImpl extends IUser {
|
||||||
|
UserRepo repo;
|
||||||
|
IUserImpl({
|
||||||
|
required this.repo,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Unit, WorkspaceError>> deleteWorkspace(String workspaceId) {
|
||||||
|
// TODO: implement deleteWorkspace
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<UserDetail, UserError>> fetchUserDetail(String userId) {
|
||||||
|
return repo.fetchUserDetail(userId: userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Unit, UserError>> signOut() {
|
||||||
|
// TODO: implement signOut
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
16
app_flowy/lib/workspace/infrastructure/repos/user_repo.dart
Normal file
16
app_flowy/lib/workspace/infrastructure/repos/user_repo.dart
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
|
||||||
|
class UserRepo {
|
||||||
|
final UserDetail user;
|
||||||
|
UserRepo({
|
||||||
|
required this.user,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<Either<UserDetail, UserError>> fetchUserDetail(
|
||||||
|
{required String userId}) {
|
||||||
|
return UserEventGetStatus().send();
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import 'package:dartz/dartz.dart';
|
|||||||
import 'package:flowy_infra/flowy_logger.dart';
|
import 'package:flowy_infra/flowy_logger.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-observable/subject.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-observable/subject.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/observable.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/observable.pb.dart';
|
||||||
@ -13,9 +14,9 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_query.pb.dart';
|
|||||||
import 'package:flowy_sdk/rust_stream.dart';
|
import 'package:flowy_sdk/rust_stream.dart';
|
||||||
|
|
||||||
class WorkspaceRepo {
|
class WorkspaceRepo {
|
||||||
String workspaceId;
|
UserDetail user;
|
||||||
WorkspaceRepo({
|
WorkspaceRepo({
|
||||||
required this.workspaceId,
|
required this.user,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<Either<App, WorkspaceError>> createApp(String appName, String desc) {
|
Future<Either<App, WorkspaceError>> createApp(String appName, String desc) {
|
||||||
@ -38,7 +39,7 @@ class WorkspaceRepo {
|
|||||||
Future<Either<Workspace, WorkspaceError>> getWorkspace(
|
Future<Either<Workspace, WorkspaceError>> getWorkspace(
|
||||||
{bool readApps = false}) {
|
{bool readApps = false}) {
|
||||||
final request = QueryWorkspaceRequest.create()
|
final request = QueryWorkspaceRequest.create()
|
||||||
..workspaceId = workspaceId
|
..workspaceId = user.workspace
|
||||||
..readApps = readApps;
|
..readApps = readApps;
|
||||||
|
|
||||||
return WorkspaceEventGetWorkspace(request).send().then((result) {
|
return WorkspaceEventGetWorkspace(request).send().then((result) {
|
||||||
@ -54,13 +55,13 @@ class WorkspaceWatchRepo {
|
|||||||
StreamSubscription<ObservableSubject>? _subscription;
|
StreamSubscription<ObservableSubject>? _subscription;
|
||||||
WorkspaceAddAppCallback? _addAppCallback;
|
WorkspaceAddAppCallback? _addAppCallback;
|
||||||
WorkspaceUpdatedCallback? _updatedCallback;
|
WorkspaceUpdatedCallback? _updatedCallback;
|
||||||
final String workspaceId;
|
final UserDetail user;
|
||||||
late WorkspaceRepo _repo;
|
late WorkspaceRepo _repo;
|
||||||
|
|
||||||
WorkspaceWatchRepo({
|
WorkspaceWatchRepo({
|
||||||
required this.workspaceId,
|
required this.user,
|
||||||
}) {
|
}) {
|
||||||
_repo = WorkspaceRepo(workspaceId: workspaceId);
|
_repo = WorkspaceRepo(user: user);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startWatching(
|
void startWatching(
|
||||||
@ -70,7 +71,7 @@ class WorkspaceWatchRepo {
|
|||||||
_updatedCallback = updatedCallback;
|
_updatedCallback = updatedCallback;
|
||||||
|
|
||||||
_subscription = RustStreamReceiver.listen((observable) {
|
_subscription = RustStreamReceiver.listen((observable) {
|
||||||
if (observable.subjectId != workspaceId) {
|
if (observable.subjectId != user.workspace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ import 'package:app_flowy/workspace/application/app/app_bloc.dart';
|
|||||||
import 'package:app_flowy/workspace/application/app/app_watch_bloc.dart';
|
import 'package:app_flowy/workspace/application/app/app_watch_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/app/view_list.dart';
|
import 'package:app_flowy/workspace/presentation/app/view_list.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_list.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_list.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_size.dart';
|
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:expandable/expandable.dart';
|
import 'package:expandable/expandable.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.dart';
|
||||||
@ -15,7 +14,7 @@ import 'package:dartz/dartz.dart';
|
|||||||
|
|
||||||
class AppWidget extends MenuItem {
|
class AppWidget extends MenuItem {
|
||||||
final App app;
|
final App app;
|
||||||
const AppWidget(this.app, {Key? key}) : super(key: key);
|
AppWidget(this.app, {Key? key}) : super(key: ValueKey(app.id));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -103,11 +102,11 @@ class AppHeader extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
ExpandableIcon(
|
ExpandableIcon(
|
||||||
theme: ExpandableThemeData(
|
theme: const ExpandableThemeData(
|
||||||
expandIcon: Icons.arrow_right,
|
expandIcon: Icons.arrow_right,
|
||||||
collapseIcon: Icons.arrow_drop_down,
|
collapseIcon: Icons.arrow_drop_down,
|
||||||
iconColor: Colors.black,
|
iconColor: Colors.black,
|
||||||
iconSize: HomeMenuSize.collapseIconSize,
|
iconSize: 24,
|
||||||
iconPadding: EdgeInsets.zero,
|
iconPadding: EdgeInsets.zero,
|
||||||
hasIcon: false,
|
hasIcon: false,
|
||||||
),
|
),
|
||||||
@ -116,7 +115,7 @@ class AppHeader extends StatelessWidget {
|
|||||||
child: Text(app.name),
|
child: Text(app.name),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: HomeMenuSize.createViewButtonSize,
|
height: 30,
|
||||||
child: createViewPopupMenu(context),
|
child: createViewPopupMenu(context),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -14,8 +14,8 @@ import 'home_layout.dart';
|
|||||||
|
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatelessWidget {
|
||||||
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
|
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
|
||||||
final UserDetail userDetail;
|
final UserDetail user;
|
||||||
const HomeScreen(this.userDetail, {Key? key}) : super(key: key);
|
const HomeScreen(this.user, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -74,7 +74,7 @@ class HomeScreen extends StatelessWidget {
|
|||||||
isCollapseChanged: (isCollapse) {
|
isCollapseChanged: (isCollapse) {
|
||||||
homeBloc.add(HomeEvent.forceCollapse(isCollapse));
|
homeBloc.add(HomeEvent.forceCollapse(isCollapse));
|
||||||
},
|
},
|
||||||
workspaceId: userDetail.workspace,
|
user: user,
|
||||||
);
|
);
|
||||||
homeMenu = RepaintBoundary(child: homeMenu);
|
homeMenu = RepaintBoundary(child: homeMenu);
|
||||||
homeMenu = FocusTraversalGroup(child: homeMenu);
|
homeMenu = FocusTraversalGroup(child: homeMenu);
|
||||||
|
@ -1,32 +1,34 @@
|
|||||||
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_new_app.dart';
|
||||||
import 'package:app_flowy/workspace/application/menu/menu_watch.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_top_bar.dart';
|
||||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/app/app_widget.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/menu/create_app_dialog.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/menu/user_profile.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.dart';
|
||||||
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/menu/menu_watch.dart';
|
||||||
|
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/app/app_widget.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_user.dart';
|
||||||
|
|
||||||
import 'menu_list.dart';
|
import 'menu_list.dart';
|
||||||
|
|
||||||
class HomeMenu extends StatelessWidget {
|
class HomeMenu extends StatelessWidget {
|
||||||
final Function(HomeStackView?) pageContextChanged;
|
final Function(HomeStackView?) pageContextChanged;
|
||||||
final Function(bool) isCollapseChanged;
|
final Function(bool) isCollapseChanged;
|
||||||
final String workspaceId;
|
final UserDetail user;
|
||||||
|
|
||||||
const HomeMenu(
|
const HomeMenu(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
required this.pageContextChanged,
|
required this.pageContextChanged,
|
||||||
required this.isCollapseChanged,
|
required this.isCollapseChanged,
|
||||||
required this.workspaceId})
|
required this.user})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -34,10 +36,10 @@ class HomeMenu extends StatelessWidget {
|
|||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider<MenuBloc>(
|
BlocProvider<MenuBloc>(
|
||||||
create: (context) => getIt<MenuBloc>(param1: workspaceId)
|
create: (context) =>
|
||||||
..add(const MenuEvent.initial())),
|
getIt<MenuBloc>(param1: user)..add(const MenuEvent.initial())),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => getIt<MenuWatchBloc>(param1: workspaceId)
|
create: (context) => getIt<MenuWatchBloc>(param1: user)
|
||||||
..add(const MenuWatchEvent.started())),
|
..add(const MenuWatchEvent.started())),
|
||||||
],
|
],
|
||||||
child: MultiBlocListener(
|
child: MultiBlocListener(
|
||||||
@ -84,12 +86,12 @@ class HomeMenu extends StatelessWidget {
|
|||||||
return BlocBuilder<MenuWatchBloc, MenuWatchState>(
|
return BlocBuilder<MenuWatchBloc, MenuWatchState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return state.map(
|
return state.map(
|
||||||
initial: (_) => BlocBuilder<MenuBloc, MenuState>(
|
initial: (_) => MenuList(
|
||||||
builder: (context, s) => MenuList(
|
menuItems: menuItemsWithApps(context.read<MenuBloc>().state.apps),
|
||||||
menuItems: menuItemsWithApps(s.apps),
|
|
||||||
),
|
),
|
||||||
|
loadApps: (s) => MenuList(
|
||||||
|
menuItems: menuItemsWithApps(some(s.apps)),
|
||||||
),
|
),
|
||||||
loadApps: (s) => MenuList(menuItems: menuItemsWithApps(some(s.apps))),
|
|
||||||
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -111,94 +113,30 @@ class HomeMenu extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<MenuItem> menuItemsWithApps(Option<List<App>> someApps) {
|
List<MenuItem> menuItemsWithApps(Option<List<App>> someApps) {
|
||||||
List<MenuItem> menuItems = [
|
return MenuItemBuilder().withUser(user).withApps(someApps).build();
|
||||||
const UserProfile(),
|
|
||||||
];
|
|
||||||
|
|
||||||
// apps
|
|
||||||
List<MenuItem> appWidgets = someApps.fold(
|
|
||||||
() => [],
|
|
||||||
(apps) => apps.map((app) => AppWidget(app)).toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
menuItems.addAll(appWidgets);
|
|
||||||
return menuItems;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MenuTopBar extends StatelessWidget {
|
class MenuItemBuilder {
|
||||||
const MenuTopBar({Key? key}) : super(key: key);
|
List<MenuItem> items = [];
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
MenuItemBuilder();
|
||||||
return BlocBuilder<MenuBloc, MenuState>(
|
|
||||||
builder: (context, state) {
|
MenuItemBuilder withUser(UserDetail user) {
|
||||||
return Row(
|
items.add(MenuUser(user));
|
||||||
children: [
|
return this;
|
||||||
const Image(
|
}
|
||||||
fit: BoxFit.cover,
|
|
||||||
width: 25,
|
MenuItemBuilder withApps(Option<List<App>> someApps) {
|
||||||
height: 25,
|
List<MenuItem> appWidgets = someApps.foldRight(
|
||||||
image: AssetImage('assets/images/app_flowy_logo.jpg')),
|
[],
|
||||||
const HSpace(8),
|
(apps, _) => apps.map((app) => AppWidget(app)).toList(),
|
||||||
const Text(
|
|
||||||
'AppFlowy',
|
|
||||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.arrow_left),
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
onPressed: () =>
|
|
||||||
context.read<MenuBloc>().add(const MenuEvent.collapse()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
items.addAll(appWidgets);
|
||||||
}
|
return this;
|
||||||
|
}
|
||||||
class NewAppButton extends StatelessWidget {
|
|
||||||
final Function(String)? press;
|
List<MenuItem> build() {
|
||||||
|
return items;
|
||||||
const NewAppButton({this.press, Key? key}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
top: BorderSide(width: 1, color: Colors.grey.shade300),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
height: HomeSizes.menuAddButtonHeight,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const Icon(Icons.add_circle_rounded, size: 30),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () async => await _showCreateAppDialog(context),
|
|
||||||
child: const Text(
|
|
||||||
'New App',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
).padding(horizontal: Insets.l),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _showCreateAppDialog(BuildContext context) async {
|
|
||||||
await Dialogs.showWithContext(CreateAppDialogContext(
|
|
||||||
confirm: (appName) {
|
|
||||||
if (appName.isNotEmpty && press != null) {
|
|
||||||
press!(appName);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
), context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/widgets/menu/create_app_dialog.dart';
|
||||||
|
import 'package:flowy_infra/size.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
|
class NewAppButton extends StatelessWidget {
|
||||||
|
final Function(String)? press;
|
||||||
|
|
||||||
|
const NewAppButton({this.press, Key? key}) : super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
top: BorderSide(width: 1, color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: HomeSizes.menuAddButtonHeight,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.add_circle_rounded, size: 30),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async => await _showCreateAppDialog(context),
|
||||||
|
child: const Text(
|
||||||
|
'New App',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
).padding(horizontal: Insets.l),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _showCreateAppDialog(BuildContext context) async {
|
||||||
|
await Dialogs.showWithContext(CreateAppDialogContext(
|
||||||
|
confirm: (appName) {
|
||||||
|
if (appName.isNotEmpty && press != null) {
|
||||||
|
press!(appName);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
), context);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +0,0 @@
|
|||||||
class HomeMenuSize {
|
|
||||||
static double get createViewButtonSize => 30;
|
|
||||||
static double get collapseIconSize => 24;
|
|
||||||
}
|
|
@ -0,0 +1,37 @@
|
|||||||
|
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
class MenuTopBar extends StatelessWidget {
|
||||||
|
const MenuTopBar({Key? key}) : super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<MenuBloc, MenuState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
const Image(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
width: 25,
|
||||||
|
height: 25,
|
||||||
|
image: AssetImage('assets/images/app_flowy_logo.jpg')),
|
||||||
|
const HSpace(8),
|
||||||
|
const Text(
|
||||||
|
'AppFlowy',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.arrow_left),
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
onPressed: () =>
|
||||||
|
context.read<MenuBloc>().add(const MenuEvent.collapse()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_list.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_list.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class UserProfile extends MenuItem {
|
class MenuUser extends MenuItem {
|
||||||
const UserProfile({Key? key}) : super(key: key);
|
final UserDetail user;
|
||||||
|
MenuUser(this.user, {Key? key}) : super(key: ValueKey(user.id));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -12,11 +14,11 @@ class UserProfile extends MenuItem {
|
|||||||
width: 30,
|
width: 30,
|
||||||
height: 30,
|
height: 30,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(10),
|
||||||
child: const Image(image: AssetImage('assets/images/avatar.jpg')),
|
child: const Image(image: AssetImage('assets/images/avatar.jpg')),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const HSpace(6),
|
const HSpace(10),
|
||||||
const Text("nathan", style: TextStyle(fontSize: 18)),
|
const Text("nathan", style: TextStyle(fontSize: 18)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
@ -1,2 +1 @@
|
|||||||
export 'menu.dart';
|
export 'menu.dart';
|
||||||
export 'menu_size.dart';
|
|
||||||
|
Reference in New Issue
Block a user