feat: Only show the change cover button and delete button when it's hovering. (#2145)

* feat: Only show the change cover button and delete button when it's hovering.

* feat: Only show the change cover button and delete button when it's hovering

---------

Co-authored-by: gitstart <gitstart@users.noreply.github.com>
This commit is contained in:
GitStart 2023-05-03 10:22:16 +03:00 committed by GitHub
parent 22f09ddcb7
commit 473eb8bcbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 36 deletions

View File

@ -0,0 +1,54 @@
import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/util.dart';
/// Integration tests for an empty board. The [TestWorkspaceService] will load
/// a workspace from an empty board `assets/test/workspaces/board.zip` for all
/// tests.
///
/// To create another integration test with a preconfigured workspace.
/// Use the following steps.
/// 1. Create a new workspace from the AppFlowy launch screen.
/// 2. Modify the workspace until it is suitable as the starting point for
/// the integration test you need to land.
/// 3. Use a zip utility program to zip the workspace folder that you created.
/// 4. Add the zip file under `assets/test/workspaces/`
/// 5. Add a new enumeration to [TestWorkspace] in `integration_test/utils/data.dart`.
/// For example, if you added a workspace called `empty_calendar.zip`,
/// then [TestWorkspace] should have the following value:
/// ```dart
/// enum TestWorkspace {
/// board('board'),
/// empty_calendar('empty_calendar');
///
/// /* code */
/// }
/// ```
/// 6. Double check that the .zip file that you added is included as an asset in
/// the pubspec.yaml file under appflowy_flutter.
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
const service = TestWorkspaceService(TestWorkspace.coverImage);
group('cover image', () {
setUpAll(() async => await service.setUpAll());
setUp(() async => await service.setUp());
testWidgets(
'hovering on cover image will display change and delete cover image buttons',
(tester) async {
await tester.initializeAppFlowy();
expect(find.byType(Image), findsOneWidget);
final TestPointer pointer = TestPointer(1, PointerDeviceKind.mouse);
final imageFinder = find.byType(Image);
Offset offset = tester.getCenter(imageFinder);
pointer.hover(offset);
expect(find.byType(RoundedTextButton), findsOneWidget);
});
});
}

View File

@ -9,7 +9,8 @@ import 'package:shared_preferences/shared_preferences.dart';
enum TestWorkspace {
board("board"),
emptyDocument("empty_document");
emptyDocument("empty_document"),
coverImage("cover_image");
const TestWorkspace(this._name);

View File

@ -393,21 +393,32 @@ class _CoverImageState extends State<_CoverImage> {
mainAxisSize: MainAxisSize.min,
children: [
AppFlowyPopover(
onClose: () {
setOverlayButtonsHidden(true);
},
offset: const Offset(-125, 10),
controller: popoverController,
direction: PopoverDirection.bottomWithCenterAligned,
constraints: BoxConstraints.loose(const Size(380, 450)),
margin: EdgeInsets.zero,
child: RoundedTextButton(
onPressed: () {
popoverController.show();
},
hoverColor: Theme.of(context).colorScheme.surface,
textColor: Theme.of(context).colorScheme.tertiary,
fillColor: Theme.of(context).colorScheme.surface.withOpacity(0.8),
width: 120,
height: 28,
title: LocaleKeys.document_plugins_cover_changeCover.tr(),
child: Visibility(
maintainState: true,
maintainAnimation: true,
maintainSize: true,
visible: !isOverlayButtonsHidden,
child: RoundedTextButton(
onPressed: () {
popoverController.show();
setOverlayButtonsHidden(true);
},
hoverColor: Theme.of(context).colorScheme.surface,
textColor: Theme.of(context).colorScheme.onSurface,
fillColor:
Theme.of(context).colorScheme.surface.withOpacity(0.8),
width: 120,
height: 28,
title: LocaleKeys.document_plugins_cover_changeCover.tr(),
),
),
popupBuilder: (BuildContext popoverContext) {
return ChangeCoverPopover(
@ -418,18 +429,24 @@ class _CoverImageState extends State<_CoverImage> {
},
),
const SizedBox(width: 10),
FlowyIconButton(
fillColor: Theme.of(context).colorScheme.surface.withOpacity(0.8),
hoverColor: Theme.of(context).colorScheme.surface,
iconPadding: const EdgeInsets.all(5),
width: 28,
icon: svgWidget(
'editor/delete',
color: Theme.of(context).colorScheme.tertiary,
Visibility(
maintainAnimation: true,
maintainSize: true,
maintainState: true,
visible: !isOverlayButtonsHidden,
child: FlowyIconButton(
fillColor: Theme.of(context).colorScheme.surface.withOpacity(0.8),
hoverColor: Theme.of(context).colorScheme.surface,
iconPadding: const EdgeInsets.all(5),
width: 28,
icon: svgWidget(
'editor/delete',
color: Theme.of(context).colorScheme.onSurface,
),
onPressed: () {
widget.onCoverChanged(CoverSelectionType.initial, null);
},
),
onPressed: () {
widget.onCoverChanged(CoverSelectionType.initial, null);
},
),
],
),
@ -477,20 +494,30 @@ class _CoverImageState extends State<_CoverImage> {
break;
}
//OverflowBox needs to be wraped by a widget with constraints(or from its parent) first,otherwise it will occur an error
return SizedBox(
height: height,
child: OverflowBox(
maxWidth: screenSize.width,
child: Stack(
children: [
Container(
padding: const EdgeInsets.only(bottom: 10),
height: double.infinity,
width: double.infinity,
child: coverImage,
),
hasCover ? _buildCoverOverlayButtons(context) : const SizedBox()
],
return MouseRegion(
onEnter: (event) {
setOverlayButtonsHidden(false);
},
onExit: (event) {
setOverlayButtonsHidden(true);
},
child: SizedBox(
height: height,
child: OverflowBox(
maxWidth: screenSize.width,
child: Stack(
children: [
Container(
padding: const EdgeInsets.only(bottom: 10),
height: double.infinity,
width: double.infinity,
child: coverImage,
),
hasCover
? _buildCoverOverlayButtons(context)
: const SizedBox.shrink()
],
),
),
),
);