Merge pull request #901 from AppFlowy-IO/feat/board_ui_adjust

feat: Adjust UI details
This commit is contained in:
Nathan.fooo 2022-08-25 10:14:36 +08:00 committed by GitHub
commit 5605eccb89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 173 additions and 70 deletions

View File

@ -9,6 +9,9 @@ import 'package:app_flowy/plugins/grid/application/row/row_data_controller.dart'
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/cell_builder.dart'; import 'package:app_flowy/plugins/grid/presentation/widgets/cell/cell_builder.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_detail.dart'; import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_detail.dart';
import 'package:appflowy_board/appflowy_board.dart'; import 'package:appflowy_board/appflowy_board.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_infra_ui/widget/error_page.dart';
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
@ -81,21 +84,47 @@ class BoardContent extends StatelessWidget {
Widget _buildHeader( Widget _buildHeader(
BuildContext context, AFBoardColumnHeaderData headerData) { BuildContext context, AFBoardColumnHeaderData headerData) {
return AppFlowyColumnHeader( return AppFlowyColumnHeader(
icon: const Icon(Icons.lightbulb_circle), // icon: const Icon(Icons.lightbulb_circle),
title: Text(headerData.columnName), title: Flexible(
addIcon: const Icon(Icons.add, size: 20), fit: FlexFit.tight,
moreIcon: const Icon(Icons.more_horiz, size: 20), child: FlowyText.medium(
headerData.columnName,
fontSize: 14,
overflow: TextOverflow.clip,
color: context.read<AppTheme>().textColor,
),
),
// addIcon: const Icon(Icons.add, size: 20),
moreIcon: SizedBox(
width: 20,
height: 20,
child: svgWidget(
'grid/details',
color: context.read<AppTheme>().iconColor,
),
),
height: 50, height: 50,
margin: config.columnItemPadding, margin: config.headerPadding,
); );
} }
Widget _buildFooter(BuildContext context, AFBoardColumnData columnData) { Widget _buildFooter(BuildContext context, AFBoardColumnData columnData) {
return AppFlowyColumnFooter( return AppFlowyColumnFooter(
icon: const Icon(Icons.add, size: 20), icon: SizedBox(
title: const Text('New'), height: 20,
width: 20,
child: svgWidget(
"home/add",
color: context.read<AppTheme>().iconColor,
),
),
title: FlowyText.medium(
"New",
fontSize: 14,
color: context.read<AppTheme>().textColor,
),
height: 50, height: 50,
margin: config.columnItemPadding, margin: config.footerPadding,
onAddButtonClick: () { onAddButtonClick: () {
context.read<BoardBloc>().add(BoardEvent.createRow(columnData.id)); context.read<BoardBloc>().add(BoardEvent.createRow(columnData.id));
}); });
@ -124,6 +153,8 @@ class BoardContent extends StatelessWidget {
return AppFlowyColumnItemCard( return AppFlowyColumnItemCard(
key: ObjectKey(item), key: ObjectKey(item),
margin: config.cardPadding,
decoration: _makeBoxDecoration(context),
child: BoardCard( child: BoardCard(
gridId: gridId, gridId: gridId,
isEditing: isEditing, isEditing: isEditing,
@ -143,6 +174,16 @@ class BoardContent extends StatelessWidget {
); );
} }
BoxDecoration _makeBoxDecoration(BuildContext context) {
final theme = context.read<AppTheme>();
final borderSide = BorderSide(color: theme.shader6, width: 1.0);
return BoxDecoration(
color: theme.surface,
border: Border.fromBorderSide(borderSide),
borderRadius: const BorderRadius.all(Radius.circular(6)),
);
}
void _openCard(String gridId, GridFieldCache fieldCache, RowPB rowPB, void _openCard(String gridId, GridFieldCache fieldCache, RowPB rowPB,
GridRowCache rowCache, BuildContext context) { GridRowCache rowCache, BuildContext context) {
final rowInfo = RowInfo( final rowInfo = RowInfo(

View File

@ -5,6 +5,8 @@ import 'package:flowy_infra_ui/style_widget/icon_button.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';
import 'define.dart';
class BoardCheckboxCell extends StatefulWidget { class BoardCheckboxCell extends StatefulWidget {
final GridCellControllerBuilder cellControllerBuilder; final GridCellControllerBuilder cellControllerBuilder;
@ -38,13 +40,18 @@ class _BoardCheckboxCellState extends State<BoardCheckboxCell> {
final icon = state.isSelected final icon = state.isSelected
? svgWidget('editor/editor_check') ? svgWidget('editor/editor_check')
: svgWidget('editor/editor_uncheck'); : svgWidget('editor/editor_uncheck');
return Align( return Padding(
padding: EdgeInsets.symmetric(
vertical: BoardSizes.cardCellVPading,
),
child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: FlowyIconButton( child: FlowyIconButton(
iconPadding: EdgeInsets.zero, iconPadding: EdgeInsets.zero,
icon: icon, icon: icon,
width: 20, width: 20,
), ),
),
); );
}, },
), ),

View File

@ -1,9 +1,12 @@
import 'package:app_flowy/plugins/board/application/card/board_date_cell_bloc.dart'; import 'package:app_flowy/plugins/board/application/card/board_date_cell_bloc.dart';
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart'; import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.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';
import 'define.dart';
class BoardDateCell extends StatefulWidget { class BoardDateCell extends StatefulWidget {
final GridCellControllerBuilder cellControllerBuilder; final GridCellControllerBuilder cellControllerBuilder;
@ -40,9 +43,15 @@ class _BoardDateCellState extends State<BoardDateCell> {
} else { } else {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: BoardSizes.cardCellVPading,
),
child: FlowyText.regular( child: FlowyText.regular(
state.dateStr, state.dateStr,
fontSize: 14, fontSize: 13,
color: context.read<AppTheme>().shader3,
),
), ),
); );
} }

View File

@ -4,6 +4,8 @@ import 'package:flowy_infra_ui/style_widget/text.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';
import 'define.dart';
class BoardNumberCell extends StatefulWidget { class BoardNumberCell extends StatefulWidget {
final GridCellControllerBuilder cellControllerBuilder; final GridCellControllerBuilder cellControllerBuilder;
@ -38,12 +40,16 @@ class _BoardNumberCellState extends State<BoardNumberCell> {
if (state.content.isEmpty) { if (state.content.isEmpty) {
return const SizedBox(); return const SizedBox();
} else { } else {
return Align( return Padding(
padding:
EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPading),
child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: FlowyText.regular( child: FlowyText.medium(
state.content, state.content,
fontSize: 14, fontSize: 14,
), ),
),
); );
} }
}, },

View File

@ -4,6 +4,8 @@ import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_c
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'define.dart';
class BoardSelectOptionCell extends StatefulWidget { class BoardSelectOptionCell extends StatefulWidget {
final GridCellControllerBuilder cellControllerBuilder; final GridCellControllerBuilder cellControllerBuilder;
@ -42,11 +44,14 @@ class _BoardSelectOptionCellState extends State<BoardSelectOptionCell> {
), ),
) )
.toList(); .toList();
return Align( return Padding(
padding: EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPading),
child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: AbsorbPointer( child: AbsorbPointer(
child: Wrap(children: children, spacing: 4, runSpacing: 2), child: Wrap(children: children, spacing: 4, runSpacing: 2),
), ),
),
); );
}, },
), ),

