Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: last publish name #6766

Merged
merged 8 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ios_ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ on:
env:
FLUTTER_VERSION: "3.22.0"
RUST_TOOLCHAIN: "1.80.1"
CLOUD_VERSION: 0.6.51

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/rust_ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ on:

env:
CARGO_TERM_COLOR: always
CLOUD_VERSION: 0.6.51-amd64
CLOUD_VERSION: 0.7.6-amd64
RUST_TOOLCHAIN: "1.77.2"

jobs:
Expand Down Expand Up @@ -137,7 +137,7 @@ jobs:
run: |
cp deploy.env .env
sed -i 's|RUST_LOG=.*|RUST_LOG=trace|' .env
sed -i 's|GOTRUE_MAILER_AUTOCONFIRM=.*|GOTRUE_MAILER_AUTOCONFIRM=true|' .env
sed -i 's|GOTRUE_MAILER_AUTOCONFIRM=.*|GOTRUE_MAILER_AUTOCONFIRM=true|' .env
sed -i 's|API_EXTERNAL_URL=.*|API_EXTERNAL_URL=http://localhost|' .env

- name: Ensure AppFlowy-Cloud is Running with Correct Version
Expand All @@ -160,7 +160,7 @@ jobs:
else
echo "No volumes to remove."
fi

docker compose pull
docker compose up -d
echo "Waiting for the container to be ready..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,21 @@ void main() {
await tester.pumpUntilFound(errorToast2);
await tester.pumpUntilNotFound(errorToast2);

// rename with empty name
await tester.tap(inputField);
await tester.enterText(inputField, '');
await tester.tapButton(find.text(LocaleKeys.button_save.tr()));
await tester.pumpAndSettle();

// expect to see the toast with error message
final errorToast3 = find.text(
LocaleKeys.settings_sites_error_publishNameCannotBeEmpty.tr(),
);
await tester.pumpUntilFound(errorToast3);
await tester.pumpUntilNotFound(errorToast3);

// input the new path name
await tester.tap(inputField);
await tester.enterText(inputField, 'new-path-name');
// click save button
await tester.tapButton(find.text(LocaleKeys.button_save.tr()));
Expand Down Expand Up @@ -137,5 +149,72 @@ void main() {
isTrue,
);
});

