From 477d36a9ffa4fd5fa6ba4b448e6dde5e07c5868c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pasteau?= <4895034+ClementPasteau@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:23:08 +0100 Subject: [PATCH 1/2] Remove broken link and redirect to wiki --- .../HomePage/LearnSection/MainPage.js | 23 ++----------------- .../HomePage/LearnSection/index.js | 4 ---- .../EditorContainers/HomePage/index.js | 4 ---- .../HomePage/HomePage.stories.js | 1 - 4 files changed, 2 insertions(+), 30 deletions(-) diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/MainPage.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/MainPage.js index ada2824faffb..8e2c05572b2a 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/MainPage.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/MainPage.js @@ -24,7 +24,6 @@ import GridListTile from '@material-ui/core/GridListTile'; import { makeStyles } from '@material-ui/core/styles'; import ImageTileRow from '../../../../UI/ImageTileRow'; import { formatTutorialToImageTileComponent, TUTORIAL_CATEGORY_TEXTS } from '.'; -import InAppTutorialContext from '../../../../InAppTutorial/InAppTutorialContext'; import GuidedLessons from '../InAppTutorials/GuidedLessons'; import ChevronArrowRight from '../../../../UI/CustomSvgIcons/ChevronArrowRight'; import Upload from '../../../../UI/CustomSvgIcons/Upload'; @@ -108,28 +107,21 @@ export const TutorialsRow = ({ ); type Props = {| - onStartTutorial: () => void, onOpenExampleStore: () => void, onTabChange: (tab: HomeTab) => void, - onOpenHelpFinder: () => void, onSelectCategory: (?TutorialCategory) => void, tutorials: Array, selectInAppTutorial: (tutorialId: string) => void, |}; const MainPage = ({ - onStartTutorial, onOpenExampleStore, onTabChange, - onOpenHelpFinder, onSelectCategory, tutorials, selectInAppTutorial, }: Props) => { const classes = useStyles(); - const { currentlyRunningInAppTutorial } = React.useContext( - InAppTutorialContext - ); const windowWidth = useResponsiveWindowWidth(); const isMobile = windowWidth === 'small'; const isTabletOrSmallLaptop = @@ -140,22 +132,11 @@ const MainPage = ({ action: () => void, disabled?: boolean, }[] = [ - { - title: Guided Tour, - description: ( - - Learn the fundamentals of the editor with our assisted tutorial. - - ), - action: () => { - onStartTutorial(); - }, - disabled: !!currentlyRunningInAppTutorial, - }, { title: Documentation, description: Find the complete documentation on everything, - action: onOpenHelpFinder, + action: () => + Window.openExternalURL('https://wiki.gdevelop.io/gdevelop5/'), }, { title: Examples, diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/index.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/index.js index 81d0f4badc4a..a2636b77fc8e 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/index.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/index.js @@ -82,14 +82,12 @@ const styles = { type Props = {| onOpenExampleStore: () => void, onTabChange: (tab: HomeTab) => void, - onOpenHelpFinder: () => void, selectInAppTutorial: (tutorialId: string) => void, |}; const LearnSection = ({ onOpenExampleStore, onTabChange, - onOpenHelpFinder, selectInAppTutorial, }: Props) => { const { @@ -127,8 +125,6 @@ const LearnSection = ({ return !selectedCategory ? ( onTabChange('get-started')} onTabChange={onTabChange} onSelectCategory={setSelectedCategory} tutorials={tutorials} diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/index.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/index.js index e1ee3093116a..8efceaace98c 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/index.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/index.js @@ -95,7 +95,6 @@ type Props = {| onOpenProjectManager: () => void, // Other dialogs opening: - onOpenHelpFinder: () => void, onOpenLanguageDialog: () => void, onOpenProfile: () => void, selectInAppTutorial: (tutorialId: string) => void, @@ -134,7 +133,6 @@ export const HomePage = React.memo( onOpenExampleStoreWithPrivateGameTemplateListingData, onOpenPrivateGameTemplateListingData, onOpenProjectManager, - onOpenHelpFinder, onOpenLanguageDialog, onOpenProfile, setToolbar, @@ -413,7 +411,6 @@ export const HomePage = React.memo( )} @@ -481,7 +478,6 @@ export const renderHomePageContainer = ( } onOpenNewProjectSetupDialog={props.onOpenNewProjectSetupDialog} onOpenProjectManager={props.onOpenProjectManager} - onOpenHelpFinder={props.onOpenHelpFinder} onOpenLanguageDialog={props.onOpenLanguageDialog} onOpenProfile={props.onOpenProfile} selectInAppTutorial={props.selectInAppTutorial} diff --git a/newIDE/app/src/stories/componentStories/HomePage/HomePage.stories.js b/newIDE/app/src/stories/componentStories/HomePage/HomePage.stories.js index 80943f9145f0..c62c38c0b31f 100644 --- a/newIDE/app/src/stories/componentStories/HomePage/HomePage.stories.js +++ b/newIDE/app/src/stories/componentStories/HomePage/HomePage.stories.js @@ -136,7 +136,6 @@ const WrappedHomePage = ({ action('onOpenPrivateGameTemplateListingData')() } onOpenProjectManager={() => action('onOpenProjectManager')()} - onOpenHelpFinder={() => action('onOpenHelpFinder')()} onOpenLanguageDialog={() => action('open language dialog')()} onOpenNewProjectSetupDialog={() => action('onOpenNewProjectSetupDialog')() From 70e1f273292a61e7a10475d2cc2a13d010741831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pasteau?= <4895034+ClementPasteau@users.noreply.github.com> Date: Tue, 28 Nov 2023 10:58:05 +0100 Subject: [PATCH 2/2] Put Fling game back --- .../resources/inAppTutorials/flingGame.json | 4 +- .../inAppTutorialShortHeaders.json | 4 +- .../MainFrame/EditorContainers/BaseEditor.js | 1 - .../HomePage/InAppTutorials/FlingGame.js | 259 ++++++++++++++++++ .../HomePage/InAppTutorials/GuidedLessons.js | 8 +- .../InAppTutorials/InAppTutorialPhaseCard.js | 75 ++--- .../HomePage/LearnSection/MainPage.js | 12 + newIDE/app/src/MainFrame/index.js | 1 - 8 files changed, 301 insertions(+), 63 deletions(-) create mode 100644 newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/FlingGame.js diff --git a/newIDE/app/resources/inAppTutorials/flingGame.json b/newIDE/app/resources/inAppTutorials/flingGame.json index 843aa6cc4c0b..1e32bda246e2 100644 --- a/newIDE/app/resources/inAppTutorials/flingGame.json +++ b/newIDE/app/resources/inAppTutorials/flingGame.json @@ -4760,7 +4760,7 @@ { "elementToHighlightId": "objectInObjectOrResourceSelector:scoreText", "nextStepTrigger": { - "presenceOfElement": "#instruction-item-TextObject--String" + "presenceOfElement": "#instruction-item-TextContainerCapability--TextContainerBehavior--SetValue" }, "tooltip": { "description": { @@ -4777,7 +4777,7 @@ "isOnClosableDialog": true }, { - "elementToHighlightId": "#instruction-item-TextObject--String", + "elementToHighlightId": "#instruction-item-TextContainerCapability--TextContainerBehavior--SetValue", "nextStepTrigger": { "presenceOfElement": "#instruction-parameters-container" }, diff --git a/newIDE/app/resources/inAppTutorials/inAppTutorialShortHeaders.json b/newIDE/app/resources/inAppTutorials/inAppTutorialShortHeaders.json index 6bffb5f2fca0..871338855762 100644 --- a/newIDE/app/resources/inAppTutorials/inAppTutorialShortHeaders.json +++ b/newIDE/app/resources/inAppTutorials/inAppTutorialShortHeaders.json @@ -14,7 +14,7 @@ { "id": "flingGame", "contentUrl": "https://resources.gdevelop-app.com/in-app-tutorials/flingGame.json", - "availableLocales": ["en", "fr", "es", "pt", "th"] + "availableLocales": ["en", "fr", "es", "pt", "th", "ar"] }, { "id": "healthBar", @@ -26,7 +26,7 @@ { "id": "joystick", "contentUrl": "https://resources.gdevelop-app.com/in-app-tutorials/joystick.json", - "availableLocales": ["en", "fr", "es", "pt", "th", "ar"], + "availableLocales": ["en", "fr", "es", "pt", "th", "ar", "sq"], "initialTemplateUrl": "https://resources.gdevelop-app.com/in-app-tutorials/templates/joystick/game.json", "initialProjectData": { "gameScene": "GameScene", diff --git a/newIDE/app/src/MainFrame/EditorContainers/BaseEditor.js b/newIDE/app/src/MainFrame/EditorContainers/BaseEditor.js index 654072f5476d..2be3efb18d15 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/BaseEditor.js +++ b/newIDE/app/src/MainFrame/EditorContainers/BaseEditor.js @@ -82,7 +82,6 @@ export type RenderEditorContainerProps = {| onOpenPrivateGameTemplateListingData: ( privateGameTemplateListingData: PrivateGameTemplateListingData ) => void, - onOpenHelpFinder: () => void, onOpenLanguageDialog: () => void, selectInAppTutorial: (tutorialId: string) => void, onOpenProfile: () => void, diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/FlingGame.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/FlingGame.js new file mode 100644 index 000000000000..de7800f1bbca --- /dev/null +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/FlingGame.js @@ -0,0 +1,259 @@ +// @flow +import * as React from 'react'; +import { Trans, t } from '@lingui/macro'; +import GridList from '@material-ui/core/GridList'; +import GridListTile from '@material-ui/core/GridListTile'; +import { + useResponsiveWindowWidth, + type WidthType, +} from '../../../../UI/Reponsive/ResponsiveWindowMeasurer'; +import { Line } from '../../../../UI/Grid'; +import InAppTutorialContext from '../../../../InAppTutorial/InAppTutorialContext'; +import PlaceholderLoader from '../../../../UI/PlaceholderLoader'; +import { LARGE_WIDGET_SIZE } from '../CardWidget'; +import InAppTutorialPhaseCard from './InAppTutorialPhaseCard'; +import PlaceholderError from '../../../../UI/PlaceholderError'; +import { FLING_GAME_IN_APP_TUTORIAL_ID } from '../../../../Utils/GDevelopServices/InAppTutorial'; +import PreferencesContext from '../../../Preferences/PreferencesContext'; +import AuthenticatedUserContext from '../../../../Profile/AuthenticatedUserContext'; +import Building from './Icons/Building'; +import Unboxing from './Icons/Unboxing'; +import Podium from './Icons/Podium'; + +const getColumnsFromWidth = (width: WidthType) => { + switch (width) { + case 'small': + return 1; + case 'medium': + case 'large': + case 'xlarge': + default: + return 3; + } +}; + +const MAX_COLUMNS = getColumnsFromWidth('xlarge'); +const MAX_SECTION_WIDTH = (LARGE_WIDGET_SIZE + 2 * 5) * MAX_COLUMNS; // widget size + 5 padding per side +const ITEMS_SPACING = 5; +const styles = { + grid: { + textAlign: 'center', + // Avoid tiles taking too much space on large screens. + maxWidth: MAX_SECTION_WIDTH, + overflow: 'hidden', + width: `calc(100% + ${2 * ITEMS_SPACING}px)`, // This is needed to compensate for the `margin: -5px` added by MUI related to spacing. + }, + bannerContainer: { + width: '100%', + maxWidth: MAX_SECTION_WIDTH - 2 * ITEMS_SPACING, + }, +}; + +type Props = {| + selectInAppTutorial: (tutorialId: string) => void, +|}; + +const FlingGame = ({ selectInAppTutorial }: Props) => { + const { + inAppTutorialShortHeaders, + inAppTutorialsFetchingError, + fetchInAppTutorials, + currentlyRunningInAppTutorial, + } = React.useContext(InAppTutorialContext); + const { getTutorialProgress } = React.useContext(PreferencesContext); + const authenticatedUser = React.useContext(AuthenticatedUserContext); + const windowWidth = useResponsiveWindowWidth(); + + const getTutorialPartProgress = ({ + tutorialId, + part, + }: { + tutorialId: string, + part: number, + }) => { + const tutorialProgress = getTutorialProgress({ + tutorialId, + userId: authenticatedUser.profile + ? authenticatedUser.profile.id + : undefined, + }); + if (!tutorialProgress || !tutorialProgress.progress) return 0; + return tutorialProgress.progress[part]; + }; + + const isTutorialPartComplete = ({ + tutorialId, + part, + }: { + tutorialId: string, + part: number, + }) => { + return ( + getTutorialPartProgress({ + tutorialId, + part, + }) === 100 + ); + }; + + const flingInAppTutorialCards = [ + { + key: 'create', + title: t`Start your game`, + description: t`Add your first characters to the scene and throw your first objects.`, + keyPoints: [ + t`Game scene size`, + t`Objects and characters`, + t`Game Scenes`, + t`Throwing physics`, + ], + durationInMinutes: 5, + locked: false, // First phase is never locked + // Phase is disabled if complete or if there's a running tutorial + disabled: + !!currentlyRunningInAppTutorial || + isTutorialPartComplete({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 0, + }), + progress: getTutorialPartProgress({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 0, + }), + renderImage: props => , + }, + { + key: 'publish', + title: t`Improve and publish your Game`, + description: t`Add personality to your game and publish it online.`, + keyPoints: [ + t`Game background`, + t`In-game obstacles`, + t`“You win” message`, + t`Sharing online`, + ], + durationInMinutes: 10, + // Second phase is locked if first phase is not complete + locked: !isTutorialPartComplete({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 0, + }), + // Phase is disabled if complete or if there's a running tutorial + disabled: + !!currentlyRunningInAppTutorial || + isTutorialPartComplete({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 1, + }), + progress: getTutorialPartProgress({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 1, + }), + renderImage: props => , + }, + { + key: 'leaderboards', + title: t`Add leaderboards to your online Game`, + description: t`Add player logins to your game and add a leaderboard.`, + keyPoints: [ + t`Game personalisation`, + t`“Start” screen`, + t`Timers`, + t`Leaderboards`, + ], + durationInMinutes: 15, + // Third phase is locked if second phase is not complete + locked: !isTutorialPartComplete({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 1, + }), + // Phase is disabled if complete or if there's a running tutorial + disabled: + !!currentlyRunningInAppTutorial || + isTutorialPartComplete({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 2, + }), + progress: getTutorialPartProgress({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 2, + }), + renderImage: props => , + }, + ]; + + const isFlingTutorialComplete = + isTutorialPartComplete({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 0, + }) && + isTutorialPartComplete({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 1, + }) && + isTutorialPartComplete({ + tutorialId: FLING_GAME_IN_APP_TUTORIAL_ID, + part: 2, + }); + + return ( + +
+ {inAppTutorialsFetchingError ? ( + + An error occurred when downloading the tutorials.{' '} + + Please check your internet connection or try again later. + + + ) : inAppTutorialShortHeaders === null ? ( + + ) : ( + + {isFlingTutorialComplete ? ( + + ( + + + + + + )} + onClick={() => + selectInAppTutorial(FLING_GAME_IN_APP_TUTORIAL_ID) + } + /> + + ) : ( + flingInAppTutorialCards.map(item => ( + + + selectInAppTutorial(FLING_GAME_IN_APP_TUTORIAL_ID) + } + /> + + )) + )} + + )} +
+
+ ); +}; + +export default FlingGame; diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/GuidedLessons.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/GuidedLessons.js index 48f0c1621e58..e5f7e97618ae 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/GuidedLessons.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/GuidedLessons.js @@ -41,13 +41,13 @@ const getColumnsFromWidth = (width: WidthType) => { case 'small': return 1; case 'medium': - return 2; - case 'large': return 3; - case 'xlarge': + case 'large': return 4; + case 'xlarge': + return 6; default: - return 2; + return 3; } }; diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/InAppTutorialPhaseCard.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/InAppTutorialPhaseCard.js index 78ece79d012f..216abab7007f 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/InAppTutorialPhaseCard.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/InAppTutorials/InAppTutorialPhaseCard.js @@ -3,11 +3,7 @@ import * as React from 'react'; import { I18n } from '@lingui/react'; import Divider from '@material-ui/core/Divider'; -import { - ColumnStackLayout, - LineStackLayout, - ResponsiveLineStackLayout, -} from '../../../../UI/Layout'; +import { ColumnStackLayout, LineStackLayout } from '../../../../UI/Layout'; import Text from '../../../../UI/Text'; import { type MessageDescriptor } from '../../../../Utils/i18n/MessageDescriptor.flow'; import { CardWidget } from '../CardWidget'; @@ -153,54 +149,27 @@ const InAppTutorialPhaseCard = ({ {keyPoints && } {keyPoints && ( - - -
    - {keyPoints.map((keyPoint, index) => - index % 2 === 0 ? ( - - {i18n._(keyPoint)} - - ) : null - )} -
-
- -
    - {keyPoints.map((keyPoint, index) => - index % 2 === 1 ? ( - - {i18n._(keyPoint)} - - ) : null - )} -
-
-
+ +
    + {keyPoints.map((keyPoint, index) => ( + + {i18n._(keyPoint)} + + ))} +
+
)} diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/MainPage.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/MainPage.js index 8e2c05572b2a..bf71e68505cc 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/MainPage.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/MainPage.js @@ -28,6 +28,7 @@ import GuidedLessons from '../InAppTutorials/GuidedLessons'; import ChevronArrowRight from '../../../../UI/CustomSvgIcons/ChevronArrowRight'; import Upload from '../../../../UI/CustomSvgIcons/Upload'; import WikiSearchBar from '../../../../UI/WikiSearchBar'; +import FlingGame from '../InAppTutorials/FlingGame'; const useStyles = makeStyles({ tile: { @@ -235,6 +236,17 @@ const MainPage = ({ tutorials={tutorials} /> + + + Create and Publish a Fling game + + + + 3-part tutorial to creating and publishing a game from scratch. + + + + { setNewProjectSetupDialogOpen(true); }, onOpenProfile: () => openProfileDialog(true), - onOpenHelpFinder: openCommandPalette, onOpenLanguageDialog: () => openLanguageDialog(true), onOpenPreferences: () => openPreferencesDialog(true), onOpenAbout: () => openAboutDialog(true),