fix: show multi-line in row detail page

This commit is contained in:
appflowy
2022-09-20 16:15:05 +08:00
parent 1f2b30abfb
commit 893b6e041d
5 changed files with 88 additions and 76 deletions

View File

@ -33,8 +33,10 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
await dataController.loadTypeOptionData(); await dataController.loadTypeOptionData();
}, },
updateName: (name) { updateName: (name) {
dataController.fieldName = name; if (state.name != name) {
emit(state.copyWith(name: name)); dataController.fieldName = name;
emit(state.copyWith(name: name));
}
}, },
didReceiveFieldChanged: (FieldPB field) { didReceiveFieldChanged: (FieldPB field) {
emit(state.copyWith( emit(state.copyWith(

View File

@ -137,9 +137,11 @@ class _DragToExpandLine extends StatelessWidget {
class FieldCellButton extends StatelessWidget { class FieldCellButton extends StatelessWidget {
final VoidCallback onTap; final VoidCallback onTap;
final FieldPB field; final FieldPB field;
final int? maxLines;
const FieldCellButton({ const FieldCellButton({
required this.field, required this.field,
required this.onTap, required this.onTap,
this.maxLines = 1,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -150,7 +152,11 @@ class FieldCellButton extends StatelessWidget {
hoverColor: theme.shader6, hoverColor: theme.shader6,
onTap: onTap, onTap: onTap,
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
text: FlowyText.medium(field.name, fontSize: 12), text: FlowyText.medium(
field.name,
fontSize: 12,
maxLines: maxLines,
),
margin: GridSize.cellContentInsets, margin: GridSize.cellContentInsets,
); );
} }

View File

@ -1,10 +1,9 @@
import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart'; import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart';
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:dartz/dartz.dart' show none;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
import 'package:flowy_infra/theme.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/button.dart';
import 'package:flowy_infra_ui/style_widget/text.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/rounded_input_field.dart';
@ -59,38 +58,38 @@ class _FieldEditorState extends State<FieldEditor> {
isGroupField: widget.isGroupField, isGroupField: widget.isGroupField,
loader: widget.typeOptionLoader, loader: widget.typeOptionLoader,
)..add(const FieldEditorEvent.initial()), )..add(const FieldEditorEvent.initial()),
child: BlocBuilder<FieldEditorBloc, FieldEditorState>( child: ListView(
builder: (context, state) { shrinkWrap: true,
return ListView( children: [
shrinkWrap: true, FlowyText.medium(
children: [ LocaleKeys.grid_field_editProperty.tr(),
FlowyText.medium( fontSize: 12,
LocaleKeys.grid_field_editProperty.tr(), ),
fontSize: 12, const VSpace(10),
), _FieldNameTextField(popoverMutex: popoverMutex),
const VSpace(10), const VSpace(10),
_FieldNameTextField(popoverMutex: popoverMutex), ..._addDeleteFieldButton(),
const VSpace(10), _FieldTypeOptionCell(popoverMutex: popoverMutex),
..._addDeleteFieldButton(state), ],
_FieldTypeOptionCell(popoverMutex: popoverMutex),
],
);
},
), ),
); );
} }
List<Widget> _addDeleteFieldButton(FieldEditorState state) { List<Widget> _addDeleteFieldButton() {
if (widget.onDeleted == null) { if (widget.onDeleted == null) {
return []; return [];
} }
return [ return [
_DeleteFieldButton( BlocBuilder<FieldEditorBloc, FieldEditorState>(
popoverMutex: popoverMutex, builder: (context, state) {
onDeleted: () { return _DeleteFieldButton(
state.field.fold( popoverMutex: popoverMutex,
() => Log.error('Can not delete the field'), onDeleted: () {
(field) => widget.onDeleted?.call(field.id), state.field.fold(
() => Log.error('Can not delete the field'),
(field) => widget.onDeleted?.call(field.id),
);
},
); );
}, },
), ),
@ -139,13 +138,13 @@ class _FieldNameTextField extends StatefulWidget {
} }
class _FieldNameTextFieldState extends State<_FieldNameTextField> { class _FieldNameTextFieldState extends State<_FieldNameTextField> {
late String name;
FocusNode focusNode = FocusNode(); FocusNode focusNode = FocusNode();
VoidCallback? _popoverCallback; VoidCallback? _popoverCallback;
TextEditingController controller = TextEditingController(); late TextEditingController controller;
@override @override
void initState() { void initState() {
controller = TextEditingController();
focusNode.addListener(() { focusNode.addListener(() {
if (focusNode.hasFocus) { if (focusNode.hasFocus) {
widget.popoverMutex.close(); widget.popoverMutex.close();
@ -158,20 +157,29 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = context.watch<AppTheme>(); final theme = context.watch<AppTheme>();
return MultiBlocListener(
controller.text = context.read<FieldEditorBloc>().state.name; listeners: [
return BlocListener<FieldEditorBloc, FieldEditorState>( BlocListener<FieldEditorBloc, FieldEditorState>(
listenWhen: (previous, current) => previous.name != current.name, listenWhen: (p, c) => p.field == none(),
listener: (context, state) { listener: (context, state) {
controller.text = state.name; focusNode.requestFocus();
}, },
),
BlocListener<FieldEditorBloc, FieldEditorState>(
listenWhen: (p, c) => controller.text != c.name,
listener: (context, state) {
controller.text = state.name;
},
),
],
child: BlocBuilder<FieldEditorBloc, FieldEditorState>( child: BlocBuilder<FieldEditorBloc, FieldEditorState>(
buildWhen: (previous, current) =>
previous.errorText != current.errorText,
builder: (context, state) { builder: (context, state) {
listenOnPopoverChanged(context); listenOnPopoverChanged(context);
return RoundedInputField( return RoundedInputField(
height: 36, height: 36,
autoFocus: true,
focusNode: focusNode, focusNode: focusNode,
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500), style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500),
controller: controller, controller: controller,
@ -202,14 +210,6 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> {
} }
}); });
} }
@override
void didUpdateWidget(covariant _FieldNameTextField oldWidget) {
controller.selection = TextSelection.fromPosition(
TextPosition(offset: controller.text.length));
super.didUpdateWidget(oldWidget);
}
} }
class _DeleteFieldButton extends StatelessWidget { class _DeleteFieldButton extends StatelessWidget {
@ -235,29 +235,11 @@ class _DeleteFieldButton extends StatelessWidget {
fontSize: 12, fontSize: 12,
color: enable ? null : theme.shader4, color: enable ? null : theme.shader4,
), ),
onTap: () => onDeleted?.call(),
); );
if (enable) button = _wrapPopover(button); // if (enable) button = button;
return button; return button;
}, },
); );
} }
Widget _wrapPopover(Widget widget) {
return AppFlowyPopover(
triggerActions: PopoverTriggerFlags.click,
constraints: BoxConstraints.loose(const Size(400, 240)),
mutex: popoverMutex,
direction: PopoverDirection.center,
popupBuilder: (popupContext) {
return PopoverAlertView(
title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(),
cancel: () {},
confirm: () {
onDeleted?.call();
},
);
},
child: widget,
);
}
} }

View File

@ -285,6 +285,7 @@ class _RowDetailCellState extends State<_RowDetailCell> {
child: SizedBox( child: SizedBox(
width: 150, width: 150,
child: FieldCellButton( child: FieldCellButton(
maxLines: null,
field: widget.cellId.fieldContext.field, field: widget.cellId.fieldContext.field,
onTap: () { onTap: () {
popover.show(); popover.show();

View File

@ -8,6 +8,7 @@ class FlowyText extends StatelessWidget {
final double fontSize; final double fontSize;
final FontWeight fontWeight; final FontWeight fontWeight;
final TextAlign? textAlign; final TextAlign? textAlign;
final int? maxLines;
final Color? color; final Color? color;
const FlowyText( const FlowyText(
@ -18,21 +19,40 @@ class FlowyText extends StatelessWidget {
this.fontWeight = FontWeight.w400, this.fontWeight = FontWeight.w400,
this.textAlign, this.textAlign,
this.color, this.color,
this.maxLines = 1,
}) : super(key: key); }) : super(key: key);
const FlowyText.semibold(this.title, const FlowyText.semibold(
{Key? key, this.fontSize = 16, this.overflow, this.color, this.textAlign}) this.title, {
: fontWeight = FontWeight.w600, Key? key,
this.fontSize = 16,
this.overflow,
this.color,
this.textAlign,
this.maxLines = 1,
}) : fontWeight = FontWeight.w600,
super(key: key); super(key: key);
const FlowyText.medium(this.title, const FlowyText.medium(
{Key? key, this.fontSize = 16, this.overflow, this.color, this.textAlign}) this.title, {
: fontWeight = FontWeight.w500, Key? key,
this.fontSize = 16,
this.overflow,
this.color,
this.textAlign,
this.maxLines = 1,
}) : fontWeight = FontWeight.w500,
super(key: key); super(key: key);
const FlowyText.regular(this.title, const FlowyText.regular(
{Key? key, this.fontSize = 16, this.overflow, this.color, this.textAlign}) this.title, {
: fontWeight = FontWeight.w400, Key? key,
this.fontSize = 16,
this.overflow,
this.color,
this.textAlign,
this.maxLines = 1,
}) : fontWeight = FontWeight.w400,
super(key: key); super(key: key);
@override @override
@ -40,6 +60,7 @@ class FlowyText extends StatelessWidget {
final theme = context.watch<AppTheme>(); final theme = context.watch<AppTheme>();
return Text( return Text(
title, title,
maxLines: maxLines,
textAlign: textAlign, textAlign: textAlign,
overflow: overflow ?? TextOverflow.clip, overflow: overflow ?? TextOverflow.clip,
style: TextStyle( style: TextStyle(