[flutter]: config stack page

This commit is contained in:
appflowy 2021-10-10 15:58:57 +08:00
parent 5445853839
commit fb1733e188
24 changed files with 299 additions and 345 deletions

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:app_flowy/workspace/domain/i_workspace.dart'; import 'package:app_flowy/workspace/domain/i_workspace.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart'; import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flowy_log/flowy_log.dart'; import 'package:flowy_log/flowy_log.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
@ -37,12 +38,11 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
} }
Stream<MenuState> _performActionOnOpenPage(OpenPage e) async* { Stream<MenuState> _performActionOnOpenPage(OpenPage e) async* {
yield state.copyWith(stackView: e.stackView); yield state.copyWith(context: e.context);
} }
Stream<MenuState> _performActionOnCreateApp(CreateApp event) async* { Stream<MenuState> _performActionOnCreateApp(CreateApp event) async* {
final result = final result = await workspace.createApp(name: event.name, desc: event.desc);
await workspace.createApp(name: event.name, desc: event.desc);
yield result.fold( yield result.fold(
(app) => state.copyWith(apps: some([app])), (app) => state.copyWith(apps: some([app])),
(error) { (error) {
@ -69,7 +69,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
class MenuEvent with _$MenuEvent { class MenuEvent with _$MenuEvent {
const factory MenuEvent.initial() = _Initial; const factory MenuEvent.initial() = _Initial;
const factory MenuEvent.collapse() = Collapse; const factory MenuEvent.collapse() = Collapse;
const factory MenuEvent.openPage(HomeStackView stackView) = OpenPage; const factory MenuEvent.openPage(HomeStackContext context) = OpenPage;
const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp; const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp;
} }
@ -79,12 +79,13 @@ class MenuState with _$MenuState {
required bool isCollapse, required bool isCollapse,
required Option<List<App>> apps, required Option<List<App>> apps,
required Either<Unit, WorkspaceError> successOrFailure, required Either<Unit, WorkspaceError> successOrFailure,
HomeStackView? stackView, required HomeStackContext context,
}) = _MenuState; }) = _MenuState;
factory MenuState.initial() => MenuState( factory MenuState.initial() => MenuState(
isCollapse: false, isCollapse: false,
apps: none(), apps: none(),
successOrFailure: left(unit), successOrFailure: left(unit),
context: DefaultHomeStackContext(),
); );
} }

View File

@ -24,9 +24,9 @@ class _$MenuEventTearOff {
return const Collapse(); return const Collapse();
} }
OpenPage openPage(HomeStackView stackView) { OpenPage openPage(HomeStackContext context) {
return OpenPage( return OpenPage(
stackView, context,
); );
} }
@ -47,7 +47,7 @@ mixin _$MenuEvent {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackView stackView) openPage, required TResult Function(HomeStackContext context) openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@ -55,7 +55,7 @@ mixin _$MenuEvent {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackView stackView)? openPage, TResult Function(HomeStackContext context)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
required TResult orElse(), required TResult orElse(),
}) => }) =>
@ -133,7 +133,7 @@ class _$_Initial implements _Initial {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackView stackView) openPage, required TResult Function(HomeStackContext context) openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
}) { }) {
return initial(); return initial();
@ -144,7 +144,7 @@ class _$_Initial implements _Initial {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackView stackView)? openPage, TResult Function(HomeStackContext context)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
required TResult orElse(), required TResult orElse(),
}) { }) {
@ -224,7 +224,7 @@ class _$Collapse implements Collapse {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackView stackView) openPage, required TResult Function(HomeStackContext context) openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
}) { }) {
return collapse(); return collapse();
@ -235,7 +235,7 @@ class _$Collapse implements Collapse {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackView stackView)? openPage, TResult Function(HomeStackContext context)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
required TResult orElse(), required TResult orElse(),
}) { }) {
@ -280,7 +280,7 @@ abstract class Collapse implements MenuEvent {
abstract class $OpenPageCopyWith<$Res> { abstract class $OpenPageCopyWith<$Res> {
factory $OpenPageCopyWith(OpenPage value, $Res Function(OpenPage) then) = factory $OpenPageCopyWith(OpenPage value, $Res Function(OpenPage) then) =
_$OpenPageCopyWithImpl<$Res>; _$OpenPageCopyWithImpl<$Res>;
$Res call({HomeStackView stackView}); $Res call({HomeStackContext context});
} }
/// @nodoc /// @nodoc
@ -294,13 +294,13 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res>
@override @override
$Res call({ $Res call({
Object? stackView = freezed, Object? context = freezed,
}) { }) {
return _then(OpenPage( return _then(OpenPage(
stackView == freezed context == freezed
? _value.stackView ? _value.context
: stackView // ignore: cast_nullable_to_non_nullable : context // ignore: cast_nullable_to_non_nullable
as HomeStackView, as HomeStackContext,
)); ));
} }
} }
@ -308,28 +308,27 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$OpenPage implements OpenPage { class _$OpenPage implements OpenPage {
const _$OpenPage(this.stackView); const _$OpenPage(this.context);
@override @override
final HomeStackView stackView; final HomeStackContext context;
@override @override
String toString() { String toString() {
return 'MenuEvent.openPage(stackView: $stackView)'; return 'MenuEvent.openPage(context: $context)';
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is OpenPage && (other is OpenPage &&
(identical(other.stackView, stackView) || (identical(other.context, context) ||
const DeepCollectionEquality() const DeepCollectionEquality().equals(other.context, context)));
.equals(other.stackView, stackView)));
} }
@override @override
int get hashCode => int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(stackView); runtimeType.hashCode ^ const DeepCollectionEquality().hash(context);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@ -341,10 +340,10 @@ class _$OpenPage implements OpenPage {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackView stackView) openPage, required TResult Function(HomeStackContext context) openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
}) { }) {
return openPage(stackView); return openPage(context);
} }
@override @override
@ -352,12 +351,12 @@ class _$OpenPage implements OpenPage {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackView stackView)? openPage, TResult Function(HomeStackContext context)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (openPage != null) { if (openPage != null) {
return openPage(stackView); return openPage(context);
} }
return orElse(); return orElse();
} }
@ -390,9 +389,9 @@ class _$OpenPage implements OpenPage {
} }
abstract class OpenPage implements MenuEvent { abstract class OpenPage implements MenuEvent {
const factory OpenPage(HomeStackView stackView) = _$OpenPage; const factory OpenPage(HomeStackContext context) = _$OpenPage;
HomeStackView get stackView => throw _privateConstructorUsedError; HomeStackContext get context => throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$OpenPageCopyWith<OpenPage> get copyWith => $OpenPageCopyWith<OpenPage> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@ -473,7 +472,7 @@ class _$CreateApp implements CreateApp {
TResult when<TResult extends Object?>({ TResult when<TResult extends Object?>({
required TResult Function() initial, required TResult Function() initial,
required TResult Function() collapse, required TResult Function() collapse,
required TResult Function(HomeStackView stackView) openPage, required TResult Function(HomeStackContext context) openPage,
required TResult Function(String name, String? desc) createApp, required TResult Function(String name, String? desc) createApp,
}) { }) {
return createApp(name, desc); return createApp(name, desc);
@ -484,7 +483,7 @@ class _$CreateApp implements CreateApp {
TResult maybeWhen<TResult extends Object?>({ TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial, TResult Function()? initial,
TResult Function()? collapse, TResult Function()? collapse,
TResult Function(HomeStackView stackView)? openPage, TResult Function(HomeStackContext context)? openPage,
TResult Function(String name, String? desc)? createApp, TResult Function(String name, String? desc)? createApp,
required TResult orElse(), required TResult orElse(),
}) { }) {
@ -539,12 +538,12 @@ class _$MenuStateTearOff {
{required bool isCollapse, {required bool isCollapse,
required Option<List<App>> apps, required Option<List<App>> apps,
required Either<Unit, WorkspaceError> successOrFailure, required Either<Unit, WorkspaceError> successOrFailure,
HomeStackView? stackView}) { required HomeStackContext context}) {
return _MenuState( return _MenuState(
isCollapse: isCollapse, isCollapse: isCollapse,
apps: apps, apps: apps,
successOrFailure: successOrFailure, successOrFailure: successOrFailure,
stackView: stackView, context: context,
); );
} }
} }
@ -558,7 +557,7 @@ mixin _$MenuState {
Option<List<App>> get apps => throw _privateConstructorUsedError; Option<List<App>> get apps => throw _privateConstructorUsedError;
Either<Unit, WorkspaceError> get successOrFailure => Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
HomeStackView? get stackView => throw _privateConstructorUsedError; HomeStackContext get context => throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$MenuStateCopyWith<MenuState> get copyWith => $MenuStateCopyWith<MenuState> get copyWith =>
@ -573,7 +572,7 @@ abstract class $MenuStateCopyWith<$Res> {
{bool isCollapse, {bool isCollapse,
Option<List<App>> apps, Option<List<App>> apps,
Either<Unit, WorkspaceError> successOrFailure, Either<Unit, WorkspaceError> successOrFailure,
HomeStackView? stackView}); HomeStackContext context});
} }
/// @nodoc /// @nodoc
@ -589,7 +588,7 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
Object? isCollapse = freezed, Object? isCollapse = freezed,
Object? apps = freezed, Object? apps = freezed,
Object? successOrFailure = freezed, Object? successOrFailure = freezed,
Object? stackView = freezed, Object? context = freezed,
}) { }) {
return _then(_value.copyWith( return _then(_value.copyWith(
isCollapse: isCollapse == freezed isCollapse: isCollapse == freezed
@ -604,10 +603,10 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
? _value.successOrFailure ? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable : successOrFailure // ignore: cast_nullable_to_non_nullable
as Either<Unit, WorkspaceError>, as Either<Unit, WorkspaceError>,
stackView: stackView == freezed context: context == freezed
? _value.stackView ? _value.context
: stackView // ignore: cast_nullable_to_non_nullable : context // ignore: cast_nullable_to_non_nullable
as HomeStackView?, as HomeStackContext,
)); ));
} }
} }
@ -622,7 +621,7 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> {
{bool isCollapse, {bool isCollapse,
Option<List<App>> apps, Option<List<App>> apps,
Either<Unit, WorkspaceError> successOrFailure, Either<Unit, WorkspaceError> successOrFailure,
HomeStackView? stackView}); HomeStackContext context});
} }
/// @nodoc /// @nodoc
@ -639,7 +638,7 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
Object? isCollapse = freezed, Object? isCollapse = freezed,
Object? apps = freezed, Object? apps = freezed,
Object? successOrFailure = freezed, Object? successOrFailure = freezed,
Object? stackView = freezed, Object? context = freezed,
}) { }) {
return _then(_MenuState( return _then(_MenuState(
isCollapse: isCollapse == freezed isCollapse: isCollapse == freezed
@ -654,10 +653,10 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
? _value.successOrFailure ? _value.successOrFailure
: successOrFailure // ignore: cast_nullable_to_non_nullable : successOrFailure // ignore: cast_nullable_to_non_nullable
as Either<Unit, WorkspaceError>, as Either<Unit, WorkspaceError>,
stackView: stackView == freezed context: context == freezed
? _value.stackView ? _value.context
: stackView // ignore: cast_nullable_to_non_nullable : context // ignore: cast_nullable_to_non_nullable
as HomeStackView?, as HomeStackContext,
)); ));
} }
} }
@ -669,7 +668,7 @@ class _$_MenuState implements _MenuState {
{required this.isCollapse, {required this.isCollapse,
required this.apps, required this.apps,
required this.successOrFailure, required this.successOrFailure,
this.stackView}); required this.context});
@override @override
final bool isCollapse; final bool isCollapse;
@ -678,11 +677,11 @@ class _$_MenuState implements _MenuState {
@override @override
final Either<Unit, WorkspaceError> successOrFailure; final Either<Unit, WorkspaceError> successOrFailure;
@override @override
final HomeStackView? stackView; final HomeStackContext context;
@override @override
String toString() { String toString() {
return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, stackView: $stackView)'; return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, context: $context)';
} }
@override @override
@ -697,9 +696,8 @@ class _$_MenuState implements _MenuState {
(identical(other.successOrFailure, successOrFailure) || (identical(other.successOrFailure, successOrFailure) ||
const DeepCollectionEquality() const DeepCollectionEquality()
.equals(other.successOrFailure, successOrFailure)) && .equals(other.successOrFailure, successOrFailure)) &&
(identical(other.stackView, stackView) || (identical(other.context, context) ||
const DeepCollectionEquality() const DeepCollectionEquality().equals(other.context, context)));
.equals(other.stackView, stackView)));
} }
@override @override
@ -708,7 +706,7 @@ class _$_MenuState implements _MenuState {
const DeepCollectionEquality().hash(isCollapse) ^ const DeepCollectionEquality().hash(isCollapse) ^
const DeepCollectionEquality().hash(apps) ^ const DeepCollectionEquality().hash(apps) ^
const DeepCollectionEquality().hash(successOrFailure) ^ const DeepCollectionEquality().hash(successOrFailure) ^
const DeepCollectionEquality().hash(stackView); const DeepCollectionEquality().hash(context);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@ -721,7 +719,7 @@ abstract class _MenuState implements MenuState {
{required bool isCollapse, {required bool isCollapse,
required Option<List<App>> apps, required Option<List<App>> apps,
required Either<Unit, WorkspaceError> successOrFailure, required Either<Unit, WorkspaceError> successOrFailure,
HomeStackView? stackView}) = _$_MenuState; required HomeStackContext context}) = _$_MenuState;
@override @override
bool get isCollapse => throw _privateConstructorUsedError; bool get isCollapse => throw _privateConstructorUsedError;
@ -731,7 +729,7 @@ abstract class _MenuState implements MenuState {
Either<Unit, WorkspaceError> get successOrFailure => Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@override @override
HomeStackView? get stackView => throw _privateConstructorUsedError; HomeStackContext get context => throw _privateConstructorUsedError;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$MenuStateCopyWith<_MenuState> get copyWith => _$MenuStateCopyWith<_MenuState> get copyWith =>

View File

@ -1,48 +1,56 @@
import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:app_flowy/workspace/presentation/doc/doc_stack_page.dart'; import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
import 'package:app_flowy/workspace/presentation/widgets/blank_page.dart'; import 'package:app_flowy/workspace/presentation/stack_page/fading_index_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/fading_index_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart'; import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
abstract class HomeStackView extends Equatable { abstract class HomeStackContext extends Equatable {
final ViewType type; String get title;
final String title; String get identifier;
final String identifier; ViewType get type;
const HomeStackView( Widget render();
{required this.type, required this.title, required this.identifier});
} }
class PageStackNotifier extends ChangeNotifier { HomeStackContext stackCtxFromView(View view) {
HomeStackView? innerView; switch (view.viewType) {
case ViewType.Blank:
return DefaultHomeStackContext();
case ViewType.Doc:
return DocStackContext(view: view);
default:
return DefaultHomeStackContext();
}
}
PageStackNotifier({ class HomeStackNotifier extends ChangeNotifier {
this.innerView, HomeStackContext inner;
});
set view(HomeStackView view) { HomeStackNotifier({
innerView = view; HomeStackContext? context,
}) : inner = context ?? DefaultHomeStackContext();
set context(HomeStackContext context) {
inner = context;
notifyListeners(); notifyListeners();
} }
HomeStackView get view { HomeStackContext get context => inner;
return innerView ?? const AnnouncementStackView();
}
} }
// HomePageStack is initialized as singleton to controll the page stack. // HomePageStack is initialized as singleton to controll the page stack.
class HomePageStack { class HomeStack {
final PageStackNotifier _notifier = PageStackNotifier(); final HomeStackNotifier _notifier = HomeStackNotifier();
HomePageStack(); HomeStack();
String title() { String title() {
return _notifier.view.title; return _notifier.context.title;
} }
void setStackView(HomeStackView? stackView) { void setStack(HomeStackContext context) {
_notifier.view = stackView ?? const AnnouncementStackView(); _notifier.context = context;
} }
Widget stackTopBar() { Widget stackTopBar() {
@ -50,8 +58,8 @@ class HomePageStack {
providers: [ providers: [
ChangeNotifierProvider.value(value: _notifier), ChangeNotifierProvider.value(value: _notifier),
], ],
child: Consumer(builder: (ctx, PageStackNotifier notifier, child) { child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
return HomeTopBar(view: notifier.view); return HomeTopBar(view: notifier.context);
}), }),
); );
} }
@ -61,10 +69,16 @@ class HomePageStack {
providers: [ providers: [
ChangeNotifierProvider.value(value: _notifier), ChangeNotifierProvider.value(value: _notifier),
], ],
child: Consumer(builder: (ctx, PageStackNotifier notifier, child) { child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
return FadingIndexedStack( return FadingIndexedStack(
index: pages.indexOf(notifier.view.type), index: pages.indexOf(notifier.context.type),
children: _buildStackWidget(notifier.view), children: ViewType.values.map((viewType) {
if (viewType == notifier.context.type) {
return notifier.context.render();
} else {
return const AnnouncementStackPage();
}
}).toList(),
); );
}), }),
); );
@ -72,40 +86,3 @@ class HomePageStack {
} }
List<ViewType> pages = ViewType.values.toList(); List<ViewType> pages = ViewType.values.toList();
List<Widget> _buildStackWidget(HomeStackView stackView) {
return ViewType.values.map((viewType) {
if (viewType == stackView.type) {
switch (stackView.type) {
case ViewType.Blank:
return AnnouncementStackPage(
stackView: stackView as AnnouncementStackView);
case ViewType.Doc:
final docView = stackView as DocPageStackView;
return DocStackPage(
key: ValueKey(docView.view.id), stackView: docView);
default:
return AnnouncementStackPage(
stackView: stackView as AnnouncementStackView);
}
} else {
return const AnnouncementStackPage(stackView: AnnouncementStackView());
}
}).toList();
}
HomeStackView stackViewFromView(View view) {
switch (view.viewType) {
case ViewType.Blank:
return const AnnouncementStackView();
case ViewType.Doc:
return DocPageStackView(view);
default:
return const AnnouncementStackView();
}
}
abstract class HomeStackWidget extends StatefulWidget {
final HomeStackView stackView;
const HomeStackWidget({Key? key, required this.stackView}) : super(key: key);
}

