feat: unpublish the page auto when moving it to another space

This commit is contained in:
Lucas.Xu 2024-07-03 10:21:17 +08:00
parent 81f0100e78
commit 5be41553be
6 changed files with 82 additions and 26 deletions

View File

@ -6,7 +6,6 @@ import 'package:appflowy/plugins/document/presentation/share/pubish_color_extens
import 'package:appflowy/plugins/document/presentation/share/publish_name_generator.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/util/theme_extension.dart';
import 'package:appflowy/workspace/presentation/home/toast.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart';
@ -25,9 +24,15 @@ class PublishTab extends StatelessWidget {
listener: (context, state) {
if (state.publishResult != null) {
state.publishResult!.fold(
(value) => showSnackBarMessage(context, 'Published successfully'),
(error) =>
showSnackBarMessage(context, 'Failed to publish: $error'),
(value) => showToastNotification(
context,
message: LocaleKeys.publish_publishSuccessfully.tr(),
),
(error) => showToastNotification(
context,
message:
'${LocaleKeys.publish_publishFailed.tr()}: ${error.code}',
),
);
}
},

View File

@ -140,12 +140,14 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
},
delete: (e) async {
final result = await ViewBackendService.delete(viewId: view.id);
result.onSuccess((_) {
add(const ViewEvent.unpublish(sync: false));
});
emit(
result.fold(
(l) {
// unpublish the page if it's published
unawaited(_unpublishPage(view));
return state.copyWith(
successOrFailure: FlowyResult.success(null),
);
@ -187,8 +189,11 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
);
emit(
result.fold(
(l) =>
state.copyWith(successOrFailure: FlowyResult.success(null)),
(l) {
return state.copyWith(
successOrFailure: FlowyResult.success(null),
);
},
(error) => state.copyWith(
successOrFailure: FlowyResult.failure(error),
),
@ -243,6 +248,13 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
}
add(const ViewEvent.setIsExpanded(false));
},
unpublish: (value) async {
if (value.sync) {
await _unpublishPage(view);
} else {
unawaited(_unpublishPage(view));
}
},
);
},
);
@ -390,15 +402,29 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
return null;
}
// unpublish the page and all its child pages
Future<void> _unpublishPage(ViewPB view) async {
final allChildViews = await _getAllChildViews(view);
final views = [view, ...allChildViews];
// unpublish
for (final view in views) {
await ViewBackendService.unpublish(view);
await Future.wait(
views.map((view) => ViewBackendService.getPublishInfo(view)),
).then((results) {
final viewsToUnpublish = <ViewPB>[];
for (var i = 0; i < results.length; i++) {
final result = results[i];
if (result.isSuccess) {
viewsToUnpublish.add(views[i]);
}
}
return viewsToUnpublish;
}).then((views) async {
await Future.wait(
views.map((view) => ViewBackendService.unpublish(view)),
);
});
}
Future<List<ViewPB>> _getAllChildViews(ViewPB view) async {
final views = <ViewPB>[];
@ -468,6 +494,8 @@ class ViewEvent with _$ViewEvent {
) = UpdateViewVisibility;
const factory ViewEvent.updateIcon(String? icon) = UpdateIcon;
const factory ViewEvent.collapseAllPages() = CollapseAllPages;
// this event will unpublish the page and all its child pages if they are published
const factory ViewEvent.unpublish({required bool sync}) = Unpublish;
}
@freezed

View File

@ -11,6 +11,8 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
typedef MovePageMenuOnSelected = void Function(ViewPB space, ViewPB view);
class MovePageMenu extends StatefulWidget {
const MovePageMenu({
super.key,
@ -23,7 +25,7 @@ class MovePageMenu extends StatefulWidget {
final ViewPB sourceView;
final UserProfilePB userProfile;
final String workspaceId;
final void Function(ViewPB view) onSelected;
final MovePageMenuOnSelected onSelected;
@override
State<MovePageMenu> createState() => _MovePageMenuState();
@ -88,7 +90,7 @@ class _MovePageMenuState extends State<MovePageMenu> {
);
}
return Expanded(
child: _buildGroupedViews(state.queryResults!),
child: _buildGroupedViews(space, state.queryResults!),
);
},
),
@ -99,7 +101,7 @@ class _MovePageMenuState extends State<MovePageMenu> {
);
}
Widget _buildGroupedViews(List<ViewPB> views) {
Widget _buildGroupedViews(ViewPB space, List<ViewPB> views) {
final groupedViews = views
.where(
(view) =>
@ -108,7 +110,7 @@ class _MovePageMenuState extends State<MovePageMenu> {
.toList();
return _MovePageGroupedViews(
views: groupedViews,
onSelected: widget.onSelected,
onSelected: (view) => widget.onSelected(space, view),
);
}
@ -124,7 +126,7 @@ class _MovePageMenuState extends State<MovePageMenu> {
child: CurrentSpace(
onTapBlankArea: () {
// move the page to current space
widget.onSelected(space);
widget.onSelected(space, space);
},
space: space,
),
@ -145,7 +147,7 @@ class _MovePageMenuState extends State<MovePageMenu> {
disableSelectedStatus: true,
// hide the ... and + buttons
rightIconsBuilder: (context, view) => [],
onSelected: (_, view) => widget.onSelected(view),
onSelected: (_, view) => widget.onSelected(space, view),
),
),
),

View File

@ -7,6 +7,7 @@ import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
import 'package:appflowy/workspace/application/sidebar/rename_view/rename_view_bloc.dart';
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
import 'package:appflowy/workspace/application/view/prelude.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
@ -20,9 +21,10 @@ import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.d
import 'package:appflowy/workspace/presentation/home/menu/view/view_more_action_button.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@ -337,6 +339,7 @@ class _InnerViewItemState extends State<InnerViewItem> {
onMove: widget.isPlaceholder
? (from, to) => _moveViewCrossSection(
context,
null,
widget.view,
widget.parentView,
widget.spaceType,
@ -749,12 +752,15 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
);
break;
case ViewMoreActionType.moveTo:
final target = data;
if (target is! ViewPB) {
final value = data;
if (value is! (ViewPB, ViewPB)) {
return;
}
final space = value.$1;
final target = value.$2;
_moveViewCrossSection(
context,
space,
widget.view,
widget.parentView,
widget.spaceType,
@ -839,6 +845,7 @@ bool isReferencedDatabaseView(ViewPB view, ViewPB? parentView) {
void _moveViewCrossSection(
BuildContext context,
ViewPB? toSpace,
ViewPB view,
ViewPB? parentView,
FolderSpaceType spaceType,
@ -859,6 +866,17 @@ void _moveViewCrossSection(
final toSection = spaceType == FolderSpaceType.public
? ViewSectionPB.Public
: ViewSectionPB.Private;
final currentSpace = context.read<SpaceBloc>().state.currentSpace;
if (currentSpace != null &&
toSpace != null &&
currentSpace.id != toSpace.id) {
Log.info(
'Move view(${from.name}) to another space(${toSpace.name}), unpublish the view',
);
context.read<ViewBloc>().add(const ViewEvent.unpublish(sync: false));
}
context.read<ViewBloc>().add(
ViewEvent.move(
from,

View File

@ -192,8 +192,8 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
sourceView: sourceView,
userProfile: userProfile,
workspaceId: workspaceId,
onSelected: (view) {
onTap(controller, view);
onSelected: (space, view) {
onTap(controller, (space, view));
},
);
},

View File

@ -107,8 +107,8 @@
"clipboard": "Copy to clipboard",
"csv": "CSV",
"copyLink": "Copy Link",
"publishToTheWeb": "Publish to the web",
"publishToTheWebHint": "Publish a static website of this page",
"publishToTheWeb": "Publish to Web",
"publishToTheWebHint": "Create a website with AppFlowy",
"publish": "Publish",
"unPublish": "Unpublish",
"visitSite": "Visit site"
@ -2051,6 +2051,9 @@
"imageBlock": "The image link has been copied to the clipboard",
"mathBlock": "The math equation has been copied to the clipboard"
},
"containsPublishedPage": "This page contains one or more published page, it will be unpublished if you continue."
"containsPublishedPage": "This page contains one or more published page, it will be unpublished if you continue.",
"publishSuccessfully": "Published successfully",
"unpublishSuccessfully": "Unpublished successfully",
"publishFailed": "Failed to publish"
}
}