mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Improve wording and design across the publishing flow to Liluo
+ display game consolidated analytics on the analytics page
This commit is contained in:
@@ -66,7 +66,7 @@ const ExportHome = ({
|
||||
<div style={styles.titleContainer}>
|
||||
<Line>
|
||||
<Text size="title">
|
||||
<Trans>Share with friends</Trans>
|
||||
<Trans>Publish and share with friends on Liluo.io</Trans>
|
||||
</Text>
|
||||
</Line>
|
||||
</div>
|
||||
@@ -89,7 +89,7 @@ const ExportHome = ({
|
||||
<div style={styles.titleContainer}>
|
||||
<Line>
|
||||
<Text size="title">
|
||||
<Trans>Publish your game</Trans>
|
||||
<Trans>Publish your game on other stores</Trans>
|
||||
</Text>
|
||||
</Line>
|
||||
</div>
|
||||
|
@@ -39,6 +39,7 @@ import {
|
||||
type Game,
|
||||
} from '../../Utils/GDevelopServices/Game';
|
||||
import AuthenticatedUserContext from '../../Profile/AuthenticatedUserContext';
|
||||
import AlertMessage from '../../UI/AlertMessage';
|
||||
|
||||
const styles = {
|
||||
icon: {
|
||||
@@ -51,8 +52,8 @@ export const ExplanationHeader = () => (
|
||||
<Line>
|
||||
<Text align="center">
|
||||
<Trans>
|
||||
Generate a unique link to share your game, playable from any computer
|
||||
or mobile phone's browser.
|
||||
Generate a unique link, playable from any computer or mobile phone's
|
||||
browser.
|
||||
</Trans>
|
||||
</Text>
|
||||
</Line>
|
||||
@@ -85,11 +86,12 @@ export const WebProjectLink = ({
|
||||
const exportPending = !errored && exportStep !== '' && exportStep !== 'done';
|
||||
const isBuildComplete = build && build.status === 'complete';
|
||||
const isBuildPublished = build && game && build.id === game.publicWebBuildId;
|
||||
const gameUrl = getGameUrl(game);
|
||||
const buildUrl =
|
||||
exportPending || !isBuildComplete
|
||||
? null
|
||||
: isBuildPublished
|
||||
? getGameUrl(game)
|
||||
? gameUrl
|
||||
: getBuildArtifactUrl(build, 's3Key');
|
||||
|
||||
const loadGame = React.useCallback(
|
||||
@@ -244,53 +246,76 @@ export const WebProjectLink = ({
|
||||
</Line>
|
||||
)}
|
||||
{isBuildPublished && !navigator.share && (
|
||||
<Line justifyContent="flex-end">
|
||||
<FacebookShareButton
|
||||
url={buildUrl}
|
||||
style={styles.icon}
|
||||
quote={`Try the game I just created with GDevelop.io`}
|
||||
hashtag="#gdevelop"
|
||||
>
|
||||
<FacebookIcon size={32} round />
|
||||
</FacebookShareButton>
|
||||
<RedditShareButton
|
||||
url={buildUrl}
|
||||
title={`Try the game I just created with r/gdevelop`}
|
||||
style={styles.icon}
|
||||
>
|
||||
<RedditIcon size={32} round />
|
||||
</RedditShareButton>
|
||||
<TwitterShareButton
|
||||
title={`Try the game I just created with GDevelop.io`}
|
||||
hashtags={['gdevelop']}
|
||||
url={buildUrl}
|
||||
style={styles.icon}
|
||||
>
|
||||
<TwitterIcon size={32} round />
|
||||
</TwitterShareButton>
|
||||
<WhatsappShareButton
|
||||
title={`Try the game I just created with GDevelop.io`}
|
||||
url={buildUrl}
|
||||
style={styles.icon}
|
||||
>
|
||||
<WhatsappIcon size={32} round />
|
||||
</WhatsappShareButton>
|
||||
<EmailShareButton
|
||||
subject="My GDevelop game"
|
||||
body="Try the game I just created with GDevelop.io"
|
||||
url={buildUrl}
|
||||
style={styles.icon}
|
||||
>
|
||||
<EmailIcon size={32} round />
|
||||
</EmailShareButton>
|
||||
<Line justifyContent="space-between">
|
||||
<Column justifyContent="center">
|
||||
<AlertMessage kind="info">
|
||||
<Trans>
|
||||
This link is unique to your game. Show what you made to
|
||||
the community!
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
</Column>
|
||||
<Column justifyContent="flex-end">
|
||||
<Line>
|
||||
<FacebookShareButton
|
||||
url={buildUrl}
|
||||
style={styles.icon}
|
||||
quote={`Try the game I just created with GDevelop.io`}
|
||||
hashtag="#gdevelop"
|
||||
>
|
||||
<FacebookIcon size={32} round />
|
||||
</FacebookShareButton>
|
||||
<RedditShareButton
|
||||
url={buildUrl}
|
||||
title={`Try the game I just created with r/gdevelop`}
|
||||
style={styles.icon}
|
||||
>
|
||||
<RedditIcon size={32} round />
|
||||
</RedditShareButton>
|
||||
<TwitterShareButton
|
||||
title={`Try the game I just created with GDevelop.io`}
|
||||
hashtags={['gdevelop']}
|
||||
url={buildUrl}
|
||||
style={styles.icon}
|
||||
>
|
||||
<TwitterIcon size={32} round />
|
||||
</TwitterShareButton>
|
||||
<WhatsappShareButton
|
||||
title={`Try the game I just created with GDevelop.io`}
|
||||
url={buildUrl}
|
||||
style={styles.icon}
|
||||
>
|
||||
<WhatsappIcon size={32} round />
|
||||
</WhatsappShareButton>
|
||||
<EmailShareButton
|
||||
subject="My GDevelop game"
|
||||
body="Try the game I just created with GDevelop.io"
|
||||
url={buildUrl}
|
||||
style={styles.icon}
|
||||
>
|
||||
<EmailIcon size={32} round />
|
||||
</EmailShareButton>
|
||||
</Line>
|
||||
</Column>
|
||||
</Line>
|
||||
)}
|
||||
{!isBuildPublished && (
|
||||
<Line justifyContent="center">
|
||||
<RaisedButton
|
||||
label={<Trans>Publish this build to the game's page</Trans>}
|
||||
onClick={onUpdatePublicBuild}
|
||||
/>
|
||||
<Line>
|
||||
<AlertMessage
|
||||
kind="info"
|
||||
renderRightButton={() => (
|
||||
<RaisedButton
|
||||
label={<Trans>Update your game</Trans>}
|
||||
onClick={onUpdatePublicBuild}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<Trans>
|
||||
This link is private so you can share it with friends and
|
||||
testers. When you're ready you can update your Liluo.io game
|
||||
page.
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
</Line>
|
||||
)}
|
||||
</Column>
|
||||
|
@@ -38,6 +38,12 @@ import PlaceholderLoader from '../UI/PlaceholderLoader';
|
||||
import PublicGamePropertiesDialog from '../ProjectManager/PublicGamePropertiesDialog';
|
||||
import TextField from '../UI/TextField';
|
||||
|
||||
const styles = {
|
||||
tableRowStatColumn: {
|
||||
width: 100,
|
||||
},
|
||||
};
|
||||
|
||||
export type GamesDetailsTab = 'details' | 'builds' | 'analytics';
|
||||
|
||||
type Props = {|
|
||||
@@ -140,7 +146,8 @@ export const GameDetailsDialog = ({
|
||||
const { id } = profile;
|
||||
|
||||
try {
|
||||
setPublicGame(null); // Public game will auto update when game is updated.
|
||||
// Set public game to null as it will be refetched automatically by the callback above.
|
||||
setPublicGame(null);
|
||||
const gameId = project.getProjectUuid();
|
||||
const updatedGame = await updateGame(getAuthorizationHeader, id, gameId, {
|
||||
authorName: project.getAuthor() || 'Unspecified publisher',
|
||||
@@ -167,6 +174,30 @@ export const GameDetailsDialog = ({
|
||||
}
|
||||
};
|
||||
|
||||
const unpublishGame = React.useCallback(
|
||||
async () => {
|
||||
if (!profile) return;
|
||||
|
||||
const { id } = profile;
|
||||
try {
|
||||
// Set public game to null as it will be refetched automatically by the callback above.
|
||||
setPublicGame(null);
|
||||
const updatedGame = await updateGame(
|
||||
getAuthorizationHeader,
|
||||
id,
|
||||
game.id,
|
||||
{
|
||||
publicWebBuildId: null,
|
||||
}
|
||||
);
|
||||
onGameUpdated(updatedGame);
|
||||
} catch (err) {
|
||||
console.error('Unable to update the game', err);
|
||||
}
|
||||
},
|
||||
[game, getAuthorizationHeader, profile, onGameUpdated]
|
||||
);
|
||||
|
||||
const authorUsernames =
|
||||
publicGame && publicGame.authors
|
||||
? publicGame.authors.map(author => author.username).filter(Boolean)
|
||||
@@ -275,7 +306,7 @@ export const GameDetailsDialog = ({
|
||||
<FlatButton
|
||||
onClick={() => {
|
||||
const answer = Window.showConfirmDialog(
|
||||
"Are you sure you want to unregister this game? You won't get access to analytics and metrics, unless you register it again."
|
||||
"Are you sure you want to unregister this game? \n\nIt will disappear from your games dashboard and you won't get access to analytics, unless you register it again."
|
||||
);
|
||||
|
||||
if (!answer) return;
|
||||
@@ -285,6 +316,23 @@ export const GameDetailsDialog = ({
|
||||
label={<Trans>Unregister this game</Trans>}
|
||||
/>
|
||||
<Spacer />
|
||||
{publicGame.publicWebBuildId && (
|
||||
<>
|
||||
<RaisedButton
|
||||
onClick={() => {
|
||||
const answer = Window.showConfirmDialog(
|
||||
'Are you sure you want to unpublish this game? \n\nThis will make your Liluo unique game URL not accessible anymore. \n\nYou can decide anytime to publish it again.'
|
||||
);
|
||||
|
||||
if (!answer) return;
|
||||
|
||||
unpublishGame();
|
||||
}}
|
||||
label={<Trans>Unpublish from Liluo</Trans>}
|
||||
/>
|
||||
<Spacer />
|
||||
</>
|
||||
)}
|
||||
<RaisedButton
|
||||
primary
|
||||
onClick={() => setIsPublicGamePropertiesDialogOpen(true)}
|
||||
@@ -314,6 +362,48 @@ export const GameDetailsDialog = ({
|
||||
</PlaceholderError>
|
||||
) : (
|
||||
<ColumnStackLayout expand>
|
||||
<Line noMargin alignItems="center">
|
||||
<Text size="title">
|
||||
<Trans>Consolidated metrics</Trans>
|
||||
</Text>
|
||||
<Spacer />
|
||||
{!publicGame && <CircularProgress size={20} />}
|
||||
</Line>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableRowColumn>
|
||||
<Trans>Last week sessions count</Trans>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn style={styles.tableRowStatColumn}>
|
||||
{publicGame &&
|
||||
publicGame.metrics &&
|
||||
publicGame.metrics.lastWeekSessionsCount
|
||||
? publicGame.metrics.lastWeekSessionsCount
|
||||
: '-'}
|
||||
</TableRowColumn>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableRowColumn>
|
||||
<Trans>Last year sessions count</Trans>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn style={styles.tableRowStatColumn}>
|
||||
{publicGame &&
|
||||
publicGame.metrics &&
|
||||
publicGame.metrics.lastYearSessionsCount
|
||||
? publicGame.metrics.lastYearSessionsCount
|
||||
: '-'}
|
||||
</TableRowColumn>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Line noMargin alignItems="center">
|
||||
<Text size="title">
|
||||
<Trans>Daily metrics</Trans>
|
||||
</Text>
|
||||
<Spacer />
|
||||
{isGameMetricsLoading && <CircularProgress size={20} />}
|
||||
</Line>
|
||||
<Line noMargin>
|
||||
<SelectField
|
||||
fullWidth
|
||||
@@ -360,20 +450,13 @@ export const GameDetailsDialog = ({
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
) : null}
|
||||
<Line noMargin alignItems="center">
|
||||
<Text size="title">
|
||||
<Trans>Main metrics</Trans>
|
||||
</Text>
|
||||
<Spacer />
|
||||
{isGameMetricsLoading && <CircularProgress size={20} />}
|
||||
</Line>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableRowColumn>
|
||||
<Trans>Players count</Trans>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<TableRowColumn style={styles.tableRowStatColumn}>
|
||||
{gameRollingMetrics && gameRollingMetrics.players
|
||||
? gameRollingMetrics.players.d0Players
|
||||
: '-'}
|
||||
@@ -383,7 +466,7 @@ export const GameDetailsDialog = ({
|
||||
<TableRowColumn>
|
||||
<Trans>Sessions count</Trans>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<TableRowColumn style={styles.tableRowStatColumn}>
|
||||
{gameRollingMetrics && gameRollingMetrics.sessions
|
||||
? gameRollingMetrics.sessions.d0Sessions
|
||||
: '-'}
|
||||
@@ -393,7 +476,7 @@ export const GameDetailsDialog = ({
|
||||
<TableRowColumn>
|
||||
<Trans>New players count</Trans>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<TableRowColumn style={styles.tableRowStatColumn}>
|
||||
{gameRollingMetrics && gameRollingMetrics.players
|
||||
? gameRollingMetrics.players.d0NewPlayers
|
||||
: '-'}
|
||||
@@ -408,13 +491,6 @@ export const GameDetailsDialog = ({
|
||||
metrics for your game.
|
||||
</AlertMessage>
|
||||
) : null}
|
||||
<Line noMargin alignItems="center">
|
||||
<Text size="title">
|
||||
<Trans>Retention of players</Trans>
|
||||
</Text>
|
||||
<Spacer />
|
||||
{isGameMetricsLoading && <CircularProgress size={20} />}
|
||||
</Line>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{[1, 2, 3, 4, 5, 6, 7].map(dayIndex => (
|
||||
@@ -422,7 +498,7 @@ export const GameDetailsDialog = ({
|
||||
<TableRowColumn>
|
||||
<Trans>Day {dayIndex} retained players</Trans>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<TableRowColumn style={styles.tableRowStatColumn}>
|
||||
{gameRollingMetrics &&
|
||||
gameRollingMetrics.retention &&
|
||||
gameRollingMetrics.retention[
|
||||
|
@@ -11,6 +11,10 @@ export type PublicGame = {
|
||||
publicWebBuildId?: ?string,
|
||||
description?: string,
|
||||
authors: Array<UserPublicProfile>,
|
||||
metrics?: {
|
||||
lastWeekSessionsCount: number,
|
||||
lastYearSessionsCount: number,
|
||||
},
|
||||
};
|
||||
|
||||
export type Game = {
|
||||
|
Reference in New Issue
Block a user