chore: dart code cleanup (#4484)

* chore: use when instead of map in bloc event dispatch

* chore: dart code formatting, remove white space

* chore: remove unneeded hashmap for cell context

* fix: rebuild card content
This commit is contained in:
Richard Shiue
2024-01-25 12:26:18 +08:00
committed by GitHub
parent a1abcd7626
commit 6591d5de52
19 changed files with 88 additions and 99 deletions

View File

@ -160,7 +160,9 @@ class MobileHiddenGroup extends StatelessWidget {
final cells = group.rows.map( final cells = group.rows.map(
(item) { (item) {
final cellContext = final cellContext =
databaseController.rowCache.loadCells(item)[primaryField.id]!; databaseController.rowCache.loadCells(item).firstWhere(
(cellContext) => cellContext.fieldId == primaryField.id,
);
return TextButton( return TextButton(
style: TextButton.styleFrom( style: TextButton.styleFrom(

View File

@ -29,7 +29,8 @@ class SelectOptionCellBackendService {
final payload = RepeatedSelectOptionPayload() final payload = RepeatedSelectOptionPayload()
..viewId = viewId ..viewId = viewId
..fieldId = fieldId ..fieldId = fieldId
..rowId = rowId..items.add(option); ..rowId = rowId
..items.add(option);
return DatabaseEventInsertOrUpdateSelectOption(payload).send(); return DatabaseEventInsertOrUpdateSelectOption(payload).send();
}, },

View File

@ -8,7 +8,6 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'cell/cell_controller.dart';
import 'field/field_info.dart'; import 'field/field_info.dart';
import 'row/row_cache.dart'; import 'row/row_cache.dart';
import 'row/row_service.dart'; import 'row/row_service.dart';
@ -34,8 +33,6 @@ typedef OnNumOfRowsChanged = void Function(
typedef OnError = void Function(FlowyError); typedef OnError = void Function(FlowyError);
typedef CellContextByFieldId = LinkedHashMap<String, CellContext>;
@freezed @freezed
class LoadingState with _$LoadingState { class LoadingState with _$LoadingState {
const factory LoadingState.idle() = _Idle; const factory LoadingState.idle() = _Idle;

View File

@ -168,7 +168,11 @@ class FieldBackendService {
Future<Either<Unit, FlowyError>> updateType({ Future<Either<Unit, FlowyError>> updateType({
required FieldType fieldType, required FieldType fieldType,
}) { }) {
return updateFieldType(viewId: viewId, fieldId: fieldId, fieldType: fieldType); return updateFieldType(
viewId: viewId,
fieldId: fieldId,
fieldType: fieldType,
);
} }
Future<Either<Unit, FlowyError>> delete() { Future<Either<Unit, FlowyError>> delete() {

View File

@ -8,7 +8,6 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import '../cell/cell_cache.dart'; import '../cell/cell_cache.dart';
import '../cell/cell_controller.dart'; import '../cell/cell_controller.dart';
import '../defines.dart';
import 'row_list.dart'; import 'row_list.dart';
import 'row_service.dart'; import 'row_service.dart';
@ -189,7 +188,7 @@ class RowCache {
RowUpdateCallback addListener({ RowUpdateCallback addListener({
required RowId rowId, required RowId rowId,
void Function(CellContextByFieldId, ChangedReason)? onRowChanged, void Function(List<CellContext>, ChangedReason)? onRowChanged,
}) { }) {
void listenerHandler() async { void listenerHandler() async {
if (onRowChanged != null) { if (onRowChanged != null) {
@ -209,7 +208,7 @@ class RowCache {
_changedNotifier.removeListener(callback); _changedNotifier.removeListener(callback);
} }
CellContextByFieldId loadCells(RowMetaPB rowMeta) { List<CellContext> loadCells(RowMetaPB rowMeta) {
final rowInfo = _rowList.get(rowMeta.id); final rowInfo = _rowList.get(rowMeta.id);
if (rowInfo == null) { if (rowInfo == null) {
_loadRow(rowMeta.id); _loadRow(rowMeta.id);
@ -241,16 +240,15 @@ class RowCache {
); );
} }
CellContextByFieldId _makeCells(RowMetaPB rowMeta) { List<CellContext> _makeCells(RowMetaPB rowMeta) {
// TODO(RS): no need to use HashMap return _fieldDelegate.fieldInfos
final cellContextMap = CellContextByFieldId(); .map(
for (final fieldInfo in _fieldDelegate.fieldInfos) { (fieldInfo) => CellContext(
cellContextMap[fieldInfo.id] = CellContext(
rowId: rowMeta.id, rowId: rowMeta.id,
fieldId: fieldInfo.id, fieldId: fieldInfo.id,
); ),
} )
return cellContextMap; .toList();
} }
RowInfo buildGridRow(RowMetaPB rowMetaPB) { RowInfo buildGridRow(RowMetaPB rowMetaPB) {

View File

@ -2,10 +2,10 @@ import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../cell/cell_cache.dart'; import '../cell/cell_cache.dart';
import '../defines.dart'; import '../cell/cell_controller.dart';
import 'row_cache.dart'; import 'row_cache.dart';
typedef OnRowChanged = void Function(CellContextByFieldId, ChangedReason); typedef OnRowChanged = void Function(List<CellContext>, ChangedReason);
class RowController { class RowController {
final RowMetaPB rowMeta; final RowMetaPB rowMeta;
@ -25,7 +25,7 @@ class RowController {
this.groupId, this.groupId,
}) : _rowCache = rowCache; }) : _rowCache = rowCache;
CellContextByFieldId loadData() { List<CellContext> loadData() {
return _rowCache.loadCells(rowMeta); return _rowCache.loadCells(rowMeta);
} }

View File

@ -386,7 +386,9 @@ class HiddenGroupPopupItemList extends StatelessWidget {
context.read<BoardBloc>().databaseController; context.read<BoardBloc>().databaseController;
return HiddenGroupPopupItem( return HiddenGroupPopupItem(
cellContext: rowCache.loadCells(item)[primaryFieldId]!, cellContext: rowCache.loadCells(item).firstWhere(
(cellContext) => cellContext.fieldId == primaryFieldId,
),
rowController: rowController, rowController: rowController,
rowMeta: item, rowMeta: item,
cellBuilder: CardCellBuilder( cellBuilder: CardCellBuilder(

View File

@ -30,7 +30,6 @@ class CalendarEventEditorBloc
.id; .id;
final cells = rowController final cells = rowController
.loadData() .loadData()
.values
.where( .where(
(cellContext) => (cellContext) =>
_filterCellContext(cellContext, primaryFieldId), _filterCellContext(cellContext, primaryFieldId),
@ -61,7 +60,7 @@ class CalendarEventEditorBloc
final primaryFieldId = fieldController.fieldInfos final primaryFieldId = fieldController.fieldInfos
.firstWhere((fieldInfo) => fieldInfo.isPrimary) .firstWhere((fieldInfo) => fieldInfo.isPrimary)
.id; .id;
final cellData = cells.values final cellData = cells
.where( .where(
(cellContext) => _filterCellContext(cellContext, primaryFieldId), (cellContext) => _filterCellContext(cellContext, primaryFieldId),
) )

View File

@ -1,8 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection';
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
import 'package:appflowy/plugins/database/application/defines.dart';
import 'package:appflowy/plugins/database/application/field/field_controller.dart'; import 'package:appflowy/plugins/database/application/field/field_controller.dart';
import 'package:appflowy/plugins/database/widgets/setting/field_visibility_extension.dart'; import 'package:appflowy/plugins/database/widgets/setting/field_visibility_extension.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -48,17 +46,19 @@ class RowBloc extends Bloc<RowEvent, RowState> {
createRow: () { createRow: () {
_rowBackendSvc.createRowAfter(rowId); _rowBackendSvc.createRowAfter(rowId);
}, },
didReceiveCells: (CellContextByFieldId cellByFieldId, reason) { didReceiveCells: (List<CellContext> cellContexts, reason) {
cellByFieldId.removeWhere( final visibleCellContexts = cellContexts
(_, cellContext) => !fieldController .where(
(cellContext) => fieldController
.getField(cellContext.fieldId)! .getField(cellContext.fieldId)!
.fieldSettings! .fieldSettings!
.visibility .visibility
.isVisibleState(), .isVisibleState(),
); )
.toList();
emit( emit(
state.copyWith( state.copyWith(
cellByFieldId: cellByFieldId, cellContexts: visibleCellContexts,
changeReason: reason, changeReason: reason,
), ),
); );
@ -92,7 +92,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
class RowEvent with _$RowEvent { class RowEvent with _$RowEvent {
const factory RowEvent.createRow() = _CreateRow; const factory RowEvent.createRow() = _CreateRow;
const factory RowEvent.didReceiveCells( const factory RowEvent.didReceiveCells(
CellContextByFieldId cellsByFieldId, List<CellContext> cellsByFieldId,
ChangedReason reason, ChangedReason reason,
) = _DidReceiveCells; ) = _DidReceiveCells;
} }
@ -100,13 +100,13 @@ class RowEvent with _$RowEvent {
@freezed @freezed
class RowState with _$RowState { class RowState with _$RowState {
const factory RowState({ const factory RowState({
required CellContextByFieldId cellByFieldId, required List<CellContext> cellContexts,
ChangedReason? changeReason, ChangedReason? changeReason,
}) = _RowState; }) = _RowState;
factory RowState.initial() { factory RowState.initial() {
return RowState( return const RowState(
cellByFieldId: CellContextByFieldId(), cellContexts: [],
changeReason: null, changeReason: null,
); );
} }

View File

@ -92,7 +92,7 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
return; return;
} }
allCells.clear(); allCells.clear();
allCells.addAll(cellMap.values); allCells.addAll(cellMap);
int numHiddenFields = 0; int numHiddenFields = 0;
final visibleCells = <CellContext>[]; final visibleCells = <CellContext>[];
@ -125,7 +125,7 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
} }
void _init() { void _init() {
allCells.addAll(rowController.loadData().values); allCells.addAll(rowController.loadData());
int numHiddenFields = 0; int numHiddenFields = 0;
final visibleCells = <CellContext>[]; final visibleCells = <CellContext>[];
for (final cell in allCells) { for (final cell in allCells) {

View File

@ -1,6 +1,6 @@
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
import 'package:appflowy/plugins/database/application/database_controller.dart'; import 'package:appflowy/plugins/database/application/database_controller.dart';
import 'package:appflowy/plugins/database/application/defines.dart';
import 'package:appflowy/plugins/database/application/field/field_controller.dart'; import 'package:appflowy/plugins/database/application/field/field_controller.dart';
import 'package:appflowy/plugins/database/application/row/row_cache.dart'; import 'package:appflowy/plugins/database/application/row/row_cache.dart';
import 'package:appflowy/plugins/database/application/row/row_controller.dart'; import 'package:appflowy/plugins/database/application/row/row_controller.dart';
@ -130,7 +130,7 @@ class RowContent extends StatelessWidget {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
..._makeCells(context, state.cellByFieldId), ..._makeCells(context, state.cellContexts),
_finalCellDecoration(context), _finalCellDecoration(context),
], ],
), ),
@ -141,9 +141,9 @@ class RowContent extends StatelessWidget {
List<Widget> _makeCells( List<Widget> _makeCells(
BuildContext context, BuildContext context,
CellContextByFieldId cellByFieldId, List<CellContext> cellContexts,
) { ) {
return cellByFieldId.values.map( return cellContexts.map(
(cellContext) { (cellContext) {
final fieldInfo = fieldController.getField(cellContext.fieldId)!; final fieldInfo = fieldController.getField(cellContext.fieldId)!;
final EditableCellWidget child = builder.buildStyled( final EditableCellWidget child = builder.buildStyled(

View File

@ -1,8 +1,8 @@
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import "package:appflowy/generated/locale_keys.g.dart"; import "package:appflowy/generated/locale_keys.g.dart";
import 'package:appflowy/plugins/database/application/defines.dart';
import 'package:appflowy/plugins/database/application/field/field_controller.dart'; import 'package:appflowy/plugins/database/application/field/field_controller.dart';
import 'package:appflowy/plugins/database/application/row/row_controller.dart'; import 'package:appflowy/plugins/database/application/row/row_controller.dart';
import 'package:appflowy/plugins/database/application/row/row_service.dart'; import 'package:appflowy/plugins/database/application/row/row_service.dart';
@ -229,7 +229,7 @@ class RowContent extends StatelessWidget {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
..._makeCells(context, state.cellByFieldId), ..._makeCells(context, state.cellContexts),
_finalCellDecoration(context), _finalCellDecoration(context),
], ],
), ),
@ -240,9 +240,9 @@ class RowContent extends StatelessWidget {
List<Widget> _makeCells( List<Widget> _makeCells(
BuildContext context, BuildContext context,
CellContextByFieldId cellByFieldId, List<CellContext> cellContexts,
) { ) {
return cellByFieldId.values.map( return cellContexts.map(
(cellContext) { (cellContext) {
final fieldInfo = fieldController.getField(cellContext.fieldId)!; final fieldInfo = fieldController.getField(cellContext.fieldId)!;
final EditableCellWidget child = cellBuilder.buildStyled( final EditableCellWidget child = cellBuilder.buildStyled(

View File

@ -10,7 +10,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flutter/foundation.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';
@ -107,17 +106,6 @@ class _RowCardState extends State<RowCard> {
return BlocProvider.value( return BlocProvider.value(
value: _cardBloc, value: _cardBloc,
child: BlocBuilder<CardBloc, CardState>( child: BlocBuilder<CardBloc, CardState>(
buildWhen: (previous, current) {
// Rebuild when:
// 1. If the length of the cells is not the same or isEditing changed
if (previous.cells.length != current.cells.length ||
previous.isEditing != current.isEditing) {
return true;
}
// 2. the content of the cells changed
return !listEquals(previous.cells, current.cells);
},
builder: (context, state) => builder: (context, state) =>
PlatformExtension.isMobile ? _mobile(state) : _desktop(state), PlatformExtension.isMobile ? _mobile(state) : _desktop(state),
), ),

View File

@ -1,7 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
import 'package:appflowy/plugins/database/application/defines.dart';
import 'package:appflowy/plugins/database/application/field/field_controller.dart'; import 'package:appflowy/plugins/database/application/field/field_controller.dart';
import 'package:appflowy/plugins/database/application/row/row_cache.dart'; import 'package:appflowy/plugins/database/application/row/row_cache.dart';
import 'package:appflowy/plugins/database/application/row/row_listener.dart'; import 'package:appflowy/plugins/database/application/row/row_listener.dart';
@ -103,16 +102,16 @@ class CardBloc extends Bloc<CardEvent, CardState> {
List<CellContext> _makeCells( List<CellContext> _makeCells(
FieldController fieldController, FieldController fieldController,
String? groupFieldId, String? groupFieldId,
CellContextByFieldId cellMap, List<CellContext> cellContexts,
) { ) {
// Only show the non-hidden cells and cells that aren't of the grouping field // Only show the non-hidden cells and cells that aren't of the grouping field
cellMap.removeWhere((_, cellContext) { cellContexts.removeWhere((cellContext) {
final fieldInfo = fieldController.getField(cellContext.fieldId); final fieldInfo = fieldController.getField(cellContext.fieldId);
return fieldInfo == null || return fieldInfo == null ||
!fieldInfo.fieldSettings!.visibility.isVisibleState() || !fieldInfo.fieldSettings!.visibility.isVisibleState() ||
(groupFieldId != null && cellContext.fieldId == groupFieldId); (groupFieldId != null && cellContext.fieldId == groupFieldId);
}); });
return cellMap.values.toList(); return cellContexts.toList();
} }
@freezed @freezed

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database/application/cell/select_option_cell_service.dart';
import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
@ -8,8 +9,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import '../../../../application/cell/select_option_cell_service.dart';
part 'select_option_editor_bloc.freezed.dart'; part 'select_option_editor_bloc.freezed.dart';
class SelectOptionCellEditorBloc class SelectOptionCellEditorBloc
@ -29,47 +28,47 @@ class SelectOptionCellEditorBloc
super(SelectOptionEditorState.initial(cellController)) { super(SelectOptionEditorState.initial(cellController)) {
on<SelectOptionEditorEvent>( on<SelectOptionEditorEvent>(
(event, emit) async { (event, emit) async {
await event.map( await event.when(
initial: (_Initial value) async { initial: () async {
_startListening(); _startListening();
await _loadOptions(); await _loadOptions();
}, },
didReceiveOptions: (_DidReceiveOptions value) { didReceiveOptions: (options, selectedOptions) {
final result = _makeOptions(state.filter, value.options); final result = _makeOptions(state.filter, options);
emit( emit(
state.copyWith( state.copyWith(
allOptions: value.options, allOptions: options,
options: result.options, options: result.options,
createOption: result.createOption, createOption: result.createOption,
selectedOptions: value.selectedOptions, selectedOptions: selectedOptions,
), ),
); );
}, },
newOption: (_NewOption value) async { newOption: (optionName) async {
await _createOption(value.optionName); await _createOption(optionName);
emit( emit(
state.copyWith( state.copyWith(
filter: none(), filter: none(),
), ),
); );
}, },
deleteOption: (_DeleteOption value) async { deleteOption: (option) async {
await _deleteOption([value.option]); await _deleteOption([option]);
}, },
deleteAllOptions: (_DeleteAllOptions value) async { deleteAllOptions: () async {
if (state.allOptions.isNotEmpty) { if (state.allOptions.isNotEmpty) {
await _deleteOption(state.allOptions); await _deleteOption(state.allOptions);
} }
}, },
updateOption: (_UpdateOption value) async { updateOption: (option) async {
await _updateOption(value.option); await _updateOption(option);
}, },
selectOption: (_SelectOption value) async { selectOption: (optionId) async {
await _selectOptionService.select(optionIds: [value.optionId]); await _selectOptionService.select(optionIds: [optionId]);
final selectedOption = [ final selectedOption = [
...state.selectedOptions, ...state.selectedOptions,
state.options.firstWhere( state.options.firstWhere(
(element) => element.id == value.optionId, (element) => element.id == optionId,
), ),
]; ];
emit( emit(
@ -78,27 +77,27 @@ class SelectOptionCellEditorBloc
), ),
); );
}, },
unSelectOption: (_UnSelectOption value) async { unSelectOption: (optionId) async {
await _selectOptionService.unSelect(optionIds: [value.optionId]); await _selectOptionService.unSelect(optionIds: [optionId]);
final selectedOptions = [...state.selectedOptions] final selectedOptions = [...state.selectedOptions]
..removeWhere((e) => e.id == value.optionId); ..removeWhere((e) => e.id == optionId);
emit( emit(
state.copyWith( state.copyWith(
selectedOptions: selectedOptions, selectedOptions: selectedOptions,
), ),
); );
}, },
trySelectOption: (_TrySelectOption value) { trySelectOption: (optionName) {
_trySelectOption(value.optionName, emit); _trySelectOption(optionName, emit);
}, },
selectMultipleOptions: (_SelectMultipleOptions value) { selectMultipleOptions: (optionNames, remainder) {
if (value.optionNames.isNotEmpty) { if (optionNames.isNotEmpty) {
_selectMultipleOptions(value.optionNames); _selectMultipleOptions(optionNames);
} }
_filterOption(value.remainder, emit); _filterOption(remainder, emit);
}, },
filterOption: (_SelectOptionFilter value) { filterOption: (optionName) {
_filterOption(value.optionName, emit); _filterOption(optionName, emit);
}, },
); );
}, },