[flutter]: add flow diagrams

This commit is contained in:
appflowy 2021-10-11 13:15:41 +08:00
parent 1a10f58e6f
commit 9ddfed5b87
39 changed files with 588 additions and 537 deletions

View File

@ -1,19 +0,0 @@
import 'package:app_flowy/workspace/infrastructure/deps_resolver.dart';
import 'package:app_flowy/startup/launch.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/user/infrastructure/deps_resolver.dart';
import 'package:flowy_sdk/flowy_sdk.dart';
import 'package:get_it/get_it.dart';
void resolveDependencies(IntegrationEnv env) => initGetIt(getIt, env);
Future<void> initGetIt(
GetIt getIt,
IntegrationEnv env,
) async {
getIt.registerLazySingleton<FlowySDK>(() => const FlowySDK());
getIt.registerLazySingleton<AppLauncher>(() => AppLauncher(env, getIt));
await UserDepsResolver.resolve(getIt);
await HomeDepsResolver.resolve(getIt);
}

View File

@ -1,9 +1,28 @@
import 'package:app_flowy/startup/launch.dart';
import 'package:app_flowy/startup/launcher.dart';
import 'package:app_flowy/startup/tasks/prelude.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'deps_inject/prelude.dart';
import 'package:app_flowy/workspace/infrastructure/deps_resolver.dart';
import 'package:app_flowy/user/infrastructure/deps_resolver.dart';
import 'package:flowy_sdk/flowy_sdk.dart';
// [[diagram: flowy startup flow]]
//
// FlowyApp
//
// impl
//
// 1.run
// System EntryPoint
//
// RustSDKInitTask
//
// AppLauncher
// 2.launch
// AppWidgetTaskApplicationWidget SplashScreen
//
//
// 3.build MeterialApp
final getIt = GetIt.instance;
enum IntegrationEnv {
dev,
@ -32,3 +51,16 @@ class System {
getIt<AppLauncher>().launch();
}
}
void resolveDependencies(IntegrationEnv env) => initGetIt(getIt, env);
Future<void> initGetIt(
GetIt getIt,
IntegrationEnv env,
) async {
getIt.registerLazySingleton<FlowySDK>(() => const FlowySDK());
getIt.registerLazySingleton<AppLauncher>(() => AppLauncher(env, getIt));
await UserDepsResolver.resolve(getIt);
await HomeDepsResolver.resolve(getIt);
}

View File

