Addons
@@ -204,6 +243,13 @@ const Credits = () => (
More than 100 people have helped translate TurboWarp and its addons into many languages —
far more than we could hope to list here.
+
+ PenguinMod is (very very slowly) getting translated into other languages, in the future
+ hopefully the same number of languages can be supported. It'll take a while until we get there though.
+
+ Contributors:
+
+ The list order is randomized on each refresh.
Unfortunately due to Snail IDE's small size, we have decided to mainly focus on English.
You can still use Snail IDE with the other languages, but they will not be updated at this time.
diff --git a/src/playground/credits/users.js b/src/playground/credits/users.js
index b296b85ae23..b7e1232188d 100644
--- a/src/playground/credits/users.js
+++ b/src/playground/credits/users.js
@@ -8,7 +8,7 @@ const shuffle = list => {
return list;
};
-const fromHardcoded = ({userId, username, name}) => ({
+const fromHardcoded = ({ userId, username, name }) => ({
image: `https://trampoline.turbowarp.org/avatars/${userId}`,
href: `https://scratch.mit.edu/users/${username}/`,
text: name || username
@@ -29,15 +29,11 @@ const fromHardcodedCodeberg = username => ({
href: `https://codeberg.org/${username}/`,
text: username
});
-
-const fromHardcodedDiscord = async userId => {
- const res = await fetch(`https://pmupdatereader.jeremygamer13.repl.co/user/${userId}`);
- const json = await res.json();
- return {
- image: json.avatarURL,
- text: json.username
- };
-};
+const fromHardcodedNamed = username => ({
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ text: username
+});
const addonDevelopers = [
{
@@ -107,7 +103,7 @@ const addonDevelopers = [
},
{
userId: '9636514',
- username: 'Tacodude7729'
+ username: 'Tacodiva7729'
},
{
userId: '14792872',
@@ -120,8 +116,11 @@ const addonDevelopers = [
{
userId: '64691048',
username: 'CST1229'
+ },
+ {
+ userId: '12498592',
+ username: 'LilyMakesThings'
}
- // TODO: retronbv is banned?
].map(fromHardcoded);
const pmDevelopers = [
@@ -133,6 +132,7 @@ const pmDevelopers = [
'jwklong',
'tnix100',
'RedMan13',
+ 'SharkPool-SP',
'showierdata9978'
].map(fromHardcodedGithub);
@@ -158,9 +158,413 @@ const rubyDev = [
"adevguylol"
].map(fromHardcodedGithub)
-const logoArtists = Promise.all([
- '593554048188416001'
-].map(fromHardcodedDiscord));
+const pmPullRequestDevelopers = [ // these people made a PR that got merged, or got a dev to add something they made
+ {
+ text: 'NexusKitten',
+ image: `https://github.com/NexusKitten.png`,
+ href: `https://github.com/NexusKitten/`,
+ },
+ {
+ text: 'LilyMakesThings',
+ image: `https://github.com/LilyMakesThings.png`,
+ href: `https://github.com/LilyMakesThings/`,
+ },
+ {
+ text: 'MikeDev101',
+ image: `https://github.com/MikeDev101.png`,
+ href: `https://github.com/MikeDev101/`,
+ },
+ {
+ text: 'kokofixcomputers',
+ image: `https://github.com/kokofixcomputers.png`,
+ href: `https://github.com/kokofixcomputers/`,
+ },
+ {
+ text: 'PPPDUD',
+ image: `https://github.com/PPPDUD.png`,
+ href: `https://github.com/PPPDUD/`,
+ },
+ {
+ text: 'qbjl',
+ image: `https://github.com/qbjl.png`,
+ href: `https://github.com/qbjl/`,
+ },
+ {
+ text: 'minidogg',
+ image: `https://github.com/minidogg.png`,
+ href: `https://github.com/minidogg/`,
+ },
+ {
+ text: 'concertalyis',
+ image: `https://github.com/concertalyis.png`,
+ href: `https://github.com/concertalyis/`,
+ },
+ {
+ text: 'Steve0Greatness',
+ image: `https://github.com/Steve0Greatness.png`,
+ href: `https://github.com/Steve0Greatness/`,
+ },
+ {
+ text: 'ilikecoding-197',
+ image: `https://github.com/ilikecoding-197.png`,
+ href: `https://github.com/ilikecoding-197/`,
+ },
+ {
+ text: 'NotEmbin',
+ image: `https://github.com/NotEmbin.png`,
+ href: `https://github.com/NotEmbin/`,
+ },
+ { // rx or ry single fix
+ text: 'NotCryptid',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: `https://github.com/NotCryptid/`,
+ },
+ {
+ text: 'DogeisCut',
+ image: `https://github.com/DogeisCut.png`,
+ href: `https://github.com/Dogeiscut/`,
+ },
+ // list could be missing some people, but theres not really a way to tell
+];
+
+const pmApiDevelopers = [
+ 'JeremyGamer13',
+ 'RedMan13',
+ 'tnix100',
+ 'Ianyourgod',
+ 'JoshAtticus',
+ 'enderhacker'
+].map(fromHardcodedGithub);
+
+const pmTranslators = [
+ {
+ text: 'kolikiscool',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'n0name',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'a_pc',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'LoyalBlackBishopyBoi',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/LoyalBlackBishopyBoi`,
+ href: "https://scratch.mit.edu/users/LoyalBlackBishopyBoi/",
+ },
+ {
+ text: 'onetoanother',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/onetoanother`,
+ href: "https://penguinmod.com/profile?user=onetoanother",
+ },
+ {
+ text: 'NamelessCat',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/NamelessCat`,
+ href: "https://penguinmod.com/profile?user=NamelessCat",
+ },
+ {
+ text: 'Just-Noone',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/Just-Noone`,
+ href: "https://penguinmod.com/profile?user=Just-Noone",
+ },
+ {
+ text: 'goose_but_smart',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/goose_but_smart`,
+ href: "https://penguinmod.com/profile?user=goose_but_smart",
+ },
+ {
+ text: 'Le_Blob77',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/Le_Blob77`,
+ href: "https://penguinmod.com/profile?user=Le_Blob77",
+ },
+ {
+ text: 'MrRedstonia',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/MrRedstonia`,
+ href: "https://penguinmod.com/profile?user=MrRedstonia",
+ },
+ {
+ text: 'TheShovel',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/TheShovel`,
+ href: "https://penguinmod.com/profile?user=TheShovel",
+ },
+ {
+ text: 'SmolBoi37',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'GigantTech',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/GigantTech`,
+ href: "https://penguinmod.com/profile?user=GigantTech",
+ },
+ {
+ text: 'hacker_anonimo',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/hacker_anonimo`,
+ href: "https://penguinmod.com/profile?user=hacker_anonimo",
+ },
+ {
+ text: 'zaaxd52',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/zaaxd52`,
+ href: "https://penguinmod.com/profile?user=zaaxd52",
+ },
+ {
+ text: 'G1nX',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/G1nX`,
+ href: "https://penguinmod.com/profile?user=G1nX",
+ },
+ {
+ text: 'FNFFortune',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/FNFFortune`,
+ href: "https://penguinmod.com/profile?user=FNFFortune",
+ },
+ // has since left the server
+ // possibly they have a new account, so replace the name & url if so
+ {
+ text: 'Gabberythethughunte',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://penguinmod.com/profile?user=Gabberythethughunte",
+ },
+ {
+ text: 'keriyo',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/keriyo`,
+ href: "https://penguinmod.com/profile?user=keriyo",
+ },
+ {
+ text: 'DenPlayTS',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/DenPlayTS`,
+ href: "https://penguinmod.com/profile?user=DenPlayTS",
+ },
+ {
+ text: 'Tsalbre',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/Tsalbre`,
+ href: "https://penguinmod.com/profile?user=Tsalbre",
+ },
+ {
+ text: 'MubiLop',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/MubiLop`,
+ href: "https://penguinmod.com/profile?user=MubiLop",
+ },
+ {
+ text: 'TLP136',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/TLP136`,
+ href: "https://penguinmod.com/profile?user=TLP136",
+ },
+ {
+ text: 'Cymock',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/Cymock`,
+ href: "https://penguinmod.com/profile?user=Cymock",
+ },
+ {
+ text: 'ItzzEndr',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/ItzzEndr`,
+ href: "https://penguinmod.com/profile?user=ItzzEndr",
+ },
+ {
+ text: 'Capysussa',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/Capysussa`,
+ href: "https://penguinmod.com/profile?user=Capysussa",
+ },
+ // con-zie is now banned from PenguinMod
+ {
+ text: 'con-zie',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'ImNotScratchY_lolol',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/ImNotScratchY_lolol`,
+ href: "https://penguinmod.com/profile?user=ImNotScratchY_lolol",
+ },
+ {
+ text: 'justablock',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/justablock`,
+ href: "https://penguinmod.com/profile?user=justablock",
+ },
+ {
+ text: 'inventionpro',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/inventionpro`,
+ href: "https://penguinmod.com/profile?user=inventionpro",
+ },
+ {
+ text: 'SkyBuilder1717',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/SkyBuilder1717`,
+ href: "https://penguinmod.com/profile?user=SkyBuilder1717",
+ },
+ {
+ text: 'Parham1258',
+ image: `https://avatars.githubusercontent.com/u/95162943?v=4`,
+ href: "https://github.com/Parham1258",
+ },
+ {
+ text: 'lem0n0fficial',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/lem0n0fficial`,
+ href: "https://penguinmod.com/profile?user=lem0n0fficial",
+ },
+ {
+ text: 'Oldcoinmania',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/Oldcoinmania`,
+ href: "https://penguinmod.com/profile?user=Oldcoinmania",
+ },
+ {
+ text: 'mariocraft987',
+ image: `https://avatars.githubusercontent.com/u/154646419?v=4`,
+ href: "https://github.com/mariocraft987",
+ },
+];
+
+const pmCostumeSubmittors = [
+ // accounts
+ {
+ text: 'budc123',
+ image: `https://github.com/budc123.png`,
+ href: `https://github.com/budc123/`,
+ },
+ {
+ text: 'concertalyis',
+ image: `https://github.com/concertalyis.png`,
+ href: `https://github.com/concertalyis/`,
+ },
+ {
+ text: 'WojtekCodesToday',
+ image: `https://github.com/WojtekCodesToday.png`,
+ href: `https://github.com/WojtekCodesToday/`,
+ },
+ {
+ text: 'ddededodediamante',
+ image: `https://github.com/ddededodediamante.png`,
+ href: `https://github.com/ddededodediamante/`,
+ },
+ {
+ text: 'G1nX',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/G1nX`,
+ href: "https://penguinmod.com/profile?user=G1nX",
+ },
+ // unknown
+ {
+ text: 'maroonmball',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'eviepepsi',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: '1340073',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'cubeycreator',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'novaspiderultra',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'poundpound0209',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'gdplayer1035',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'cognitixsammy',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'thebusyman',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'skyglide5',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'cxnnie09',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'hoveras',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'blockgamer904',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+];
+const pmSoundSubmittors = [
+ // accounts
+ {
+ text: 'ddededodediamante',
+ image: `https://github.com/ddededodediamante.png`,
+ href: `https://github.com/ddededodediamante/`,
+ },
+ {
+ text: 'concertalyis',
+ image: `https://github.com/concertalyis.png`,
+ href: `https://github.com/concertalyis/`,
+ },
+ {
+ text: 'G1nX',
+ image: `https://trampoline.turbowarp.org/avatars/by-username/G1nX`,
+ href: "https://penguinmod.com/profile?user=G1nX",
+ },
+ // unknown
+ {
+ text: 'maroonmball',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'jn567',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'lukepuke311',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'ma_01',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'poundpound0209',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'cognitixsammy',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+ {
+ text: 'mememaster9000',
+ image: `https://penguinmod.com/unknown_user.png`,
+ href: "https://studio.penguinmod.com/credits.html#",
+ },
+];
const extensionDevelopers = [
'GarboMuffin',
@@ -176,14 +580,42 @@ const extensionDevelopers = [
'pooiod',
'dogeiscut'
].map(fromHardcodedGithub);
+const pmExtensionDevelopers = [
+ 'qbjl',
+ 'NexusKitten',
+ 'Gen1x-ALT',
+ 'SharkPool-SP',
+ 'DogeisCut', // listed as a collaborator on a SharkPool extension
+ 'David-Orangemoon',
+ 'pooiod',
+ 'WAYLIVES',
+ 'MrRedstonia',
+ 'MikeDev101',
+ 'liablelua',
+ 'AlexSchoolOH',
+ 'Monochromasity',
+ 'LilyMakesThings',
+ 'TheShovel',
+ 'skyhigh173',
+ 'Ruby-Devs',
+ 'oc9x97',
+ 'lego7set',
+ 'mariocraft987',
+ 'AshimeeAlt'
+].map(fromHardcodedGithub);
export default {
addonDevelopers: shuffle(addonDevelopers),
pmDevelopers: shuffle(pmDevelopers),
snDev: shuffle(snDev),
rubyDev: shuffle(rubyDev),
- logoArtists: shuffle(logoArtists),
extensionDevelopers: shuffle(extensionDevelopers),
snContributeCodeBerg: shuffle(snContributeCodeBerg),
- fromOther: shuffle(fromOther)
+ fromOther: shuffle(fromOther),
+ pmExtensionDevelopers: shuffle(pmExtensionDevelopers),
+ pmApiDevelopers: shuffle(pmApiDevelopers),
+ pmTranslators: shuffle(pmTranslators),
+ pmSoundSubmittors: shuffle(pmSoundSubmittors),
+ pmCostumeSubmittors: shuffle(pmCostumeSubmittors),
+ pmPullRequestDevelopers: shuffle(pmPullRequestDevelopers)
};
diff --git a/src/playground/embed.jsx b/src/playground/embed.jsx
index 5df39233d17..cb079d68fc4 100644
--- a/src/playground/embed.jsx
+++ b/src/playground/embed.jsx
@@ -15,9 +15,9 @@ import appTarget from './app-target';
const getProjectId = () => {
// For compatibility reasons, we first look at the hash.
// eg. https://turbowarp.org/embed.html#1
- const hashMatch = location.hash.match(/#(\d+)/);
- if (hashMatch !== null) {
- return hashMatch[1];
+ const hashMatch = location.hash.slice(1);
+ if (hashMatch !== '') {
+ return hashMatch;
}
// Otherwise, we'll recreate what "wildcard" routing does.
// eg. https://turbowarp.org/1/embed
diff --git a/src/playground/index.ejs b/src/playground/index.ejs
index 487e8c4dde4..f724f0075ff 100644
--- a/src/playground/index.ejs
+++ b/src/playground/index.ejs
@@ -30,9 +30,6 @@
100% { transform: rotate(360deg); }
}
-
-
-
diff --git a/src/playground/interface.css b/src/playground/interface.css
index 2471b774bf1..c9673d69698 100644
--- a/src/playground/interface.css
+++ b/src/playground/interface.css
@@ -107,14 +107,34 @@ a {
color: #4af;
}
-.unshared-update {
+.unshared-update,
+.infobox {
line-height: 1.5em;
padding: 0.5rem;
margin: 5px 0 8px 0;
border: 1px solid #b9d6ff;
background-color: #dbebff;
border-radius: 0.5rem;
+ border: 1px solid #b9d6ff;
+ background-color: #dbebff;
+}
+[theme="dark"] .infobox {
+ border-color: #203652;
+ background-color: #16202c;
+}
+.infobox p {
+ margin: 4px 0;
+}
+.infobox a {
+ font-weight: bold;
+ text-decoration: none;
}
+
+/* .unshared-update {
+ border-color: #ffb9b9;
+ background-color: #ffdbdb;
+} */
+
[theme="dark"] .unshared-update {
border-color: #203652;
background-color: #16202c;
@@ -147,7 +167,53 @@ a {
text-decoration: none;
}
+.remix-author-image {
+ width: 32px;
+ height: 32px;
+ margin-right: 4px;
+ border-radius: 4px;
+}
+
+.project-details {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin: 8px 0;
+}
+.project-metadata {
+ display: flex;
+ flex-direction: column;
+}
+.project-author-image {
+ width: 50px;
+ height: 50px;
+ border-radius: 4px;
+ margin-right: 8px;
+}
+.project-metadata h2 {
+ line-height: 1.4em;
+}
+.project-metadata p {
+ font-size: 0.85rem;
+}
+.project-metadata p a,
+.project-metadata a {
+ text-decoration: none;
+ font-weight: bold;
+}
+
+.center-sector {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+}
.report-link,
+.share-link {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+.share-link > img,
.report-link > img {
height: 16px;
margin-right: 4px;
@@ -155,10 +221,26 @@ a {
.report-link {
color: red !important;
}
-
-.profilelink,
-.profilelink {
- color: rgb(14, 141, 20) !important;
+.share-link {
+ background: transparent;
+ padding: 0;
+ margin: 0;
+ border: 0;
+ color: rgb(90, 90, 90) !important;
+ text-decoration: underline;
+ cursor: pointer;
+}
+.share-link:active {
+ filter: brightness(0.8);
+}
+.share-link > img {
+ filter: brightness(0.3529411765);
+}
+[theme="dark"] .share-link {
+ color: rgb(202, 202, 202) !important;
+}
+[theme="dark"] .share-link > img {
+ filter: brightness(0.7921568627);
}
.remixList {
@@ -190,4 +272,4 @@ a {
}
[theme="dark"] .remixProject:hover {
background-color: rgba(0, 0, 0, 5%);
-}
\ No newline at end of file
+}
diff --git a/src/playground/playground-interface.jsx b/src/playground/playground-interface.jsx
index d1e03d178af..3701c668ece 100644
--- a/src/playground/playground-interface.jsx
+++ b/src/playground/playground-interface.jsx
@@ -39,9 +39,9 @@ import styles from './interface.css';
const messages = defineMessages({
defaultTitle: {
- defaultMessage: 'A mod of TurboWarp',
+ defaultMessage: 'Playground',
description: 'Title of homepage',
- id: 'tw.guiDefaultTitle'
+ id: 'pm.playgroundDefaultTitle'
}
});
diff --git a/src/playground/render-interface.jsx b/src/playground/render-interface.jsx
index 4360f791e94..be3786a5ee7 100644
--- a/src/playground/render-interface.jsx
+++ b/src/playground/render-interface.jsx
@@ -17,10 +17,10 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { useState } from 'react';
-import { connect } from 'react-redux';
-import { compose } from 'redux';
-import { FormattedMessage, defineMessages, injectIntl, intlShape } from 'react-intl';
-import { getIsLoading } from '../reducers/project-state.js';
+import {connect} from 'react-redux';
+import {compose} from 'redux';
+import {FormattedMessage, defineMessages, injectIntl, intlShape} from 'react-intl';
+import {getIsLoading} from '../reducers/project-state.js';
import DOMElementRenderer from '../containers/dom-element-renderer.jsx';
import AppStateHOC from '../lib/app-state-hoc.jsx';
import Comments from '../components/comments/comments.jsx';
@@ -30,7 +30,6 @@ import TWStateManagerHOC from '../lib/tw-state-manager-hoc.jsx';
import TWThemeHOC from '../lib/tw-theme-hoc.jsx';
import SBFileUploaderHOC from '../lib/sb-file-uploader-hoc.jsx';
import TWPackagerIntegrationHOC from '../lib/tw-packager-integration-hoc.jsx';
-import TWRestorePointHOC from '../lib/tw-restore-point-hoc.jsx';
import SettingsStore from '../addons/settings-store-singleton';
import '../lib/tw-fix-history-api';
import GUI from './render-gui.jsx';
@@ -40,22 +39,21 @@ import ProjectInput from '../components/tw-project-input/project-input.jsx';
import FeaturedProjects from '../components/tw-featured-projects/featured-projects.jsx';
import LikeButton from '../components/sn-likebtn/LikeButton.jsx';
import Description from '../components/tw-description/description.jsx';
-import WebGlModal from '../containers/webgl-modal.jsx';
import BrowserModal from '../components/browser-modal/browser-modal.jsx';
-import CloudVariableBadge from '../components/tw-cloud-variable-badge/cloud-variable-badge.jsx';
-import { isRendererSupported, isBrowserSupported } from '../lib/tw-environment-support-prober';
+import CloudVariableBadge from '../containers/tw-cloud-variable-badge.jsx';
+import {isBrowserSupported} from '../lib/tw-environment-support-prober';
import AddonChannels from '../addons/channels';
-import { loadServiceWorker } from './load-service-worker';
+import {loadServiceWorker} from './load-service-worker';
import runAddons from '../addons/entry';
import styles from './interface.css';
import restore from './restore.js';
const urlparams = new URLSearchParams(location.search);
-const restoring = urlparams.get("restore");
-const restoreHandler = urlparams.get("handler");
-if (String(restoring) === "true") {
- console.log(restore)
+const restoring = urlparams.get('restore');
+const restoreHandler = urlparams.get('handler');
+if (String(restoring) === 'true') {
+ // console.log(restore)
restore(restoreHandler);
}
@@ -71,11 +69,36 @@ const handleClickAddonSettings = () => {
window.open(`${process.env.ROOT}${path}`);
};
+const xmlEscape = function (unsafe) {
+ return unsafe.replace(/[<>&'"]/g, c => {
+ switch (c) {
+ case '<': return '<';
+ case '>': return '>';
+ case '&': return '&';
+ case '\'': return ''';
+ case '"': return '"';
+ }
+ });
+};
+const formatProjectTitle = _title => {
+ const title = xmlEscape(String(_title));
+ const emojiRegex = /:(\w+):/g;
+ return title.replace(emojiRegex, match => {
+ const emojiName = match.replace(/:/gmi, '');
+ return `
`;
+ });
+};
+
const messages = defineMessages({
defaultTitle: {
defaultMessage: 'A mod of PenguinMod',
description: 'Title of homepage',
- id: 'tw.guiDefaultTitle'
+ id: 'pm.guiDefaultTitle'
}
});
@@ -132,9 +155,9 @@ const Footer = () => (
id="tw.footer.credits"
/>
-
+
@@ -148,7 +171,7 @@ const Footer = () => (
@@ -467,6 +562,20 @@ Interface.propTypes = {
credits: PropTypes.string,
instructions: PropTypes.string
}),
+ extraProjectInfo: PropTypes.shape({
+ accepted: PropTypes.bool,
+ isRemix: PropTypes.bool,
+ remixId: PropTypes.string,
+ tooLarge: PropTypes.bool,
+ author: PropTypes.string,
+ releaseDate: PropTypes.shape(Date),
+ isUpdated: PropTypes.bool
+ }),
+ remixedProjectInfo: PropTypes.shape({
+ loaded: PropTypes.bool,
+ name: PropTypes.string,
+ author: PropTypes.string
+ }),
isFullScreen: PropTypes.bool,
isLoading: PropTypes.bool,
isPlayerOnly: PropTypes.bool,
@@ -478,7 +587,10 @@ Interface.propTypes = {
const mapStateToProps = state => ({
hasCloudVariables: state.scratchGui.tw.hasCloudVariables,
customStageSize: state.scratchGui.customStageSize,
+ title: state.scratchGui.projectTitle,
description: state.scratchGui.tw.description,
+ extraProjectInfo: state.scratchGui.tw.extraProjectInfo,
+ remixedProjectInfo: state.scratchGui.tw.remixedProjectInfo,
isFullScreen: state.scratchGui.mode.isFullScreen,
isLoading: getIsLoading(state.scratchGui.projectState.loadingState),
isPlayerOnly: state.scratchGui.mode.isPlayerOnly,
@@ -499,7 +611,6 @@ const WrappedInterface = compose(
TWProjectMetaFetcherHOC,
TWStateManagerHOC,
TWThemeHOC,
- TWRestorePointHOC,
TWPackagerIntegrationHOC
)(ConnectedInterface);
diff --git a/src/playground/vote-frame.jsx b/src/playground/vote-frame.jsx
index 53e214ad11d..f855d7330a3 100644
--- a/src/playground/vote-frame.jsx
+++ b/src/playground/vote-frame.jsx
@@ -5,7 +5,11 @@ const VoteFrame = props => (
);
diff --git a/src/reducers/editor-tab.js b/src/reducers/editor-tab.js
index e44a7ca8420..6ad096a3a14 100644
--- a/src/reducers/editor-tab.js
+++ b/src/reducers/editor-tab.js
@@ -4,6 +4,8 @@ const ACTIVATE_TAB = 'scratch-gui/navigation/ACTIVATE_TAB';
const BLOCKS_TAB_INDEX = 0;
const COSTUMES_TAB_INDEX = 1;
const SOUNDS_TAB_INDEX = 2;
+const VARIABLES_TAB_INDEX = 3;
+const FILES_TAB_INDEX = 4;
const initialState = {
activeTabIndex: BLOCKS_TAB_INDEX
@@ -34,5 +36,7 @@ export {
activateTab,
BLOCKS_TAB_INDEX,
COSTUMES_TAB_INDEX,
- SOUNDS_TAB_INDEX
+ SOUNDS_TAB_INDEX,
+ VARIABLES_TAB_INDEX,
+ FILES_TAB_INDEX
};
diff --git a/src/reducers/modals.js b/src/reducers/modals.js
index 5dd5d529e0b..400be1b7f21 100644
--- a/src/reducers/modals.js
+++ b/src/reducers/modals.js
@@ -15,6 +15,8 @@ const MODAL_USERNAME = 'usernameModal';
const MODAL_SETTINGS = 'settingsModal';
const MODAL_EXTS = 'extensionManagerModal';
const MODAL_CUSTOM_EXTENSION = 'customExtensionModal';
+const MODAL_RESTORE_POINTS = 'restorePointModal';
+const MODAL_FONTS = 'fontsModal';
const initialState = {
[MODAL_BACKDROP_LIBRARY]: false,
@@ -30,16 +32,22 @@ const initialState = {
[MODAL_USERNAME]: false,
[MODAL_SETTINGS]: false,
[MODAL_EXTS]: false,
- [MODAL_CUSTOM_EXTENSION]: false
+ [MODAL_CUSTOM_EXTENSION]: false,
+ [MODAL_RESTORE_POINTS]: false,
+ [MODAL_FONTS]: false,
+ extensionModalSwapId: null
};
const reducer = function (state, action) {
if (typeof state === 'undefined') state = initialState;
switch (action.type) {
- case OPEN_MODAL:
- return Object.assign({}, state, {
+ case OPEN_MODAL: {
+ const makeState = {
[action.modal]: true
- });
+ };
+ if (action.extensionModalSwapId) makeState.extensionModalSwapId = action.extensionModalSwapId;
+ return Object.assign({}, state, makeState);
+ }
case CLOSE_MODAL:
return Object.assign({}, state, {
[action.modal]: false
@@ -48,10 +56,11 @@ const reducer = function (state, action) {
return state;
}
};
-const openModal = function (modal) {
+const openModal = function (modal, extensionModalSwapId) {
return {
type: OPEN_MODAL,
- modal: modal
+ modal: modal,
+ extensionModalSwapId
};
};
const closeModal = function (modal) {
@@ -60,6 +69,9 @@ const closeModal = function (modal) {
modal: modal
};
};
+const openExtManagerModal = () => {
+ return openModal(MODAL_EXTS);
+}
const openBackdropLibrary = function () {
return openModal(MODAL_BACKDROP_LIBRARY);
};
@@ -96,11 +108,14 @@ const openUsernameModal = function () {
const openSettingsModal = function () {
return openModal(MODAL_SETTINGS);
};
-const openExtManagerModal = () => {
- return openModal(MODAL_EXTS);
-}
-const openCustomExtensionModal = function () {
- return openModal(MODAL_CUSTOM_EXTENSION);
+const openCustomExtensionModal = function (swapId) {
+ return openModal(MODAL_CUSTOM_EXTENSION, swapId);
+};
+const openRestorePointModal = function () {
+ return openModal(MODAL_RESTORE_POINTS);
+};
+const openFontsModal = function () {
+ return openModal(MODAL_FONTS);
};
const closeBackdropLibrary = function () {
return closeModal(MODAL_BACKDROP_LIBRARY);
@@ -144,9 +159,16 @@ const closeExtManagerModal = () => {
const closeCustomExtensionModal = function () {
return closeModal(MODAL_CUSTOM_EXTENSION);
};
+const closeRestorePointModal = function () {
+ return closeModal(MODAL_RESTORE_POINTS);
+};
+const closeFontsModal = function () {
+ return closeModal(MODAL_FONTS);
+};
export {
reducer as default,
initialState as modalsInitialState,
+ openExtManagerModal,
openBackdropLibrary,
openCostumeLibrary,
openExtensionLibrary,
@@ -159,8 +181,10 @@ export {
openConnectionModal,
openUsernameModal,
openSettingsModal,
- openExtManagerModal,
openCustomExtensionModal,
+ openRestorePointModal,
+ openFontsModal,
+ closeExtManagerModal,
closeBackdropLibrary,
closeCostumeLibrary,
closeExtensionLibrary,
@@ -173,6 +197,7 @@ export {
closeConnectionModal,
closeUsernameModal,
closeSettingsModal,
- closeExtManagerModal,
- closeCustomExtensionModal
+ closeCustomExtensionModal,
+ closeRestorePointModal,
+ closeFontsModal
};
\ No newline at end of file
diff --git a/src/reducers/tw.js b/src/reducers/tw.js
index 8f1fbae3ae2..4413a44eaa8 100644
--- a/src/reducers/tw.js
+++ b/src/reducers/tw.js
@@ -15,6 +15,7 @@ const ADD_COMPILE_ERROR = 'tw/ADD_COMPILE_ERROR';
const CLEAR_COMPILE_ERRORS = 'tw/CLEAR_COMPILE_ERRORS';
const SET_FILE_HANDLE = 'tw/SET_FILE_HANDLE';
const SET_USERNAME_INVALID = 'tw/SET_USERNAME_INVALID';
+const SET_USERNAME_LOGGED_IN = 'tw/SET_USERNAME_LOGGED_IN';
const SET_HAS_CLOUD_VARIABLES = 'tw/SET_HAS_CLOUD_VARIABLES';
const SET_CLOUD_HOST = 'tw/SET_CLOUD_HOST';
@@ -31,6 +32,8 @@ export const initialState = {
runtimeOptions: {
maxClones: 300,
miscLimits: true,
+ dangerousOptimizations: false,
+ disableOffscreenRendering: false,
fencing: true
},
isWindowFullScreen: false,
@@ -58,6 +61,7 @@ export const initialState = {
compileErrors: [],
fileHandle: null,
usernameInvalid: false,
+ usernameLoggedIn: false,
hasCloudVariables: false,
cloudHost: ''
};
@@ -136,6 +140,10 @@ const reducer = function (state, action) {
return Object.assign({}, state, {
usernameInvalid: action.usernameInvalid
});
+ case SET_USERNAME_LOGGED_IN:
+ return Object.assign({}, state, {
+ usernameLoggedIn: action.usernameLoggedIn
+ });
case SET_HAS_CLOUD_VARIABLES:
return Object.assign({}, state, {
hasCloudVariables: action.hasCloudVariables
@@ -267,6 +275,13 @@ const setUsernameInvalid = function (usernameInvalid) {
};
};
+const setUsernameLoggedIn = function (usernameLoggedIn) {
+ return {
+ type: SET_USERNAME_LOGGED_IN,
+ usernameLoggedIn: usernameLoggedIn
+ };
+};
+
const setHasCloudVariables = function (hasCloudVariables) {
return {
type: SET_HAS_CLOUD_VARIABLES,
@@ -301,6 +316,7 @@ export {
clearCompileErrors,
setFileHandle,
setUsernameInvalid,
+ setUsernameLoggedIn,
setHasCloudVariables,
setCloudHost
};
\ No newline at end of file
diff --git a/src/reducers/vm-status.js b/src/reducers/vm-status.js
index e99b80368d6..b350f5daf19 100644
--- a/src/reducers/vm-status.js
+++ b/src/reducers/vm-status.js
@@ -1,9 +1,11 @@
const SET_RUNNING_STATE = 'scratch-gui/vm-status/SET_RUNNING_STATE';
+const SET_PAUSED_STATE = 'scratch-gui/vm-status/SET_PAUSED_STATE';
const SET_TURBO_STATE = 'scratch-gui/vm-status/SET_TURBO_STATE';
const SET_STARTED_STATE = 'scratch-gui/vm-status/SET_STARTED_STATE';
const initialState = {
running: false,
+ paused: false,
started: false,
turbo: false
};
@@ -19,6 +21,10 @@ const reducer = function (state, action) {
return Object.assign({}, state, {
running: action.running
});
+ case SET_PAUSED_STATE:
+ return Object.assign({}, state, {
+ paused: action.paused
+ });
case SET_TURBO_STATE:
return Object.assign({}, state, {
turbo: action.turbo
@@ -35,6 +41,13 @@ const setStartedState = function (started) {
};
};
+const setPausedState = function (paused) {
+ return {
+ type: SET_PAUSED_STATE,
+ paused: paused
+ };
+};
+
const setRunningState = function (running) {
return {
@@ -54,6 +67,7 @@ export {
reducer as default,
initialState as vmStatusInitialState,
setRunningState,
+ setPausedState,
setStartedState,
setTurboState
};
diff --git a/static/bloomfilter.svg b/static/bloomfilter.svg
new file mode 100644
index 00000000000..fa538bb9b39
--- /dev/null
+++ b/static/bloomfilter.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/static/favicon.png b/static/favicon.png
new file mode 100644
index 00000000000..d361c2365da
Binary files /dev/null and b/static/favicon.png differ
diff --git a/static/featured_project.png b/static/featured_project.png
new file mode 100644
index 00000000000..d92d93a8814
Binary files /dev/null and b/static/featured_project.png differ
diff --git a/static/iframeposttest.html b/static/iframeposttest.html
new file mode 100644
index 00000000000..1d3f4fab5ef
--- /dev/null
+++ b/static/iframeposttest.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+ aegewg
+
+
+
+
+ post msg
+
+
+
+
+
\ No newline at end of file
diff --git a/static/iframereceivetest.html b/static/iframereceivetest.html
new file mode 100644
index 00000000000..a23aa256cfd
--- /dev/null
+++ b/static/iframereceivetest.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/static/privacy.html b/static/privacy.html
index bc22e11b0d9..90b2a7ecd63 100644
--- a/static/privacy.html
+++ b/static/privacy.html
@@ -1,7 +1,7 @@
-
+
- Privacy Policy
+ PenguinMod - Privacy Policy