From 52fa2d27100a0822e62447c47e2d25c24cd5f8f4 Mon Sep 17 00:00:00 2001 From: Hanxing Yang Date: Wed, 16 Oct 2024 17:59:23 +0800 Subject: [PATCH 1/2] Project publish (#988) * project publish * adjust thumbnail generation --- spx-gui/src/apis/project-release.ts | 31 +++ spx-gui/src/apis/project.ts | 5 +- .../components/community/CommunityNavbar.vue | 1 + .../community/user/EditProfileModal.vue | 1 - .../components/editor/navbar/EditorNavbar.vue | 71 +++++-- .../editor/navbar/icons/project-page.svg | 4 + .../navbar/icons/{share.svg => publish.svg} | 0 .../icons/{stop-sharing.svg => unpublish.svg} | 0 .../editor/preview/EditorPreview.vue | 2 +- .../preview/stage-viewer/StageViewer.vue | 8 +- .../src/components/navbar/NavbarProfile.vue | 2 +- .../src/components/project/ProjectItem.vue | 8 +- .../project/ProjectPublishModal.vue | 188 ++++++++++++++++++ .../project/ProjectPublishedModal.vue | 90 +++++++++ spx-gui/src/components/project/index.ts | 48 ++--- .../project/runner/RunnerContainer.vue | 40 ++-- .../src/components/ui/UIConfigProvider.vue | 3 + spx-gui/src/main.ts | 4 + spx-gui/src/models/common/cloud.ts | 18 +- spx-gui/src/models/project/index.test.ts | 6 + spx-gui/src/models/project/index.ts | 64 ++++-- spx-gui/src/pages/community/project.vue | 23 ++- spx-gui/src/utils/file.ts | 2 +- spx-gui/src/utils/utils.ts | 23 ++- 24 files changed, 531 insertions(+), 111 deletions(-) create mode 100644 spx-gui/src/apis/project-release.ts create mode 100644 spx-gui/src/components/editor/navbar/icons/project-page.svg rename spx-gui/src/components/editor/navbar/icons/{share.svg => publish.svg} (100%) rename spx-gui/src/components/editor/navbar/icons/{stop-sharing.svg => unpublish.svg} (100%) create mode 100644 spx-gui/src/components/project/ProjectPublishModal.vue create mode 100644 spx-gui/src/components/project/ProjectPublishedModal.vue diff --git a/spx-gui/src/apis/project-release.ts b/spx-gui/src/apis/project-release.ts new file mode 100644 index 000000000..0b94fbf64 --- /dev/null +++ b/spx-gui/src/apis/project-release.ts @@ -0,0 +1,31 @@ +import { client, type FileCollection } from './common' + +export type ProjectRelease = { + /** Unique identifier */ + id: string + /** Creation timestamp */ + createdAt: string + /** Last update timestamp */ + updatedAt: string + /** Full name of the project, in the format `owner/project`. */ + projectFullName: string + /** Unique name of the project release, adhering to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). */ + name: string + /** rief description of the release. */ + description: string + /** File paths and their corresponding universal URLs associated with the release. */ + files: FileCollection + /** Universal URL of the release's thumbnail image. */ + thumbnail: string + /** Number of times the release has been remixed. */ + remixCount: number +} + +export type CreateReleaseParams = Pick< + ProjectRelease, + 'projectFullName' | 'name' | 'description' | 'thumbnail' +> + +export function createRelease(params: CreateReleaseParams) { + return client.post('/project-release', params) as Promise +} diff --git a/spx-gui/src/apis/project.ts b/spx-gui/src/apis/project.ts index 59f5044c5..88df81c3f 100644 --- a/spx-gui/src/apis/project.ts +++ b/spx-gui/src/apis/project.ts @@ -34,7 +34,7 @@ export type ProjectData = { description: string /** Instructions on how to interact with the project */ instructions: string - /** URL of the project's thumbnail image */ + /** Universal URL of the project's thumbnail image */ thumbnail: string /** Number of times the project has been viewed */ viewCount: number @@ -52,7 +52,8 @@ export async function addProject(params: AddProjectParams, signal?: AbortSignal) return client.post('/project', params, { signal }) as Promise } -export type UpdateProjectParams = Pick +export type UpdateProjectParams = Pick & + Partial> function encode(owner: string, name: string) { return `${encodeURIComponent(owner)}/${encodeURIComponent(name)}` diff --git a/spx-gui/src/components/community/CommunityNavbar.vue b/spx-gui/src/components/community/CommunityNavbar.vue index 05c65f8be..fe37415a9 100644 --- a/spx-gui/src/components/community/CommunityNavbar.vue +++ b/spx-gui/src/components/community/CommunityNavbar.vue @@ -45,6 +45,7 @@ function handleSearch() { diff --git a/spx-gui/src/components/editor/navbar/icons/project-page.svg b/spx-gui/src/components/editor/navbar/icons/project-page.svg new file mode 100644 index 000000000..14f7c12bf --- /dev/null +++ b/spx-gui/src/components/editor/navbar/icons/project-page.svg @@ -0,0 +1,4 @@ + + + + diff --git a/spx-gui/src/components/editor/navbar/icons/share.svg b/spx-gui/src/components/editor/navbar/icons/publish.svg similarity index 100% rename from spx-gui/src/components/editor/navbar/icons/share.svg rename to spx-gui/src/components/editor/navbar/icons/publish.svg diff --git a/spx-gui/src/components/editor/navbar/icons/stop-sharing.svg b/spx-gui/src/components/editor/navbar/icons/unpublish.svg similarity index 100% rename from spx-gui/src/components/editor/navbar/icons/stop-sharing.svg rename to spx-gui/src/components/editor/navbar/icons/unpublish.svg diff --git a/spx-gui/src/components/editor/preview/EditorPreview.vue b/spx-gui/src/components/editor/preview/EditorPreview.vue index 4b61eaa43..27e5ff655 100644 --- a/spx-gui/src/components/editor/preview/EditorPreview.vue +++ b/spx-gui/src/components/editor/preview/EditorPreview.vue @@ -10,7 +10,7 @@ - +
diff --git a/spx-gui/src/components/editor/preview/stage-viewer/StageViewer.vue b/spx-gui/src/components/editor/preview/stage-viewer/StageViewer.vue index 8730b6bde..c53b9d41d 100644 --- a/spx-gui/src/components/editor/preview/stage-viewer/StageViewer.vue +++ b/spx-gui/src/components/editor/preview/stage-viewer/StageViewer.vue @@ -243,10 +243,10 @@ async function moveZorder(direction: 'up' | 'down' | 'top' | 'bottom') { menuVisible.value = false } -async function takeScreenshot(name: string) { - const stage = await untilNotNull(stageRef) - const nodeTransformer = await untilNotNull(nodeTransformerRef) - await until(() => !loading.value) +async function takeScreenshot(name: string, signal?: AbortSignal) { + const stage = await untilNotNull(stageRef, signal) + const nodeTransformer = await untilNotNull(nodeTransformerRef, signal) + await until(() => !loading.value, signal) // Omit transform control when taking screenshot const dataUrl = nodeTransformer.withHidden(() => stage.getStage().toDataURL({ diff --git a/spx-gui/src/components/navbar/NavbarProfile.vue b/spx-gui/src/components/navbar/NavbarProfile.vue index c11e51447..d5de75528 100644 --- a/spx-gui/src/components/navbar/NavbarProfile.vue +++ b/spx-gui/src/components/navbar/NavbarProfile.vue @@ -56,7 +56,7 @@ function handleProjects() { diff --git a/spx-gui/src/components/project/ProjectPublishedModal.vue b/spx-gui/src/components/project/ProjectPublishedModal.vue new file mode 100644 index 000000000..bb7c20360 --- /dev/null +++ b/spx-gui/src/components/project/ProjectPublishedModal.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/spx-gui/src/components/project/index.ts b/spx-gui/src/components/project/index.ts index cf177dff1..40532d1b0 100644 --- a/spx-gui/src/components/project/index.ts +++ b/spx-gui/src/components/project/index.ts @@ -1,10 +1,12 @@ import { useModal, useConfirmDialog } from '@/components/ui' import { Visibility, deleteProject } from '@/apis/project' +import { useI18n } from '@/utils/i18n' +import type { Project } from '@/models/project' import ProjectCreateModal from './ProjectCreateModal.vue' import ProjectOpenModal from './ProjectOpenModal.vue' import ProjectSharingLinkModal from './ProjectSharingLinkModal.vue' -import { useI18n } from '@/utils/i18n' -import type { Project } from '@/models/project' +import ProjectPublishModal from './ProjectPublishModal.vue' +import ProjectPublishedModal from './ProjectPublishedModal.vue' export function useCreateProject() { const modal = useModal(ProjectCreateModal) @@ -46,37 +48,17 @@ export function useCreateProjectSharingLink() { } } -/** - * Share given project - * - make project public - * - copy sharing link - */ -export function useShareProject() { - const { t } = useI18n() - const withConfirm = useConfirmDialog() - const createProjectSharingLink = useCreateProjectSharingLink() - - async function makePublic(project: Project) { - project.setVisibility(Visibility.Public) - await project.saveToCloud() - } +export function usePublishProject() { + const invokePublishModal = useModal(ProjectPublishModal) + const invokePublishedModal = useModal(ProjectPublishedModal) - return async function shareProject(project: Project) { - if (project.visibility !== Visibility.Public) { - await withConfirm({ - title: t({ en: 'Share project', zh: '分享项目' }), - content: t({ - en: 'To share the current project, it will be made public. Would you like to proceed?', - zh: '为了分享当前项目,它将被设置为公开。确认继续吗?' - }), - confirmHandler: () => makePublic(project) - }) - } - return createProjectSharingLink(project) + return async function publishProject(project: Project) { + await invokePublishModal({ project }) + return invokePublishedModal({ project }) } } -export function useStopSharingProject() { +export function useUnpublishProject() { const { t } = useI18n() const withConfirm = useConfirmDialog() @@ -85,12 +67,12 @@ export function useStopSharingProject() { await project.saveToCloud() } - return async function stopSharingProject(project: Project) { + return async function unpublishProject(project: Project) { return withConfirm({ - title: t({ en: 'Stop sharing project', zh: '停止分享项目' }), + title: t({ en: 'Unpublish project', zh: '取消发布项目' }), content: t({ - en: 'If sharing is stopped, others will no longer have access to the current project, and its sharing links will expire. Would you like to proceed?', - zh: '如果停止分享,其他人将无法访问当前项目,且分享链接将会失效。确认继续吗?' + en: 'If project unpublished, others will no longer have access to the current project, and its sharing links will expire. Would you like to proceed?', + zh: '如果取消发布,其他人将无法访问当前项目,且分享链接将会失效。确认继续吗?' }), confirmHandler: () => makePrivate(project) }) diff --git a/spx-gui/src/components/project/runner/RunnerContainer.vue b/spx-gui/src/components/project/runner/RunnerContainer.vue index 8a52ee1eb..4d9b8aedd 100644 --- a/spx-gui/src/components/project/runner/RunnerContainer.vue +++ b/spx-gui/src/components/project/runner/RunnerContainer.vue @@ -1,3 +1,5 @@ + +