This commit is contained in:
QbeRoot 2021-07-05 02:19:54 +02:00
commit 2b0fb10cf7
15 changed files with 1269 additions and 1018 deletions

View file

@ -1,13 +1,9 @@
ARG VARIANT=12 # Update the VARIANT arg in docker-compose.yml to pick a Node version: 10, 12, 14
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:${VARIANT} ARG VARIANT=14
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment if you want to install an additional version of node using nvm # Update args in docker-compose.yaml to set the UID/GID of the "node" user.
# ARG EXTRA_NODE_VERSION=10 ARG USER_UID=1000
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" ARG USER_GID=$USER_UID
RUN if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then groupmod --gid $USER_GID node && usermod --uid $USER_UID --gid $USER_GID node; fi
# [Optional] Uncomment if you want to install more global node modules
# RUN sudo -u node npm install -g <your-package-list-here>

View file

@ -1,25 +1,19 @@
{ {
"name": "Node.js", "name": "GCT Generator",
"build": { "build": {
"dockerfile": "Dockerfile", "dockerfile": "Dockerfile",
// Update 'VARIANT' to pick a Node version: 10, 12, 14 "args": { "VARIANT": "14" }
"args": { "VARIANT": "12" }
}, },
// Set *default* container specific settings.json values on container create.
"settings": { "settings": {
"terminal.integrated.shell.linux": "/bin/bash" "terminal.integrated.defaultProfile.linux": "/bin/bash"
}, },
"extensions": [
// Add the IDs of extensions you want installed when the container is created. "dbaeumer.vscode-eslint",
"extensions": ["dbaeumer.vscode-eslint"], "esbenp.prettier-vscode",
"ms-vsliveshare.vsliveshare",
// Use 'forwardPorts' to make a list of ports inside the container available locally. "wayou.vscode-todo-highlight",
],
"forwardPorts": [8080], "forwardPorts": [8080],
"postCreateCommand": "yarn install",
// Use 'postCreateCommand' to run commands after the container is created. "remoteUser": "node"
"postCreateCommand": "yarn install"
// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
// "remoteUser": "node"
} }

57
.vscode/settings.json vendored
View file

@ -1,7 +1,58 @@
{ {
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.quickSuggestions": {
"strings": true
},
"editor.suggest.insertMode": "replace",
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"breadcrumbs.symbolSortOrder": "type",
"editor.codeLens": true,
"editor.detectIndentation": true,
"editor.formatOnSave": true,
"editor.minimap.maxColumn": 150,
"editor.tabSize": 2,
"explorer.confirmDragAndDrop": false,
"files.associations": {
"*.erb": "html",
"*.html.erb": "html"
},
"git.confirmSync": false,
"git.enableSmartCommit": true,
"html.format.wrapLineLength": 150,
"javascript.updateImportsOnFileMove.enabled": "always",
"search.exclude": { "search.exclude": {
"**/dist": true, "**/*.eot": true,
"**/*.png": true,
"**/*.svg": true,
"**/*.ttf": true,
"**/*.woff": true,
"**/*.woff2": true,
"**/.git": true,
"**/bower_components": true,
"**/dist/": true,
"**/node_modules": true, "**/node_modules": true,
"yarn.lock": true "**/tmp": true
} },
"telemetry.enableCrashReporter": false,
"todohighlight.keywords": [
"@TODO"
],
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.referencesCodeLens.enabled": true,
"typescript.referencesCodeLens.showOnAllFunctions": true,
"typescript.reportStyleChecksAsWarnings": true,
"typescript.updateImportsOnFileMove.enabled": "always",
"window.zoomLevel": 0,
"workbench.editor.enablePreview": false,
"workbench.editor.enablePreviewFromQuickOpen": false
} }

View file