View File

@ -4,6 +4,8 @@ import 'package:flowy_infra_ui/style_widget/text.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';
import 'define.dart';
class BoardTextCell extends StatefulWidget { class BoardTextCell extends StatefulWidget {
final GridCellControllerBuilder cellControllerBuilder; final GridCellControllerBuilder cellControllerBuilder;
const BoardTextCell({required this.cellControllerBuilder, Key? key}) const BoardTextCell({required this.cellControllerBuilder, Key? key})
@ -37,11 +39,10 @@ class _BoardTextCellState extends State<BoardTextCell> {
} else { } else {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: ConstrainedBox( child: Padding(
constraints: BoxConstraints.loose( padding:
const Size(double.infinity, 100), EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPading),
), child: FlowyText.medium(
child: FlowyText.regular(
state.content, state.content,
fontSize: 14, fontSize: 14,
), ),

View File

@ -4,6 +4,8 @@ import 'package:flowy_infra/theme.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';
import 'define.dart';
class BoardUrlCell extends StatefulWidget { class BoardUrlCell extends StatefulWidget {
final GridCellControllerBuilder cellControllerBuilder; final GridCellControllerBuilder cellControllerBuilder;
@ -38,7 +40,10 @@ class _BoardUrlCellState extends State<BoardUrlCell> {
if (state.content.isEmpty) { if (state.content.isEmpty) {
return const SizedBox(); return const SizedBox();
} else { } else {
return Align( return Padding(
padding:
EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPading),
child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: RichText( child: RichText(
textAlign: TextAlign.left, textAlign: TextAlign.left,
@ -51,6 +56,7 @@ class _BoardUrlCellState extends State<BoardUrlCell> {
), ),
), ),
), ),
),
); );
} }
}, },

View File

@ -73,7 +73,7 @@ class _BoardCardState extends State<BoardCard> {
(cellId) { (cellId) {
final child = widget.cellBuilder.buildCell(cellId); final child = widget.cellBuilder.buildCell(cellId);
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 5), padding: const EdgeInsets.symmetric(horizontal: 6),
child: child, child: child,
); );
}, },
@ -92,7 +92,7 @@ class _CardMoreOption extends StatelessWidget with CardAccessory {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return svgWidget('home/details', color: context.read<AppTheme>().iconColor); return svgWidget('grid/details', color: context.read<AppTheme>().iconColor);
} }
@override @override

