chore: enable drag to expand field's width

This commit is contained in:
appflowy 2022-05-31 16:14:12 +08:00
parent 4e3d2672ec
commit ab896cbc8f
5 changed files with 50 additions and 42 deletions

View File

@ -24,13 +24,15 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
_startListening();
},
didReceiveFieldUpdate: (field) {
emit(state.copyWith(field: field));
emit(state.copyWith(field: cellContext.field));
},
updateWidth: (offset) {
final defaultWidth = state.field.width.toDouble();
final width = defaultWidth + offset;
if (width > defaultWidth && width < 300) {
_fieldService.updateField(width: width);
startUpdateWidth: (offset) {
final width = state.width + offset;
emit(state.copyWith(width: width));
},
endUpdateWidth: () {
if (state.width != state.field.width.toDouble()) {
_fieldService.updateField(width: state.width);
}
},
);
@ -61,7 +63,8 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
class FieldCellEvent with _$FieldCellEvent {
const factory FieldCellEvent.initial() = _InitialCell;
const factory FieldCellEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate;
const factory FieldCellEvent.updateWidth(double offset) = _UpdateWidth;
const factory FieldCellEvent.startUpdateWidth(double offset) = _StartUpdateWidth;
const factory FieldCellEvent.endUpdateWidth() = _EndUpdateWidth;
}
@freezed
@ -69,10 +72,12 @@ class FieldCellState with _$FieldCellState {
const factory FieldCellState({
required String gridId,
required Field field,
required double width,
}) = _FieldCellState;
factory FieldCellState.initial(GridFieldCellContext cellContext) => FieldCellState(
gridId: cellContext.gridId,
field: cellContext.field,
width: cellContext.field.width.toDouble(),
);
}

View File

@ -30,7 +30,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
_rowService.createRow();
},
didReceiveCellDatas: (_DidReceiveCellDatas value) async {
final fields = value.gridCellMap.values.map((e) => CellSnapshot(e.field)).toList();
final fields = value.gridCellMap.values.map((e) => GridCellEquatable(e.field)).toList();
final snapshots = UnmodifiableListView(fields);
emit(state.copyWith(
gridCellMap: value.gridCellMap,
@ -74,26 +74,27 @@ class RowState with _$RowState {
const factory RowState({
required GridRow rowData,
required GridCellMap gridCellMap,
required UnmodifiableListView<CellSnapshot> snapshots,
required UnmodifiableListView<GridCellEquatable> snapshots,
GridRowChangeReason? changeReason,
}) = _RowState;
factory RowState.initial(GridRow rowData, GridCellMap cellDataMap) => RowState(
rowData: rowData,
gridCellMap: cellDataMap,
snapshots: UnmodifiableListView(cellDataMap.values.map((e) => CellSnapshot(e.field)).toList()),
snapshots: UnmodifiableListView(cellDataMap.values.map((e) => GridCellEquatable(e.field)).toList()),
);
}
class CellSnapshot extends Equatable {
class GridCellEquatable extends Equatable {
final Field _field;
const CellSnapshot(Field field) : _field = field;
const GridCellEquatable(Field field) : _field = field;
@override
List<Object?> get props => [
_field.id,
_field.fieldType,
_field.visibility,
_field.width,
];
}

View File

@ -6,7 +6,6 @@ import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -24,6 +23,7 @@ class GridFieldCell extends StatelessWidget {
return BlocProvider(
create: (context) => FieldCellBloc(cellContext: cellContext)..add(const FieldCellEvent.initial()),
child: BlocBuilder<FieldCellBloc, FieldCellState>(
// buildWhen: (p, c) => p.field != c.field,
builder: (context, state) {
final button = FieldCellButton(
field: state.field,
@ -38,7 +38,7 @@ class GridFieldCell extends StatelessWidget {
);
return _GridHeaderCellContainer(
width: state.field.width.toDouble(),
width: state.width,
child: Stack(
alignment: Alignment.centerRight,
fit: StackFit.expand,
@ -60,13 +60,14 @@ class GridFieldCell extends StatelessWidget {
void _showFieldEditor(BuildContext context) {
final state = context.read<FieldCellBloc>().state;
final field = state.field;
FieldEditor(
gridId: state.gridId,
fieldName: state.field.name,
fieldName: field.name,
contextLoader: FieldContextLoader(
gridId: state.gridId,
field: state.field,
field: field,
),
).show(context);
}
@ -113,19 +114,17 @@ class _DragToExpandLine extends StatelessWidget {
onTap: () {},
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onHorizontalDragCancel: () {},
onHorizontalDragUpdate: (value) {
// context.read<FieldCellBloc>().add(FieldCellEvent.updateWidth(value.delta.dx));
Log.info(value);
context.read<FieldCellBloc>().add(FieldCellEvent.startUpdateWidth(value.delta.dx));
},
onHorizontalDragEnd: (end) {
Log.info(end);
context.read<FieldCellBloc>().add(const FieldCellEvent.endUpdateWidth());
},
child: FlowyHover(
style: HoverStyle(
hoverColor: theme.main1,
borderRadius: BorderRadius.zero,
contentMargin: const EdgeInsets.only(left: 5),
contentMargin: const EdgeInsets.only(left: 6),
),
child: const SizedBox(width: 2),
),

View File

@ -27,7 +27,7 @@ impl TypeOptionBuilder for RichTextTypeOptionBuilder {
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
pub struct RichTextTypeOption {
#[pb(index = 1)]
data: String, //It's not used.
data: String, //It's not used yet
}
impl_type_option!(RichTextTypeOption, FieldType::RichText);

View File

@ -30,7 +30,7 @@ impl TypeOptionBuilder for URLTypeOptionBuilder {
#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
pub struct URLTypeOption {
#[pb(index = 1)]
data: String, //It's not used.
data: String, //It's not used yet.
}
impl_type_option!(URLTypeOption, FieldType::URL);
@ -56,28 +56,31 @@ impl CellDataOperation<EncodedCellData<URLCellData>, String> for URLTypeOption {
C: Into<CellContentChangeset>,
{
let changeset = changeset.into();
let mut cell_data = URLCellData {
url: "".to_string(),
content: changeset.to_string(),
};
let mut url = "".to_string();
if let Ok(Some(m)) = URL_REGEX.find(&changeset) {
// Only support https scheme by now
match url::Url::parse(m.as_str()) {
Ok(url) => {
if url.scheme() == "https" {
cell_data.url = url.into();
} else {
cell_data.url = format!("https://{}", m.as_str());
}
}
Err(_) => {
cell_data.url = format!("https://{}", m.as_str());
}
url = auto_append_scheme(m.as_str());
}
URLCellData {
url,
content: changeset.to_string(),
}
.to_json()
}
}
fn auto_append_scheme(s: &str) -> String {
// Only support https scheme by now
match url::Url::parse(s) {
Ok(url) => {
if url.scheme() == "https" {
url.into()
} else {
format!("https://{}", s)
}
}
cell_data.to_json()
Err(_) => {
format!("https://{}", s)
}
}
}