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 { enum TestWorkspace {
board("board"), board("board"),
emptyDocument("empty_document"); emptyDocument("empty_document"),
coverImage("cover_image");
const TestWorkspace(this._name); const TestWorkspace(this._name);

View File

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