testWidgets('re-publish the document', (tester) async {
await tester.initializeAppFlowy(
cloudType: AuthenticatorType.appflowyCloudSelfHost,
);
await tester.tapGoogleLoginInButton();
await tester.expectToSeeHomePageWithGetStartedPage();

const pageName = 'Document';

await tester.createNewPageInSpace(
spaceName: Constants.generalSpaceName,
layout: ViewLayoutPB.Document,
pageName: pageName,
);

// open the publish menu
await tester.openPublishMenu();

// publish the document
final publishButton = find.byType(PublishButton);
await tester.tapButton(publishButton);

// rename the path name
final inputField = find.descendant(
of: find.byType(ShareMenu),
matching: find.byType(TextField),
);

// input the new path name
const newName = 'new-path-name';
await tester.enterText(inputField, newName);
// click save button
await tester.tapButton(find.text(LocaleKeys.button_save.tr()));
await tester.pumpAndSettle();

// expect to see the toast with success message
final successToast = find.text(
LocaleKeys.settings_sites_success_updatePathNameSuccess.tr(),
);
await tester.pumpUntilNotFound(successToast);

// unpublish the document
final unpublishButton = find.byType(UnPublishButton);
await tester.tapButton(unpublishButton);

final unpublishSuccessToast = find.text(
LocaleKeys.publish_unpublishSuccessfully.tr(),
);
await tester.pumpUntilNotFound(unpublishSuccessToast);

// re-publish the document
await tester.tapButton(publishButton);

// expect to see the toast with success message
final rePublishSuccessToast = find.text(
LocaleKeys.publish_publishSuccessfully.tr(),
);
await tester.pumpUntilNotFound(rePublishSuccessToast);

// check the clipboard has the link
final content = await Clipboard.getData(Clipboard.kTextPlain);
expect(
content?.text?.contains(newName),
isTrue,
);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:appflowy/plugins/shared/share/constants.dart';
import 'package:appflowy/plugins/shared/share/publish_name_generator.dart';
import 'package:appflowy/plugins/shared/share/share_bloc.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/util/string_extension.dart';
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
import 'package:appflowy/workspace/application/view/prelude.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
Expand Down Expand Up @@ -97,9 +98,12 @@ class MobileViewPageMoreBottomSheet extends StatelessWidget {

Future<void> _publish(BuildContext context) async {
final id = context.read<ShareBloc>().view.id;
final publishName = await generatePublishName(
id,
view.name,
final lastPublishName = context.read<ShareBloc>().state.pathName;
final publishName = lastPublishName.orDefault(
await generatePublishName(
id,
view.name,
),
);
if (context.mounted) {
context.read<ShareBloc>().add(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:appflowy/plugins/shared/share/publish_name_generator.dart';
import 'package:appflowy/plugins/shared/share/share_bloc.dart';
import 'package:appflowy/shared/error_code/error_code_map.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/util/string_extension.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy_backend/log.dart';
Expand Down Expand Up @@ -50,9 +51,12 @@ class PublishTab extends StatelessWidget {
return _PublishWidget(
onPublish: (selectedViews) async {
final id = context.read<ShareBloc>().view.id;
final publishName = await generatePublishName(
id,
viewName,
final lastPublishName = context.read<ShareBloc>().state.pathName;
final publishName = lastPublishName.orDefault(
await generatePublishName(
id,
viewName,
),
);

if (selectedViews.isNotEmpty) {
Expand Down
78 changes: 51 additions & 27 deletions frontend/appflowy_flutter/lib/plugins/shared/share/share_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:appflowy/workspace/application/view/view_listener.dart';
import 'package:appflowy/workspace/application/view/view_service.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
Expand Down Expand Up @@ -188,39 +189,47 @@ class ShareBloc extends Bloc<ShareEvent, ShareState> {
(v) => v.authenticator == AuthenticatorPB.AppFlowyCloud,
(p) => false,
);

Log.info(
'get publish info: $publishInfo for view: ${view.name}(${view.id})',
);

String workspaceId = state.workspaceId;
if (workspaceId.isEmpty) {
workspaceId = await UserBackendService.getCurrentWorkspace()
.fold((s) => s.id, (f) => '');
workspaceId = await UserBackendService.getCurrentWorkspace().fold(
(s) => s.id,
(f) => '',
);
}
publishInfo.fold((s) {
emit(
state.copyWith(
isPublished: true,
namespace: s.namespace,
pathName: s.publishName,
url: ShareConstants.buildPublishUrl(

final (isPublished, namespace, pathName, url) = publishInfo.fold(
(s) {
return (
// if the unpublishedAtTimestampSec is not set, it means the view is not unpublished.
!s.hasUnpublishedAtTimestampSec(),
s.namespace,
s.publishName,
ShareConstants.buildPublishUrl(
nameSpace: s.namespace,
publishName: s.publishName,
),
viewName: view.name,
enablePublish: enablePublish,
workspaceId: workspaceId,
viewId: view.id,
),
);
}, (f) {
emit(
state.copyWith(
isPublished: false,
url: '',
viewName: view.name,
enablePublish: enablePublish,
workspaceId: workspaceId,
viewId: view.id,
),
);
});
);
},
(f) => (false, '', '', ''),
);

emit(
state.copyWith(
isPublished: isPublished,
namespace: namespace,
pathName: pathName,
url: url,
viewName: view.name,
enablePublish: enablePublish,
workspaceId: workspaceId,
viewId: view.id,
),
);
}

Future<void> _updatePathName(
Expand All @@ -232,6 +241,21 @@ class ShareBloc extends Bloc<ShareEvent, ShareState> {
updatePathNameResult: null,
),
);

if (pathName.isEmpty) {
emit(
state.copyWith(
updatePathNameResult: FlowyResult.failure(
FlowyError(
code: ErrorCode.ViewNameInvalid,
msg: 'Path name is invalid',
),
),
),
);
return;
}

final request = SetPublishNamePB()
..viewId = view.id
..newName = pathName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ extension PublishNameErrorCodeMap on ErrorCode {
LocaleKeys.settings_sites_error_publishNameTooLong.tr(),
ErrorCode.UserUnauthorized =>
LocaleKeys.settings_sites_error_publishPermissionDenied.tr(),
ErrorCode.ViewNameInvalid =>
LocaleKeys.settings_sites_error_publishNameCannotBeEmpty.tr(),
_ => null,
};
}
Expand Down
3 changes: 2 additions & 1 deletion frontend/resources/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,8 @@
"publishNameTooLong": "The path name is too long, please try another one",
"publishNameAlreadyInUse": "The path name is already in use, please try another one",
"namespaceContainsInvalidCharacters": "The namespace contains invalid character(s), please try another one",
"publishPermissionDenied": "Only the workspace owner or page publisher can manage the publish settings"
"publishPermissionDenied": "Only the workspace owner or page publisher can manage the publish settings",
"publishNameCannotBeEmpty": "The path name cannot be empty, please try another one"
},
"success": {
"namespaceUpdated": "Updated namespace successfully",
Expand Down
Loading
Loading