@ -4,7 +4,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:window_size/window_size.dart';
import 'package:app_flowy/startup/launch.dart';
import 'package:app_flowy/startup/launcher.dart';
class AppWidgetTask extends LaunchTask {
@override
@ -30,8 +30,10 @@ class ApplicationWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
const ratio = 1.73;
setWindowMinSize(const Size(500, 500 / ratio));
setWindowFrame(const Rect.fromLTRB(0, 0, 1310, 1310 / ratio));
const minWidth = 500.0;
const launchWidth = 1310.0;
setWindowMinSize(const Size(minWidth, minWidth / ratio));
setWindowFrame(const Rect.fromLTRB(0, 0, launchWidth, launchWidth / ratio));
final theme = AppTheme.fromType(ThemeType.light);
return Provider.value(

View File

@ -1,5 +1,5 @@
import 'dart:io';
import 'package:app_flowy/startup/launch.dart';
import 'package:app_flowy/startup/launcher.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:bloc/bloc.dart';
import 'package:path_provider/path_provider.dart';
@ -20,9 +20,7 @@ class RustSDKInitTask extends LaunchTask {
Directory directory = await getApplicationDocumentsDirectory();
final documentPath = directory.path;
return Directory('$documentPath/flowy')
.create()
.then((Directory directory) async {
return Directory('$documentPath/flowy').create().then((Directory directory) async {
switch (context.env) {
case IntegrationEnv.dev:
// await context.getIt<FlowySDK>().init(Directory('./temp/flowy_dev'));
@ -42,8 +40,7 @@ class ApplicationBlocObserver extends BlocObserver {
@override
// ignore: unnecessary_overrides
void onTransition(Bloc bloc, Transition transition) {
Log.debug(
"[current]: ${transition.currentState} \n[next]: ${transition.nextState}");
Log.debug("[current]: ${transition.currentState} \n[next]: ${transition.nextState}");
super.onTransition(bloc, transition);
}

View File

@ -8,7 +8,7 @@ import 'package:app_flowy/user/infrastructure/i_auth_impl.dart';
import 'package:app_flowy/user/infrastructure/i_splash_impl.dart';
import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart';
import 'package:app_flowy/workspace/application/home/home_bloc.dart';
import 'package:app_flowy/workspace/application/home/home_auth_bloc.dart';
import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
import 'package:app_flowy/workspace/domain/i_user.dart';
import 'package:app_flowy/workspace/infrastructure/i_user_impl.dart';
import 'package:get_it/get_it.dart';
@ -31,9 +31,9 @@ class UserDepsResolver {
getIt.registerFactory<EditPannelBloc>(() => EditPannelBloc());
getIt.registerFactory<SplashBloc>(() => SplashBloc(getIt<ISplashUser>()));
getIt.registerFactoryParam<HomeAuthBloc, UserProfile, void>(
(user, _) => HomeAuthBloc(
getIt<IUserWatch>(param1: user),
getIt.registerFactoryParam<HomeListenBloc, UserProfile, void>(
(user, _) => HomeListenBloc(
getIt<IUserListener>(param1: user),
),
);
}

View File

@ -8,6 +8,16 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart' as workspace;
// [[diagram: splash screen]]
// 1.get user 2.send UserEventCheckUser
// SplashScreen SplashBlocISplashUser
//
//
//
//
// HomeScreen BlocListener RustSDK
//
// 4. Show HomeScreen or SignIn 3.return AuthState
class SplashScreen extends StatelessWidget {
const SplashScreen({Key? key}) : super(key: key);
@ -37,8 +47,7 @@ class SplashScreen extends StatelessWidget {
WorkspaceEventReadCurWorkspace().send().then(
(result) {
return result.fold(
(workspace) => getIt<ISplashRoute>()
.pushHomeScreen(context, userProfile, workspace.id),
(workspace) => getIt<ISplashRoute>().pushHomeScreen(context, userProfile, workspace.id),
(error) async {
assert(error.code == workspace.ErrorCode.RecordNotFound);
getIt<ISplashRoute>().pushWelcomeScreen(context, userProfile);
@ -70,8 +79,7 @@ class Body extends StatelessWidget {
fit: BoxFit.cover,
width: size.width,
height: size.height,
image: const AssetImage(
'assets/images/appflowy_launch_splash.jpg')),
image: const AssetImage('assets/images/appflowy_launch_splash.jpg')),
const CircularProgressIndicator.adaptive(),
],
),

View File

@ -0,0 +1,55 @@
import 'package:app_flowy/workspace/domain/i_app.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dartz/dartz.dart';
part 'app_listen_bloc.freezed.dart';
class AppListenBloc extends Bloc<AppListenEvent, AppListenState> {
final IAppListenr listener;
AppListenBloc(this.listener) : super(const AppListenState.initial());
@override
Stream<AppListenState> mapEventToState(
AppListenEvent event,
) async* {
yield* event.map(started: (_) async* {
listener.start(
addViewCallback: (viewsOrFail) => _handleViewsOrFail(viewsOrFail),
);
}, viewsReceived: (ViewsReceived value) async* {
yield value.viewsOrFail.fold(
(views) => AppListenState.loadViews(views),
(error) => AppListenState.loadFail(error),
);
});
}
void _handleViewsOrFail(Either<List<View>, WorkspaceError> viewsOrFail) {
viewsOrFail.fold(
(views) => add(AppListenEvent.viewsReceived(left(views))),
(error) => add(AppListenEvent.viewsReceived(right(error))),
);
}
}
@freezed
class AppListenEvent with _$AppListenEvent {
const factory AppListenEvent.started() = _Started;
const factory AppListenEvent.viewsReceived(Either<List<View>, WorkspaceError> viewsOrFail) = ViewsReceived;
}
@freezed
class AppListenState with _$AppListenState {
const factory AppListenState.initial() = _Initial;
const factory AppListenState.loadViews(
List<View> views,
) = _LoadViews;
const factory AppListenState.loadFail(
WorkspaceError error,
) = _LoadFail;
}

View File

@ -1,7 +1,7 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
part of 'app_watch_bloc.dart';
part of 'app_listen_bloc.dart';
// **************************************************************************
// FreezedGenerator
@ -13,8 +13,8 @@ final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
class _$AppWatchEventTearOff {
const _$AppWatchEventTearOff();
class _$AppListenEventTearOff {
const _$AppListenEventTearOff();
_Started started() {
return const _Started();
@ -28,10 +28,10 @@ class _$AppWatchEventTearOff {
}
/// @nodoc
const $AppWatchEvent = _$AppWatchEventTearOff();
const $AppListenEvent = _$AppListenEventTearOff();
/// @nodoc
mixin _$AppWatchEvent {
mixin _$AppListenEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
@ -63,20 +63,20 @@ mixin _$AppWatchEvent {
}
/// @nodoc
abstract class $AppWatchEventCopyWith<$Res> {
factory $AppWatchEventCopyWith(
AppWatchEvent value, $Res Function(AppWatchEvent) then) =
_$AppWatchEventCopyWithImpl<$Res>;
abstract class $AppListenEventCopyWith<$Res> {
factory $AppListenEventCopyWith(
AppListenEvent value, $Res Function(AppListenEvent) then) =
_$AppListenEventCopyWithImpl<$Res>;
}
/// @nodoc
class _$AppWatchEventCopyWithImpl<$Res>
implements $AppWatchEventCopyWith<$Res> {
_$AppWatchEventCopyWithImpl(this._value, this._then);
class _$AppListenEventCopyWithImpl<$Res>
implements $AppListenEventCopyWith<$Res> {
_$AppListenEventCopyWithImpl(this._value, this._then);
final AppWatchEvent _value;
final AppListenEvent _value;
// ignore: unused_field
final $Res Function(AppWatchEvent) _then;
final $Res Function(AppListenEvent) _then;
}
/// @nodoc
@ -86,7 +86,7 @@ abstract class _$StartedCopyWith<$Res> {
}
/// @nodoc
class __$StartedCopyWithImpl<$Res> extends _$AppWatchEventCopyWithImpl<$Res>
class __$StartedCopyWithImpl<$Res> extends _$AppListenEventCopyWithImpl<$Res>
implements _$StartedCopyWith<$Res> {
__$StartedCopyWithImpl(_Started _value, $Res Function(_Started) _then)
: super(_value, (v) => _then(v as _Started));
@ -102,7 +102,7 @@ class _$_Started implements _Started {
@override
String toString() {
return 'AppWatchEvent.started()';
return 'AppListenEvent.started()';
}
@override
@ -160,7 +160,7 @@ class _$_Started implements _Started {
}
}
abstract class _Started implements AppWatchEvent {
abstract class _Started implements AppListenEvent {
const factory _Started() = _$_Started;
}
@ -174,7 +174,7 @@ abstract class $ViewsReceivedCopyWith<$Res> {
/// @nodoc
class _$ViewsReceivedCopyWithImpl<$Res>
extends _$AppWatchEventCopyWithImpl<$Res>
extends _$AppListenEventCopyWithImpl<$Res>
implements $ViewsReceivedCopyWith<$Res> {
_$ViewsReceivedCopyWithImpl(
ViewsReceived _value, $Res Function(ViewsReceived) _then)
@ -206,7 +206,7 @@ class _$ViewsReceived implements ViewsReceived {
@override
String toString() {
return 'AppWatchEvent.viewsReceived(viewsOrFail: $viewsOrFail)';
return 'AppListenEvent.viewsReceived(viewsOrFail: $viewsOrFail)';
}
@override
@ -274,7 +274,7 @@ class _$ViewsReceived implements ViewsReceived {
}
}
abstract class ViewsReceived implements AppWatchEvent {
abstract class ViewsReceived implements AppListenEvent {
const factory ViewsReceived(Either<List<View>, WorkspaceError> viewsOrFail) =
_$ViewsReceived;
@ -286,8 +286,8 @@ abstract class ViewsReceived implements AppWatchEvent {
}
/// @nodoc
class _$AppWatchStateTearOff {
const _$AppWatchStateTearOff();
class _$AppListenStateTearOff {
const _$AppListenStateTearOff();
_Initial initial() {
return const _Initial();
@ -307,10 +307,10 @@ class _$AppWatchStateTearOff {
}
/// @nodoc
const $AppWatchState = _$AppWatchStateTearOff();
const $AppListenState = _$AppListenStateTearOff();
/// @nodoc
mixin _$AppWatchState {
mixin _$AppListenState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
@ -344,20 +344,20 @@ mixin _$AppWatchState {
}
/// @nodoc
abstract class $AppWatchStateCopyWith<$Res> {
factory $AppWatchStateCopyWith(
AppWatchState value, $Res Function(AppWatchState) then) =
_$AppWatchStateCopyWithImpl<$Res>;
abstract class $AppListenStateCopyWith<$Res> {
factory $AppListenStateCopyWith(
AppListenState value, $Res Function(AppListenState) then) =
_$AppListenStateCopyWithImpl<$Res>;
}
/// @nodoc
class _$AppWatchStateCopyWithImpl<$Res>
implements $AppWatchStateCopyWith<$Res> {
_$AppWatchStateCopyWithImpl(this._value, this._then);
class _$AppListenStateCopyWithImpl<$Res>
implements $AppListenStateCopyWith<$Res> {
_$AppListenStateCopyWithImpl(this._value, this._then);
final AppWatchState _value;
final AppListenState _value;
// ignore: unused_field
final $Res Function(AppWatchState) _then;
final $Res Function(AppListenState) _then;
}
/// @nodoc
@ -367,7 +367,7 @@ abstract class _$InitialCopyWith<$Res> {
}
/// @nodoc
class __$InitialCopyWithImpl<$Res> extends _$AppWatchStateCopyWithImpl<$Res>
class __$InitialCopyWithImpl<$Res> extends _$AppListenStateCopyWithImpl<$Res>
implements _$InitialCopyWith<$Res> {
__$InitialCopyWithImpl(_Initial _value, $Res Function(_Initial) _then)
: super(_value, (v) => _then(v as _Initial));
@ -383,7 +383,7 @@ class _$_Initial implements _Initial {
@override
String toString() {
return 'AppWatchState.initial()';
return 'AppListenState.initial()';
}
@override
@ -443,7 +443,7 @@ class _$_Initial implements _Initial {
}
}
abstract class _Initial implements AppWatchState {
abstract class _Initial implements AppListenState {
const factory _Initial() = _$_Initial;
}
@ -456,7 +456,7 @@ abstract class _$LoadViewsCopyWith<$Res> {
}
/// @nodoc
class __$LoadViewsCopyWithImpl<$Res> extends _$AppWatchStateCopyWithImpl<$Res>
class __$LoadViewsCopyWithImpl<$Res> extends _$AppListenStateCopyWithImpl<$Res>
implements _$LoadViewsCopyWith<$Res> {
__$LoadViewsCopyWithImpl(_LoadViews _value, $Res Function(_LoadViews) _then)
: super(_value, (v) => _then(v as _LoadViews));
@ -487,7 +487,7 @@ class _$_LoadViews implements _LoadViews {
@override
String toString() {
return 'AppWatchState.loadViews(views: $views)';
return 'AppListenState.loadViews(views: $views)';
}
@override
@ -556,7 +556,7 @@ class _$_LoadViews implements _LoadViews {
}
}
abstract class _LoadViews implements AppWatchState {
abstract class _LoadViews implements AppListenState {
const factory _LoadViews(List<View> views) = _$_LoadViews;
List<View> get views => throw _privateConstructorUsedError;
@ -573,7 +573,7 @@ abstract class _$LoadFailCopyWith<$Res> {
}
/// @nodoc
class __$LoadFailCopyWithImpl<$Res> extends _$AppWatchStateCopyWithImpl<$Res>
class __$LoadFailCopyWithImpl<$Res> extends _$AppListenStateCopyWithImpl<$Res>
implements _$LoadFailCopyWith<$Res> {
__$LoadFailCopyWithImpl(_LoadFail _value, $Res Function(_LoadFail) _then)
: super(_value, (v) => _then(v as _LoadFail));
@ -604,7 +604,7 @@ class _$_LoadFail implements _LoadFail {
@override
String toString() {
return 'AppWatchState.loadFail(error: $error)';
return 'AppListenState.loadFail(error: $error)';
}
@override
@ -673,7 +673,7 @@ class _$_LoadFail implements _LoadFail {
}
}
abstract class _LoadFail implements AppWatchState {
abstract class _LoadFail implements AppListenState {
const factory _LoadFail(WorkspaceError error) = _$_LoadFail;
WorkspaceError get error => throw _privateConstructorUsedError;

View File

@ -1,56 +0,0 @@
import 'package:app_flowy/workspace/domain/i_app.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dartz/dartz.dart';
part 'app_watch_bloc.freezed.dart';
class AppWatchBloc extends Bloc<AppWatchEvent, AppWatchState> {
final IAppWatch watcher;
AppWatchBloc(this.watcher) : super(const AppWatchState.initial());
@override
Stream<AppWatchState> mapEventToState(
AppWatchEvent event,
) async* {
yield* event.map(started: (_) async* {
watcher.startWatching(
addViewCallback: (viewsOrFail) => _handleViewsOrFail(viewsOrFail),
);
}, viewsReceived: (ViewsReceived value) async* {
yield value.viewsOrFail.fold(
(views) => AppWatchState.loadViews(views),
(error) => AppWatchState.loadFail(error),
);
});
}
void _handleViewsOrFail(Either<List<View>, WorkspaceError> viewsOrFail) {
viewsOrFail.fold(
(views) => add(AppWatchEvent.viewsReceived(left(views))),
(error) => add(AppWatchEvent.viewsReceived(right(error))),
);
}
}
@freezed
class AppWatchEvent with _$AppWatchEvent {
const factory AppWatchEvent.started() = _Started;
const factory AppWatchEvent.viewsReceived(
Either<List<View>, WorkspaceError> viewsOrFail) = ViewsReceived;
}
@freezed
class AppWatchState with _$AppWatchState {
const factory AppWatchState.initial() = _Initial;
const factory AppWatchState.loadViews(
List<View> views,
) = _LoadViews;
const factory AppWatchState.loadFail(
WorkspaceError error,
) = _LoadFail;
}

View File

@ -1,53 +0,0 @@
import 'package:app_flowy/workspace/domain/i_user.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dartz/dartz.dart';
part 'home_auth_bloc.freezed.dart';
class HomeAuthBloc extends Bloc<HomeAuthEvent, HomeAuthState> {
final IUserWatch watch;
HomeAuthBloc(this.watch) : super(const HomeAuthState.loading());
@override
Stream<HomeAuthState> mapEventToState(
HomeAuthEvent event,
) async* {
yield* event.map(
started: (_) async* {
watch.setAuthCallback(_authStateChanged);
watch.startWatching();
},
stop: (_) async* {},
unauthorized: (e) async* {
yield HomeAuthState.unauthorized(e.msg);
},
);
}
@override
Future<void> close() async {
await watch.stopWatching();
super.close();
}
void _authStateChanged(Either<Unit, UserError> errorOrNothing) {
errorOrNothing.fold((_) {}, (error) {
if (error.code == ErrorCode.UserUnauthorized) {
add(HomeAuthEvent.unauthorized(error.msg));
}
});
}
}
@freezed
class HomeAuthEvent with _$HomeAuthEvent {
const factory HomeAuthEvent.started() = _Started;
const factory HomeAuthEvent.stop() = _Stop;
const factory HomeAuthEvent.unauthorized(String msg) = _Unauthorized;
}
@freezed
class HomeAuthState with _$HomeAuthState {
const factory HomeAuthState.loading() = Loading;
const factory HomeAuthState.unauthorized(String msg) = Unauthorized;
}

View File

@ -0,0 +1,53 @@
import 'package:app_flowy/workspace/domain/i_user.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dartz/dartz.dart';
part 'home_listen_bloc.freezed.dart';
class HomeListenBloc extends Bloc<HomeListenEvent, HomeListenState> {
final IUserListener listener;
HomeListenBloc(this.listener) : super(const HomeListenState.loading());
@override
Stream<HomeListenState> mapEventToState(
HomeListenEvent event,
) async* {
yield* event.map(
started: (_) async* {
listener.setAuthCallback(_authStateChanged);
listener.start();
},
stop: (_) async* {},
unauthorized: (e) async* {
yield HomeListenState.unauthorized(e.msg);
},
);
}
@override
Future<void> close() async {
await listener.stop();
super.close();
}
void _authStateChanged(Either<Unit, UserError> errorOrNothing) {
errorOrNothing.fold((_) {}, (error) {
if (error.code == ErrorCode.UserUnauthorized) {
add(HomeListenEvent.unauthorized(error.msg));
}
});
}
}
@freezed
class HomeListenEvent with _$HomeListenEvent {
const factory HomeListenEvent.started() = _Started;
const factory HomeListenEvent.stop() = _Stop;
const factory HomeListenEvent.unauthorized(String msg) = _Unauthorized;
}
@freezed
class HomeListenState with _$HomeListenState {
const factory HomeListenState.loading() = Loading;
const factory HomeListenState.unauthorized(String msg) = Unauthorized;
}

View File

@ -1,7 +1,7 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
part of 'home_auth_bloc.dart';
part of 'home_listen_bloc.dart';
// **************************************************************************
// FreezedGenerator
@ -13,8 +13,8 @@ final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
class _$HomeAuthEventTearOff {
const _$HomeAuthEventTearOff();
class _$HomeListenEventTearOff {
const _$HomeListenEventTearOff();
_Started started() {
return const _Started();
@ -32,10 +32,10 @@ class _$HomeAuthEventTearOff {
}
/// @nodoc
const $HomeAuthEvent = _$HomeAuthEventTearOff();
const $HomeListenEvent = _$HomeListenEventTearOff();
/// @nodoc
mixin _$HomeAuthEvent {
mixin _$HomeListenEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
@ -69,20 +69,20 @@ mixin _$HomeAuthEvent {
}
/// @nodoc
abstract class $HomeAuthEventCopyWith<$Res> {
factory $HomeAuthEventCopyWith(
HomeAuthEvent value, $Res Function(HomeAuthEvent) then) =
_$HomeAuthEventCopyWithImpl<$Res>;
abstract class $HomeListenEventCopyWith<$Res> {
factory $HomeListenEventCopyWith(
HomeListenEvent value, $Res Function(HomeListenEvent) then) =
_$HomeListenEventCopyWithImpl<$Res>;
}
/// @nodoc
class _$HomeAuthEventCopyWithImpl<$Res>
implements $HomeAuthEventCopyWith<$Res> {
_$HomeAuthEventCopyWithImpl(this._value, this._then);
class _$HomeListenEventCopyWithImpl<$Res>
implements $HomeListenEventCopyWith<$Res> {
_$HomeListenEventCopyWithImpl(this._value, this._then);
final HomeAuthEvent _value;
final HomeListenEvent _value;
// ignore: unused_field
final $Res Function(HomeAuthEvent) _then;
final $Res Function(HomeListenEvent) _then;
}
/// @nodoc
@ -92,7 +92,7 @@ abstract class _$StartedCopyWith<$Res> {
}
/// @nodoc
class __$StartedCopyWithImpl<$Res> extends _$HomeAuthEventCopyWithImpl<$Res>
class __$StartedCopyWithImpl<$Res> extends _$HomeListenEventCopyWithImpl<$Res>
implements _$StartedCopyWith<$Res> {
__$StartedCopyWithImpl(_Started _value, $Res Function(_Started) _then)
: super(_value, (v) => _then(v as _Started));
@ -108,7 +108,7 @@ class _$_Started implements _Started {
@override
String toString() {
return 'HomeAuthEvent.started()';
return 'HomeListenEvent.started()';
}
@override
@ -168,7 +168,7 @@ class _$_Started implements _Started {
}
}
abstract class _Started implements HomeAuthEvent {
abstract class _Started implements HomeListenEvent {
const factory _Started() = _$_Started;
}
@ -179,7 +179,7 @@ abstract class _$StopCopyWith<$Res> {
}
/// @nodoc
class __$StopCopyWithImpl<$Res> extends _$HomeAuthEventCopyWithImpl<$Res>
class __$StopCopyWithImpl<$Res> extends _$HomeListenEventCopyWithImpl<$Res>
implements _$StopCopyWith<$Res> {
__$StopCopyWithImpl(_Stop _value, $Res Function(_Stop) _then)
: super(_value, (v) => _then(v as _Stop));
@ -195,7 +195,7 @@ class _$_Stop implements _Stop {
@override
String toString() {
return 'HomeAuthEvent.stop()';
return 'HomeListenEvent.stop()';
}
@override
@ -255,7 +255,7 @@ class _$_Stop implements _Stop {
}
}
abstract class _Stop implements HomeAuthEvent {
abstract class _Stop implements HomeListenEvent {
const factory _Stop() = _$_Stop;
}
@ -269,7 +269,7 @@ abstract class _$UnauthorizedCopyWith<$Res> {
/// @nodoc
class __$UnauthorizedCopyWithImpl<$Res>
extends _$HomeAuthEventCopyWithImpl<$Res>
extends _$HomeListenEventCopyWithImpl<$Res>
implements _$UnauthorizedCopyWith<$Res> {
__$UnauthorizedCopyWithImpl(
_Unauthorized _value, $Res Function(_Unauthorized) _then)
@ -301,7 +301,7 @@ class _$_Unauthorized implements _Unauthorized {
@override
String toString() {
return 'HomeAuthEvent.unauthorized(msg: $msg)';
return 'HomeListenEvent.unauthorized(msg: $msg)';
}
@override
@ -370,7 +370,7 @@ class _$_Unauthorized implements _Unauthorized {
}
}
abstract class _Unauthorized implements HomeAuthEvent {
abstract class _Unauthorized implements HomeListenEvent {
const factory _Unauthorized(String msg) = _$_Unauthorized;
String get msg => throw _privateConstructorUsedError;
@ -380,8 +380,8 @@ abstract class _Unauthorized implements HomeAuthEvent {
}
/// @nodoc
class _$HomeAuthStateTearOff {
const _$HomeAuthStateTearOff();
class _$HomeListenStateTearOff {
const _$HomeListenStateTearOff();
Loading loading() {
return const Loading();
@ -395,10 +395,10 @@ class _$HomeAuthStateTearOff {
}
/// @nodoc
const $HomeAuthState = _$HomeAuthStateTearOff();
const $HomeListenState = _$HomeListenStateTearOff();
/// @nodoc
mixin _$HomeAuthState {
mixin _$HomeListenState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() loading,
@ -428,20 +428,20 @@ mixin _$HomeAuthState {
}
/// @nodoc
abstract class $HomeAuthStateCopyWith<$Res> {
factory $HomeAuthStateCopyWith(
HomeAuthState value, $Res Function(HomeAuthState) then) =
_$HomeAuthStateCopyWithImpl<$Res>;
abstract class $HomeListenStateCopyWith<$Res> {
factory $HomeListenStateCopyWith(
HomeListenState value, $Res Function(HomeListenState) then) =
_$HomeListenStateCopyWithImpl<$Res>;
}
/// @nodoc
class _$HomeAuthStateCopyWithImpl<$Res>
implements $HomeAuthStateCopyWith<$Res> {
_$HomeAuthStateCopyWithImpl(this._value, this._then);
class _$HomeListenStateCopyWithImpl<$Res>
implements $HomeListenStateCopyWith<$Res> {
_$HomeListenStateCopyWithImpl(this._value, this._then);
final HomeAuthState _value;
final HomeListenState _value;
// ignore: unused_field
final $Res Function(HomeAuthState) _then;
final $Res Function(HomeListenState) _then;
}
/// @nodoc
@ -451,7 +451,7 @@ abstract class $LoadingCopyWith<$Res> {
}
/// @nodoc
class _$LoadingCopyWithImpl<$Res> extends _$HomeAuthStateCopyWithImpl<$Res>
class _$LoadingCopyWithImpl<$Res> extends _$HomeListenStateCopyWithImpl<$Res>
implements $LoadingCopyWith<$Res> {
_$LoadingCopyWithImpl(Loading _value, $Res Function(Loading) _then)
: super(_value, (v) => _then(v as Loading));
@ -467,7 +467,7 @@ class _$Loading implements Loading {
@override
String toString() {
return 'HomeAuthState.loading()';
return 'HomeListenState.loading()';
}
@override
@ -523,7 +523,7 @@ class _$Loading implements Loading {
}
}
abstract class Loading implements HomeAuthState {
abstract class Loading implements HomeListenState {
const factory Loading() = _$Loading;
}
@ -536,7 +536,8 @@ abstract class $UnauthorizedCopyWith<$Res> {
}
/// @nodoc
class _$UnauthorizedCopyWithImpl<$Res> extends _$HomeAuthStateCopyWithImpl<$Res>
class _$UnauthorizedCopyWithImpl<$Res>
extends _$HomeListenStateCopyWithImpl<$Res>
implements $UnauthorizedCopyWith<$Res> {
_$UnauthorizedCopyWithImpl(
Unauthorized _value, $Res Function(Unauthorized) _then)
@ -568,7 +569,7 @@ class _$Unauthorized implements Unauthorized {
@override
String toString() {
return 'HomeAuthState.unauthorized(msg: $msg)';
return 'HomeListenState.unauthorized(msg: $msg)';
}
@override
@ -633,7 +634,7 @@ class _$Unauthorized implements Unauthorized {
}
}
abstract class Unauthorized implements HomeAuthState {
abstract class Unauthorized implements HomeListenState {
const factory Unauthorized(String msg) = _$Unauthorized;
String get msg => throw _privateConstructorUsedError;

View File

@ -86,6 +86,6 @@ class MenuState with _$MenuState {
isCollapse: false,
apps: none(),
successOrFailure: left(unit),
context: DefaultHomeStackContext(),
context: BlankStackContext(),
);
}

View File

@ -7,14 +7,14 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dartz/dartz.dart';
part 'menu_watch.freezed.dart';
part 'menu_listen.freezed.dart';
class MenuWatchBloc extends Bloc<MenuWatchEvent, MenuWatchState> {
class MenuListenBloc extends Bloc<MenuListenEvent, MenuListenState> {
final IWorkspaceWatch watch;
MenuWatchBloc(this.watch) : super(const MenuWatchState.initial());
MenuListenBloc(this.watch) : super(const MenuListenState.initial());
@override
Stream<MenuWatchState> mapEventToState(MenuWatchEvent event) async* {
Stream<MenuListenState> mapEventToState(MenuListenEvent event) async* {
yield* event.map(
started: (_) async* {
watch.startWatching(
@ -23,8 +23,8 @@ class MenuWatchBloc extends Bloc<MenuWatchEvent, MenuWatchState> {
},
appsReceived: (e) async* {
yield e.appsOrFail.fold(
(apps) => MenuWatchState.loadApps(apps),
(error) => MenuWatchState.loadFail(error),
(apps) => MenuListenState.loadApps(apps),
(error) => MenuListenState.loadFail(error),
);
},
);
@ -38,31 +38,30 @@ class MenuWatchBloc extends Bloc<MenuWatchEvent, MenuWatchState> {
void _handleAppsOrFail(Either<List<App>, WorkspaceError> appsOrFail) {
appsOrFail.fold(
(apps) => add(MenuWatchEvent.appsReceived(left(apps))),
(apps) => add(MenuListenEvent.appsReceived(left(apps))),
(error) {
Log.error(error);
add(MenuWatchEvent.appsReceived(right(error)));
add(MenuListenEvent.appsReceived(right(error)));
},
);
}
}
@freezed
class MenuWatchEvent with _$MenuWatchEvent {
const factory MenuWatchEvent.started() = _Started;
const factory MenuWatchEvent.appsReceived(
Either<List<App>, WorkspaceError> appsOrFail) = AppsReceived;
class MenuListenEvent with _$MenuListenEvent {
const factory MenuListenEvent.started() = _Started;
const factory MenuListenEvent.appsReceived(Either<List<App>, WorkspaceError> appsOrFail) = AppsReceived;
}
@freezed
class MenuWatchState with _$MenuWatchState {
const factory MenuWatchState.initial() = _Initial;
class MenuListenState with _$MenuListenState {
const factory MenuListenState.initial() = _Initial;
const factory MenuWatchState.loadApps(
const factory MenuListenState.loadApps(
List<App> apps,
) = _LoadApps;
const factory MenuWatchState.loadFail(
const factory MenuListenState.loadFail(
WorkspaceError error,
) = _LoadFail;
}

View File

@ -1,7 +1,7 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
part of 'menu_watch.dart';
part of 'menu_listen.dart';
// **************************************************************************
// FreezedGenerator
@ -13,8 +13,8 @@ final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
class _$MenuWatchEventTearOff {
const _$MenuWatchEventTearOff();
class _$MenuListenEventTearOff {
const _$MenuListenEventTearOff();
_Started started() {
return const _Started();
@ -28,10 +28,10 @@ class _$MenuWatchEventTearOff {
}
/// @nodoc
const $MenuWatchEvent = _$MenuWatchEventTearOff();
const $MenuListenEvent = _$MenuListenEventTearOff();
/// @nodoc
mixin _$MenuWatchEvent {
mixin _$MenuListenEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
@ -63,20 +63,20 @@ mixin _$MenuWatchEvent {
}
/// @nodoc
abstract class $MenuWatchEventCopyWith<$Res> {
factory $MenuWatchEventCopyWith(
MenuWatchEvent value, $Res Function(MenuWatchEvent) then) =
_$MenuWatchEventCopyWithImpl<$Res>;
abstract class $MenuListenEventCopyWith<$Res> {
factory $MenuListenEventCopyWith(
MenuListenEvent value, $Res Function(MenuListenEvent) then) =
_$MenuListenEventCopyWithImpl<$Res>;
}
/// @nodoc
class _$MenuWatchEventCopyWithImpl<$Res>
implements $MenuWatchEventCopyWith<$Res> {
_$MenuWatchEventCopyWithImpl(this._value, this._then);
class _$MenuListenEventCopyWithImpl<$Res>
implements $MenuListenEventCopyWith<$Res> {
_$MenuListenEventCopyWithImpl(this._value, this._then);
final MenuWatchEvent _value;
final MenuListenEvent _value;
// ignore: unused_field
final $Res Function(MenuWatchEvent) _then;
final $Res Function(MenuListenEvent) _then;
}
/// @nodoc
@ -86,7 +86,7 @@ abstract class _$StartedCopyWith<$Res> {
}
/// @nodoc
class __$StartedCopyWithImpl<$Res> extends _$MenuWatchEventCopyWithImpl<$Res>
class __$StartedCopyWithImpl<$Res> extends _$MenuListenEventCopyWithImpl<$Res>
implements _$StartedCopyWith<$Res> {
__$StartedCopyWithImpl(_Started _value, $Res Function(_Started) _then)
: super(_value, (v) => _then(v as _Started));
@ -102,7 +102,7 @@ class _$_Started implements _Started {
@override
String toString() {
return 'MenuWatchEvent.started()';
return 'MenuListenEvent.started()';
}
@override
@ -160,7 +160,7 @@ class _$_Started implements _Started {
}
}
abstract class _Started implements MenuWatchEvent {
abstract class _Started implements MenuListenEvent {
const factory _Started() = _$_Started;
}
@ -174,7 +174,7 @@ abstract class $AppsReceivedCopyWith<$Res> {
/// @nodoc
class _$AppsReceivedCopyWithImpl<$Res>
extends _$MenuWatchEventCopyWithImpl<$Res>
extends _$MenuListenEventCopyWithImpl<$Res>
implements $AppsReceivedCopyWith<$Res> {
_$AppsReceivedCopyWithImpl(
AppsReceived _value, $Res Function(AppsReceived) _then)
@ -206,7 +206,7 @@ class _$AppsReceived implements AppsReceived {
@override
String toString() {
return 'MenuWatchEvent.appsReceived(appsOrFail: $appsOrFail)';
return 'MenuListenEvent.appsReceived(appsOrFail: $appsOrFail)';
}
@override
@ -274,7 +274,7 @@ class _$AppsReceived implements AppsReceived {
}
}
abstract class AppsReceived implements MenuWatchEvent {
abstract class AppsReceived implements MenuListenEvent {
const factory AppsReceived(Either<List<App>, WorkspaceError> appsOrFail) =
_$AppsReceived;
@ -286,8 +286,8 @@ abstract class AppsReceived implements MenuWatchEvent {
}
/// @nodoc
class _$MenuWatchStateTearOff {
const _$MenuWatchStateTearOff();
class _$MenuListenStateTearOff {
const _$MenuListenStateTearOff();
_Initial initial() {
return const _Initial();
@ -307,10 +307,10 @@ class _$MenuWatchStateTearOff {
}
/// @nodoc
const $MenuWatchState = _$MenuWatchStateTearOff();
const $MenuListenState = _$MenuListenStateTearOff();
/// @nodoc
mixin _$MenuWatchState {
mixin _$MenuListenState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
@ -344,20 +344,20 @@ mixin _$MenuWatchState {
}
/// @nodoc
abstract class $MenuWatchStateCopyWith<$Res> {
factory $MenuWatchStateCopyWith(
MenuWatchState value, $Res Function(MenuWatchState) then) =
_$MenuWatchStateCopyWithImpl<$Res>;
abstract class $MenuListenStateCopyWith<$Res> {
factory $MenuListenStateCopyWith(
MenuListenState value, $Res Function(MenuListenState) then) =
_$MenuListenStateCopyWithImpl<$Res>;
}
/// @nodoc
class _$MenuWatchStateCopyWithImpl<$Res>
implements $MenuWatchStateCopyWith<$Res> {
_$MenuWatchStateCopyWithImpl(this._value, this._then);
class _$MenuListenStateCopyWithImpl<$Res>
implements $MenuListenStateCopyWith<$Res> {
_$MenuListenStateCopyWithImpl(this._value, this._then);
final MenuWatchState _value;
final MenuListenState _value;
// ignore: unused_field
final $Res Function(MenuWatchState) _then;
final $Res Function(MenuListenState) _then;
}
/// @nodoc
@ -367,7 +367,7 @@ abstract class _$InitialCopyWith<$Res> {
}
/// @nodoc
class __$InitialCopyWithImpl<$Res> extends _$MenuWatchStateCopyWithImpl<$Res>
class __$InitialCopyWithImpl<$Res> extends _$MenuListenStateCopyWithImpl<$Res>
implements _$InitialCopyWith<$Res> {
__$InitialCopyWithImpl(_Initial _value, $Res Function(_Initial) _then)
: super(_value, (v) => _then(v as _Initial));
@ -383,7 +383,7 @@ class _$_Initial implements _Initial {
@override
String toString() {
return 'MenuWatchState.initial()';
return 'MenuListenState.initial()';
}
@override
@ -443,7 +443,7 @@ class _$_Initial implements _Initial {
}
}
abstract class _Initial implements MenuWatchState {
abstract class _Initial implements MenuListenState {
const factory _Initial() = _$_Initial;
}
@ -455,7 +455,7 @@ abstract class _$LoadAppsCopyWith<$Res> {
}
/// @nodoc
class __$LoadAppsCopyWithImpl<$Res> extends _$MenuWatchStateCopyWithImpl<$Res>
class __$LoadAppsCopyWithImpl<$Res> extends _$MenuListenStateCopyWithImpl<$Res>
implements _$LoadAppsCopyWith<$Res> {
__$LoadAppsCopyWithImpl(_LoadApps _value, $Res Function(_LoadApps) _then)
: super(_value, (v) => _then(v as _LoadApps));
@ -486,7 +486,7 @@ class _$_LoadApps implements _LoadApps {
@override
String toString() {
return 'MenuWatchState.loadApps(apps: $apps)';
return 'MenuListenState.loadApps(apps: $apps)';
}
@override
@ -555,7 +555,7 @@ class _$_LoadApps implements _LoadApps {
}
}
abstract class _LoadApps implements MenuWatchState {
abstract class _LoadApps implements MenuListenState {
const factory _LoadApps(List<App> apps) = _$_LoadApps;
List<App> get apps => throw _privateConstructorUsedError;
@ -572,7 +572,7 @@ abstract class _$LoadFailCopyWith<$Res> {
}
/// @nodoc
class __$LoadFailCopyWithImpl<$Res> extends _$MenuWatchStateCopyWithImpl<$Res>
class __$LoadFailCopyWithImpl<$Res> extends _$MenuListenStateCopyWithImpl<$Res>
implements _$LoadFailCopyWith<$Res> {
__$LoadFailCopyWithImpl(_LoadFail _value, $Res Function(_LoadFail) _then)
: super(_value, (v) => _then(v as _LoadFail));
@ -603,7 +603,7 @@ class _$_LoadFail implements _LoadFail {
@override
String toString() {
return 'MenuWatchState.loadFail(error: $error)';
return 'MenuListenState.loadFail(error: $error)';
}
@override
@ -672,7 +672,7 @@ class _$_LoadFail implements _LoadFail {
}
}
abstract class _LoadFail implements MenuWatchState {
abstract class _LoadFail implements MenuListenState {
const factory _LoadFail(WorkspaceError error) = _$_LoadFail;
WorkspaceError get error => throw _privateConstructorUsedError;

View File

@ -11,18 +11,17 @@ part 'menu_user_bloc.freezed.dart';
class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
final IUser iUserImpl;
final IUserWatch watch;
final IUserListener listener;
MenuUserBloc(this.iUserImpl, this.watch)
: super(MenuUserState.initial(iUserImpl.user));
MenuUserBloc(this.iUserImpl, this.listener) : super(MenuUserState.initial(iUserImpl.user));
@override
Stream<MenuUserState> mapEventToState(MenuUserEvent event) async* {
yield* event.map(
initial: (_) async* {
watch.setProfileCallback(_profileUpdated);
watch.setWorkspacesCallback(_workspacesUpdated);
watch.startWatching();
listener.setProfileCallback(_profileUpdated);
listener.setWorkspacesCallback(_workspacesUpdated);
listener.start();
await _initUser();
},
@ -32,7 +31,7 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
@override
Future<void> close() async {
await watch.stopWatching();
await listener.stop();
super.close();
}
@ -42,8 +41,7 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
}
void _profileUpdated(Either<UserProfile, UserError> userOrFailed) {}
void _workspacesUpdated(
Either<List<Workspace>, WorkspaceError> workspacesOrFailed) {
void _workspacesUpdated(Either<List<Workspace>, WorkspaceError> workspacesOrFailed) {
// fetch workspaces
// iUserImpl.fetchWorkspaces().then((result) {
// result.fold(

View File

@ -11,9 +11,8 @@ part 'welcome_bloc.freezed.dart';
class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
final UserRepo repo;
final IUserWatch watch;
WelcomeBloc({required this.repo, required this.watch})
: super(WelcomeState.initial());
final IUserListener watch;
WelcomeBloc({required this.repo, required this.watch}) : super(WelcomeState.initial());
@override
Stream<WelcomeState> mapEventToState(
@ -21,7 +20,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
) async* {
yield* event.map(initial: (e) async* {
watch.setWorkspacesCallback(_workspacesUpdated);
watch.startWatching();
watch.start();
//
yield* _fetchWorkspaces();
}, openWorkspace: (e) async* {
@ -30,8 +29,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
yield* _createWorkspace(e.name, e.desc);
}, workspacesReveived: (e) async* {
yield e.workspacesOrFail.fold(
(workspaces) => state.copyWith(
workspaces: workspaces, successOrFailure: left(unit)),
(workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
(error) => state.copyWith(successOrFailure: right(error)),
);
});
@ -39,15 +37,14 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
@override
Future<void> close() async {
await watch.stopWatching();
await watch.stop();
super.close();
}
Stream<WelcomeState> _fetchWorkspaces() async* {
final workspacesOrFailed = await repo.getWorkspaces();
yield workspacesOrFailed.fold(
(workspaces) =>
state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
(workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
(error) {
Log.error(error);
return state.copyWith(successOrFailure: right(error));
@ -80,8 +77,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
);
}
void _workspacesUpdated(
Either<List<Workspace>, WorkspaceError> workspacesOrFail) {
void _workspacesUpdated(Either<List<Workspace>, WorkspaceError> workspacesOrFail) {
add(WelcomeEvent.workspacesReveived(workspacesOrFail));
}
}
@ -90,12 +86,10 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
class WelcomeEvent with _$WelcomeEvent {
const factory WelcomeEvent.initial() = Initial;
// const factory WelcomeEvent.fetchWorkspaces() = FetchWorkspace;
const factory WelcomeEvent.createWorkspace(String name, String desc) =
CreateWorkspace;
const factory WelcomeEvent.createWorkspace(String name, String desc) = CreateWorkspace;
const factory WelcomeEvent.openWorkspace(Workspace workspace) = OpenWorkspace;
const factory WelcomeEvent.workspacesReveived(
Either<List<Workspace>, WorkspaceError> workspacesOrFail) =
const factory WelcomeEvent.workspacesReveived(Either<List<Workspace>, WorkspaceError> workspacesOrFail) =
WorkspacesReceived;
}

View File

@ -2,23 +2,18 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/protobuf.dart';
import 'package:dartz/dartz.dart';
typedef AppUpdatedCallback = void Function(String name, String desc);
typedef AppCreateViewCallback = void Function(
Either<List<View>, WorkspaceError> viewsOrFailed);
typedef AppCreateViewCallback = void Function(Either<List<View>, WorkspaceError> viewsOrFailed);
typedef AppDeleteViewCallback = void Function(
Either<List<View>, WorkspaceError> viewsOrFailed);
typedef AppDeleteViewCallback = void Function(Either<List<View>, WorkspaceError> viewsOrFailed);
abstract class IApp {
Future<Either<List<View>, WorkspaceError>> getViews();
Future<Either<View, WorkspaceError>> createView(
{required String name, String? desc, required ViewType viewType});
Future<Either<View, WorkspaceError>> createView({required String name, String? desc, required ViewType viewType});
}
abstract class IAppWatch {
void startWatching(
{AppCreateViewCallback? addViewCallback,
AppUpdatedCallback? updatedCallback});
abstract class IAppListenr {
void start({AppCreateViewCallback? addViewCallback, AppUpdatedCallback? updatedCallback});
Future<void> stopWatching();
Future<void> stop();
}

View File

@ -17,18 +17,16 @@ abstract class IUser {
Future<Either<Unit, UserError>> initUser();
}
typedef UserProfileUpdateCallback = void Function(
Either<UserProfile, UserError>);
typedef UserProfileUpdateCallback = void Function(Either<UserProfile, UserError>);
typedef AuthChangedCallback = void Function(Either<Unit, UserError>);
typedef WorkspacesUpdatedCallback = void Function(
Either<List<Workspace>, WorkspaceError> workspacesOrFailed);
typedef WorkspacesUpdatedCallback = void Function(Either<List<Workspace>, WorkspaceError> workspacesOrFailed);
abstract class IUserWatch {
void startWatching();
abstract class IUserListener {
void start();
void setProfileCallback(UserProfileUpdateCallback profileCallback);
void setAuthCallback(AuthChangedCallback authCallback);
void setWorkspacesCallback(WorkspacesUpdatedCallback workspacesCallback);
Future<void> stopWatching();
Future<void> stop();
}

View File

@ -6,7 +6,7 @@ import 'package:provider/provider.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
import 'package:app_flowy/workspace/presentation/stack_page/fading_index_stack.dart';
import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
typedef NavigationCallback = void Function(String id);
@ -16,7 +16,7 @@ abstract class NavigationItem {
String get identifier;
NavigationCallback get action => (id) {
getIt<HomeStack>().setStackWithId(id);
getIt<HomeStackManager>().setStackWithId(id);
};
}
@ -37,17 +37,17 @@ abstract class HomeStackContext extends Equatable with NavigationItem {
HomeStackContext stackCtxFromView(View view) {
switch (view.viewType) {
case ViewType.Blank:
return DefaultHomeStackContext();
return BlankStackContext();
case ViewType.Doc:
return DocStackContext(view: view);
default:
return DefaultHomeStackContext();
return BlankStackContext();
}
}
class HomeStackNotifier extends ChangeNotifier {
HomeStackContext inner;
HomeStackNotifier({HomeStackContext? context}) : inner = context ?? DefaultHomeStackContext();
HomeStackNotifier({HomeStackContext? context}) : inner = context ?? BlankStackContext();
set context(HomeStackContext context) {
inner = context;
@ -58,9 +58,9 @@ class HomeStackNotifier extends ChangeNotifier {
}
// HomeStack is initialized as singleton to controll the page stack.
class HomeStack {
class HomeStackManager {
final HomeStackNotifier _notifier = HomeStackNotifier();
HomeStack();
HomeStackManager();
String title() {
return _notifier.context.title;
@ -95,7 +95,7 @@ class HomeStack {
if (viewType == notifier.context.type) {
return notifier.context.render();
} else {
return const AnnouncementStackPage();
return const BlankStackPage();
}
}).toList(),
);

View File

@ -1,10 +1,10 @@
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_listen_bloc.dart';
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
import 'package:app_flowy/workspace/application/doc/doc_edit_bloc.dart';
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
import 'package:app_flowy/workspace/application/menu/menu_watch.dart';
import 'package:app_flowy/workspace/application/menu/menu_listen.dart';
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
import 'package:app_flowy/workspace/application/view/view_list_bloc.dart';
import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart';
@ -28,11 +28,11 @@ import 'i_view_impl.dart';
class HomeDepsResolver {
static Future<void> resolve(GetIt getIt) async {
//
getIt.registerLazySingleton<HomeStack>(() => HomeStack());
getIt.registerLazySingleton<HomeStackManager>(() => HomeStackManager());
//App
getIt.registerFactoryParam<IApp, String, void>((appId, _) => IAppImpl(repo: AppRepository(appId: appId)));
getIt.registerFactoryParam<IAppWatch, String, void>(
getIt.registerFactoryParam<IAppListenr, String, void>(
(appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId)));
//workspace
@ -51,20 +51,21 @@ class HomeDepsResolver {
// User
getIt.registerFactoryParam<IUser, UserProfile, void>((user, _) => IUserImpl(repo: UserRepo(user: user)));
getIt.registerFactoryParam<IUserWatch, UserProfile, void>((user, _) => IUserWatchImpl(user: user));
getIt.registerFactoryParam<IUserListener, UserProfile, void>((user, _) => IUserWatchImpl(user: user));
//Menu Bloc
getIt.registerFactoryParam<MenuBloc, UserProfile, String>(
(user, workspaceId) => MenuBloc(getIt<IWorkspace>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuWatchBloc, UserProfile, String>(
(user, workspaceId) => MenuWatchBloc(getIt<IWorkspaceWatch>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuListenBloc, UserProfile, String>(
(user, workspaceId) => MenuListenBloc(getIt<IWorkspaceWatch>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
(user, _) => MenuUserBloc(getIt<IUser>(param1: user), getIt<IUserWatch>(param1: user)));
(user, _) => MenuUserBloc(getIt<IUser>(param1: user), getIt<IUserListener>(param1: user)));
//
getIt.registerFactoryParam<AppBloc, String, void>((appId, _) => AppBloc(getIt<IApp>(param1: appId)));
getIt.registerFactoryParam<AppWatchBloc, String, void>((appId, _) => AppWatchBloc(getIt<IAppWatch>(param1: appId)));
getIt.registerFactoryParam<AppListenBloc, String, void>(
(appId, _) => AppListenBloc(getIt<IAppListenr>(param1: appId)));
getIt
.registerFactoryParam<ViewBloc, String, void>((viewId, _) => ViewBloc(iViewImpl: getIt<IView>(param1: viewId)));
@ -79,7 +80,7 @@ class HomeDepsResolver {
getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
(user, _) => WelcomeBloc(
repo: UserRepo(user: user),
watch: getIt<IUserWatch>(param1: user),
watch: getIt<IUserListener>(param1: user),
),
);

View File

@ -28,21 +28,19 @@ class IAppImpl extends IApp {
}
}
class IAppWatchImpl extends IAppWatch {
class IAppWatchImpl extends IAppListenr {
AppWatchRepository repo;
IAppWatchImpl({
required this.repo,
});
@override
void startWatching(
{AppCreateViewCallback? addViewCallback,
AppUpdatedCallback? updatedCallback}) {
void start({AppCreateViewCallback? addViewCallback, AppUpdatedCallback? updatedCallback}) {
repo.startWatching(createView: addViewCallback, update: updatedCallback);
}
@override
Future<void> stopWatching() async {
Future<void> stop() async {
await repo.close();
}
}

View File

@ -49,7 +49,7 @@ class IUserImpl extends IUser {
}
}
class IUserWatchImpl extends IUserWatch {
class IUserWatchImpl extends IUserListener {
StreamSubscription<ObservableSubject>? _subscription;
WorkspacesUpdatedCallback? _workspacesUpdated;
AuthChangedCallback? _authChanged;
@ -65,12 +65,10 @@ class IUserWatchImpl extends IUserWatch {
}
@override
void startWatching() {
_workspaceParser = WorkspaceObservableParser(
id: _user.token, callback: _workspaceObservableCallback);
void start() {
_workspaceParser = WorkspaceObservableParser(id: _user.token, callback: _workspaceObservableCallback);
_userParser = UserObservableParser(
id: _user.token, callback: _userObservableCallback);
_userParser = UserObservableParser(id: _user.token, callback: _userObservableCallback);
_subscription = RustStreamReceiver.listen((observable) {
_workspaceParser.parse(observable);
@ -79,7 +77,7 @@ class IUserWatchImpl extends IUserWatch {
}
@override
Future<void> stopWatching() async {
Future<void> stop() async {
await _subscription?.cancel();
}
@ -98,8 +96,7 @@ class IUserWatchImpl extends IUserWatch {
_workspacesUpdated = workspacesCallback;
}
void _workspaceObservableCallback(
WorkspaceObservable ty, Either<Uint8List, WorkspaceError> result) {
void _workspaceObservableCallback(WorkspaceObservable ty, Either<Uint8List, WorkspaceError> result) {
switch (ty) {
case WorkspaceObservable.UserCreateWorkspace:
case WorkspaceObservable.UserDeleteWorkspace:
@ -118,10 +115,7 @@ class IUserWatchImpl extends IUserWatch {
if (_authChanged != null) {
result.fold(
(_) {},
(error) => {
_authChanged!(right(UserError.create()
..code = user_error.ErrorCode.UserUnauthorized))
},
(error) => {_authChanged!(right(UserError.create()..code = user_error.ErrorCode.UserUnauthorized))},
);
}
break;
@ -130,8 +124,7 @@ class IUserWatchImpl extends IUserWatch {
}
}
void _userObservableCallback(
user.UserObservable ty, Either<Uint8List, UserError> result) {
void _userObservableCallback(user.UserObservable ty, Either<Uint8List, UserError> result) {
switch (ty) {
case user.UserObservable.UserUnauthorized:
if (_profileUpdated != null) {

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/workspace/application/home/home_bloc.dart';
import 'package:app_flowy/workspace/application/home/home_auth_bloc.dart';
import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:flowy_log/flowy_log.dart';
@ -12,6 +13,29 @@ import 'package:styled_widget/styled_widget.dart';
import 'home_layout.dart';
// [[diagram: Home's widget structure]]
// 1.start listening user auth state
//
// HomeListenBloc IUserListener
//
//
// HomeScreen
//
// BlocListener
//
//
// HomeBloc HomeStack
//
//
// BlocBuilder HomeMenu
//
//
// 2.1 show login screen if user EditPannel
// session is invalid
//
// 2.2 build home screen
//
//
class HomeScreen extends StatelessWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
final UserProfile user;
@ -22,14 +46,14 @@ class HomeScreen extends StatelessWidget {
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<HomeAuthBloc>(
create: (context) => getIt<HomeAuthBloc>(param1: user)..add(const HomeAuthEvent.started()),
BlocProvider<HomeListenBloc>(
create: (context) => getIt<HomeListenBloc>(param1: user)..add(const HomeListenEvent.started()),
),
BlocProvider<HomeBloc>(create: (context) => getIt<HomeBloc>()),
],
child: Scaffold(
key: HomeScreen.scaffoldKey,
body: BlocListener<HomeAuthBloc, HomeAuthState>(
body: BlocListener<HomeListenBloc, HomeListenState>(
listener: (context, state) {
state.map(
loading: (_) {},
@ -58,7 +82,7 @@ class HomeScreen extends StatelessWidget {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final layout = HomeLayout(context, constraints, forceCollapse);
const homePage = HomePage();
const homeStack = HomeStack();
final menu = _buildHomeMenu(
layout: layout,
context: context,
@ -68,7 +92,7 @@ class HomeScreen extends StatelessWidget {
layout: layout,
context: context,
);
return _layoutWidgets(layout: layout, homePage: homePage, homeMenu: menu, editPannel: editPannel);
return _layoutWidgets(layout: layout, homeStack: homeStack, homeMenu: menu, editPannel: editPannel);
},
);
}
@ -77,7 +101,7 @@ class HomeScreen extends StatelessWidget {
final homeBloc = context.read<HomeBloc>();
Widget homeMenu = HomeMenu(
pageContextChanged: (pageContext) {
getIt<HomeStack>().setStack(pageContext);
getIt<HomeStackManager>().setStack(pageContext);
},
isCollapseChanged: (isCollapse) {
homeBloc.add(HomeEvent.forceCollapse(isCollapse));
@ -102,7 +126,7 @@ class HomeScreen extends StatelessWidget {
}
Widget _layoutWidgets(
{required HomeLayout layout, required Widget homeMenu, required Widget homePage, required Widget editPannel}) {
{required HomeLayout layout, required Widget homeMenu, required Widget homeStack, required Widget editPannel}) {
return Stack(
children: [
homeMenu
@ -112,7 +136,7 @@ class HomeScreen extends StatelessWidget {
)
.positioned(left: 0, top: 0, width: layout.menuWidth, bottom: 0, animate: true)
.animate(layout.animDuration, Curves.easeOut),
homePage
homeStack
.constrained(minWidth: 500)
.positioned(left: layout.homePageLOffset, right: layout.homePageROffset, bottom: 0, top: 0, animate: true)
.animate(layout.animDuration, Curves.easeOut),
@ -127,28 +151,3 @@ class HomeScreen extends StatelessWidget {
);
}
}
class HomePage extends StatelessWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
// final Size size;
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
Log.info('HomePage build');
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIt<HomeStack>().stackTopBar(),
Expanded(
child: Container(
color: Colors.white,
child: FocusTraversalGroup(
child: getIt<HomeStack>().stackWidget(),
),
),
),
],
);
}
}

View File

@ -18,7 +18,7 @@ class NavigationNotifier with ChangeNotifier {
List<NavigationItem> get naviItems => homeStackNotifier.context.navigationItems;
}
// [[Navigation]]
// [[diagram: HomeStack navigation flow]]
//
// 2.notify listeners DefaultHomeStackContext
//

View File

@ -2,7 +2,7 @@ import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flutter/material.dart';
class DefaultHomeStackContext extends HomeStackContext {
class BlankStackContext extends HomeStackContext {
@override
String get identifier => "1";
@ -17,21 +17,21 @@ class DefaultHomeStackContext extends HomeStackContext {
@override
Widget render() {
return const AnnouncementStackPage();
return const BlankStackPage();
}
@override
List<NavigationItem> get navigationItems => [this];
}
class AnnouncementStackPage extends StatefulWidget {
const AnnouncementStackPage({Key? key}) : super(key: key);
class BlankStackPage extends StatefulWidget {
const BlankStackPage({Key? key}) : super(key: key);
@override
State<AnnouncementStackPage> createState() => _AnnouncementPage();
State<BlankStackPage> createState() => _AnnouncementPage();
}
class _AnnouncementPage extends State<AnnouncementStackPage> {
class _AnnouncementPage extends State<BlankStackPage> {
@override
Widget build(BuildContext context) {
return SizedBox.expand(

View File

@ -1,44 +0,0 @@
import 'package:flutter/material.dart';
import 'package:time/time.dart';
class FadingIndexedStack extends StatefulWidget {
final int index;
final List<Widget> children;
final Duration duration;
const FadingIndexedStack({
Key? key,
required this.index,
required this.children,
this.duration = const Duration(
milliseconds: 250,
),
}) : super(key: key);
@override
_FadingIndexedStackState createState() => _FadingIndexedStackState();
}
class _FadingIndexedStackState extends State<FadingIndexedStack> {
double _targetOpacity = 1;
@override
void didUpdateWidget(FadingIndexedStack oldWidget) {
if (oldWidget.index == widget.index) return;
setState(() => _targetOpacity = 0);
Future.delayed(1.milliseconds, () => setState(() => _targetOpacity = 1));
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder<double>(
duration: _targetOpacity > 0 ? widget.duration : 0.milliseconds,
tween: Tween(begin: 0, end: _targetOpacity),
builder: (_, value, child) {
return Opacity(opacity: value, child: child);
},
child: IndexedStack(index: widget.index, children: widget.children),
);
}
}

View File

@ -0,0 +1,83 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:flowy_log/flowy_log.dart';
import 'package:flutter/material.dart';
import 'package:time/time.dart';
// [[diagram: HomeStack's widget structure]]
//
//
// BlankStackContext BlankStackPage
//
// HomeStack HomeStackManager HomeStackContext
//
// DocStackContext DocStackPage
//
//
//
class HomeStack extends StatelessWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
// final Size size;
const HomeStack({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
Log.info('HomePage build');
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIt<HomeStackManager>().stackTopBar(),
Expanded(
child: Container(
color: Colors.white,
child: FocusTraversalGroup(
child: getIt<HomeStackManager>().stackWidget(),
),
),
),
],
);
}
}
class FadingIndexedStack extends StatefulWidget {
final int index;
final List<Widget> children;
final Duration duration;
const FadingIndexedStack({
Key? key,
required this.index,
required this.children,
this.duration = const Duration(
milliseconds: 250,
),
}) : super(key: key);
@override
_FadingIndexedStackState createState() => _FadingIndexedStackState();
}
class _FadingIndexedStackState extends State<FadingIndexedStack> {
double _targetOpacity = 1;
@override
void didUpdateWidget(FadingIndexedStack oldWidget) {
if (oldWidget.index == widget.index) return;
setState(() => _targetOpacity = 0);
Future.delayed(1.milliseconds, () => setState(() => _targetOpacity = 1));
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder<double>(
duration: _targetOpacity > 0 ? widget.duration : 0.milliseconds,
tween: Tween(begin: 0, end: _targetOpacity),
builder: (_, value, child) {
return Opacity(opacity: value, child: child);
},
child: IndexedStack(index: widget.index, children: widget.children),
);
}
}

View File

@ -8,17 +8,40 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:expandable/expandable.dart';
import 'package:flowy_infra/time/duration.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/application/menu/menu_listen.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/user.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/menu_user.dart';
import 'menu_list.dart';
import 'widget/app/app.dart';
import 'widget/app/menu_app.dart';
import 'widget/app/create_button.dart';
// [[diagram: HomeMenu's widget structure]]
// get user profile or modify user
//
// IUser
// MenuTopBar
// MenuUserMenuUserBloc
//
// HomeMenu IUserListener
//
// listen workspace changes or user
// impl profile changes
//
// MenuList MenuItem
//
// AppBloc fetch app's views or modify view
//
//
// MenuApp
//
//
// AppListenBloc Receive view changes
//
class HomeMenu extends StatelessWidget {
final Function(HomeStackContext) pageContextChanged;
final Function(bool) isCollapseChanged;
@ -41,7 +64,7 @@ class HomeMenu extends StatelessWidget {
create: (context) => getIt<MenuBloc>(param1: user, param2: workspaceId)..add(const MenuEvent.initial())),
BlocProvider(
create: (context) =>
getIt<MenuWatchBloc>(param1: user, param2: workspaceId)..add(const MenuWatchEvent.started())),
getIt<MenuListenBloc>(param1: user, param2: workspaceId)..add(const MenuListenEvent.started())),
],
child: MultiBlocListener(
listeners: [
@ -85,7 +108,7 @@ class HomeMenu extends StatelessWidget {
}
Widget _renderMenuList(BuildContext context) {
return BlocBuilder<MenuWatchBloc, MenuWatchState>(
return BlocBuilder<MenuListenBloc, MenuListenState>(
builder: (context, state) {
return state.map(
initial: (_) => MenuList(
@ -128,7 +151,7 @@ class MenuItemBuilder {
MenuItemBuilder withApps(Option<List<App>> someApps) {
List<MenuItem> appWidgets = someApps.foldRight(
[],
(apps, _) => apps.map((app) => AppPage(AppPageContext(app))).toList(),
(apps, _) => apps.map((app) => MenuApp(MenuAppContext(app))).toList(),
);
items.addAll(appWidgets);
return this;
@ -138,3 +161,44 @@ class MenuItemBuilder {
return items;
}
}
enum MenuItemType {
userProfile,
dashboard,
favorites,
app,
}
abstract class MenuItem extends StatelessWidget {
const MenuItem({Key? key}) : super(key: key);
MenuItemType get type;
}
class MenuList extends StatelessWidget {
final List<MenuItem> menuItems;
const MenuList({required this.menuItems, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ExpandableTheme(
data: ExpandableThemeData(useInkWell: true, animationDuration: Durations.medium),
child: Expanded(
child: ListView.separated(
itemCount: menuItems.length,
separatorBuilder: (context, index) {
if (index == 0) {
return const VSpace(29);
} else {
return const VSpace(24);
}
},
physics: const BouncingScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return menuItems[index];
},
),
),
);
}
}

View File

@ -1,45 +0,0 @@
import 'package:expandable/expandable.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_infra/time/duration.dart';
import 'package:flutter/material.dart';
enum MenuItemType {
userProfile,
dashboard,
favorites,
app,
}
abstract class MenuItem extends StatelessWidget {
const MenuItem({Key? key}) : super(key: key);
MenuItemType get type;
}
class MenuList extends StatelessWidget {
final List<MenuItem> menuItems;
const MenuList({required this.menuItems, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ExpandableTheme(
data: ExpandableThemeData(useInkWell: true, animationDuration: Durations.medium),
child: Expanded(
child: ListView.separated(
itemCount: menuItems.length,
separatorBuilder: (context, index) {
if (index == 0) {
return const VSpace(29);
} else {
return const VSpace(24);
}
},
physics: const BouncingScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return menuItems[index];
},
),
),
);
}
}

View File

@ -1 +1 @@
export 'menu_page.dart';
export 'menu.dart';

View File

@ -11,11 +11,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.dart';
import 'app.dart';
import 'menu_app.dart';
class AppHeader extends StatelessWidget {
class MenuAppHeader extends StatelessWidget {
final App app;
const AppHeader(
const MenuAppHeader(
this.app, {
Key? key,
}) : super(key: key);
@ -38,13 +38,13 @@ class AppHeader extends StatelessWidget {
expandIcon: FlowyIconData.drop_down_show,
collapseIcon: FlowyIconData.drop_down_hide,
iconColor: theme.shader1,
iconSize: AppPageSize.expandedIconSize,
iconSize: MenuAppSizes.expandedIconSize,
iconPadding: EdgeInsets.zero,
hasIcon: false,
),
),
),
HSpace(AppPageSize.expandedIconPadding),
HSpace(MenuAppSizes.expandedIconPadding),
Expanded(
child: GestureDetector(
onTapDown: (_) {
@ -62,7 +62,7 @@ class AppHeader extends StatelessWidget {
// FlowyOverlay.of(context)
// .insert(widget: Text('test'), identifier: 'identifier');
},
).padding(right: AppPageSize.expandedIconPadding),
).padding(right: MenuAppSizes.expandedIconPadding),
// PopupMenuButton(
// iconSize: 16,
// tooltip: 'create new view',

View File

@ -7,33 +7,31 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:app_flowy/startup/startup.dart';
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/presentation/widgets/menu/menu_list.dart';
import 'package:app_flowy/workspace/application/app/app_listen_bloc.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
import 'section/section.dart';
class AppPageSize {
class MenuAppSizes {
static double expandedIconSize = 16;
static double expandedIconPadding = 6;
static double scale = 1;
static double get expandedPadding => expandedIconSize * scale + expandedIconPadding;
}
class AppPageContext {
class MenuAppContext {
final App app;
final viewListData = ViewSectionData();
AppPageContext(
this.app,
);
MenuAppContext(this.app);
Key valueKey() => ValueKey("${app.id}${app.version}");
}
class AppPage extends MenuItem {
final AppPageContext appCtx;
AppPage(this.appCtx, {Key? key}) : super(key: appCtx.valueKey());
class MenuApp extends MenuItem {
final MenuAppContext appCtx;
MenuApp(this.appCtx, {Key? key}) : super(key: appCtx.valueKey());
@override
Widget build(BuildContext context) {
@ -44,13 +42,13 @@ class AppPage extends MenuItem {
appBloc.add(const AppEvent.initial());
return appBloc;
}),
BlocProvider<AppWatchBloc>(create: (context) {
final watchBloc = getIt<AppWatchBloc>(param1: appCtx.app.id);
watchBloc.add(const AppWatchEvent.started());
BlocProvider<AppListenBloc>(create: (context) {
final watchBloc = getIt<AppListenBloc>(param1: appCtx.app.id);
watchBloc.add(const AppListenEvent.started());
return watchBloc;
}),
],
child: BlocBuilder<AppWatchBloc, AppWatchState>(
child: BlocBuilder<AppListenBloc, AppListenState>(
builder: (context, state) {
final child = state.map(
initial: (_) => BlocBuilder<AppBloc, AppState>(
@ -82,7 +80,7 @@ class AppPage extends MenuItem {
iconPadding: EdgeInsets.zero,
hasIcon: false,
),
header: AppHeader(appCtx.app),
header: MenuAppHeader(appCtx.app),
expanded: child,
collapsed: const SizedBox(),
),

View File

@ -1,4 +1,4 @@
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/app.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
@ -65,8 +65,8 @@ class ViewSectionItem extends StatelessWidget {
Widget widget = Container(
child: Row(children: children).padding(
left: AppPageSize.expandedPadding,
right: AppPageSize.expandedIconPadding,
left: MenuAppSizes.expandedPadding,
right: MenuAppSizes.expandedIconPadding,
),
height: 24,
alignment: Alignment.centerLeft,

View File

@ -73,7 +73,7 @@ class ViewSection extends StatelessWidget {
Log.debug("Open view: $view");
context.read<ViewSectionNotifier>().setSelectedView(view);
final stackView = stackCtxFromView(viewCtx.view);
getIt<HomeStack>().setStack(stackView);
getIt<HomeStackManager>().setStack(stackView);
},
);

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import '../../menu_list.dart';
import '../../menu.dart';
class FavoriteHeader extends MenuItem {
const FavoriteHeader({Key? key}) : super(key: key);

View File

@ -1,6 +1,6 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_list.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
import 'package:flutter/material.dart';

View File

@ -2,4 +2,4 @@ export '../stack_page/blank/blank_page.dart';
export './edit_pannel/edit_pannel.dart';
export './edit_pannel/pannel_animation.dart';
export './home_top_bar.dart';
export 'menu/menu_page.dart';
export 'menu/menu.dart';