mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: fix some bugs
This commit is contained in:
parent
4697acde48
commit
6c1bc2cbd9
@ -28,7 +28,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
||||
final viewOrFailed = await appManager.createView(name: value.name, desc: value.desc, viewType: value.viewType);
|
||||
yield viewOrFailed.fold(
|
||||
(view) => state.copyWith(
|
||||
selectedView: view,
|
||||
latestCreatedView: view,
|
||||
successOrFailure: left(unit),
|
||||
),
|
||||
(error) {
|
||||
@ -71,12 +71,12 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
||||
}
|
||||
|
||||
Stream<AppState> handleDidReceiveViews(List<View> views) async* {
|
||||
final selectedView = state.selectedView;
|
||||
final latestCreatedView = state.latestCreatedView;
|
||||
AppState newState = state.copyWith(views: views);
|
||||
if (selectedView != null) {
|
||||
final index = views.indexWhere((element) => element.id == selectedView.id);
|
||||
if (latestCreatedView != null) {
|
||||
final index = views.indexWhere((element) => element.id == latestCreatedView.id);
|
||||
if (index == -1) {
|
||||
newState = newState.copyWith(selectedView: null);
|
||||
newState = newState.copyWith(latestCreatedView: null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ class AppState with _$AppState {
|
||||
required App app,
|
||||
required bool isLoading,
|
||||
required List<View>? views,
|
||||
View? selectedView,
|
||||
View? latestCreatedView,
|
||||
required Either<Unit, WorkspaceError> successOrFailure,
|
||||
}) = _AppState;
|
||||
|
||||
@ -119,7 +119,7 @@ class AppState with _$AppState {
|
||||
app: app,
|
||||
isLoading: false,
|
||||
views: null,
|
||||
selectedView: null,
|
||||
latestCreatedView: null,
|
||||
successOrFailure: left(unit),
|
||||
);
|
||||
}
|
||||
|
@ -873,13 +873,13 @@ class _$AppStateTearOff {
|
||||
{required App app,
|
||||
required bool isLoading,
|
||||
required List<View>? views,
|
||||
View? selectedView,
|
||||
View? latestCreatedView,
|
||||
required Either<Unit, WorkspaceError> successOrFailure}) {
|
||||
return _AppState(
|
||||
app: app,
|
||||
isLoading: isLoading,
|
||||
views: views,
|
||||
selectedView: selectedView,
|
||||
latestCreatedView: latestCreatedView,
|
||||
successOrFailure: successOrFailure,
|
||||
);
|
||||
}
|
||||
@ -893,7 +893,7 @@ mixin _$AppState {
|
||||
App get app => throw _privateConstructorUsedError;
|
||||
bool get isLoading => throw _privateConstructorUsedError;
|
||||
List<View>? get views => throw _privateConstructorUsedError;
|
||||
View? get selectedView => throw _privateConstructorUsedError;
|
||||
View? get latestCreatedView => throw _privateConstructorUsedError;
|
||||
Either<Unit, WorkspaceError> get successOrFailure =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
||||
@ -910,7 +910,7 @@ abstract class $AppStateCopyWith<$Res> {
|
||||
{App app,
|
||||
bool isLoading,
|
||||
List<View>? views,
|
||||
View? selectedView,
|
||||
View? latestCreatedView,
|
||||
Either<Unit, WorkspaceError> successOrFailure});
|
||||
}
|
||||
|
||||
@ -927,7 +927,7 @@ class _$AppStateCopyWithImpl<$Res> implements $AppStateCopyWith<$Res> {
|
||||
Object? app = freezed,
|
||||
Object? isLoading = freezed,
|
||||
Object? views = freezed,
|
||||
Object? selectedView = freezed,
|
||||
Object? latestCreatedView = freezed,
|
||||
Object? successOrFailure = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
@ -943,9 +943,9 @@ class _$AppStateCopyWithImpl<$Res> implements $AppStateCopyWith<$Res> {
|
||||
? _value.views
|
||||
: views // ignore: cast_nullable_to_non_nullable
|
||||
as List<View>?,
|
||||
selectedView: selectedView == freezed
|
||||
? _value.selectedView
|
||||
: selectedView // ignore: cast_nullable_to_non_nullable
|
||||
latestCreatedView: latestCreatedView == freezed
|
||||
? _value.latestCreatedView
|
||||
: latestCreatedView // ignore: cast_nullable_to_non_nullable
|
||||
as View?,
|
||||
successOrFailure: successOrFailure == freezed
|
||||
? _value.successOrFailure
|
||||
@ -964,7 +964,7 @@ abstract class _$AppStateCopyWith<$Res> implements $AppStateCopyWith<$Res> {
|
||||
{App app,
|
||||
bool isLoading,
|
||||
List<View>? views,
|
||||
View? selectedView,
|
||||
View? latestCreatedView,
|
||||
Either<Unit, WorkspaceError> successOrFailure});
|
||||
}
|
||||
|
||||
@ -982,7 +982,7 @@ class __$AppStateCopyWithImpl<$Res> extends _$AppStateCopyWithImpl<$Res>
|
||||
Object? app = freezed,
|
||||
Object? isLoading = freezed,
|
||||
Object? views = freezed,
|
||||
Object? selectedView = freezed,
|
||||
Object? latestCreatedView = freezed,
|
||||
Object? successOrFailure = freezed,
|
||||
}) {
|
||||
return _then(_AppState(
|
||||
@ -998,9 +998,9 @@ class __$AppStateCopyWithImpl<$Res> extends _$AppStateCopyWithImpl<$Res>
|
||||
? _value.views
|
||||
: views // ignore: cast_nullable_to_non_nullable
|
||||
as List<View>?,
|
||||
selectedView: selectedView == freezed
|
||||
? _value.selectedView
|
||||
: selectedView // ignore: cast_nullable_to_non_nullable
|
||||
latestCreatedView: latestCreatedView == freezed
|
||||
? _value.latestCreatedView
|
||||
: latestCreatedView // ignore: cast_nullable_to_non_nullable
|
||||
as View?,
|
||||
successOrFailure: successOrFailure == freezed
|
||||
? _value.successOrFailure
|
||||
@ -1017,7 +1017,7 @@ class _$_AppState implements _AppState {
|
||||
{required this.app,
|
||||
required this.isLoading,
|
||||
required this.views,
|
||||
this.selectedView,
|
||||
this.latestCreatedView,
|
||||
required this.successOrFailure});
|
||||
|
||||
@override
|
||||
@ -1027,13 +1027,13 @@ class _$_AppState implements _AppState {
|
||||
@override
|
||||
final List<View>? views;
|
||||
@override
|
||||
final View? selectedView;
|
||||
final View? latestCreatedView;
|
||||
@override
|
||||
final Either<Unit, WorkspaceError> successOrFailure;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppState(app: $app, isLoading: $isLoading, views: $views, selectedView: $selectedView, successOrFailure: $successOrFailure)';
|
||||
return 'AppState(app: $app, isLoading: $isLoading, views: $views, latestCreatedView: $latestCreatedView, successOrFailure: $successOrFailure)';
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1047,9 +1047,9 @@ class _$_AppState implements _AppState {
|
||||
.equals(other.isLoading, isLoading)) &&
|
||||
(identical(other.views, views) ||
|
||||
const DeepCollectionEquality().equals(other.views, views)) &&
|
||||
(identical(other.selectedView, selectedView) ||
|
||||
(identical(other.latestCreatedView, latestCreatedView) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.selectedView, selectedView)) &&
|
||||
.equals(other.latestCreatedView, latestCreatedView)) &&
|
||||
(identical(other.successOrFailure, successOrFailure) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.successOrFailure, successOrFailure)));
|
||||
@ -1061,7 +1061,7 @@ class _$_AppState implements _AppState {
|
||||
const DeepCollectionEquality().hash(app) ^
|
||||
const DeepCollectionEquality().hash(isLoading) ^
|
||||
const DeepCollectionEquality().hash(views) ^
|
||||
const DeepCollectionEquality().hash(selectedView) ^
|
||||
const DeepCollectionEquality().hash(latestCreatedView) ^
|
||||
const DeepCollectionEquality().hash(successOrFailure);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@ -1075,7 +1075,7 @@ abstract class _AppState implements AppState {
|
||||
{required App app,
|
||||
required bool isLoading,
|
||||
required List<View>? views,
|
||||
View? selectedView,
|
||||
View? latestCreatedView,
|
||||
required Either<Unit, WorkspaceError> successOrFailure}) = _$_AppState;
|
||||
|
||||
@override
|
||||
@ -1085,7 +1085,7 @@ abstract class _AppState implements AppState {
|
||||
@override
|
||||
List<View>? get views => throw _privateConstructorUsedError;
|
||||
@override
|
||||
View? get selectedView => throw _privateConstructorUsedError;
|
||||
View? get latestCreatedView => throw _privateConstructorUsedError;
|
||||
@override
|
||||
Either<Unit, WorkspaceError> get successOrFailure =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
@ -8,16 +8,19 @@ import 'widget/style_widgets/style_widgets.dart';
|
||||
|
||||
DefaultStyles customStyles(BuildContext context) {
|
||||
const baseSpacing = Tuple2<double, double>(6, 0);
|
||||
|
||||
final theme = context.watch<AppTheme>();
|
||||
final themeData = theme.themeData;
|
||||
final fontFamily = makeFontFamily(themeData);
|
||||
|
||||
final defaultTextStyle = DefaultTextStyle.of(context);
|
||||
final baseStyle = defaultTextStyle.style.copyWith(
|
||||
fontSize: 18,
|
||||
height: 1.3,
|
||||
fontWeight: FontWeight.w300,
|
||||
letterSpacing: 0.6,
|
||||
fontFamily: fontFamily,
|
||||
);
|
||||
final theme = context.watch<AppTheme>();
|
||||
final themeData = theme.themeData;
|
||||
final fontFamily = makeFontFamily(themeData);
|
||||
|
||||
return DefaultStyles(
|
||||
h1: DefaultTextBlockStyle(
|
||||
@ -111,7 +114,7 @@ String makeFontFamily(ThemeData themeData) {
|
||||
switch (themeData.platform) {
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
fontFamily = 'Menlo';
|
||||
fontFamily = 'Mulish';
|
||||
break;
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
|
@ -5,8 +5,10 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.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-workspace/app_create.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
@ -58,7 +60,8 @@ class HomeMenu extends StatelessWidget {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<MenuBloc>(
|
||||
create: (context) => getIt<MenuBloc>(param1: user, param2: workspaceId)..add(const MenuEvent.initial())),
|
||||
create: (context) => getIt<MenuBloc>(param1: user, param2: workspaceId)..add(const MenuEvent.initial()),
|
||||
),
|
||||
],
|
||||
child: MultiBlocListener(
|
||||
listeners: [
|
||||
@ -91,7 +94,7 @@ class HomeMenu extends StatelessWidget {
|
||||
children: [
|
||||
_renderTopBar(context),
|
||||
const VSpace(32),
|
||||
_renderMenuList(context),
|
||||
_renderApps(context),
|
||||
],
|
||||
).padding(horizontal: Insets.l),
|
||||
),
|
||||
@ -104,9 +107,41 @@ class HomeMenu extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _renderMenuList(BuildContext context) {
|
||||
return MenuList(
|
||||
menuItems: buildMenuItems(context.read<MenuBloc>().state.apps),
|
||||
Widget _renderTopBar(BuildContext context) {
|
||||
return const MenuTopBar();
|
||||
}
|
||||
|
||||
Widget _renderApps(BuildContext context) {
|
||||
final apps = context.read<MenuBloc>().state.apps;
|
||||
List<Widget> menuItems = [];
|
||||
menuItems.add(MenuUser(user));
|
||||
List<MenuApp> appWidgets = apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(app)).toList());
|
||||
menuItems.addAll(appWidgets);
|
||||
|
||||
return ExpandableTheme(
|
||||
data: ExpandableThemeData(useInkWell: true, animationDuration: Durations.medium),
|
||||
child: Expanded(
|
||||
child: ScrollConfiguration(
|
||||
behavior: const ScrollBehavior().copyWith(scrollbars: false),
|
||||
child: ChangeNotifierProvider(
|
||||
create: (_) => MenuSharedState(),
|
||||
child: ListView.separated(
|
||||
itemCount: menuItems.length,
|
||||
separatorBuilder: (context, index) {
|
||||
if (index == 0) {
|
||||
return const VSpace(29);
|
||||
} else {
|
||||
return VSpace(MenuAppSizes.appVPadding);
|
||||
}
|
||||
},
|
||||
physics: StyledScrollPhysics(),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return menuItems[index];
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -119,62 +154,40 @@ class HomeMenu extends StatelessWidget {
|
||||
press: (appName) => context.read<MenuBloc>().add(MenuEvent.createApp(appName, desc: "")),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _renderTopBar(BuildContext context) {
|
||||
return const MenuTopBar();
|
||||
class MenuSharedState extends ChangeNotifier {
|
||||
View? _view;
|
||||
View? _forcedOpenView;
|
||||
|
||||
void addForcedOpenViewListener(void Function(View) callback) {
|
||||
super.addListener(() {
|
||||
if (_forcedOpenView != null) {
|
||||
callback(_forcedOpenView!);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
List<MenuItem> buildMenuItems(Option<List<App>> apps) {
|
||||
List<MenuItem> items = [];
|
||||
items.add(MenuUser(user));
|
||||
|
||||
List<MenuItem> appWidgets = apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(app)).toList());
|
||||
|
||||
items.addAll(appWidgets);
|
||||
return items;
|
||||
void addSelectedViewListener(void Function(View?) callback) {
|
||||
super.addListener(() {
|
||||
callback(_view);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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: ScrollConfiguration(
|
||||
behavior: const ScrollBehavior().copyWith(scrollbars: false),
|
||||
child: ListView.separated(
|
||||
itemCount: menuItems.length,
|
||||
separatorBuilder: (context, index) {
|
||||
if (index == 0) {
|
||||
return const VSpace(29);
|
||||
} else {
|
||||
return VSpace(MenuAppSizes.appVPadding);
|
||||
}
|
||||
},
|
||||
physics: StyledScrollPhysics(),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return menuItems[index];
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
set forcedOpenView(View? view) {
|
||||
if (_forcedOpenView != view) {
|
||||
_forcedOpenView = view;
|
||||
selectedView = view;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
set selectedView(View? view) {
|
||||
if (_view != view) {
|
||||
_view = view;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
View? get selecedtView => _view;
|
||||
}
|
||||
|
@ -66,30 +66,35 @@ class MenuAppHeader extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _renderTitle(BuildContext context) {
|
||||
return BlocSelector<AppBloc, AppState, App>(
|
||||
selector: (state) => state.app,
|
||||
builder: (context, state) {
|
||||
return Expanded(
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
ExpandableController.of(context, rebuildOnChange: false, required: true)?.toggle();
|
||||
},
|
||||
onSecondaryTap: () {
|
||||
final actionList = AppDisclosureActions(onSelected: (action) => _handleAction(context, action));
|
||||
actionList.show(
|
||||
context,
|
||||
context,
|
||||
anchorDirection: AnchorDirection.bottomWithCenterAligned,
|
||||
);
|
||||
},
|
||||
child: FlowyText.medium(
|
||||
state.name,
|
||||
return Expanded(
|
||||
child: BlocListener<AppBloc, AppState>(
|
||||
listenWhen: (p, c) => (p.latestCreatedView == null && c.latestCreatedView != null),
|
||||
listener: (context, state) {
|
||||
final expandableController = ExpandableController.of(context, rebuildOnChange: false, required: true)!;
|
||||
if (!expandableController.expanded) {
|
||||
expandableController.toggle();
|
||||
}
|
||||
},
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () => ExpandableController.of(context, rebuildOnChange: false, required: true)?.toggle(),
|
||||
onSecondaryTap: () {
|
||||
final actionList = AppDisclosureActions(onSelected: (action) => _handleAction(context, action));
|
||||
actionList.show(
|
||||
context,
|
||||
context,
|
||||
anchorDirection: AnchorDirection.bottomWithCenterAligned,
|
||||
);
|
||||
},
|
||||
child: BlocSelector<AppBloc, AppState, App>(
|
||||
selector: (state) => state.app,
|
||||
builder: (context, app) => FlowyText.medium(
|
||||
app.name,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/header/header.dart';
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
||||
@ -6,24 +7,28 @@ 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/presentation/widgets/menu/menu.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'section/section.dart';
|
||||
|
||||
class MenuApp extends MenuItem {
|
||||
class MenuApp extends StatefulWidget {
|
||||
final App app;
|
||||
final notifier = AppDataNotifier();
|
||||
|
||||
MenuApp(this.app, {Key? key}) : super(key: ValueKey("${app.id}${app.version}"));
|
||||
|
||||
@override
|
||||
State<MenuApp> createState() => _MenuAppState();
|
||||
}
|
||||
|
||||
class _MenuAppState extends State<MenuApp> {
|
||||
final notifier = AppDataNotifier();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<AppBloc>(
|
||||
create: (context) {
|
||||
final appBloc = getIt<AppBloc>(param1: app);
|
||||
final appBloc = getIt<AppBloc>(param1: widget.app);
|
||||
appBloc.add(const AppEvent.initial());
|
||||
return appBloc;
|
||||
},
|
||||
@ -31,7 +36,9 @@ class MenuApp extends MenuItem {
|
||||
],
|
||||
child: BlocSelector<AppBloc, AppState, AppDataNotifier>(
|
||||
selector: (state) {
|
||||
notifier.selectView = state.selectedView;
|
||||
if (state.latestCreatedView != null) {
|
||||
Provider.of<MenuSharedState>(context, listen: false).forcedOpenView = state.latestCreatedView;
|
||||
}
|
||||
notifier.views = state.views;
|
||||
return notifier;
|
||||
},
|
||||
@ -58,7 +65,7 @@ class MenuApp extends MenuItem {
|
||||
iconPadding: EdgeInsets.zero,
|
||||
hasIcon: false,
|
||||
),
|
||||
header: MenuAppHeader(app),
|
||||
header: MenuAppHeader(widget.app),
|
||||
expanded: child,
|
||||
collapsed: const SizedBox(),
|
||||
),
|
||||
@ -76,9 +83,6 @@ class MenuApp extends MenuItem {
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
MenuItemType get type => MenuItemType.app;
|
||||
}
|
||||
|
||||
class MenuAppSizes {
|
||||
@ -93,7 +97,6 @@ class MenuAppSizes {
|
||||
|
||||
class AppDataNotifier extends ChangeNotifier {
|
||||
List<View> _views = [];
|
||||
View? _selectedView;
|
||||
AppDataNotifier();
|
||||
|
||||
set views(List<View>? items) {
|
||||
@ -111,14 +114,5 @@ class AppDataNotifier extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
set selectView(View? view) {
|
||||
if (_selectedView != view) {
|
||||
_selectedView = view;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
get selectedView => _selectedView;
|
||||
|
||||
List<View> get views => _views;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -11,58 +12,6 @@ import 'package:styled_widget/styled_widget.dart';
|
||||
import 'item.dart';
|
||||
import 'package:async/async.dart';
|
||||
|
||||
class ViewSectionNotifier with ChangeNotifier {
|
||||
List<View> _views;
|
||||
View? _selectedView;
|
||||
CancelableOperation? _notifyListenerOperation;
|
||||
ViewSectionNotifier(List<View> views) : _views = views;
|
||||
|
||||
set views(List<View> views) {
|
||||
if (_views != views) {
|
||||
_views = views;
|
||||
_notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
List<View> get views => _views;
|
||||
|
||||
set selectView(View? view) {
|
||||
if (_selectedView == view) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (view != null) {
|
||||
_selectedView = view;
|
||||
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
getIt<HomeStackManager>().setStack(view.stackContext());
|
||||
});
|
||||
|
||||
_notifyListeners();
|
||||
} else {
|
||||
// WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
// getIt<HomeStackManager>().setStack(BlankStackContext());
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
View? get selectedView => _selectedView;
|
||||
|
||||
void update(AppDataNotifier notifier) {
|
||||
views = notifier.views;
|
||||
selectView = notifier.selectedView;
|
||||
}
|
||||
|
||||
void _notifyListeners() {
|
||||
_notifyListenerOperation?.cancel();
|
||||
_notifyListenerOperation = CancelableOperation.fromFuture(
|
||||
Future.delayed(const Duration(milliseconds: 30), () {}),
|
||||
).then((_) {
|
||||
notifyListeners();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ViewSection extends StatelessWidget {
|
||||
const ViewSection({Key? key}) : super(key: key);
|
||||
|
||||
@ -72,7 +21,7 @@ class ViewSection extends StatelessWidget {
|
||||
return ChangeNotifierProxyProvider<AppDataNotifier, ViewSectionNotifier>(
|
||||
create: (_) {
|
||||
final views = Provider.of<AppDataNotifier>(context, listen: false).views;
|
||||
return ViewSectionNotifier(views);
|
||||
return ViewSectionNotifier(views, context);
|
||||
},
|
||||
update: (_, notifier, controller) => controller!..update(notifier),
|
||||
child: Consumer(builder: (context, ViewSectionNotifier notifier, child) {
|
||||
@ -87,7 +36,8 @@ class ViewSection extends StatelessWidget {
|
||||
view: view,
|
||||
isSelected: _isViewSelected(context, view.id),
|
||||
onSelected: (view) {
|
||||
context.read<ViewSectionNotifier>().selectView = view;
|
||||
context.read<ViewSectionNotifier>().selectedView = view;
|
||||
Provider.of<MenuSharedState>(context, listen: false).selectedView = view;
|
||||
},
|
||||
).padding(vertical: 4),
|
||||
);
|
||||
@ -103,3 +53,61 @@ class ViewSection extends StatelessWidget {
|
||||
return view.id == viewId;
|
||||
}
|
||||
}
|
||||
|
||||
class ViewSectionNotifier with ChangeNotifier {
|
||||
List<View> _views;
|
||||
View? _selectedView;
|
||||
CancelableOperation? _notifyListenerOperation;
|
||||
ViewSectionNotifier(List<View> views, BuildContext context) : _views = views {
|
||||
final menuSharedState = Provider.of<MenuSharedState>(context, listen: false);
|
||||
menuSharedState.addForcedOpenViewListener((forcedOpenView) {
|
||||
selectedView = forcedOpenView;
|
||||
});
|
||||
|
||||
menuSharedState.addSelectedViewListener((currentSelectedView) {
|
||||
if (currentSelectedView != selectedView) {
|
||||
selectedView = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
set views(List<View> views) {
|
||||
if (_views != views) {
|
||||
_views = views;
|
||||
_notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
List<View> get views => _views;
|
||||
|
||||
set selectedView(View? view) {
|
||||
if (_selectedView == view) {
|
||||
return;
|
||||
}
|
||||
_selectedView = view;
|
||||
_notifyListeners();
|
||||
|
||||
if (view != null) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
getIt<HomeStackManager>().setStack(view.stackContext());
|
||||
});
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
View? get selectedView => _selectedView;
|
||||
|
||||
void update(AppDataNotifier notifier) {
|
||||
views = notifier.views;
|
||||
}
|
||||
|
||||
void _notifyListeners() {
|
||||
_notifyListenerOperation?.cancel();
|
||||
_notifyListenerOperation = CancelableOperation.fromFuture(
|
||||
Future.delayed(const Duration(milliseconds: 30), () {}),
|
||||
).then((_) {
|
||||
notifyListeners();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../menu.dart';
|
||||
|
||||
class FavoriteHeader extends MenuItem {
|
||||
class FavoriteHeader extends StatelessWidget {
|
||||
const FavoriteHeader({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
MenuItemType get type => MenuItemType.favorites;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
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.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
@ -9,11 +8,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||
|
||||
class MenuUser extends MenuItem {
|
||||
class MenuUser extends StatelessWidget {
|
||||
final UserProfile user;
|
||||
MenuUser(this.user, {Key? key}) : super(key: ValueKey(user.id));
|
||||
@override
|
||||
MenuItemType get type => MenuItemType.userProfile;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -43,6 +43,7 @@ class FlowyText extends StatelessWidget {
|
||||
color: textColor,
|
||||
fontWeight: fontWeight,
|
||||
fontSize: fontSize + 2,
|
||||
fontFamily: 'Mulish',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user