From 188302d4ba5eda194dac82b1aa4bd623f07a6eb0 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 22 Mar 2022 20:51:15 +0800 Subject: [PATCH] chore: config field editor --- .../app_flowy/assets/images/grid/delete.svg | 6 + .../assets/images/grid/duplicate.svg | 4 + .../app_flowy/assets/images/grid/hide.svg | 4 + .../app_flowy/assets/images/grid/left.svg | 5 + .../app_flowy/assets/images/grid/right.svg | 5 + .../app_flowy/assets/translations/en.json | 9 + .../lib/startup/home_deps_resolver.dart | 15 +- .../lib/user/presentation/sign_in_screen.dart | 4 +- .../lib/user/presentation/sign_up_screen.dart | 6 +- .../grid/cell_bloc/cell_service.dart | 2 +- .../application/grid/column_bloc.dart | 42 ---- .../application/grid/column_service.dart | 1 - .../grid/field/field_edit_bloc.dart | 58 +++++ .../application/grid/field/field_service.dart | 1 + .../grid/field/grid_header_bloc.dart | 42 ++++ .../workspace/application/grid/prelude.dart | 9 +- .../application/grid/{ => row}/row_bloc.dart | 2 +- .../grid/{ => row}/row_listener.dart | 0 .../grid/{ => row}/row_service.dart | 2 +- .../plugins/grid/src/layout/sizes.dart | 5 + .../src/widgets/content/cell_builder.dart | 2 +- .../src/widgets/content/checkbox_cell.dart | 3 +- .../grid/src/widgets/content/date_cell.dart | 3 +- .../grid/src/widgets/content/number_cell.dart | 3 +- .../grid/src/widgets/content/text_cell.dart | 4 +- .../grid/src/widgets/header/field_editor.dart | 207 ++++++++++++++++++ .../grid/src/widgets/header/header.dart | 8 +- .../grid/src/widgets/header/header_cell.dart | 41 +--- .../presentation/widgets/pop_up_window.dart | 5 +- .../lib/src/flowy_overlay/flowy_overlay.dart | 2 + .../lib/src/flowy_overlay/list_overlay.dart | 39 ++-- .../src/flowy_overlay/overlay_container.dart | 30 +++ .../lib/style_widget/hover.dart | 17 +- .../lib/widget/rounded_input_field.dart | 109 +++++---- .../lib/widget/text_field_container.dart | 40 ---- frontend/app_flowy/pubspec.yaml | 1 + 36 files changed, 504 insertions(+), 232 deletions(-) create mode 100644 frontend/app_flowy/assets/images/grid/delete.svg create mode 100644 frontend/app_flowy/assets/images/grid/duplicate.svg create mode 100644 frontend/app_flowy/assets/images/grid/hide.svg create mode 100644 frontend/app_flowy/assets/images/grid/left.svg create mode 100644 frontend/app_flowy/assets/images/grid/right.svg delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/column_service.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart rename frontend/app_flowy/lib/workspace/application/grid/{ => row}/row_bloc.dart (97%) rename frontend/app_flowy/lib/workspace/application/grid/{ => row}/row_listener.dart (100%) rename frontend/app_flowy/lib/workspace/application/grid/{ => row}/row_service.dart (93%) create mode 100644 frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart delete mode 100644 frontend/app_flowy/packages/flowy_infra_ui/lib/widget/text_field_container.dart diff --git a/frontend/app_flowy/assets/images/grid/delete.svg b/frontend/app_flowy/assets/images/grid/delete.svg new file mode 100644 index 0000000000..fcfbf2f6dd --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/delete.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/app_flowy/assets/images/grid/duplicate.svg b/frontend/app_flowy/assets/images/grid/duplicate.svg new file mode 100644 index 0000000000..f11048fd2f --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/duplicate.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/hide.svg b/frontend/app_flowy/assets/images/grid/hide.svg new file mode 100644 index 0000000000..dfb6dbb90c --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/hide.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/app_flowy/assets/images/grid/left.svg b/frontend/app_flowy/assets/images/grid/left.svg new file mode 100644 index 0000000000..0f771a3858 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/left.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/app_flowy/assets/images/grid/right.svg b/frontend/app_flowy/assets/images/grid/right.svg new file mode 100644 index 0000000000..7d738f4e69 --- /dev/null +++ b/frontend/app_flowy/assets/images/grid/right.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 7717e71229..27574db94e 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -141,5 +141,14 @@ "lightLabel": "Light Mode", "darkLabel": "Dark Mode" } + }, + "grid": { + "field": { + "hide": "Hide", + "insertLeft": "Insert Left", + "insertRight": "Insert Right", + "duplicate": "Duplicate", + "delete": "Delete" + } } } diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 2dcf6ca077..688c53ad2a 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -3,7 +3,7 @@ import 'package:app_flowy/user/application/user_service.dart'; import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:app_flowy/workspace/application/grid/row_listener.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_listener.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; import 'package:app_flowy/workspace/application/workspace/prelude.dart'; import 'package:app_flowy/workspace/application/view/prelude.dart'; @@ -101,10 +101,17 @@ class HomeDepsResolver { ), ); - getIt.registerFactoryParam, void>( - (data, _) => ColumnBloc( + getIt.registerFactoryParam, void>( + (data, _) => GridHeaderBloc( data: GridColumnData(fields: data), - service: ColumnService(), + service: FieldService(), + ), + ); + + getIt.registerFactoryParam( + (field, _) => FieldEditBloc( + field: field, + service: FieldService(), ), ); diff --git a/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart b/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart index f7afa0b4d3..8124241cf4 100644 --- a/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart +++ b/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart @@ -174,7 +174,7 @@ class PasswordTextField extends StatelessWidget { obscureHideIcon: svg("home/show"), hintText: LocaleKeys.signIn_passwordHint.tr(), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.passwordError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignInEvent.passwordChanged(value)), @@ -199,7 +199,7 @@ class EmailTextField extends StatelessWidget { hintText: LocaleKeys.signIn_emailHint.tr(), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.emailError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignInEvent.emailChanged(value)), diff --git a/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart b/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart index 931ccff516..06d4db6da2 100644 --- a/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart +++ b/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart @@ -139,7 +139,7 @@ class PasswordTextField extends StatelessWidget { style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), hintText: LocaleKeys.signUp_passwordHint.tr(), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.passwordError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignUpEvent.passwordChanged(value)), @@ -167,7 +167,7 @@ class RepeatPasswordTextField extends StatelessWidget { style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), hintText: LocaleKeys.signUp_repeatPasswordHint.tr(), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.repeatPasswordError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignUpEvent.repeatPasswordChanged(value)), @@ -192,7 +192,7 @@ class EmailTextField extends StatelessWidget { hintText: LocaleKeys.signUp_emailHint.tr(), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), normalBorderColor: theme.shader4, - highlightBorderColor: theme.red, + errorBorderColor: theme.red, cursorColor: theme.main1, errorText: context.read().state.emailError.fold(() => "", (error) => error), onChanged: (value) => context.read().add(SignUpEvent.emailChanged(value)), diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index 44cf86e5d2..79b4d2cf52 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart deleted file mode 100644 index 39badc922a..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'dart:async'; -import 'column_service.dart'; -import 'data.dart'; - -part 'column_bloc.freezed.dart'; - -class ColumnBloc extends Bloc { - final ColumnService service; - final GridColumnData data; - - ColumnBloc({required this.data, required this.service}) : super(ColumnState.initial(data.fields)) { - on( - (event, emit) async { - await event.map( - initial: (_InitialColumn value) async {}, - createColumn: (_CreateColumn value) {}, - ); - }, - ); - } - - @override - Future close() async { - return super.close(); - } -} - -@freezed -abstract class ColumnEvent with _$ColumnEvent { - const factory ColumnEvent.initial() = _InitialColumn; - const factory ColumnEvent.createColumn() = _CreateColumn; -} - -@freezed -abstract class ColumnState with _$ColumnState { - const factory ColumnState({required List fields}) = _ColumnState; - - factory ColumnState.initial(List fields) => ColumnState(fields: fields); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_service.dart b/frontend/app_flowy/lib/workspace/application/grid/column_service.dart deleted file mode 100644 index c074dcf616..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/column_service.dart +++ /dev/null @@ -1 +0,0 @@ -class ColumnService {} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart new file mode 100644 index 0000000000..2d4aea16da --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_edit_bloc.dart @@ -0,0 +1,58 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field_service.dart'; + +part 'field_edit_bloc.freezed.dart'; + +class FieldEditBloc extends Bloc { + final FieldService service; + + FieldEditBloc({required Field field, required this.service}) : super(FieldEditState.initial(field)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialField value) {}, + createField: (_CreateField value) {}, + updateFieldName: (_UpdateFieldName value) { + // + }, + hideField: (_HideField value) {}, + deleteField: (_DeleteField value) {}, + insertField: (_InsertField value) {}, + duplicateField: (_DuplicateField value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class FieldEditEvent with _$FieldEditEvent { + const factory FieldEditEvent.initial() = _InitialField; + const factory FieldEditEvent.createField() = _CreateField; + const factory FieldEditEvent.updateFieldName(String name) = _UpdateFieldName; + const factory FieldEditEvent.hideField() = _HideField; + const factory FieldEditEvent.duplicateField() = _DuplicateField; + const factory FieldEditEvent.insertField({required bool onLeft}) = _InsertField; + const factory FieldEditEvent.deleteField() = _DeleteField; +} + +@freezed +class FieldEditState with _$FieldEditState { + const factory FieldEditState({ + required Field field, + required String errorText, + }) = _FieldEditState; + + factory FieldEditState.initial(Field field) => FieldEditState( + field: field, + errorText: '', + ); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart new file mode 100644 index 0000000000..48d4aa21bd --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -0,0 +1 @@ +class FieldService {} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart new file mode 100644 index 0000000000..fd22d7a505 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart @@ -0,0 +1,42 @@ +import 'package:app_flowy/workspace/application/grid/data.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; +import 'field_service.dart'; + +part 'grid_header_bloc.freezed.dart'; + +class GridHeaderBloc extends Bloc { + final FieldService service; + final GridColumnData data; + + GridHeaderBloc({required this.data, required this.service}) : super(GridHeaderState.initial(data.fields)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialHeader value) async {}, + createField: (_CreateField value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class GridHeaderEvent with _$GridHeaderEvent { + const factory GridHeaderEvent.initial() = _InitialHeader; + const factory GridHeaderEvent.createField() = _CreateField; +} + +@freezed +class GridHeaderState with _$GridHeaderState { + const factory GridHeaderState({required List fields}) = _GridHeaderState; + + factory GridHeaderState.initial(List fields) => GridHeaderState(fields: fields); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index d28df04c62..3190ced75d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -1,10 +1,11 @@ export 'grid_bloc.dart'; -export 'row_bloc.dart'; -export 'row_service.dart'; +export 'row/row_bloc.dart'; +export 'row/row_service.dart'; export 'grid_service.dart'; export 'data.dart'; -export 'column_service.dart'; -export 'column_bloc.dart'; +export 'field/field_service.dart'; +export 'field/grid_header_bloc.dart'; +export 'field/field_edit_bloc.dart'; export 'cell_bloc/text_cell_bloc.dart'; export 'cell_bloc/number_cell_bloc.dart'; export 'cell_bloc/selection_cell_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart similarity index 97% rename from frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index 67fcc5cbc2..a30bea39ee 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -1,9 +1,9 @@ +import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'grid_service.dart'; import 'row_listener.dart'; import 'row_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/application/grid/row_listener.dart rename to frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart similarity index 93% rename from frontend/app_flowy/lib/workspace/application/grid/row_service.dart rename to frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 013ae3fb1c..6819a9a40e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -3,7 +3,7 @@ import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'grid_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; class RowService { final GridRowData rowData; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index 0daca272b6..e94507ab52 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -21,6 +21,11 @@ class GridSize { vertical: GridSize.cellContentPadding, ); + static EdgeInsets get fieldContentInsets => EdgeInsets.symmetric( + horizontal: GridSize.cellContentPadding, + vertical: GridSize.cellContentPadding, + ); + static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB( 0, GridSize.headerContainerPadding, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 187a81c1bc..7aa412589e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index eec381914a..2f067ab1fa 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index 5d9f452c78..5d69783fc5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index ea3f70fed3..0402b85b12 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 937c5d84ab..d3a9e88c2e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,8 +1,6 @@ import 'dart:async'; - import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/row_service.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index 8b13789179..531d83a1f3 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -1 +1,208 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/rounded_input_field.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:app_flowy/generated/locale_keys.g.dart'; +class FieldEditor extends StatelessWidget { + final Field field; + const FieldEditor({required this.field, Key? key}) : super(key: key); + + static void show(BuildContext context, Field field) { + final editor = FieldEditor(field: field); + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer(child: editor), + identifier: editor.identifier(), + anchorContext: context, + anchorDirection: AnchorDirection.bottomWithLeftAligned, + style: FlowyOverlayStyle(blur: false), + ); + } + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocProvider( + create: (context) => getIt(param1: field)..add(const FieldEditEvent.initial()), + child: Container( + color: theme.surface, + constraints: BoxConstraints.loose(const Size(300, 200)), + child: SingleChildScrollView( + child: Column(children: [ + const FieldNameTextField(), + // FieldTypeSwitcher(), + const VSpace(10), + FieldOperationList( + onTap: () { + FlowyOverlay.of(context).remove(identifier()); + }, + ), + ]), + ), + ), + ); + } + + String identifier() { + return toString(); + } +} + +class FieldNameTextField extends StatelessWidget { + const FieldNameTextField({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return BlocBuilder( + buildWhen: ((previous, current) => previous.field.name == current.field.name), + builder: (context, state) { + return RoundedInputField( + height: 36, + style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), + initialValue: state.field.name, + normalBorderColor: theme.shader4, + errorBorderColor: theme.red, + focusBorderColor: theme.main1, + cursorColor: theme.main1, + errorText: state.errorText, + onChanged: (value) { + context.read().add(FieldEditEvent.updateFieldName(value)); + }, + ); + }, + ); + } +} + +class FieldTypeSwitcher extends StatelessWidget { + const FieldTypeSwitcher({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return FlowyButton( + text: FlowyText.medium(context.read().state.field.name, fontSize: 12), + hoverColor: theme.hover, + onTap: () {}, + leftIcon: svg("editor/details", color: theme.iconColor), + ); + } +} + +class FieldOperationList extends StatelessWidget { + final VoidCallback onTap; + const FieldOperationList({required this.onTap, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final children = FieldAction.values + .map((action) => FieldActionItem( + action: action, + onTap: onTap, + )) + .toList(); + return GridView( + // https://api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html + shrinkWrap: true, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 4.0, + mainAxisSpacing: 8, + ), + children: children, + ); + } +} + +class FieldActionItem extends StatelessWidget { + final VoidCallback onTap; + final FieldAction action; + const FieldActionItem({required this.action, required this.onTap, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyButton( + text: FlowyText.medium(action.title(), fontSize: 12), + hoverColor: theme.hover, + onTap: () { + action.run(context); + onTap(); + }, + leftIcon: svg(action.iconName(), color: theme.iconColor), + ); + } +} + +enum FieldAction { + hide, + insertLeft, + duplicate, + insertRight, + delete, +} + +extension _FieldActionExtension on FieldAction { + String iconName() { + switch (this) { + case FieldAction.hide: + return 'grid/hide'; + case FieldAction.insertLeft: + return 'grid/left'; + case FieldAction.insertRight: + return 'grid/right'; + case FieldAction.duplicate: + return 'grid/duplicate'; + case FieldAction.delete: + return 'grid/delete'; + } + } + + String title() { + switch (this) { + case FieldAction.hide: + return LocaleKeys.grid_field_hide.tr(); + case FieldAction.insertLeft: + return LocaleKeys.grid_field_insertLeft.tr(); + case FieldAction.insertRight: + return LocaleKeys.grid_field_insertRight.tr(); + case FieldAction.duplicate: + return LocaleKeys.grid_field_duplicate.tr(); + case FieldAction.delete: + return LocaleKeys.grid_field_delete.tr(); + } + } + + void run(BuildContext context) { + final bloc = context.read(); + + switch (this) { + case FieldAction.hide: + bloc.add(const FieldEditEvent.hideField()); + break; + case FieldAction.insertLeft: + bloc.add(const FieldEditEvent.insertField(onLeft: true)); + break; + case FieldAction.insertRight: + bloc.add(const FieldEditEvent.insertField(onLeft: false)); + break; + case FieldAction.duplicate: + bloc.add(const FieldEditEvent.duplicateField()); + break; + case FieldAction.delete: + bloc.add(const FieldEditEvent.deleteField()); + break; + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index a9fb91bb00..40f6a3e3b0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -1,5 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/column_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -44,8 +44,8 @@ class GridHeader extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return BlocProvider( - create: (context) => getIt(param1: fields)..add(const ColumnEvent.initial()), - child: BlocBuilder( + create: (context) => getIt(param1: fields)..add(const GridHeaderEvent.initial()), + child: BlocBuilder( builder: (context, state) { final headers = state.fields .map( @@ -111,7 +111,7 @@ class CreateColumnButton extends StatelessWidget { return FlowyButton( text: const FlowyText.medium('New column', fontSize: 12), hoverColor: theme.hover, - onTap: () => context.read().add(const ColumnEvent.createColumn()), + onTap: () => context.read().add(const GridHeaderEvent.createField()), leftIcon: svg("home/add"), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 4e870ae27d..fa8a3692c5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -1,5 +1,5 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/widgets/pop_up_window.dart'; + import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; @@ -8,6 +8,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'field_editor.dart'; + class HeaderCell extends StatelessWidget { final Field field; const HeaderCell(this.field, {Key? key}) : super(key: key); @@ -16,44 +18,17 @@ class HeaderCell extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return FlowyButton( - text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(field.name, fontSize: 12)), + text: Padding( + padding: GridSize.cellContentInsets, + child: FlowyText.medium(field.name, fontSize: 12), + ), hoverColor: theme.hover, - onTap: () { - FlowyPoppuWindow.show( - context, - size: Size(300, 100), - child: CusTextField(), - ); - - // StyledDialog( - // child: SingleChildScrollView( - // child: Container( - // color: Colors.red, - // child: TextField(), - // ), - // ), - // ).show(context); - }, + onTap: () => FieldEditor.show(context, field), rightIcon: svg("editor/details", color: theme.iconColor), ); } } -class CusTextField extends StatelessWidget { - const CusTextField({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return Container( - color: theme.bg3, - child: TextField( - decoration: InputDecoration(hintText: 'Please enter a text'), - onSubmitted: print, - )); - } -} - class HeaderCellContainer extends StatelessWidget { final HeaderCell child; final double width; diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart index bea342747b..1803257672 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_window.dart @@ -22,10 +22,7 @@ class FlowyPoppuWindow extends StatelessWidget { }) async { final window = await getWindowInfo(); FlowyOverlay.of(context).insertWithRect( - widget: SizedBox.fromSize( - size: size, - child: FlowyPoppuWindow(child: child), - ), + widget: FlowyPoppuWindow(child: child), identifier: 'FlowyPoppuWindow', anchorPosition: Offset(-size.width / 2.0, -size.height / 2.0), anchorSize: window.frame.size, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart index 11ec524ed4..26760dc411 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart @@ -5,6 +5,8 @@ import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart'; import 'package:flutter/material.dart'; import 'dart:ui'; +export './overlay_container.dart'; + /// Specifies how overlay are anchored to the SourceWidget enum AnchorDirection { // Corner aligned with a corner of the SourceWidget diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart index b83c454322..6c0a4019d1 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart @@ -35,36 +35,29 @@ class ListOverlay extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = context.watch(); const padding = EdgeInsets.symmetric(horizontal: 6, vertical: 6); double totalHeight = height + padding.vertical; if (footer != null) { totalHeight = totalHeight + footer!.height + footer!.padding.vertical; } - return Material( - type: MaterialType.transparency, - child: Container( - decoration: FlowyDecoration.decoration(theme.surface, theme.shadowColor.withOpacity(0.1)), - constraints: BoxConstraints.tight(Size(width, totalHeight)), - child: Padding( - padding: padding, - child: Column( - children: [ - ListView.builder( - shrinkWrap: true, - itemBuilder: itemBuilder, - itemCount: itemCount, - controller: controller, - ), - if (footer != null) - Padding( - padding: footer!.padding, - child: footer!.widget, - ), - ], + return OverlayContainer( + constraints: BoxConstraints.tight(Size(width, totalHeight)), + padding: padding, + child: Column( + children: [ + ListView.builder( + shrinkWrap: true, + itemBuilder: itemBuilder, + itemCount: itemCount, + controller: controller, ), - ), + if (footer != null) + Padding( + padding: footer!.padding, + child: footer!.widget, + ), + ], ), ); } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart new file mode 100644 index 0000000000..bee123d248 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_container.dart @@ -0,0 +1,30 @@ +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/decoration.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class OverlayContainer extends StatelessWidget { + final Widget child; + final BoxConstraints? constraints; + final EdgeInsets padding; + const OverlayContainer({ + required this.child, + this.constraints, + this.padding = const EdgeInsets.all(12), + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return Material( + type: MaterialType.transparency, + child: Container( + padding: padding, + decoration: FlowyDecoration.decoration(theme.surface, theme.shadowColor.withOpacity(0.1)), + constraints: constraints, + child: child, + ), + ); + } +} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart index a85867e456..b19578fe54 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flowy_infra/time/duration.dart'; typedef HoverBuilder = Widget Function(BuildContext context, bool onHover); - typedef IsOnSelected = bool Function(); class FlowyHover extends StatefulWidget { @@ -29,23 +28,20 @@ class _FlowyHoverState extends State { Widget build(BuildContext context) { return MouseRegion( cursor: SystemMouseCursors.click, - onEnter: (p) => setOnHover(true), - onExit: (p) => setOnHover(false), + onEnter: (p) => setState(() => _onHover = true), + onExit: (p) => setState(() => _onHover = false), child: render(), ); } - void setOnHover(bool value) => setState(() => _onHover = value); - Widget render() { var showHover = _onHover; - - if (showHover == false && widget.isOnSelected != null) { + if (!showHover && widget.isOnSelected != null) { showHover = widget.isOnSelected!(); } if (showHover) { - return FlowyHoverBackground( + return FlowyHoverContainer( config: widget.config, child: widget.builder(context, _onHover), ); @@ -68,12 +64,11 @@ class HoverDisplayConfig { required this.hoverColor}); } -class FlowyHoverBackground extends StatelessWidget { +class FlowyHoverContainer extends StatelessWidget { final HoverDisplayConfig config; - final Widget child; - const FlowyHoverBackground({ + const FlowyHoverContainer({ Key? key, required this.child, required this.config, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart index e6e9684854..0cd2265cce 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart @@ -1,85 +1,105 @@ import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; -import 'package:flowy_infra_ui/widget/text_field_container.dart'; import 'package:flutter/material.dart'; import 'package:flowy_infra/time/duration.dart'; -// ignore: must_be_immutable class RoundedInputField extends StatefulWidget { final String? hintText; - final IconData? icon; final bool obscureText; final Widget? obscureIcon; final Widget? obscureHideIcon; final Color normalBorderColor; - final Color highlightBorderColor; + final Color errorBorderColor; final Color cursorColor; + final Color? focusBorderColor; final String errorText; final TextStyle style; final ValueChanged? onChanged; final String? initialValue; - late bool enableObscure; - var _text = ""; + final EdgeInsets margin; + final EdgeInsets padding; + final EdgeInsets contentPadding; + final double height; - RoundedInputField({ + const RoundedInputField({ Key? key, this.hintText, this.errorText = "", this.initialValue, - this.icon, this.obscureText = false, this.obscureIcon, this.obscureHideIcon, this.onChanged, this.normalBorderColor = Colors.transparent, - this.highlightBorderColor = Colors.transparent, + this.errorBorderColor = Colors.transparent, + this.focusBorderColor, this.cursorColor = Colors.black, this.style = const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), - }) : super(key: key) { - enableObscure = obscureText; - } + this.margin = EdgeInsets.zero, + this.padding = EdgeInsets.zero, + this.contentPadding = const EdgeInsets.symmetric(horizontal: 10), + this.height = 48, + }) : super(key: key); @override State createState() => _RoundedInputFieldState(); } class _RoundedInputFieldState extends State { + String inputText = ""; + bool obscuteText = false; + + @override + void initState() { + obscuteText = widget.obscureText; + super.initState(); + } + @override Widget build(BuildContext context) { - final Icon? newIcon = widget.icon == null - ? null - : Icon( - widget.icon!, - color: const Color(0xFF6F35A5), - ); - var borderColor = widget.normalBorderColor; + var focusBorderColor = widget.focusBorderColor ?? borderColor; + if (widget.errorText.isNotEmpty) { - borderColor = widget.highlightBorderColor; + borderColor = widget.errorBorderColor; + focusBorderColor = borderColor; } List children = [ - TextFieldContainer( - height: 48, - borderRadius: Corners.s10Border, - borderColor: borderColor, + Container( + margin: widget.margin, + padding: widget.padding, + height: widget.height, child: TextFormField( initialValue: widget.initialValue, onChanged: (value) { - widget._text = value; + inputText = value; if (widget.onChanged != null) { widget.onChanged!(value); } setState(() {}); }, cursorColor: widget.cursorColor, - obscureText: widget.enableObscure, + obscureText: obscuteText, decoration: InputDecoration( - icon: newIcon, + contentPadding: widget.contentPadding, hintText: widget.hintText, hintStyle: TextStyle(color: widget.normalBorderColor), - border: InputBorder.none, - suffixIcon: suffixIcon(), + border: OutlineInputBorder( + borderSide: BorderSide( + color: borderColor, + width: 1.0, + ), + borderRadius: Corners.s10Border, + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: focusBorderColor, + width: 1.0, + ), + borderRadius: Corners.s10Border, + ), + suffixIcon: obscureIcon(), ), ), ), @@ -100,39 +120,32 @@ class _RoundedInputFieldState extends State { return AnimatedSize( duration: .4.seconds, curve: Curves.easeInOut, - child: Column( - children: children, - ), + child: Column(children: children), ); } - Widget? suffixIcon() { + Widget? obscureIcon() { if (widget.obscureText == false) { return null; } - if (widget._text.isEmpty) { - return SizedBox.fromSize(size: const Size.square(16)); + const double iconWidth = 16; + if (inputText.isEmpty) { + return SizedBox.fromSize(size: const Size.square(iconWidth)); } + assert(widget.obscureIcon != null && widget.obscureHideIcon != null); Widget? icon; - if (widget.obscureText == true) { - assert(widget.obscureIcon != null && widget.obscureHideIcon != null); - if (widget.enableObscure) { - icon = widget.obscureIcon!; - } else { - icon = widget.obscureHideIcon!; - } - } - - if (icon == null) { - return null; + if (obscuteText) { + icon = widget.obscureIcon!; + } else { + icon = widget.obscureHideIcon!; } return RoundedImageButton( - size: 16, + size: iconWidth, press: () { - widget.enableObscure = !widget.enableObscure; + obscuteText = !obscuteText; setState(() {}); }, child: icon, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/text_field_container.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/text_field_container.dart deleted file mode 100644 index 7c1bf131a1..0000000000 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/widget/text_field_container.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -class TextFieldContainer extends StatelessWidget { - final Widget child; - final BorderRadius borderRadius; - final Color borderColor; - final double? height; - final double? width; - const TextFieldContainer({ - Key? key, - required this.child, - this.borderRadius = BorderRadius.zero, - this.borderColor = Colors.white, - this.height, - this.width, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - margin: const EdgeInsets.symmetric(vertical: 10), - padding: const EdgeInsets.symmetric(horizontal: 15), - height: height, - width: width, - decoration: BoxDecoration( - border: Border.all(color: borderColor), - color: Colors.white, - borderRadius: borderRadius, - ), - child: Align(alignment: Alignment.center, child: child), - ); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(DiagnosticsProperty('child', child)); - } -} diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index 41ee902083..61b69b45f1 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -111,6 +111,7 @@ flutter: - assets/images/ - assets/images/home/ - assets/images/editor/ + - assets/images/grid/ - assets/translations/ # - images/a_dot_ham.jpeg