mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: grid header cell refresh after field was changed
This commit is contained in:
parent
fc77e0857a
commit
fc4ed6c057
@ -0,0 +1,66 @@
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
||||
part 'field_cell_bloc.freezed.dart';
|
||||
|
||||
class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
||||
final FieldListener _fieldListener;
|
||||
|
||||
FieldCellBloc({
|
||||
required GridFieldCellContext cellContext,
|
||||
}) : _fieldListener = FieldListener(fieldId: cellContext.field.id),
|
||||
super(FieldCellState.initial(cellContext)) {
|
||||
on<FieldCellEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
initial: (_InitialCell value) async {
|
||||
_startListening();
|
||||
},
|
||||
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
|
||||
emit(state.copyWith(field: value.field));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _fieldListener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
_fieldListener.updateFieldNotifier.addPublishListener((result) {
|
||||
result.fold(
|
||||
(field) => add(FieldCellEvent.didReceiveFieldUpdate(field)),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
_fieldListener.start();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class FieldCellEvent with _$FieldCellEvent {
|
||||
const factory FieldCellEvent.initial() = _InitialCell;
|
||||
const factory FieldCellEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class FieldCellState with _$FieldCellState {
|
||||
const factory FieldCellState({
|
||||
required String gridId,
|
||||
required Field field,
|
||||
}) = _FieldCellState;
|
||||
|
||||
factory FieldCellState.initial(GridFieldCellContext cellContext) => FieldCellState(
|
||||
gridId: cellContext.gridId,
|
||||
field: cellContext.field,
|
||||
);
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_cell_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
@ -12,46 +13,55 @@ import 'field_cell_action_sheet.dart';
|
||||
import 'field_editor.dart';
|
||||
|
||||
class GridFieldCell extends StatelessWidget {
|
||||
final GridFieldCellContext fieldCellContext;
|
||||
const GridFieldCell(this.fieldCellContext, {Key? key}) : super(key: key);
|
||||
final GridFieldCellContext cellContext;
|
||||
const GridFieldCell(this.cellContext, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
final field = fieldCellContext.field;
|
||||
|
||||
final button = FlowyButton(
|
||||
hoverColor: theme.hover,
|
||||
onTap: () => _showActionSheet(context),
|
||||
rightIcon: svgWidget("editor/details", color: theme.iconColor),
|
||||
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
|
||||
text: FlowyText.medium(field.name, fontSize: 12),
|
||||
padding: GridSize.cellContentInsets,
|
||||
);
|
||||
return BlocProvider(
|
||||
create: (context) => FieldCellBloc(cellContext: cellContext)..add(const FieldCellEvent.initial()),
|
||||
child: BlocBuilder<FieldCellBloc, FieldCellState>(
|
||||
builder: (context, state) {
|
||||
final button = FlowyButton(
|
||||
hoverColor: theme.hover,
|
||||
onTap: () => _showActionSheet(context),
|
||||
rightIcon: svgWidget("editor/details", color: theme.iconColor),
|
||||
leftIcon: svgWidget(state.field.fieldType.iconName(), color: theme.iconColor),
|
||||
text: FlowyText.medium(state.field.name, fontSize: 12),
|
||||
padding: GridSize.cellContentInsets,
|
||||
);
|
||||
|
||||
final borderSide = BorderSide(color: theme.shader4, width: 0.4);
|
||||
final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide));
|
||||
final borderSide = BorderSide(color: theme.shader4, width: 0.4);
|
||||
final decoration = BoxDecoration(border: Border(top: borderSide, right: borderSide, bottom: borderSide));
|
||||
|
||||
return Container(
|
||||
width: field.width.toDouble(),
|
||||
decoration: decoration,
|
||||
child: button,
|
||||
return Container(
|
||||
width: state.field.width.toDouble(),
|
||||
decoration: decoration,
|
||||
child: button,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showActionSheet(BuildContext context) {
|
||||
final state = context.read<FieldCellBloc>().state;
|
||||
GridFieldCellActionSheet(
|
||||
fieldCellContext: fieldCellContext,
|
||||
cellContext: GridFieldCellContext(gridId: state.gridId, field: state.field),
|
||||
onEdited: () => _showFieldEditor(context),
|
||||
).show(context);
|
||||
}
|
||||
|
||||
void _showFieldEditor(BuildContext context) {
|
||||
final state = context.read<FieldCellBloc>().state;
|
||||
|
||||
FieldEditor(
|
||||
gridId: fieldCellContext.gridId,
|
||||
gridId: state.gridId,
|
||||
fieldContextLoader: FieldContextLoaderAdaptor(
|
||||
gridId: fieldCellContext.gridId,
|
||||
field: fieldCellContext.field,
|
||||
gridId: state.gridId,
|
||||
field: state.field,
|
||||
),
|
||||
).show(context);
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
||||
class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate {
|
||||
final GridFieldCellContext fieldCellContext;
|
||||
final GridFieldCellContext cellContext;
|
||||
final VoidCallback onEdited;
|
||||
const GridFieldCellActionSheet({required this.fieldCellContext, required this.onEdited, Key? key}) : super(key: key);
|
||||
const GridFieldCellActionSheet({required this.cellContext, required this.onEdited, Key? key}) : super(key: key);
|
||||
|
||||
void show(BuildContext overlayContext) {
|
||||
FlowyOverlay.of(overlayContext).insertWithAnchor(
|
||||
@ -33,7 +33,7 @@ class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => getIt<FieldActionSheetBloc>(param1: fieldCellContext),
|
||||
create: (context) => getIt<FieldActionSheetBloc>(param1: cellContext),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
@ -44,7 +44,7 @@ class GridFieldCellActionSheet extends StatelessWidget with FlowyOverlayDelegate
|
||||
},
|
||||
),
|
||||
const VSpace(6),
|
||||
_FieldOperationList(fieldCellContext, () => FlowyOverlay.of(context).remove(identifier())),
|
||||
_FieldOperationList(cellContext, () => FlowyOverlay.of(context).remove(identifier())),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -58,7 +58,7 @@ class _GridHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||
@override
|
||||
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
|
||||
if (oldDelegate is _GridHeaderDelegate) {
|
||||
return fields != oldDelegate.fields;
|
||||
return fields.length != oldDelegate.fields.length;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ edition = "2018"
|
||||
name = "dart_ffi"
|
||||
# this value will change depending on the target os
|
||||
# default static lib
|
||||
crate-type = ["staticlib"]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
|
@ -58,7 +58,7 @@ impl ClientGridEditor {
|
||||
start_field_id,
|
||||
grid_id,
|
||||
} = params;
|
||||
|
||||
let field_id = field.id.clone();
|
||||
let _ = self
|
||||
.modify(|grid| {
|
||||
if grid.contain_field(&field.id) {
|
||||
@ -84,6 +84,7 @@ impl ClientGridEditor {
|
||||
})
|
||||
.await?;
|
||||
let _ = self.notify_did_update_grid().await?;
|
||||
let _ = self.notify_did_update_field(&field_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -409,12 +410,13 @@ impl ClientGridEditor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||
async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> {
|
||||
let mut field_metas = self.get_field_metas(Some(vec![field_id])).await?;
|
||||
debug_assert!(field_metas.len() == 1);
|
||||
|
||||
if let Some(field_meta) = field_metas.pop() {
|
||||
send_dart_notification(&self.grid_id, GridNotification::DidUpdateField)
|
||||
send_dart_notification(&field_id, GridNotification::DidUpdateField)
|
||||
.payload(field_meta)
|
||||
.send();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user