fix: offset row actions by cover height (#6390)

This commit is contained in:
Mathias Mogensen 2024-09-24 14:33:23 +02:00 committed by GitHub
parent 5fbd07e96a
commit e125e9493a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 91 additions and 48 deletions

View File

@ -39,7 +39,11 @@ import 'package:universal_platform/universal_platform.dart';
import '../../../document/presentation/editor_plugins/plugins.dart';
const _coverHeight = 250.0;
/// We have the cover height as public as it is used in the row_detail.dart file
/// Used to determine the position of the row actions depending on if there is a cover or not.
///
const rowCoverHeight = 250.0;
const _iconHeight = 60.0;
const _toolbarHeight = 40.0;
@ -181,11 +185,11 @@ class _RowBannerState extends State<RowBanner> {
double _calculateOverallHeight(bool hasIcon, bool hasCover) {
switch ((hasIcon, hasCover)) {
case (true, true):
return _coverHeight + _toolbarHeight;
return rowCoverHeight + _toolbarHeight;
case (true, false):
return 50 + _iconHeight + _toolbarHeight;
case (false, true):
return _coverHeight + _toolbarHeight;
return rowCoverHeight + _toolbarHeight;
case (false, false):
return _toolbarHeight;
}
@ -224,7 +228,7 @@ class _RowCoverState extends State<RowCover> {
@override
Widget build(BuildContext context) {
return SizedBox(
height: _coverHeight,
height: rowCoverHeight,
child: MouseRegion(
onEnter: (_) => setState(() => isOverlayButtonsHidden = false),
onExit: (_) => setState(() => isOverlayButtonsHidden = true),
@ -364,7 +368,7 @@ class _DesktopRowCoverState extends State<DesktopRowCover> {
Widget build(BuildContext context) {
if (cover.coverType == CoverTypePB.FileCover) {
return SizedBox(
height: _coverHeight,
height: rowCoverHeight,
width: double.infinity,
child: AFImage(
url: cover.data,
@ -376,7 +380,7 @@ class _DesktopRowCoverState extends State<DesktopRowCover> {
if (cover.coverType == CoverTypePB.AssetCover) {
return SizedBox(
height: _coverHeight,
height: rowCoverHeight,
width: double.infinity,
child: Image.asset(
PageStyleCoverImageType.builtInImagePath(cover.data),
@ -389,7 +393,7 @@ class _DesktopRowCoverState extends State<DesktopRowCover> {
final color = FlowyTint.fromId(cover.data)?.color(context) ??
cover.data.tryToColor();
return Container(
height: _coverHeight,
height: rowCoverHeight,
width: double.infinity,
color: color,
);
@ -397,7 +401,7 @@ class _DesktopRowCoverState extends State<DesktopRowCover> {
if (cover.coverType == CoverTypePB.GradientCover) {
return Container(
height: _coverHeight,
height: rowCoverHeight,
width: double.infinity,
decoration: BoxDecoration(
gradient: FlowyGradientColor.fromId(cover.data).linear,

View File

@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
@ -41,13 +42,26 @@ class RowDetailPage extends StatefulWidget with FlowyOverlayDelegate {
}
class _RowDetailPageState extends State<RowDetailPage> {
final scrollController = ScrollController();
late final cellBuilder = EditableCellBuilder(
databaseController: widget.databaseController,
);
late final ScrollController scrollController;
double scrollOffset = 0;
@override
void initState() {
super.initState();
scrollController = ScrollController(
onAttach: (_) => attachScrollListener(),
);
}
void attachScrollListener() => scrollController.addListener(onScrollChanged);
@override
void dispose() {
scrollController.removeListener(onScrollChanged);
scrollController.dispose();
super.dispose();
}
@ -65,53 +79,78 @@ class _RowDetailPageState extends State<RowDetailPage> {
),
BlocProvider.value(value: getIt<ReminderBloc>()),
],
child: Stack(
children: [
ListView(
controller: scrollController,
children: [
RowBanner(
databaseController: widget.databaseController,
rowController: widget.rowController,
cellBuilder: cellBuilder,
allowOpenAsFullPage: widget.allowOpenAsFullPage,
userProfile: widget.userProfile,
),
const VSpace(16),
Padding(
padding: const EdgeInsets.only(left: 40, right: 60),
child: RowPropertyList(
child: BlocBuilder<RowDetailBloc, RowDetailState>(
builder: (context, state) => Stack(
children: [
ListView(
controller: scrollController,
physics: const ClampingScrollPhysics(),
children: [
RowBanner(
databaseController: widget.databaseController,
rowController: widget.rowController,
cellBuilder: cellBuilder,
viewId: widget.databaseController.viewId,
fieldController: widget.databaseController.fieldController,
allowOpenAsFullPage: widget.allowOpenAsFullPage,
userProfile: widget.userProfile,
),
),
const VSpace(20),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 60),
child: Divider(height: 1.0),
),
const VSpace(20),
RowDocument(
viewId: widget.rowController.viewId,
rowId: widget.rowController.rowId,
),
],
),
Positioned(
top: 12,
right: 12,
child: Row(
children: _actions(context),
const VSpace(16),
Padding(
padding: const EdgeInsets.only(left: 40, right: 60),
child: RowPropertyList(
cellBuilder: cellBuilder,
viewId: widget.databaseController.viewId,
fieldController:
widget.databaseController.fieldController,
),
),
const VSpace(20),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 60),
child: Divider(height: 1.0),
),
const VSpace(20),
RowDocument(
viewId: widget.rowController.viewId,
rowId: widget.rowController.rowId,
),
],
),
),
],
Positioned(
top: calculateActionsOffset(
state.rowMeta.cover.data.isNotEmpty,
),
right: 12,
child: Row(
children: actions(context),
),
),
],
),
),
),
);
}
List<Widget> _actions(BuildContext context) {
void onScrollChanged() {
if (scrollOffset != scrollController.offset) {
setState(() => scrollOffset = scrollController.offset);
}
}
double calculateActionsOffset(bool hasCover) {
if (!hasCover) {
return 12;
}
final offsetByScroll = clampDouble(
rowCoverHeight - scrollOffset,
0,
rowCoverHeight,
);
return 12 + offsetByScroll;
}
List<Widget> actions(BuildContext context) {
return [
if (widget.allowOpenAsFullPage) ...[
FlowyTooltip(