mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
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:
parent
22f09ddcb7
commit
473eb8bcbe
BIN
frontend/appflowy_flutter/assets/test/workspaces/cover_image.zip
Normal file
BIN
frontend/appflowy_flutter/assets/test/workspaces/cover_image.zip
Normal file
Binary file not shown.
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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()
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user