View File

@ -116,7 +116,7 @@ class _CardEnterRegion extends StatelessWidget {
.onEnter = false, .onEnter = false,
child: IntrinsicHeight( child: IntrinsicHeight(
child: Stack( child: Stack(
alignment: AlignmentDirectional.center, alignment: AlignmentDirectional.topEnd,
fit: StackFit.expand, fit: StackFit.expand,
children: children, children: children,
)), )),

View File

@ -0,0 +1,3 @@
class BoardSizes {
static double get cardCellVPading => 4;
}

View File

@ -279,7 +279,6 @@ class IGridCellController<T, D> extends Equatable {
_loadDataOperation?.cancel(); _loadDataOperation?.cancel();
_loadDataOperation = Timer(const Duration(milliseconds: 10), () { _loadDataOperation = Timer(const Duration(milliseconds: 10), () {
_cellDataLoader.loadData().then((data) { _cellDataLoader.loadData().then((data) {
Log.debug('$fieldId CellData: Did Get cell data');
_cellsCache.insert(_cacheKey, GridCell(object: data)); _cellsCache.insert(_cacheKey, GridCell(object: data));
_cellDataNotifier?.value = data; _cellDataNotifier?.value = data;
}); });

View File

@ -114,7 +114,7 @@ class _MultiBoardListExampleState extends State<MultiBoardListExample> {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 40), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 60),
child: Text(item.s), child: Text(item.s),
), ),
); );
@ -124,7 +124,7 @@ class _MultiBoardListExampleState extends State<MultiBoardListExample> {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Padding( child: Padding(
padding: const EdgeInsets.all(20), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 60),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

View File

@ -12,12 +12,18 @@ class AFBoardConfig {
final double cornerRadius; final double cornerRadius;
final EdgeInsets columnPadding; final EdgeInsets columnPadding;
final EdgeInsets columnItemPadding; final EdgeInsets columnItemPadding;
final EdgeInsets footerPadding;
final EdgeInsets headerPadding;
final EdgeInsets cardPadding;
final Color columnBackgroundColor; final Color columnBackgroundColor;
const AFBoardConfig({ const AFBoardConfig({
this.cornerRadius = 6.0, this.cornerRadius = 6.0,
this.columnPadding = const EdgeInsets.symmetric(horizontal: 8), this.columnPadding = const EdgeInsets.symmetric(horizontal: 8),
this.columnItemPadding = const EdgeInsets.symmetric(horizontal: 10), this.columnItemPadding = const EdgeInsets.symmetric(horizontal: 12),
this.footerPadding = const EdgeInsets.symmetric(horizontal: 12),
this.headerPadding = const EdgeInsets.symmetric(horizontal: 16),
this.cardPadding = const EdgeInsets.symmetric(horizontal: 3, vertical: 4),
this.columnBackgroundColor = Colors.transparent, this.columnBackgroundColor = Colors.transparent,
}); });
} }

View File

@ -2,16 +2,17 @@ import 'package:flutter/material.dart';
class AppFlowyColumnItemCard extends StatefulWidget { class AppFlowyColumnItemCard extends StatefulWidget {
final Widget? child; final Widget? child;
final Color backgroundColor;
final double cornerRadius;
final EdgeInsets margin; final EdgeInsets margin;
final BoxConstraints boxConstraints; final BoxConstraints boxConstraints;
final BoxDecoration decoration;
const AppFlowyColumnItemCard({ const AppFlowyColumnItemCard({
this.child, this.child,
this.cornerRadius = 0.0,
this.margin = const EdgeInsets.all(4), this.margin = const EdgeInsets.all(4),
this.backgroundColor = Colors.white, this.decoration = const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.zero,
),
this.boxConstraints = const BoxConstraints(minHeight: 40), this.boxConstraints = const BoxConstraints(minHeight: 40),
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -24,14 +25,11 @@ class _AppFlowyColumnItemCardState extends State<AppFlowyColumnItemCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
padding: const EdgeInsets.all(4), padding: widget.margin,
child: Container( child: Container(
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
constraints: widget.boxConstraints, constraints: widget.boxConstraints,
decoration: BoxDecoration( decoration: widget.decoration,
color: widget.backgroundColor,
borderRadius: BorderRadius.circular(widget.cornerRadius),
),
child: widget.child, child: widget.child,
), ),
); );

View File

@ -12,7 +12,7 @@ class AppFlowyColumnFooter extends StatefulWidget {
const AppFlowyColumnFooter({ const AppFlowyColumnFooter({
this.icon, this.icon,
this.title, this.title,
this.margin = EdgeInsets.zero, this.margin = const EdgeInsets.symmetric(horizontal: 12),
required this.height, required this.height,
this.onAddButtonClick, this.onAddButtonClick,
Key? key, Key? key,
@ -30,12 +30,13 @@ class _AppFlowyColumnFooterState extends State<AppFlowyColumnFooter> {
child: SizedBox( child: SizedBox(
height: widget.height, height: widget.height,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10), padding: widget.margin,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
if (widget.icon != null) widget.icon!, if (widget.icon != null) widget.icon!,
const SizedBox(width: 8),
if (widget.title != null) widget.title!, if (widget.title != null) widget.title!,
], ],
), ),

View File

@ -45,15 +45,25 @@ class _AppFlowyColumnHeaderState extends State<AppFlowyColumnHeader> {
} }
if (widget.moreIcon != null) { if (widget.moreIcon != null) {
children.add(const Spacer()); // children.add(const Spacer());
children.add( children.add(
IconButton(onPressed: widget.onMoreButtonClick, icon: widget.moreIcon!), IconButton(
onPressed: widget.onMoreButtonClick,
icon: widget.moreIcon!,
padding: const EdgeInsets.all(4),
constraints: const BoxConstraints(),
),
); );
} }
if (widget.addIcon != null) { if (widget.addIcon != null) {
children.add( children.add(
IconButton(onPressed: widget.onAddButtonClick, icon: widget.addIcon!), IconButton(
onPressed: widget.onAddButtonClick,
icon: widget.addIcon!,
padding: const EdgeInsets.all(4),
constraints: const BoxConstraints(),
),
); );
} }
@ -61,9 +71,7 @@ class _AppFlowyColumnHeaderState extends State<AppFlowyColumnHeader> {
height: widget.height, height: widget.height,
child: Padding( child: Padding(
padding: widget.margin, padding: widget.margin,
child: Row( child: Row(children: children),
children: children,
),
), ),
); );
} }

View File

@ -20,18 +20,31 @@ class FlowyText extends StatelessWidget {
}) : super(key: key); }) : super(key: key);
const FlowyText.semibold(this.title, const FlowyText.semibold(this.title,
{Key? key, this.fontSize = 16, TextOverflow? overflow, this.color, this.textAlign}) {Key? key,
this.fontSize = 16,
TextOverflow? overflow,
this.color,
this.textAlign})
: fontWeight = FontWeight.w600, : fontWeight = FontWeight.w600,
overflow = overflow ?? TextOverflow.ellipsis, overflow = overflow ?? TextOverflow.ellipsis,
super(key: key); super(key: key);
const FlowyText.medium(this.title, {Key? key, this.fontSize = 16, TextOverflow? overflow, this.color, this.textAlign}) const FlowyText.medium(this.title,
{Key? key,
this.fontSize = 16,
TextOverflow? overflow,
this.color,
this.textAlign})
: fontWeight = FontWeight.w500, : fontWeight = FontWeight.w500,
overflow = overflow ?? TextOverflow.ellipsis, overflow = overflow ?? TextOverflow.ellipsis,
super(key: key); super(key: key);
const FlowyText.regular(this.title, const FlowyText.regular(this.title,
{Key? key, this.fontSize = 16, TextOverflow? overflow, this.color, this.textAlign}) {Key? key,
this.fontSize = 16,
TextOverflow? overflow,
this.color,
this.textAlign})
: fontWeight = FontWeight.w400, : fontWeight = FontWeight.w400,
overflow = overflow ?? TextOverflow.ellipsis, overflow = overflow ?? TextOverflow.ellipsis,
super(key: key); super(key: key);
@ -40,9 +53,9 @@ class FlowyText extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = context.watch<AppTheme>(); final theme = context.watch<AppTheme>();
return Text(title, return Text(title,
overflow: overflow,
softWrap: false, softWrap: false,
textAlign: textAlign, textAlign: textAlign,
overflow: overflow,
style: TextStyle( style: TextStyle(
color: color ?? theme.textColor, color: color ?? theme.textColor,
fontWeight: fontWeight, fontWeight: fontWeight,

View File

@ -319,7 +319,7 @@ async fn group_move_group_test() {
#[tokio::test] #[tokio::test]
async fn group_update_field_test() { async fn group_update_field_test() {
let mut test = GridGroupTest::new().await; let mut test = GridGroupTest::new().await;
let mut group = test.group_at_index(0).await; let group = test.group_at_index(0).await;
let changeset = FieldChangesetParams { let changeset = FieldChangesetParams {
field_id: group.field_id.clone(), field_id: group.field_id.clone(),
grid_id: test.grid_id.clone(), grid_id: test.grid_id.clone(),