fix: mobile ui fixes (#4780)

* fix: adjust mobile grid padding

* fix: reorder field not working
This commit is contained in:
Richard Shiue 2024-02-29 09:44:48 +08:00 committed by GitHub
parent 01f2b15f70
commit f826d05f03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 106 additions and 85 deletions

View File

@ -7,16 +7,16 @@ class CalendarSize {
static double get headerContainerPadding => 12 * scale; static double get headerContainerPadding => 12 * scale;
static EdgeInsets get contentInsets => EdgeInsets.fromLTRB( static EdgeInsets get contentInsets => EdgeInsets.fromLTRB(
GridSize.leadingHeaderPadding, GridSize.horizontalHeaderPadding,
CalendarSize.headerContainerPadding, CalendarSize.headerContainerPadding,
GridSize.leadingHeaderPadding, GridSize.horizontalHeaderPadding,
CalendarSize.headerContainerPadding, CalendarSize.headerContainerPadding,
); );
static EdgeInsets get contentInsetsMobile => EdgeInsets.fromLTRB( static EdgeInsets get contentInsetsMobile => EdgeInsets.fromLTRB(
GridSize.leadingHeaderPadding / 2, GridSize.horizontalHeaderPadding / 2,
0, 0,
GridSize.leadingHeaderPadding / 2, GridSize.horizontalHeaderPadding / 2,
0, 0,
); );

View File

@ -16,7 +16,7 @@ class GridLayout {
.reduce((value, element) => value + element); .reduce((value, element) => value + element);
return fieldsWidth + return fieldsWidth +
GridSize.leadingHeaderPadding + GridSize.horizontalHeaderPadding +
GridSize.trailHeaderPadding; GridSize.trailHeaderPadding;
} }
} }

View File

