mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00

* The Get Started page has been removed and replaced by the Learn page as the first page displayed when GDevelop launches * The Learn page has been completely reworked to put forward the different resources a creator can use to improve their skills with Game Creation * A new option in the Preferences allows users to define the Create page as the default first page on launch * Courses can now be purchased as a whole instead of per chapter, making it simpler to follow a full course * Bundles with multiple courses are coming up soon!
122 lines
3.3 KiB
JavaScript
122 lines
3.3 KiB
JavaScript
// @flow
|
|
|
|
import * as React from 'react';
|
|
import { Trans } from '@lingui/macro';
|
|
|
|
import type {
|
|
Course,
|
|
LockedVideoBasedCourseChapter,
|
|
LockedTextBasedCourseChapter,
|
|
} from '../Utils/GDevelopServices/Asset';
|
|
import Text from '../UI/Text';
|
|
import { ColumnStackLayout } from '../UI/Layout';
|
|
import Paper from '../UI/Paper';
|
|
import RaisedButton from '../UI/RaisedButton';
|
|
import { useResponsiveWindowSize } from '../UI/Responsive/ResponsiveWindowMeasurer';
|
|
import Lock from '../UI/CustomSvgIcons/Lock';
|
|
import { getYoutubeVideoIdFromUrl } from '../Utils/Youtube';
|
|
|
|
const styles = {
|
|
videoAndMaterialsContainer: {
|
|
display: 'flex',
|
|
marginTop: 8,
|
|
gap: 8,
|
|
alignItems: 'stretch',
|
|
flexWrap: 'wrap',
|
|
marginBottom: 8,
|
|
flex: 1,
|
|
minWidth: 0,
|
|
},
|
|
lockedChapterTextContainer: {
|
|
// Similar to Line component but without the minWidth:0 that somehow
|
|
// prevents container to wrap when overflowing.
|
|
display: 'flex',
|
|
flex: 1,
|
|
minHeight: 0,
|
|
},
|
|
videoContainer: {
|
|
flex: 2,
|
|
minWidth: 300,
|
|
display: 'flex',
|
|
position: 'relative',
|
|
},
|
|
videoThumbnail: {
|
|
flex: 1,
|
|
aspectRatio: '16 / 9',
|
|
objectFit: 'cover',
|
|
width: '100%',
|
|
borderRadius: 4,
|
|
},
|
|
lockerImage: { height: 60, width: 60 },
|
|
lockedOverlay: {
|
|
position: 'absolute',
|
|
background: 'rgba(0, 0, 0, 0.6)',
|
|
borderRadius: 4,
|
|
inset: 0,
|
|
height: `100%`,
|
|
display: 'flex',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
color: 'white', // Force text/icon color since it's on a dark overlay.
|
|
},
|
|
sideBar: { padding: 16, display: 'flex' },
|
|
};
|
|
|
|
const LockedOverlay = () => (
|
|
<div style={styles.lockedOverlay}>
|
|
<Lock style={styles.lockerImage} />
|
|
</div>
|
|
);
|
|
|
|
type Props = {|
|
|
course: Course,
|
|
courseChapter: LockedVideoBasedCourseChapter | LockedTextBasedCourseChapter,
|
|
onClickUnlock: () => void,
|
|
|};
|
|
|
|
const LockedCourseChapterPreview = React.forwardRef<Props, HTMLDivElement>(
|
|
({ course, courseChapter, onClickUnlock }, ref) => {
|
|
const { windowSize } = useResponsiveWindowSize();
|
|
const youtubeVideoId = courseChapter.videoUrl
|
|
? getYoutubeVideoIdFromUrl(courseChapter.videoUrl)
|
|
: null;
|
|
|
|
return (
|
|
<div style={styles.videoAndMaterialsContainer}>
|
|
{youtubeVideoId && (
|
|
<div
|
|
style={{
|
|
...styles.videoContainer,
|
|
maxWidth: windowSize === 'xlarge' ? 960 : 640,
|
|
}}
|
|
>
|
|
<img
|
|
alt={`Video for lesson ${courseChapter.title}`}
|
|
style={styles.videoThumbnail}
|
|
src={`https://i.ytimg.com/vi/${youtubeVideoId}/sddefault.jpg`}
|
|
/>
|
|
<LockedOverlay />
|
|
</div>
|
|
)}
|
|
<div style={styles.lockedChapterTextContainer}>
|
|
<Paper background="medium" style={styles.sideBar}>
|
|
<ColumnStackLayout noMargin justifyContent="center">
|
|
<Text noMargin size="sub-title">
|
|
<Trans>Unlock this lesson to finish the course</Trans>
|
|
</Text>
|
|
<RaisedButton
|
|
primary
|
|
fullWidth
|
|
label={<Trans>Unlock the whole course</Trans>}
|
|
onClick={onClickUnlock}
|
|
/>
|
|
</ColumnStackLayout>
|
|
</Paper>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
|
|
export default LockedCourseChapterPreview;
|