@ -24,7 +24,7 @@
"jsdom": "16.6.0", "jsdom": "16.6.0",
"markdown-it-attrs": "4.0.0", "markdown-it-attrs": "4.0.0",
"pre-commit": "1.2.2", "pre-commit": "1.2.2",
"prettier": "2.3.1", "prettier": "2.3.2",
"vuepress": "1.8.2" "vuepress": "1.8.2"
}, },
"dependencies": { "dependencies": {

View file

@ -1,7 +1,8 @@
<template> <template>
<ul> <ul>
<li <li
v-for="code in availableCodes" v-for="(code, idx) in availableCodes"
v-bind:key="idx"
:class="code.selected ? 'checked' : ''" :class="code.selected ? 'checked' : ''"
@click="toggle(code)" @click="toggle(code)"
@mouseover="inspect(code)" @mouseover="inspect(code)"

View file

@ -1,14 +1,17 @@
<template> <template>
<div>
<ButtonComponent <ButtonComponent
label="Download" label="Download"
:onClick="onClick" :onClick="onClick"
:disabled="(!codes || codes.length === 0) && !stageLoaderCode" :disabled="(!codes || codes.length === 0) && !stageLoaderCode"
/> ></ButtonComponent>
<FeedbackModal v-if="showFeedbackModal" />
</div>
</template> </template>
<script> <script>
// Components // Components
import ButtonComponent from './ButtonComponent'; import FeedbackModal from './FeedbackModal';
// Data // Data
import gameVersions from '../data/gameVersions.json'; import gameVersions from '../data/gameVersions.json';
@ -23,6 +26,11 @@ export default {
format: { type: String }, format: { type: String },
versionIdentifier: { type: String }, versionIdentifier: { type: String },
}, },
data() {
return {
showFeedbackModal: false,
};
},
methods: { methods: {
onClick() { onClick() {
if (!(this.codes || this.codes.length === 0) && !this.stageLoaderCode) { if (!(this.codes || this.codes.length === 0) && !this.stageLoaderCode) {
@ -55,7 +63,7 @@ export default {
]); ]);
} catch {} } catch {}
console.log(`Preparing download for ${this.format}`); console.log(`Preparing jdownload for ${this.format}`);
const fileName = gameVersions.find((v) => v.identifier === this.versionIdentifier).version; const fileName = gameVersions.find((v) => v.identifier === this.versionIdentifier).version;
switch (this.format) { switch (this.format) {
@ -69,6 +77,10 @@ export default {
this.generateCheatManagerTXT(c, fileName); this.generateCheatManagerTXT(c, fileName);
break; break;
} }
if (!this.showFeedbackModal && this.$lang === 'en-US') {
this.showFeedbackModal = true;
}
}, },
generateGCT(codes, version) { generateGCT(codes, version) {
let code = '00D0C0DE00D0C0DE'; let code = '00D0C0DE00D0C0DE';

View file

@ -0,0 +1,109 @@
<template>
<transition v-if="showModal" name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div v-if="showModal" class="modal-body">
<p>
If you have 5 minutes please fill out our
<a @click="onFormClick" href="https://forms.gle/WYdGEYARPArd7uYx5" target="_blank"
>feedback form</a
>. Thanks!
</p>
<div>
<ButtonComponent
label="Ok"
:onClick="
() => {
this.showModal = false;
}
"
/>
</div>
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
// Components
import ButtonComponent from './ButtonComponent';
export default {
name: 'FeedbackModal',
data() {
return {
showModal: false,
};
},
mounted() {
if (localStorage.getItem('feedback-modal-displayed') !== 'y') {
this.showModal = true;
localStorage.setItem('feedback-modal-displayed', 'y');
try {
window._paq.push(['trackEvent', 'GCT Generator', 'Feedback', 'Open Modal']);
} catch {}
}
},
methods: {
onFormClick() {
try {
window._paq.push(['trackEvent', 'GCT Generator', 'Feedback', 'Open Form']);
} catch {
} finally {
return true;
}
},
},
};
</script>
<style scoped>
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: table;
transition: opacity 0.3s ease;
}
.modal-wrapper {
display: table-cell;
vertical-align: middle;
}
.modal-container {
width: 300px;
margin: 0px auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
transition: all 0.3s ease;
font-family: Helvetica, Arial, sans-serif;
}
.modal-body {
margin: 20px 0;
}
.modal-enter {
opacity: 0;
}
.modal-leave-active {
opacity: 0;
}
.modal-enter .modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>

View file

@ -99,15 +99,6 @@
</template> </template>
<script> <script>
// Components
import VersionSelect from './VersionSelect';
import FormatSelect from './FormatSelect';
import SelectComponent from './SelectComponent';
import StageLoader from './StageLoader';
import CodeInfo from './CodeInfo';
import CodeList from './CodeList';
import DownloadButton from './DownloadButton';
// Data // Data
import gameVersions from '../data/gameVersions.json'; import gameVersions from '../data/gameVersions.json';
@ -141,16 +132,43 @@ export default {
this.codes = gameVersions.find((c) => c.identifier === e).codes; this.codes = gameVersions.find((c) => c.identifier === e).codes;
this.stageLoaderCodes = gameVersions.find((c) => c.identifier === e).fastCode; this.stageLoaderCodes = gameVersions.find((c) => c.identifier === e).fastCode;
this.inspectingCode = null; this.inspectingCode = null;
try {
window._paq.push([
'trackEvent',
'GCT Generator',
'Change Version',
JSON.stringify({ version: e }),
]);
} catch {}
}, },
onFormatChanged(e) { onFormatChanged(e) {
this.selectedFormat = e; this.selectedFormat = e;
try {
window._paq.push([
'trackEvent',
'GCT Generator',
'Change Format',
JSON.stringify({ format: e }),
]);
} catch {}
}, },
onStageLoaderChanged(e) { onStageLoaderChanged(e) {
this.useStageLoader = e === true || e === 'true'; this.useStageLoader = e === true || e === 'true';
if (!this.useStageLoader) this.selectedStageLoader = null; if (!this.useStageLoader) this.selectedStageLoader = null;
try {
window._paq.push([
'trackEvent',
'GCT Generator',
'Change StageLoader State',
JSON.stringify({ enabled: e }),
]);
} catch {}
}, },
onCheatSelectionChanged(e) { onCheatSelectionChanged(e) {
this.selectedCheats = e; this.selectedCheats = e;
try {
window._paq.push(['trackEvent', 'GCT Generator', 'Change Cheat Selection', '']);
} catch {}
}, },
onStageLoaderCodeChanged(e) { onStageLoaderCodeChanged(e) {
this.selectedStageLoader = e; this.selectedStageLoader = e;

View file

@ -4,9 +4,14 @@
<option v-if="placeholder != null" value="placeholder" selected disabled> <option v-if="placeholder != null" value="placeholder" selected disabled>
{{ placeholder }} {{ placeholder }}
</option> </option>
<optgroup v-for="optGroup in optGroups" :label="getLabel(optGroup.label)"> <optgroup
v-for="(optGroup, oIdx) in optGroups"
v-bind:key="oIdx"
:label="getLabel(optGroup.label)"
>
<option <option
v-for="option in optGroup.options" v-for="(option, iIdx) in optGroup.options"
v-bind:key="iIdx"
:value="option.value" :value="option.value"
:selected="selectedValue && option.value === selectedValue" :selected="selectedValue && option.value === selectedValue"
> >

View file

@ -5,7 +5,8 @@
{{ placeholder }} {{ placeholder }}
</option> </option>
<option <option
v-for="option in options" v-for="(option, idx) in options"
v-bind:key="idx"
:value="option.value" :value="option.value"
:selected="selectedValue && option.value === selectedValue" :selected="selectedValue && option.value === selectedValue"
> >

View file

@ -42,18 +42,16 @@
ghost-class="ghost" ghost-class="ghost"
@end="onDragEnd" @end="onDragEnd"
> >
<li v-for="(level, index) in selectedRoute"> <li v-for="(level, idx) in selectedRoute" v-bind:key="idx">
<div class="route-drag">&#8801;</div> <div class="route-drag">&#8801;</div>
<GroupSelectComponent <GroupSelectComponent
:selectedValue="level.value" :selectedValue="level.value"
:optGroups="stageLoaderLevelOptions" :optGroups="stageLoaderLevelOptions"
:onChange="(e) => onStageLoaderLevelChanged(index, e)" :onChange="(e) => onStageLoaderLevelChanged(idx, e)"
:key="index" :key="idx"
/> />
<button @click="onLevelDeleted(index)" type="button" class="route-remove"> <button @click="onLevelDeleted(idx)" type="button" class="route-remove">&#215;</button>
&#215;
</button>
</li> </li>
</draggable> </draggable>
</ul> </ul>

View file

@ -1,6 +1,11 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<div v-for="version in gameVersions" class="card" @click="onCardClick(version)"> <div
v-for="(version, idx) in gameVersions"
v-bind:key="idx"
class="card"
@click="onCardClick(version)"
>
<h3>{{ getLabel(`common.${version.identifier}`) }}</h3> <h3>{{ getLabel(`common.${version.identifier}`) }}</h3>
</div> </div>
</div> </div>
@ -22,8 +27,6 @@ export default {
}, },
methods: { methods: {
onCardClick(v) { onCardClick(v) {
const localePaths = Object.keys(locales);
let localePath = ''; let localePath = '';
Object.keys(locales).forEach((l) => { Object.keys(locales).forEach((l) => {

View file

@ -9,8 +9,10 @@ export default ({
options, // the options for the root Vue instance options, // the options for the root Vue instance
router, // the router instance for the app router, // the router instance for the app
siteData, // site metadata siteData, // site metadata
isServer,
}) => { }) => {
if (typeof document === 'undefined') return; if (isServer) return;
document.onreadystatechange = () => { document.onreadystatechange = () => {
if (document.readyState === 'complete') { if (document.readyState === 'complete') {
if (location.hash && location.hash.length > 0) { if (location.hash && location.hash.length > 0) {

View file

@ -11,7 +11,7 @@
"headers": { "headers": {
"codelist": "Available Codes", "codelist": "Available Codes",
"help": "Help", "help": "Help",
"stageloader": "Stage Loader" "stageloader": "Stage List Loader"
}, },
"codeinfo": { "codeinfo": {
"author": "Author:", "author": "Author:",
@ -23,7 +23,7 @@
"label": "Game Version:", "label": "Game Version:",
"placeholder": "Choose Version.." "placeholder": "Choose Version.."
}, },
"usestageloader": "Use Stage Loader", "usestageloader": "Use Stage List Loader",
"downloadformat": { "downloadformat": {
"label": "Download Format:", "label": "Download Format:",
"options": { "options": {
@ -35,7 +35,7 @@
}, },
"landingpage": { "landingpage": {
"title": "Super Mario Sunshine Practice File Generator", "title": "Super Mario Sunshine Practice File Generator",
"summary": "This is a cheatfile generator for Super Mario Sunshine speedrun practice. If this is your first time using the generator we highly recommend to check out the <a href='/guide.html' target='_blank'>guide</a> first. Visit the <a href='/guide.html#troubleshooting' target='_blank'>the troubleshooting section</a> if you encounter any issues.", "summary": "This is a cheatfile generator for Super Mario Sunshine speedrun practice. If this is your first time using the generator we highly recommend to check out the <a href='/guide.html' target='_blank'>guide</a> first. Visit the <a href='/guide.html#troubleshooting' target='_blank'>the troubleshooting section</a> if you encounter any issues. For an overview of all available codes check out the <a href='/code-reference' target='_blank'>code reference</a> for your version.",
"community": "The SMS Speedrunning Community", "community": "The SMS Speedrunning Community",
"links": { "links": {
"discord": "Discord", "discord": "Discord",

1965
yarn.lock

File diff suppressed because it is too large Load diff