@ -7,19 +7,14 @@ class GridSize {
static double get scrollBarSize => 8 * scale; static double get scrollBarSize => 8 * scale;
static double get headerHeight => 40 * scale; static double get headerHeight => 40 * scale;
static double get footerHeight => 40 * scale; static double get footerHeight => 40 * scale;
static double get leadingHeaderPadding => static double get horizontalHeaderPadding =>
PlatformExtension.isDesktop ? 40 * scale : 20 * scale; PlatformExtension.isDesktop ? 40 * scale : 16 * scale;
static double get trailHeaderPadding => 140 * scale; static double get trailHeaderPadding => 140 * scale;
static double get headerContainerPadding => 0 * scale;
static double get cellHPadding => 10 * scale; static double get cellHPadding => 10 * scale;
static double get cellVPadding => 10 * scale; static double get cellVPadding => 10 * scale;
static double get popoverItemHeight => 26 * scale; static double get popoverItemHeight => 26 * scale;
static double get typeOptionSeparatorHeight => 4 * scale; static double get typeOptionSeparatorHeight => 4 * scale;
static EdgeInsets get headerContentInsets => EdgeInsets.symmetric(
horizontal: GridSize.headerContainerPadding,
vertical: GridSize.headerContainerPadding,
);
static EdgeInsets get cellContentInsets => EdgeInsets.symmetric( static EdgeInsets get cellContentInsets => EdgeInsets.symmetric(
horizontal: GridSize.cellHPadding, horizontal: GridSize.cellHPadding,
vertical: GridSize.cellVPadding, vertical: GridSize.cellVPadding,
@ -36,18 +31,13 @@ class GridSize {
const EdgeInsets.symmetric(horizontal: 8, vertical: 2); const EdgeInsets.symmetric(horizontal: 8, vertical: 2);
static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB( static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB(
GridSize.leadingHeaderPadding, GridSize.horizontalHeaderPadding,
GridSize.headerContainerPadding, 0,
PlatformExtension.isMobile PlatformExtension.isMobile ? GridSize.horizontalHeaderPadding : 0,
? GridSize.leadingHeaderPadding PlatformExtension.isMobile ? 100 : 0,
: GridSize.headerContainerPadding,
PlatformExtension.isMobile ? 100 : GridSize.headerContainerPadding,
); );
static EdgeInsets get contentInsets => EdgeInsets.fromLTRB( static EdgeInsets get contentInsets => EdgeInsets.symmetric(
GridSize.leadingHeaderPadding, horizontal: GridSize.horizontalHeaderPadding,
GridSize.headerContainerPadding,
GridSize.leadingHeaderPadding,
GridSize.headerContainerPadding,
); );
} }

View File

@ -157,12 +157,14 @@ class _GridPageContentState extends State<GridPageContent> {
final _scrollController = GridScrollController( final _scrollController = GridScrollController(
scrollGroupController: LinkedScrollControllerGroup(), scrollGroupController: LinkedScrollControllerGroup(),
); );
late final ScrollController headerScrollController; late final ScrollController contentScrollController;
late final ScrollController reorderableController;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
headerScrollController = _scrollController.linkHorizontalController(); contentScrollController = _scrollController.linkHorizontalController();
reorderableController = _scrollController.linkHorizontalController();
} }
@override @override
@ -196,7 +198,8 @@ class _GridPageContentState extends State<GridPageContent> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_GridHeader( _GridHeader(
headerScrollController: headerScrollController, contentScrollController: contentScrollController,
reorderableController: reorderableController,
), ),
_GridRows( _GridRows(
viewId: widget.view.id, viewId: widget.view.id,
@ -205,8 +208,8 @@ class _GridPageContentState extends State<GridPageContent> {
], ],
), ),
Positioned( Positioned(
bottom: 20, bottom: 16,
right: 20, right: 16,
child: getGridFabs(context), child: getGridFabs(context),
), ),
], ],
@ -216,9 +219,13 @@ class _GridPageContentState extends State<GridPageContent> {
} }
class _GridHeader extends StatelessWidget { class _GridHeader extends StatelessWidget {
const _GridHeader({required this.headerScrollController}); const _GridHeader({
required this.contentScrollController,
required this.reorderableController,
});
final ScrollController headerScrollController; final ScrollController contentScrollController;
final ScrollController reorderableController;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -226,7 +233,8 @@ class _GridHeader extends StatelessWidget {
builder: (context, state) { builder: (context, state) {
return MobileGridHeader( return MobileGridHeader(
viewId: state.viewId, viewId: state.viewId,
anchorScrollController: headerScrollController, contentScrollController: contentScrollController,
reorderableController: reorderableController,
); );
}, },
); );
@ -247,7 +255,7 @@ class _GridRows extends StatelessWidget {
return BlocBuilder<GridBloc, GridState>( return BlocBuilder<GridBloc, GridState>(
buildWhen: (previous, current) => previous.fields != current.fields, buildWhen: (previous, current) => previous.fields != current.fields,
builder: (context, state) { builder: (context, state) {
final double contentWidth = _getContentWidth(state.fields); final double contentWidth = getMobileGridContentWidth(state.fields);
return Expanded( return Expanded(
child: _WrapScrollView( child: _WrapScrollView(
scrollController: scrollController, scrollController: scrollController,
@ -277,14 +285,6 @@ class _GridRows extends StatelessWidget {
); );
} }
double _getContentWidth(List<FieldInfo> fields) {
final visibleFields = fields.where(
(field) =>
field.fieldSettings?.visibility != FieldVisibility.AlwaysHidden,
);
return (visibleFields.length + 1) * 200 + GridSize.leadingHeaderPadding * 2;
}
Widget _renderList( Widget _renderList(
BuildContext context, BuildContext context,
GridState state, GridState state,
@ -438,3 +438,11 @@ class _AddRowButton extends StatelessWidget {
); );
} }
} }
double getMobileGridContentWidth(List<FieldInfo> fields) {
final visibleFields = fields.where(
(field) => field.fieldSettings?.visibility != FieldVisibility.AlwaysHidden,
);
return (visibleFields.length + 1) * 200 +
GridSize.horizontalHeaderPadding * 2;
}

View File

@ -139,7 +139,7 @@ class _GridHeaderState extends State<_GridHeader> {
} }
Widget _cellLeading() { Widget _cellLeading() {
return SizedBox(width: GridSize.leadingHeaderPadding); return SizedBox(width: GridSize.horizontalHeaderPadding);
} }
} }
@ -158,7 +158,6 @@ class _CellTrailing extends StatelessWidget {
bottom: BorderSide(color: Theme.of(context).dividerColor), bottom: BorderSide(color: Theme.of(context).dividerColor),
), ),
), ),
padding: GridSize.headerContentInsets,
child: CreateFieldButton( child: CreateFieldButton(
viewId: viewId, viewId: viewId,
onFieldCreated: (fieldId) => context onFieldCreated: (fieldId) => context

View File

@ -13,17 +13,22 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import '../../layout/sizes.dart'; import '../../layout/sizes.dart';
import '../../mobile_grid_page.dart';
import 'mobile_field_button.dart'; import 'mobile_field_button.dart';
const double _kGridHeaderHeight = 50.0;
class MobileGridHeader extends StatefulWidget { class MobileGridHeader extends StatefulWidget {
const MobileGridHeader({ const MobileGridHeader({
super.key, super.key,
required this.viewId, required this.viewId,
required this.anchorScrollController, required this.contentScrollController,
required this.reorderableController,
}); });
final String viewId; final String viewId;
final ScrollController anchorScrollController; final ScrollController contentScrollController;
final ScrollController reorderableController;
@override @override
State<MobileGridHeader> createState() => _MobileGridHeaderState(); State<MobileGridHeader> createState() => _MobileGridHeaderState();
@ -41,30 +46,46 @@ class _MobileGridHeaderState extends State<MobileGridHeader> {
fieldController: fieldController, fieldController: fieldController,
)..add(const GridHeaderEvent.initial()); )..add(const GridHeaderEvent.initial());
}, },
child: SingleChildScrollView( child: Stack(
children: [
BlocBuilder<GridHeaderBloc, GridHeaderState>(
builder: (context, state) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
controller: widget.anchorScrollController, controller: widget.contentScrollController,
child: Row( child: Stack(
mainAxisSize: MainAxisSize.min,
children: [ children: [
HSpace(GridSize.leadingHeaderPadding), Positioned(
Stack( top: 0,
children: [ left: GridSize.horizontalHeaderPadding + 24,
Positioned(top: 0, left: 24, right: 24, child: _divider()), right: GridSize.horizontalHeaderPadding + 24,
Positioned(bottom: 0, left: 0, right: 0, child: _divider()), child: _divider(),
),
Positioned(
bottom: 0,
left: GridSize.horizontalHeaderPadding,
right: GridSize.horizontalHeaderPadding,
child: _divider(),
),
SizedBox( SizedBox(
height: 50, height: _kGridHeaderHeight,
width: getMobileGridContentWidth(state.fields),
),
],
),
);
},
),
SizedBox(
height: _kGridHeaderHeight,
child: _GridHeader( child: _GridHeader(
viewId: widget.viewId, viewId: widget.viewId,
fieldController: fieldController, fieldController: fieldController,
scrollController: widget.reorderableController,
), ),
), ),
], ],
), ),
const HSpace(20),
],
),
),
); );
} }
@ -81,10 +102,12 @@ class _GridHeader extends StatefulWidget {
const _GridHeader({ const _GridHeader({
required this.viewId, required this.viewId,
required this.fieldController, required this.fieldController,
required this.scrollController,
}); });
final String viewId; final String viewId;
final FieldController fieldController; final FieldController fieldController;
final ScrollController scrollController;
@override @override
State<_GridHeader> createState() => _GridHeaderState(); State<_GridHeader> createState() => _GridHeaderState();
@ -114,13 +137,16 @@ class _GridHeaderState extends State<_GridHeader> {
.toList(); .toList();
return ReorderableListView.builder( return ReorderableListView.builder(
scrollController: ScrollController(), scrollController: widget.scrollController,
shrinkWrap: true, shrinkWrap: true,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
proxyDecorator: (child, index, anim) => Material( proxyDecorator: (child, index, anim) => Material(
color: Colors.transparent, color: Colors.transparent,
child: child, child: child,
), ),
padding: EdgeInsets.symmetric(
horizontal: GridSize.horizontalHeaderPadding,
),
header: firstField != null header: firstField != null
? MobileFieldButton.first( ? MobileFieldButton.first(
viewId: widget.viewId, viewId: widget.viewId,

View File

@ -68,7 +68,7 @@ class _MobileGridRowState extends State<MobileGridRow> {
builder: (context, state) { builder: (context, state) {
return Row( return Row(
children: [ children: [
SizedBox(width: GridSize.leadingHeaderPadding), SizedBox(width: GridSize.horizontalHeaderPadding),
Expanded( Expanded(
child: RowContent( child: RowContent(
fieldController: widget.databaseController.fieldController, fieldController: widget.databaseController.fieldController,
@ -163,7 +163,6 @@ class RowContent extends StatelessWidget {
Widget _finalCellDecoration(BuildContext context) { Widget _finalCellDecoration(BuildContext context) {
return Container( return Container(
width: 200, width: 200,
padding: GridSize.headerContentInsets,
constraints: const BoxConstraints(minHeight: 46), constraints: const BoxConstraints(minHeight: 46),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border(

View File

@ -115,7 +115,7 @@ class _RowLeadingState extends State<_RowLeading> {
child: Consumer<RegionStateNotifier>( child: Consumer<RegionStateNotifier>(
builder: (context, state, _) { builder: (context, state, _) {
return SizedBox( return SizedBox(
width: GridSize.leadingHeaderPadding, width: GridSize.horizontalHeaderPadding,
child: state.onEnter ? _activeWidget() : null, child: state.onEnter ? _activeWidget() : null,
); );
}, },
@ -283,7 +283,6 @@ class RowContent extends StatelessWidget {
cursor: SystemMouseCursors.basic, cursor: SystemMouseCursors.basic,
child: Container( child: Container(
width: GridSize.trailHeaderPadding, width: GridSize.trailHeaderPadding,
padding: GridSize.headerContentInsets,
constraints: const BoxConstraints(minHeight: 46), constraints: const BoxConstraints(minHeight: 46),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border(

View File

@ -57,7 +57,7 @@ class _DatabaseViewSettingContent extends StatelessWidget {
builder: (context, state) { builder: (context, state) {
return Padding( return Padding(
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: GridSize.leadingHeaderPadding, horizontal: GridSize.horizontalHeaderPadding,
), ),
child: DecoratedBox( child: DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(

View File

@ -1,3 +1,4 @@
import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.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';
@ -21,8 +22,11 @@ class TabBarHeader extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return Container(
height: 30, height: 30,
padding: EdgeInsets.symmetric(
horizontal: GridSize.horizontalHeaderPadding,
),
child: Stack( child: Stack(
children: [ children: [
Positioned( Positioned(

View File

@ -1,3 +1,4 @@
import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.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';
@ -26,8 +27,11 @@ class _MobileTabBarHeaderState extends State<MobileTabBarHeader> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
padding: const EdgeInsets.only(top: 14.0) + padding: EdgeInsets.only(
const EdgeInsets.symmetric(horizontal: 20), left: GridSize.horizontalHeaderPadding,
top: 14.0,
right: GridSize.horizontalHeaderPadding - 5.0,
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.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/tab_bar_bloc.dart'; import 'package:appflowy/plugins/database/application/tab_bar_bloc.dart';
import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart';
import 'package:appflowy/plugins/database/widgets/share_button.dart'; import 'package:appflowy/plugins/database/widgets/share_button.dart';
import 'package:appflowy/plugins/util.dart'; import 'package:appflowy/plugins/util.dart';
import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/plugin/plugin.dart';
@ -112,16 +111,9 @@ class _DatabaseTabBarViewState extends State<DatabaseTabBarView> {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
if (PlatformExtension.isDesktop) { return PlatformExtension.isDesktop
return Padding( ? const TabBarHeader()
padding: EdgeInsets.symmetric( : const MobileTabBarHeader();
horizontal: GridSize.leadingHeaderPadding,
),
child: const TabBarHeader(),
);
}
return const MobileTabBarHeader();
}, },
); );
}, },