diff --git a/localtypings/pxtarget.d.ts b/localtypings/pxtarget.d.ts index 9e80da123020..58c0781c0e85 100644 --- a/localtypings/pxtarget.d.ts +++ b/localtypings/pxtarget.d.ts @@ -540,6 +540,7 @@ declare namespace pxt { enabledFeatures?: pxt.Map; forceEnableAiErrorHelp?: boolean; // Enables the AI Error Help feature, regardless of geo setting. shareHomepageContent?: boolean; // Show buttons to share links to homepage content more easily + showProjectDescription?: boolean; // Show project description in pxtjson editor and share dialog } interface DownloadDialogTheme { diff --git a/localtypings/pxteditor.d.ts b/localtypings/pxteditor.d.ts index 309cf0b11b23..357abd7f4855 100644 --- a/localtypings/pxteditor.d.ts +++ b/localtypings/pxteditor.d.ts @@ -989,7 +989,7 @@ declare namespace pxt.editor { anonymousPublishHeaderByIdAsync(headerId: string, projectName?: string): Promise; publishCurrentHeaderAsync(persistent: boolean, screenshotUri?: string): Promise; - publishAsync (name: string, screenshotUri?: string, forceAnonymous?: boolean): Promise; + publishAsync (name: string, description?: string,screenshotUri?: string, forceAnonymous?: boolean): Promise; startStopSimulator(opts?: SimulatorStartOptions): void; stopSimulator(unload?: boolean, opts?: SimulatorStartOptions): void; diff --git a/react-common/components/share/Share.tsx b/react-common/components/share/Share.tsx index 6474dcfd880d..07e5ed6d8c80 100644 --- a/react-common/components/share/Share.tsx +++ b/react-common/components/share/Share.tsx @@ -18,6 +18,7 @@ export interface ShareData { export interface ShareProps { projectName: string; + projectDescription?: string; screenshotUri?: string; isLoggedIn?: boolean; hasProjectBeenPersistentShared?: boolean; @@ -26,13 +27,14 @@ export interface ShareProps { kind?: "multiplayer" | "vscode" | "share"; // Arcade: Was the share dialog opened specifically for hosting a multiplayer game? setAnonymousSharePreference?: (anonymousByDefault: boolean) => void; simRecorder: SimRecorder; - publishAsync: (name: string, screenshotUri?: string, forceAnonymous?: boolean) => Promise; + publishAsync: (name: string, description?: string, screenshotUri?: string, forceAnonymous?: boolean) => Promise; onClose: () => void; } export const Share = (props: ShareProps) => { const { projectName, + projectDescription, screenshotUri, isLoggedIn, simRecorder, @@ -47,6 +49,7 @@ export const Share = (props: ShareProps) => { return
Promise; + publishAsync: (name: string, description?: string, screenshotUri?: string, forceAnonymous?: boolean) => Promise; isMultiplayerGame?: boolean; // Arcade: Does the game being shared have multiplayer enabled? kind?: "multiplayer" | "vscode" | "share"; // Arcade: Was the share dialog opened specifically for hosting a multiplayer game? anonymousShareByDefault?: boolean; @@ -37,7 +37,7 @@ export interface ShareInfoProps { export const ShareInfo = (props: ShareInfoProps) => { const { projectName, - description, + projectDescription, screenshotUri, isLoggedIn, simRecorder, @@ -50,6 +50,7 @@ export const ShareInfo = (props: ShareInfoProps) => { onClose, } = props; const [ name, setName ] = React.useState(projectName); + const [ description, setDescription ] = React.useState(projectDescription); const [ thumbnailUri, setThumbnailUri ] = React.useState(screenshotUri); const [ shareState, setShareState ] = React.useState<"share" | "gifrecord" | "publish" | "publish-vscode" | "publishing">("share"); const [ shareData, setShareData ] = React.useState(); @@ -95,7 +96,7 @@ export const ShareInfo = (props: ShareInfoProps) => { const handlePublishClick = async () => { setShareState("publishing"); setLastShareWasAnonymous(isAnonymous); - let publishedShareData = await publishAsync(name, thumbnailUri, isAnonymous); + let publishedShareData = await publishAsync(name, description, thumbnailUri, isAnonymous); setShareData(publishedShareData); if (!publishedShareData?.error) setShareState("publish"); else setShareState("share") @@ -104,7 +105,7 @@ export const ShareInfo = (props: ShareInfoProps) => { const handlePublishInVscodeClick = async () => { setShareState("publishing"); setLastShareWasAnonymous(isAnonymous); - let publishedShareData = await publishAsync(name, thumbnailUri, isAnonymous); + let publishedShareData = await publishAsync(name, description, thumbnailUri, isAnonymous); setShareData(publishedShareData); if (!publishedShareData?.error) { setShareState("publish-vscode"); @@ -238,9 +239,9 @@ export const ShareInfo = (props: ShareInfoProps) => { const handleMultiplayerShareConfirmClick = async () => { setShareState("publishing"); setIsShowingMultiConfirmation(false); - setLastShareWasAnonymous(isAnonymous); + setLastShareWasAnonymous(isAnonymous); - const publishedShareData = await publishAsync(name, thumbnailUri, isAnonymous); + const publishedShareData = await publishAsync(name, description, thumbnailUri, isAnonymous); // TODO multiplayer: This won't work on staging (parseScriptId domains check doesn't include staging urls) // but those wouldn't load anyways (as staging multiplayer is currently fetching games from prod links) @@ -322,7 +323,7 @@ export const ShareInfo = (props: ShareInfoProps) => { if (setAnonymousSharePreference) setAnonymousSharePreference(!newValue); } - const inputTitle = prePublish ? lf("Project Title") : + const inputTitle = prePublish ? lf("Project Name") : (shareState === "publish-vscode" ? lf("Share Successful") : lf("Project Link")); const shareAttemptWasAnonymous = lastShareWasAnonymous === undefined ? isAnonymous : lastShareWasAnonymous; @@ -378,6 +379,19 @@ export const ShareInfo = (props: ShareInfoProps) => { onBlur={setName} onEnterKey={setName} preserveValueOnBlur={true} /> + {pxt.appTarget.appTheme.showProjectDescription && <> +
+ {lf("Project Description")} +
+