mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-11-13 08:58:05 +00:00
fix: offset row actions by cover height (#6390)
This commit is contained in:
parent
5fbd07e96a
commit
e125e9493a
@ -39,7 +39,11 @@ import 'package:universal_platform/universal_platform.dart';
|
|||||||
|
|
||||||
import '../../../document/presentation/editor_plugins/plugins.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 _iconHeight = 60.0;
|
||||||
const _toolbarHeight = 40.0;
|
const _toolbarHeight = 40.0;
|
||||||
|
|
||||||
@ -181,11 +185,11 @@ class _RowBannerState extends State<RowBanner> {
|
|||||||
double _calculateOverallHeight(bool hasIcon, bool hasCover) {
|
double _calculateOverallHeight(bool hasIcon, bool hasCover) {
|
||||||
switch ((hasIcon, hasCover)) {
|
switch ((hasIcon, hasCover)) {
|
||||||
case (true, true):
|
case (true, true):
|
||||||
return _coverHeight + _toolbarHeight;
|
return rowCoverHeight + _toolbarHeight;
|
||||||
case (true, false):
|
case (true, false):
|
||||||
return 50 + _iconHeight + _toolbarHeight;
|
return 50 + _iconHeight + _toolbarHeight;
|
||||||
case (false, true):
|
case (false, true):
|
||||||
return _coverHeight + _toolbarHeight;
|
return rowCoverHeight + _toolbarHeight;
|
||||||
case (false, false):
|
case (false, false):
|
||||||
return _toolbarHeight;
|
return _toolbarHeight;
|
||||||
}
|
}
|
||||||
@ -224,7 +228,7 @@ class _RowCoverState extends State<RowCover> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: _coverHeight,
|
height: rowCoverHeight,
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
onEnter: (_) => setState(() => isOverlayButtonsHidden = false),
|
onEnter: (_) => setState(() => isOverlayButtonsHidden = false),
|
||||||
onExit: (_) => setState(() => isOverlayButtonsHidden = true),
|
onExit: (_) => setState(() => isOverlayButtonsHidden = true),
|
||||||
@ -364,7 +368,7 @@ class _DesktopRowCoverState extends State<DesktopRowCover> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (cover.coverType == CoverTypePB.FileCover) {
|
if (cover.coverType == CoverTypePB.FileCover) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: _coverHeight,
|
height: rowCoverHeight,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: AFImage(
|
child: AFImage(
|
||||||
url: cover.data,
|
url: cover.data,
|
||||||
@ -376,7 +380,7 @@ class _DesktopRowCoverState extends State<DesktopRowCover> {
|
|||||||
|
|
||||||
if (cover.coverType == CoverTypePB.AssetCover) {
|
if (cover.coverType == CoverTypePB.AssetCover) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: _coverHeight,
|
height: rowCoverHeight,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
PageStyleCoverImageType.builtInImagePath(cover.data),
|
PageStyleCoverImageType.builtInImagePath(cover.data),
|
||||||
@ -389,7 +393,7 @@ class _DesktopRowCoverState extends State<DesktopRowCover> {
|
|||||||
final color = FlowyTint.fromId(cover.data)?.color(context) ??
|
final color = FlowyTint.fromId(cover.data)?.color(context) ??
|
||||||
cover.data.tryToColor();
|
cover.data.tryToColor();
|
||||||
return Container(
|
return Container(
|
||||||
height: _coverHeight,
|
height: rowCoverHeight,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
color: color,
|
color: color,
|
||||||
);
|
);
|
||||||
@ -397,7 +401,7 @@ class _DesktopRowCoverState extends State<DesktopRowCover> {
|
|||||||
|
|
||||||
if (cover.coverType == CoverTypePB.GradientCover) {
|
if (cover.coverType == CoverTypePB.GradientCover) {
|
||||||
return Container(
|
return Container(
|
||||||
height: _coverHeight,
|
height: rowCoverHeight,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: FlowyGradientColor.fromId(cover.data).linear,
|
gradient: FlowyGradientColor.fromId(cover.data).linear,
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/foundation.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';
|
||||||
@ -41,13 +42,26 @@ class RowDetailPage extends StatefulWidget with FlowyOverlayDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _RowDetailPageState extends State<RowDetailPage> {
|
class _RowDetailPageState extends State<RowDetailPage> {
|
||||||
final scrollController = ScrollController();
|
|
||||||
late final cellBuilder = EditableCellBuilder(
|
late final cellBuilder = EditableCellBuilder(
|
||||||
databaseController: widget.databaseController,
|
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
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
scrollController.removeListener(onScrollChanged);
|
||||||
scrollController.dispose();
|
scrollController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
@ -65,53 +79,78 @@ class _RowDetailPageState extends State<RowDetailPage> {
|
|||||||
),
|
),
|
||||||
BlocProvider.value(value: getIt<ReminderBloc>()),
|
BlocProvider.value(value: getIt<ReminderBloc>()),
|
||||||
],
|
],
|
||||||
child: Stack(
|
child: BlocBuilder<RowDetailBloc, RowDetailState>(
|
||||||
children: [
|
builder: (context, state) => Stack(
|
||||||
ListView(
|
children: [
|
||||||
controller: scrollController,
|
ListView(
|
||||||
children: [
|
controller: scrollController,
|
||||||
RowBanner(
|
physics: const ClampingScrollPhysics(),
|
||||||
databaseController: widget.databaseController,
|
children: [
|
||||||
rowController: widget.rowController,
|
RowBanner(
|
||||||
cellBuilder: cellBuilder,
|
databaseController: widget.databaseController,
|
||||||
allowOpenAsFullPage: widget.allowOpenAsFullPage,
|
rowController: widget.rowController,
|
||||||
userProfile: widget.userProfile,
|
|
||||||
),
|
|
||||||
const VSpace(16),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 40, right: 60),
|
|
||||||
child: RowPropertyList(
|
|
||||||
cellBuilder: cellBuilder,
|
cellBuilder: cellBuilder,
|
||||||
viewId: widget.databaseController.viewId,
|
allowOpenAsFullPage: widget.allowOpenAsFullPage,
|
||||||
fieldController: widget.databaseController.fieldController,
|
userProfile: widget.userProfile,
|
||||||
),
|
),
|
||||||
),
|
const VSpace(16),
|
||||||
const VSpace(20),
|
Padding(
|
||||||
const Padding(
|
padding: const EdgeInsets.only(left: 40, right: 60),
|
||||||
padding: EdgeInsets.symmetric(horizontal: 60),
|
child: RowPropertyList(
|
||||||
child: Divider(height: 1.0),
|
cellBuilder: cellBuilder,
|
||||||
),
|
viewId: widget.databaseController.viewId,
|
||||||
const VSpace(20),
|
fieldController:
|
||||||
RowDocument(
|
widget.databaseController.fieldController,
|
||||||
viewId: widget.rowController.viewId,
|
),
|
||||||
rowId: widget.rowController.rowId,
|
),
|
||||||
),
|
const VSpace(20),
|
||||||
],
|
const Padding(
|
||||||
),
|
padding: EdgeInsets.symmetric(horizontal: 60),
|
||||||
Positioned(
|
child: Divider(height: 1.0),
|
||||||
top: 12,
|
),
|
||||||
right: 12,
|
const VSpace(20),
|
||||||
child: Row(
|
RowDocument(
|
||||||
children: _actions(context),
|
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 [
|
return [
|
||||||
if (widget.allowOpenAsFullPage) ...[
|
if (widget.allowOpenAsFullPage) ...[
|
||||||
FlowyTooltip(
|
FlowyTooltip(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user