app_page.dart 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import 'package:expandable/expandable.dart';
  2. import 'package:flowy_infra_ui/widget/error_page.dart';
  3. import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
  4. import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter_bloc/flutter_bloc.dart';
  7. import 'package:app_flowy/startup/startup.dart';
  8. import 'package:app_flowy/workspace/application/app/app_bloc.dart';
  9. import 'package:app_flowy/workspace/application/app/app_watch_bloc.dart';
  10. import 'package:app_flowy/workspace/presentation/app/view_list_page.dart';
  11. import 'package:app_flowy/workspace/presentation/widgets/menu/menu_list.dart';
  12. import 'package:provider/provider.dart';
  13. import 'package:styled_widget/styled_widget.dart';
  14. import 'app_header.dart';
  15. class AppPageSize {
  16. static double expandedIconSize = 16;
  17. static double expandedIconRightSpace = 6;
  18. static double scale = 1;
  19. static double get expandedPadding => expandedIconSize * scale + expandedIconRightSpace;
  20. }
  21. class ViewListData extends ChangeNotifier {
  22. List<View>? innerViews;
  23. ViewListData();
  24. set views(List<View> views) {
  25. innerViews = views;
  26. notifyListeners();
  27. }
  28. List<View> get views => innerViews ?? [];
  29. }
  30. class AppPageContext {
  31. final App app;
  32. final viewListData = ViewListData();
  33. AppPageContext(
  34. this.app,
  35. );
  36. Key valueKey() => ValueKey("${app.id}${app.version}");
  37. }
  38. class AppPage extends MenuItem {
  39. final AppPageContext appCtx;
  40. AppPage(this.appCtx, {Key? key}) : super(key: appCtx.valueKey());
  41. @override
  42. Widget build(BuildContext context) {
  43. return MultiBlocProvider(
  44. providers: [
  45. BlocProvider<AppBloc>(create: (context) {
  46. final appBloc = getIt<AppBloc>(param1: appCtx.app.id);
  47. appBloc.add(const AppEvent.initial());
  48. return appBloc;
  49. }),
  50. BlocProvider<AppWatchBloc>(create: (context) {
  51. final watchBloc = getIt<AppWatchBloc>(param1: appCtx.app.id);
  52. watchBloc.add(const AppWatchEvent.started());
  53. return watchBloc;
  54. }),
  55. ],
  56. child: BlocBuilder<AppWatchBloc, AppWatchState>(
  57. builder: (context, state) {
  58. final child = state.map(
  59. initial: (_) => BlocBuilder<AppBloc, AppState>(
  60. builder: (context, state) => _renderViewList(state.views),
  61. ),
  62. loadViews: (s) => _renderViewList(s.views),
  63. loadFail: (s) => FlowyErrorPage(s.error.toString()),
  64. );
  65. return expandableWrapper(context, child);
  66. },
  67. ),
  68. );
  69. }
  70. ExpandableNotifier expandableWrapper(BuildContext context, Widget child) {
  71. return ExpandableNotifier(
  72. child: ScrollOnExpand(
  73. scrollOnExpand: true,
  74. scrollOnCollapse: false,
  75. child: Column(
  76. children: <Widget>[
  77. ExpandablePanel(
  78. theme: const ExpandableThemeData(
  79. headerAlignment: ExpandablePanelHeaderAlignment.center,
  80. tapBodyToExpand: false,
  81. tapBodyToCollapse: false,
  82. tapHeaderToExpand: false,
  83. iconPadding: EdgeInsets.zero,
  84. hasIcon: false,
  85. ),
  86. header: AppHeader(appCtx.app),
  87. expanded: child,
  88. collapsed: const SizedBox(),
  89. ),
  90. ],
  91. ),
  92. ),
  93. );
  94. }
  95. Widget _renderViewList(List<View>? views) {
  96. appCtx.viewListData.views = views ?? List.empty(growable: false);
  97. return MultiProvider(
  98. providers: [
  99. ChangeNotifierProvider.value(value: appCtx.viewListData),
  100. ],
  101. child: Consumer(builder: (context, ViewListData notifier, child) {
  102. return ViewListPage(notifier.views).padding(vertical: 8);
  103. }),
  104. );
  105. }
  106. @override
  107. MenuItemType get type => MenuItemType.app;
  108. }