View File

@ -28,68 +28,53 @@ import 'i_view_impl.dart';
class HomeDepsResolver { class HomeDepsResolver {
static Future<void> resolve(GetIt getIt) async { static Future<void> resolve(GetIt getIt) async {
// //
getIt.registerLazySingleton<HomePageStack>(() => HomePageStack()); getIt.registerLazySingleton<HomeStack>(() => HomeStack());
//App //App
getIt.registerFactoryParam<IApp, String, void>( getIt.registerFactoryParam<IApp, String, void>((appId, _) => IAppImpl(repo: AppRepository(appId: appId)));
(appId, _) => IAppImpl(repo: AppRepository(appId: appId)));
getIt.registerFactoryParam<IAppWatch, String, void>( getIt.registerFactoryParam<IAppWatch, String, void>(
(appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId))); (appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId)));
//workspace //workspace
getIt.registerFactoryParam<IWorkspace, UserProfile, String>( getIt.registerFactoryParam<IWorkspace, UserProfile, String>(
(user, workspaceId) => IWorkspaceImpl( (user, workspaceId) => IWorkspaceImpl(repo: WorkspaceRepo(user: user, workspaceId: workspaceId)));
repo: WorkspaceRepo(user: user, workspaceId: workspaceId)));
getIt.registerFactoryParam<IWorkspaceWatch, UserProfile, String>( getIt.registerFactoryParam<IWorkspaceWatch, UserProfile, String>(
(user, workspaceId) => IWorkspaceWatchImpl( (user, workspaceId) => IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(user: user, workspaceId: workspaceId)));
repo: WorkspaceWatchRepo(user: user, workspaceId: workspaceId)));
// View // View
getIt.registerFactoryParam<IView, View, void>( getIt.registerFactoryParam<IView, View, void>((view, _) => IViewImpl(repo: ViewRepository(view: view)));
(view, _) => IViewImpl(repo: ViewRepository(view: view)));
getIt.registerFactoryParam<IViewWatch, View, void>( getIt.registerFactoryParam<IViewWatch, View, void>(
(view, _) => IViewWatchImpl(repo: ViewWatchRepository(view: view))); (view, _) => IViewWatchImpl(repo: ViewWatchRepository(view: view)));
// Doc // Doc
getIt.registerFactoryParam<IDoc, String, void>( getIt.registerFactoryParam<IDoc, String, void>((docId, _) => IDocImpl(repo: DocRepository(docId: docId)));
(docId, _) => IDocImpl(repo: DocRepository(docId: docId)));
// User // User
getIt.registerFactoryParam<IUser, UserProfile, void>( getIt.registerFactoryParam<IUser, UserProfile, void>((user, _) => IUserImpl(repo: UserRepo(user: user)));
(user, _) => IUserImpl(repo: UserRepo(user: user))); getIt.registerFactoryParam<IUserWatch, UserProfile, void>((user, _) => IUserWatchImpl(user: user));
getIt.registerFactoryParam<IUserWatch, UserProfile, void>(
(user, _) => IUserWatchImpl(user: user));
//Menu Bloc //Menu Bloc
getIt.registerFactoryParam<MenuBloc, UserProfile, String>( getIt.registerFactoryParam<MenuBloc, UserProfile, String>(
(user, workspaceId) => (user, workspaceId) => MenuBloc(getIt<IWorkspace>(param1: user, param2: workspaceId)));
MenuBloc(getIt<IWorkspace>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuWatchBloc, UserProfile, String>( getIt.registerFactoryParam<MenuWatchBloc, UserProfile, String>(
(user, workspaceId) => MenuWatchBloc( (user, workspaceId) => MenuWatchBloc(getIt<IWorkspaceWatch>(param1: user, param2: workspaceId)));
getIt<IWorkspaceWatch>(param1: user, param2: workspaceId)));
getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>((user, _) => getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
MenuUserBloc( (user, _) => MenuUserBloc(getIt<IUser>(param1: user), getIt<IUserWatch>(param1: user)));
getIt<IUser>(param1: user), getIt<IUserWatch>(param1: user)));
// //
getIt.registerFactoryParam<AppBloc, String, void>( getIt.registerFactoryParam<AppBloc, String, void>((appId, _) => AppBloc(getIt<IApp>(param1: appId)));
(appId, _) => AppBloc(getIt<IApp>(param1: appId))); getIt.registerFactoryParam<AppWatchBloc, String, void>((appId, _) => AppWatchBloc(getIt<IAppWatch>(param1: appId)));
getIt.registerFactoryParam<AppWatchBloc, String, void>(
(appId, _) => AppWatchBloc(getIt<IAppWatch>(param1: appId)));
getIt.registerFactoryParam<ViewBloc, String, void>( getIt
(viewId, _) => ViewBloc(iViewImpl: getIt<IView>(param1: viewId))); .registerFactoryParam<ViewBloc, String, void>((viewId, _) => ViewBloc(iViewImpl: getIt<IView>(param1: viewId)));
getIt.registerFactoryParam<DocBloc, String, void>( getIt.registerFactoryParam<DocBloc, String, void>((docId, _) => DocBloc(iDocImpl: getIt<IDoc>(param1: docId)));
(docId, _) => DocBloc(iDocImpl: getIt<IDoc>(param1: docId)));
getIt.registerFactoryParam<DocEditBloc, String, void>( getIt.registerFactoryParam<DocEditBloc, String, void>((docId, _) => DocEditBloc(getIt<IDoc>(param1: docId)));
(docId, _) => DocEditBloc(getIt<IDoc>(param1: docId)));
// editor // editor
getIt.registerFactoryParam<ViewListBloc, List<View>, void>( getIt.registerFactoryParam<ViewListBloc, List<View>, void>((views, _) => ViewListBloc(views: views));
(views, _) => ViewListBloc(views: views));
getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>( getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
(user, _) => WelcomeBloc( (user, _) => WelcomeBloc(

View File

@ -77,7 +77,7 @@ class HomeScreen extends StatelessWidget {
final homeBloc = context.read<HomeBloc>(); final homeBloc = context.read<HomeBloc>();
Widget homeMenu = HomeMenu( Widget homeMenu = HomeMenu(
pageContextChanged: (pageContext) { pageContextChanged: (pageContext) {
getIt<HomePageStack>().setStackView(pageContext); getIt<HomeStack>().setStack(pageContext);
}, },
isCollapseChanged: (isCollapse) { isCollapseChanged: (isCollapse) {
homeBloc.add(HomeEvent.forceCollapse(isCollapse)); homeBloc.add(HomeEvent.forceCollapse(isCollapse));
@ -139,12 +139,12 @@ class HomePage extends StatelessWidget {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
getIt<HomePageStack>().stackTopBar(), getIt<HomeStack>().stackTopBar(),
Expanded( Expanded(
child: Container( child: Container(
color: Colors.white, color: Colors.white,
child: FocusTraversalGroup( child: FocusTraversalGroup(
child: getIt<HomePageStack>().stackWidget(), child: getIt<HomeStack>().stackWidget(),
), ),
), ),
), ),
@ -152,30 +152,3 @@ class HomePage extends StatelessWidget {
); );
} }
} }
// class HomeIndexStack extends StatelessWidget {
// const HomeIndexStack({Key? key}) : super(key: key);
// @override
// Widget build(BuildContext context) {
// return BlocBuilder<HomeBloc, HomeState>(
// buildWhen: (p, c) {
// if (p.pageContext != c.pageContext) {
// Log.info(
// 'PageContext switch from ${p.pageContext.pageType} to ${c.pageContext.pageType}');
// }
// return p.pageContext != c.pageContext;
// },
// builder: (context, state) {
// final pageContext = context.read<HomeBloc>().state.pageContext;
// return Expanded(
// child: Container(
// color: Colors.white,
// child: FocusTraversalGroup(
// child: getIt<FlowyHomeIndexStack>().indexStack(pageContext),
// ),
// ),
// );
// },
// );
// }
// }

View File

@ -14,17 +14,17 @@ abstract class NaviItem {
} }
class NavigationNotifier with ChangeNotifier { class NavigationNotifier with ChangeNotifier {
PageStackNotifier pageStackNotifier; HomeStackNotifier pageStackNotifier;
NavigationNotifier(this.pageStackNotifier); NavigationNotifier(this.pageStackNotifier);
void update(PageStackNotifier notifier) { void update(HomeStackNotifier notifier) {
pageStackNotifier = notifier; pageStackNotifier = notifier;
notifyListeners(); notifyListeners();
} }
List<NaviItem> get naviItems { List<NaviItem> get naviItems {
List<NaviItem> items = [ List<NaviItem> items = [
ViewNaviItemImpl(pageStackNotifier.view), ViewNaviItemImpl(pageStackNotifier.context),
// ViewNaviItemImpl(pageStackNotifier.view), // ViewNaviItemImpl(pageStackNotifier.view),
// ViewNaviItemImpl(pageStackNotifier.view), // ViewNaviItemImpl(pageStackNotifier.view),
// ViewNaviItemImpl(pageStackNotifier.view), // ViewNaviItemImpl(pageStackNotifier.view),
@ -35,14 +35,14 @@ class NavigationNotifier with ChangeNotifier {
} }
} }
class StyledNavigationList extends StatelessWidget { class FlowyNavigation extends StatelessWidget {
const StyledNavigationList({Key? key}) : super(key: key); const FlowyNavigation({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ChangeNotifierProxyProvider<PageStackNotifier, NavigationNotifier>( return ChangeNotifierProxyProvider<HomeStackNotifier, NavigationNotifier>(
create: (_) => NavigationNotifier( create: (_) => NavigationNotifier(
Provider.of<PageStackNotifier>( Provider.of<HomeStackNotifier>(
context, context,
listen: false, listen: false,
), ),
@ -63,9 +63,7 @@ class StyledNavigationList extends StatelessWidget {
Widget last = NaviItemWidget(newItems.removeLast()); Widget last = NaviItemWidget(newItems.removeLast());
List<Widget> widgets = List.empty(growable: true); List<Widget> widgets = List.empty(growable: true);
widgets.addAll(newItems widgets.addAll(newItems.map((item) => NaviItemDivider(child: NaviItemWidget(item))).toList());
.map((item) => NaviItemDivider(child: NaviItemWidget(item)))
.toList());
widgets.add(last); widgets.add(last);
return widgets; return widgets;

View File

@ -2,21 +2,30 @@ import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AnnouncementStackView extends HomeStackView { class DefaultHomeStackContext extends HomeStackContext {
const AnnouncementStackView() @override
: super(type: ViewType.Blank, title: 'Blank', identifier: "Announcement"); String get identifier => "1";
@override @override
List<Object> get props => []; List<Object?> get props => ["1"];
@override
String get title => "Blank page";
@override
ViewType get type => ViewType.Blank;
@override
Widget render() {
return const AnnouncementStackPage();
}
} }
class AnnouncementStackPage extends HomeStackWidget { class AnnouncementStackPage extends StatefulWidget {
const AnnouncementStackPage( const AnnouncementStackPage({Key? key}) : super(key: key);
{Key? key, required AnnouncementStackView stackView})
: super(key: key, stackView: stackView);
@override @override
State<StatefulWidget> createState() => _AnnouncementPage(); State<AnnouncementStackPage> createState() => _AnnouncementPage();
} }
class _AnnouncementPage extends State<AnnouncementStackPage> { class _AnnouncementPage extends State<AnnouncementStackPage> {

View File

@ -1,25 +1,23 @@
import 'dart:io'; import 'dart:io';
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/doc/doc_edit_bloc.dart'; import 'package:app_flowy/workspace/application/doc/doc_edit_bloc.dart';
import 'package:app_flowy/workspace/domain/i_doc.dart'; import 'package:app_flowy/workspace/domain/i_doc.dart';
// import 'package:flowy_editor/flowy_editor.dart';
import 'package:editor/flutter_quill.dart'; import 'package:editor/flutter_quill.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';
class DocPage extends StatefulWidget { class DocPage extends StatefulWidget {
late QuillController controller; final QuillController controller;
late DocEditBloc editBloc; final DocEditBloc editBloc;
final FlowyDoc doc; final FlowyDoc doc;
DocPage({Key? key, required this.doc}) : super(key: key) { DocPage({Key? key, required this.doc})
editBloc = getIt<DocEditBloc>(param1: doc.id); : controller = QuillController(
controller = QuillController(
document: doc.document, document: doc.document,
selection: const TextSelection.collapsed(offset: 0), selection: const TextSelection.collapsed(offset: 0),
); ),
} editBloc = getIt<DocEditBloc>(param1: doc.id),
super(key: key);
@override @override
State<DocPage> createState() => _DocPageState(); State<DocPage> createState() => _DocPageState();

View File

@ -1,7 +1,6 @@
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart'; import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart'; import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/doc/doc_page.dart';
import 'package:flowy_log/flowy_log.dart'; import 'package:flowy_log/flowy_log.dart';
import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_infra_ui/widget/error_page.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
@ -9,9 +8,31 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flowy_infra_ui/style_widget/progress_indicator.dart'; import 'package:flowy_infra_ui/style_widget/progress_indicator.dart';
class DocStackPage extends HomeStackWidget { import 'doc_page.dart';
const DocStackPage({Key? key, required DocPageStackView stackView})
: super(key: key, stackView: stackView); class DocStackContext extends HomeStackContext {
final View _view;
DocStackContext({required View view, Key? key}) : _view = view;
@override
String get title => _view.name;
@override
String get identifier => _view.id;
@override
ViewType get type => _view.viewType;
@override
List<Object?> get props => [_view.id];
@override
Widget render() {
return DocStackPage(_view, key: ValueKey(_view.id));
}
}
class DocStackPage extends StatefulWidget {
final View view;
const DocStackPage(this.view, {Key? key}) : super(key: key);
@override @override
_DocStackPageState createState() => _DocStackPageState(); _DocStackPageState createState() => _DocStackPageState();
@ -20,15 +41,12 @@ class DocStackPage extends HomeStackWidget {
class _DocStackPageState extends State<DocStackPage> { class _DocStackPageState extends State<DocStackPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final stackView = widget.stackView as DocPageStackView;
return MultiBlocProvider( return MultiBlocProvider(
providers: [ providers: [
BlocProvider<DocBloc>( BlocProvider<DocBloc>(
create: (context) => getIt<DocBloc>(param1: stackView.view.id) create: (context) => getIt<DocBloc>(param1: widget.view.id)..add(const DocEvent.loadDoc())),
..add(const DocEvent.loadDoc())),
], ],
child: BlocBuilder<DocBloc, DocState>(builder: (context, state) { child: BlocBuilder<DocBloc, DocState>(builder: (context, state) {
assert(widget.stackView is DocPageStackView);
return state.map( return state.map(
loading: (_) => const FlowyProgressIndicator(), loading: (_) => const FlowyProgressIndicator(),
loadDoc: (s) => DocPage(doc: s.doc), loadDoc: (s) => DocPage(doc: s.doc),
@ -56,16 +74,3 @@ class _DocStackPageState extends State<DocStackPage> {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
} }
} }
class DocPageStackView extends HomeStackView {
final View view;
DocPageStackView(this.view)
: super(
type: view.viewType,
title: view.name,
identifier: view.id,
);
@override
List<Object> get props => [view.id, type];
}

View File

@ -1,7 +0,0 @@
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:flutter/material.dart';
abstract class HomeStackPage extends StatefulWidget {
final HomeStackView pageContext;
const HomeStackPage({Key? key, required this.pageContext}) : super(key: key);
}

View File

@ -2,7 +2,7 @@ import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/domain/image.dart'; import 'package:app_flowy/workspace/domain/image.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart'; import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart'; import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
import 'package:app_flowy/workspace/presentation/home/navigation_list.dart'; import 'package:app_flowy/workspace/presentation/home/navigation.dart';
import 'package:flowy_infra_ui/widget/rounded_button.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
@ -13,7 +13,7 @@ import 'package:flowy_infra_ui/style_widget/extension.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
class HomeTopBar extends StatelessWidget { class HomeTopBar extends StatelessWidget {
final HomeStackView view; final HomeStackContext view;
const HomeTopBar({Key? key, required this.view}) : super(key: key); const HomeTopBar({Key? key, required this.view}) : super(key: key);
@override @override
@ -23,7 +23,7 @@ class HomeTopBar extends StatelessWidget {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
_renderNavigationList(view), _renderNavigation(view),
const Spacer(), const Spacer(),
_renderShareButton(), _renderShareButton(),
_renderMoreButton(), _renderMoreButton(),
@ -52,15 +52,14 @@ class HomeTopBar extends StatelessWidget {
Widget _renderMoreButton() { Widget _renderMoreButton() {
return ViewMoreButton( return ViewMoreButton(
width: 24,
onPressed: () { onPressed: () {
debugPrint('show more'); debugPrint('show more');
}, },
); );
} }
Widget _renderNavigationList(HomeStackView view) { Widget _renderNavigation(HomeStackContext view) {
return const StyledNavigationList(); return const FlowyNavigation();
} }
} }
@ -89,12 +88,12 @@ class HomeTitle extends StatelessWidget {
} }
class ViewNaviItemImpl extends NaviItem { class ViewNaviItemImpl extends NaviItem {
final HomeStackView view; final HomeStackContext view;
ViewNaviItemImpl(this.view); ViewNaviItemImpl(this.view);
@override @override
NaviAction get action => () => getIt<HomePageStack>().setStackView(view); NaviAction get action => () => getIt<HomeStack>().setStack(view);
@override @override
String get identifier => view.identifier; String get identifier => view.identifier;

View File

@ -20,7 +20,7 @@ import 'widget/app/app.dart';
import 'widget/app/create_button.dart'; import 'widget/app/create_button.dart';
class HomeMenu extends StatelessWidget { class HomeMenu extends StatelessWidget {
final Function(HomeStackView?) pageContextChanged; final Function(HomeStackContext) pageContextChanged;
final Function(bool) isCollapseChanged; final Function(bool) isCollapseChanged;
final UserProfile user; final UserProfile user;
final String workspaceId; final String workspaceId;
@ -46,8 +46,8 @@ class HomeMenu extends StatelessWidget {
child: MultiBlocListener( child: MultiBlocListener(
listeners: [ listeners: [
BlocListener<MenuBloc, MenuState>( BlocListener<MenuBloc, MenuState>(
listenWhen: (p, c) => p.stackView != c.stackView, listenWhen: (p, c) => p.context != c.context,
listener: (context, state) => pageContextChanged(state.stackView), listener: (context, state) => pageContextChanged(state.context),
), ),
BlocListener<MenuBloc, MenuState>( BlocListener<MenuBloc, MenuState>(
listenWhen: (p, c) => p.isCollapse != c.isCollapse, listenWhen: (p, c) => p.isCollapse != c.isCollapse,

View File

@ -11,19 +11,18 @@ 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/presentation/widgets/menu/menu_list.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'section/section.dart';
import 'view/view_list.dart';
class AppPageSize { class AppPageSize {
static double expandedIconSize = 16; static double expandedIconSize = 16;
static double expandedIconRightSpace = 6; static double expandedIconPadding = 6;
static double scale = 1; static double scale = 1;
static double get expandedPadding => expandedIconSize * scale + expandedIconRightSpace; static double get expandedPadding => expandedIconSize * scale + expandedIconPadding;
} }
class AppPageContext { class AppPageContext {
final App app; final App app;
final viewListData = ViewListData(); final viewListData = ViewSectionData();
AppPageContext( AppPageContext(
this.app, this.app,
@ -55,9 +54,9 @@ class AppPage extends MenuItem {
builder: (context, state) { builder: (context, state) {
final child = state.map( final child = state.map(
initial: (_) => BlocBuilder<AppBloc, AppState>( initial: (_) => BlocBuilder<AppBloc, AppState>(
builder: (context, state) => _renderViewList(state.views), builder: (context, state) => _renderViewSection(state.views),
), ),
loadViews: (s) => _renderViewList(s.views), loadViews: (s) => _renderViewSection(s.views),
loadFail: (s) => FlowyErrorPage(s.error.toString()), loadFail: (s) => FlowyErrorPage(s.error.toString()),
); );
@ -93,14 +92,14 @@ class AppPage extends MenuItem {
); );
} }
Widget _renderViewList(List<View>? views) { Widget _renderViewSection(List<View>? views) {
appCtx.viewListData.views = views ?? List.empty(growable: false); appCtx.viewListData.views = views ?? List.empty(growable: false);
return MultiProvider( return MultiProvider(
providers: [ providers: [
ChangeNotifierProvider.value(value: appCtx.viewListData), ChangeNotifierProvider.value(value: appCtx.viewListData),
], ],
child: Consumer(builder: (context, ViewListData notifier, child) { child: Consumer(builder: (context, ViewSectionData notifier, child) {
return ViewListPage(notifier.views).padding(vertical: 8); return ViewSection(notifier.views).padding(vertical: 8);
}), }),
); );
} }

View File

@ -1,7 +1,7 @@
import 'package:app_flowy/workspace/application/app/app_bloc.dart'; import 'package:app_flowy/workspace/application/app/app_bloc.dart';
import 'package:expandable/expandable.dart'; import 'package:expandable/expandable.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_infra/flowy_icon_data_icons.dart'; import 'package:flowy_infra/flowy_icon_data_icons.dart';
@ -9,6 +9,7 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/view_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 'app.dart'; import 'app.dart';
@ -43,7 +44,7 @@ class AppHeader extends StatelessWidget {
), ),
), ),
), ),
HSpace(AppPageSize.expandedIconRightSpace), HSpace(AppPageSize.expandedIconPadding),
Expanded( Expanded(
child: GestureDetector( child: GestureDetector(
onTapDown: (_) { onTapDown: (_) {
@ -55,21 +56,20 @@ class AppHeader extends StatelessWidget {
), ),
)), )),
// FlowyIconButton( ViewAddButton(
// icon: const Icon(Icons.add), onPressed: () {
// onPressed: () { debugPrint('add view');
// debugPrint('add view');
// FlowyOverlay.of(context) // FlowyOverlay.of(context)
// .insert(widget: Text('test'), identifier: 'identifier'); // .insert(widget: Text('test'), identifier: 'identifier');
// }, },
// ), ).padding(right: AppPageSize.expandedIconPadding),
PopupMenuButton( // PopupMenuButton(
iconSize: 16, // iconSize: 16,
tooltip: 'create new view', // tooltip: 'create new view',
icon: svg("home/add"), // icon: svg("home/add"),
padding: EdgeInsets.zero, // padding: EdgeInsets.zero,
onSelected: (viewType) => _createView(viewType as ViewType, context), // onSelected: (viewType) => _createView(viewType as ViewType, context),
itemBuilder: (context) => menuItemBuilder()) // itemBuilder: (context) => menuItemBuilder())
], ],
), ),
); );

View File

@ -20,11 +20,11 @@ class ViewWidgetContext {
typedef OpenViewCallback = void Function(View); typedef OpenViewCallback = void Function(View);
class ViewPage extends StatelessWidget { class ViewSectionItem extends StatelessWidget {
final ViewWidgetContext viewCtx; final ViewWidgetContext viewCtx;
final bool isSelected; final bool isSelected;
final OpenViewCallback onOpen; final OpenViewCallback onOpen;
ViewPage({Key? key, required this.viewCtx, required this.onOpen, required this.isSelected}) ViewSectionItem({Key? key, required this.viewCtx, required this.onOpen, required this.isSelected})
: super(key: viewCtx.valueKey()); : super(key: viewCtx.valueKey());
@override @override
@ -57,7 +57,6 @@ class ViewPage extends StatelessWidget {
if (onHover) { if (onHover) {
children.add(const Spacer()); children.add(const Spacer());
children.add(ViewMoreButton( children.add(ViewMoreButton(
width: 16,
onPressed: () { onPressed: () {
debugPrint('show view setting'); debugPrint('show view setting');
}, },
@ -67,7 +66,7 @@ class ViewPage extends StatelessWidget {
Widget widget = Container( Widget widget = Container(
child: Row(children: children).padding( child: Row(children: children).padding(
left: AppPageSize.expandedPadding, left: AppPageSize.expandedPadding,
right: 12, right: AppPageSize.expandedIconPadding,
), ),
height: 24, height: 24,
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,

View File

@ -6,12 +6,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart'; import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'item.dart';
import 'view_page.dart'; class ViewSectionData extends ChangeNotifier {
class ViewListData extends ChangeNotifier {
List<View>? innerViews; List<View>? innerViews;
ViewListData(); ViewSectionData();
set views(List<View> views) { set views(List<View> views) {
innerViews = views; innerViews = views;
@ -21,10 +20,10 @@ class ViewListData extends ChangeNotifier {
List<View> get views => innerViews ?? []; List<View> get views => innerViews ?? [];
} }
class ViewListNotifier with ChangeNotifier { class ViewSectionNotifier with ChangeNotifier {
List<View> innerViews; List<View> innerViews;
View? _selectedView; View? _selectedView;
ViewListNotifier(this.innerViews); ViewSectionNotifier(this.innerViews);
set views(List<View> views) => innerViews = views; set views(List<View> views) => innerViews = views;
List<View> get views => innerViews; List<View> get views => innerViews;
@ -36,51 +35,51 @@ class ViewListNotifier with ChangeNotifier {
View? get selectedView => _selectedView; View? get selectedView => _selectedView;
void update(ViewListData notifier) { void update(ViewSectionData notifier) {
innerViews = notifier.views; innerViews = notifier.views;
notifyListeners(); notifyListeners();
} }
} }
class ViewListPage extends StatelessWidget { class ViewSection extends StatelessWidget {
final List<View> views; final List<View> views;
const ViewListPage(this.views, {Key? key}) : super(key: key); const ViewSection(this.views, {Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// The ViewListNotifier will be updated after ViewListData changed passed by parent widget // The ViewListNotifier will be updated after ViewListData changed passed by parent widget
return ChangeNotifierProxyProvider<ViewListData, ViewListNotifier>( return ChangeNotifierProxyProvider<ViewSectionData, ViewSectionNotifier>(
create: (_) => ViewListNotifier( create: (_) => ViewSectionNotifier(
Provider.of<ViewListData>( Provider.of<ViewSectionData>(
context, context,
listen: false, listen: false,
).views, ).views,
), ),
update: (_, notifier, controller) => controller!..update(notifier), update: (_, notifier, controller) => controller!..update(notifier),
child: Consumer(builder: (context, ViewListNotifier notifier, child) { child: Consumer(builder: (context, ViewSectionNotifier notifier, child) {
return _renderViews(context, notifier.views); return _renderItems(context, notifier.views);
}), }),
); );
} }
Widget _renderViews(BuildContext context, List<View> views) { Widget _renderItems(BuildContext context, List<View> views) {
var viewWidgets = views.map((view) { var viewWidgets = views.map((view) {
final viewCtx = ViewWidgetContext(view); final viewCtx = ViewWidgetContext(view);
final viewWidget = ViewPage( final item = ViewSectionItem(
viewCtx: viewCtx, viewCtx: viewCtx,
isSelected: _isViewSelected(context, view.id), isSelected: _isViewSelected(context, view.id),
onOpen: (view) { onOpen: (view) {
Log.debug("Open view: $view"); Log.debug("Open view: $view");
context.read<ViewListNotifier>().setSelectedView(view); context.read<ViewSectionNotifier>().setSelectedView(view);
final stackView = stackViewFromView(viewCtx.view); final stackView = stackCtxFromView(viewCtx.view);
getIt<HomePageStack>().setStackView(stackView); getIt<HomeStack>().setStack(stackView);
}, },
); );
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 4), padding: const EdgeInsets.symmetric(vertical: 4),
child: viewWidget, child: item,
); );
}).toList(growable: false); }).toList(growable: false);
@ -90,7 +89,7 @@ class ViewListPage extends StatelessWidget {
} }
bool _isViewSelected(BuildContext context, String viewId) { bool _isViewSelected(BuildContext context, String viewId) {
final view = context.read<ViewListNotifier>().selectedView; final view = context.read<ViewSectionNotifier>().selectedView;
if (view != null) { if (view != null) {
return view.id == viewId; return view.id == viewId;
} else { } else {

View File

@ -1,14 +0,0 @@
import 'package:flutter/material.dart';
import '../menu_list.dart';
class MenuFav extends MenuItem {
@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
}
@override
// TODO: implement type
MenuItemType get type => throw UnimplementedError();
}

View File

@ -0,0 +1,14 @@
import 'package:flutter/material.dart';
import '../../menu_list.dart';
class FavoriteHeader extends MenuItem {
const FavoriteHeader({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
throw UnimplementedError();
}
@override
MenuItemType get type => MenuItemType.favorites;
}

View File

@ -1,7 +1,6 @@
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/menu/menu_user_bloc.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_list.dart';
import 'package:flowy_infra/image.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_profile.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -16,8 +15,7 @@ class MenuUser extends MenuItem {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider<MenuUserBloc>( return BlocProvider<MenuUserBloc>(
create: (context) => create: (context) => getIt<MenuUserBloc>(param1: user)..add(const MenuUserEvent.initial()),
getIt<MenuUserBloc>(param1: user)..add(const MenuUserEvent.initial()),
child: BlocBuilder<MenuUserBloc, MenuUserState>( child: BlocBuilder<MenuUserBloc, MenuUserState>(
builder: (context, state) => Row( builder: (context, state) => Row(
children: [ children: [
@ -56,10 +54,7 @@ class MenuUser extends MenuItem {
} }
Widget _renderDropButton(BuildContext context) { Widget _renderDropButton(BuildContext context) {
return FlowyIconButton( return FlowyDropdownButton(
width: 20,
iconRatio: 1.0,
icon: svg("home/drop_down_show"),
onPressed: () { onPressed: () {
debugPrint('show user profile'); debugPrint('show user profile');
}, },

View File

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

View File

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
class FlowyIconButton extends StatelessWidget { class FlowyIconButton extends StatelessWidget {
final double width; final double width;
final double? height; final double? height;
final double iconRatio;
final Widget icon; final Widget icon;
final VoidCallback? onPressed; final VoidCallback? onPressed;
@ -14,7 +13,6 @@ class FlowyIconButton extends StatelessWidget {
this.onPressed, this.onPressed,
this.width = 30, this.width = 30,
required this.icon, required this.icon,
this.iconRatio = 0.5,
}) : super(key: key); }) : super(key: key);
@override @override
@ -25,7 +23,7 @@ class FlowyIconButton extends StatelessWidget {
child: IconButton( child: IconButton(
icon: icon, icon: icon,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
iconSize: width * iconRatio, iconSize: width,
alignment: Alignment.center, alignment: Alignment.center,
onPressed: onPressed, onPressed: onPressed,
), ),
@ -33,25 +31,53 @@ class FlowyIconButton extends StatelessWidget {
} }
} }
class ViewMoreButton extends StatelessWidget { class FlowyDropdownButton extends StatelessWidget {
final double width;
final double? height;
final VoidCallback? onPressed; final VoidCallback? onPressed;
const FlowyDropdownButton({
const ViewMoreButton({
Key? key, Key? key,
this.height,
this.onPressed, this.onPressed,
required this.width,
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FlowyIconButton( return FlowyIconButton(
width: width, width: 16,
height: height,
icon: svg("editor/details"),
onPressed: onPressed, onPressed: onPressed,
icon: svg("home/drop_down_show"),
);
}
}
class ViewAddButton extends StatelessWidget {
final VoidCallback? onPressed;
const ViewAddButton({
Key? key,
this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return FlowyIconButton(
width: 16,
onPressed: onPressed,
icon: svg("home/add"),
);
}
}
class ViewMoreButton extends StatelessWidget {
final VoidCallback? onPressed;
const ViewMoreButton({
Key? key,
this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return FlowyIconButton(
width: 16,
onPressed: onPressed,
icon: svg("editor/details"),
); );
} }
} }