Merge pull request 'GitHub pages flow fix, image errors and field duplication and field unfocus in mod submission fix' (#83) from staging into master
All checks were successful
Release to Staging / build_and_release (push) Successful in 44s
Reviewed-on: #83
84
.github/workflows/release-pages-production.yaml
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Simple workflow for deploying static content to GitHub Pages
|
||||||
|
name: Release to DEG-Mods.github.io
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ['master']
|
||||||
|
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# Allow one concurrent deployment
|
||||||
|
concurrency:
|
||||||
|
group: 'pages'
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: 'npm'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Create .env File
|
||||||
|
run: |
|
||||||
|
echo "VITE_APP_RELAY=${{ vars.VITE_APP_RELAY }}" >> .env
|
||||||
|
echo "VITE_ADMIN_NPUBS=${{ vars.VITE_ADMIN_NPUBS }}" >> .env
|
||||||
|
echo "VITE_FALLBACK_GAME_IMAGE=${{ vars.VITE_FALLBACK_GAME_IMAGE }}" >> .env
|
||||||
|
echo "VITE_FALLBACK_MOD_IMAGE=${{ vars.VITE_FALLBACK_MOD_IMAGE }}" >> .env
|
||||||
|
echo "VITE_REPORTING_NPUB=${{ vars.VITE_REPORTING_NPUB }}" >> .env
|
||||||
|
cat .env
|
||||||
|
- name: Build
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: './dist'
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: ${{ vars.ORGANIZATION_NAME }}/${{ vars.REPOSITORY_NAME }}
|
||||||
|
path: ${{ vars.REPOSITORY_NAME }}
|
||||||
|
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||||
|
|
||||||
|
- name: Clear target repo
|
||||||
|
run: |
|
||||||
|
rm -rf ${{ vars.REPOSITORY_NAME }}/*
|
||||||
|
|
||||||
|
- name: Download build artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: ./dist
|
||||||
|
|
||||||
|
- name: Prepare files
|
||||||
|
run: |
|
||||||
|
cp -r dist/* ${{ vars.REPOSITORY_NAME }}/
|
||||||
|
echo ${{ vars.CUSTOM_DOMAIN }} > ${{ vars.REPOSITORY_NAME }}/CNAME
|
||||||
|
touch ${{ vars.REPOSITORY_NAME }}/.nojekyll
|
||||||
|
|
||||||
|
- name: Commit and push
|
||||||
|
run: |
|
||||||
|
cd ${{ vars.REPOSITORY_NAME }}
|
||||||
|
git config --global user.name 'github-actions[bot]'
|
||||||
|
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||||
|
git add .
|
||||||
|
git commit -m 'Deploy from source repo'
|
||||||
|
git push origin main
|
31
index.html
@ -4,40 +4,9 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
|
||||||
<!-- Open Graph Meta Tags -->
|
|
||||||
<meta property="og:title" content="DEG Mods - Liberating Game Mods" />
|
|
||||||
<meta
|
|
||||||
property="og:description"
|
|
||||||
content="Never get your game mods censored, get banned, lose your history, nor lose the connection between game mod creators and fans. Download your mods freely."
|
|
||||||
/>
|
|
||||||
<meta property="og:image" content="/assets/img/DEGM%20Thumb.png" />
|
|
||||||
<meta property="og:url" content="https://degmods.com" />
|
|
||||||
<meta property="og:type" content="website" />
|
|
||||||
|
|
||||||
<!-- Twitter Card Meta Tags -->
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
|
||||||
<meta name="twitter:title" content="DEG Mods - Liberating Game Mods" />
|
|
||||||
<meta
|
|
||||||
name="twitter:description"
|
|
||||||
content="Never get your game mods censored, get banned, lose your history, nor lose the connection between game mod creators and fans. Download your mods freely."
|
|
||||||
/>
|
|
||||||
<meta name="twitter:image" content="/assets/img/DEGM%20Thumb.png" />
|
|
||||||
|
|
||||||
<!-- Other Meta Tags -->
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
content="Never get your game mods censored, get banned, lose your history, nor lose the connection between game mod creators and fans. Download your mods freely."
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Links and Stylesheets -->
|
<!-- Links and Stylesheets -->
|
||||||
<link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.min.css" />
|
<link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.min.css" />
|
||||||
<link rel="stylesheet" href="/assets/fonts/fontawesome-all.min.css" />
|
<link rel="stylesheet" href="/assets/fonts/fontawesome-all.min.css" />
|
||||||
<link
|
|
||||||
rel="icon"
|
|
||||||
type="image/png"
|
|
||||||
sizes="935x934"
|
|
||||||
href="/assets/img/Logo%20with%20circle.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<title>DEG Mods - Liberating Game Mods</title>
|
<title>DEG Mods - Liberating Game Mods</title>
|
||||||
</head>
|
</head>
|
||||||
|
48
package-lock.json
generated
@ -16,6 +16,7 @@
|
|||||||
"@tiptap/extension-link": "2.6.6",
|
"@tiptap/extension-link": "2.6.6",
|
||||||
"@tiptap/react": "2.6.6",
|
"@tiptap/react": "2.6.6",
|
||||||
"@tiptap/starter-kit": "2.6.6",
|
"@tiptap/starter-kit": "2.6.6",
|
||||||
|
"@types/react-helmet": "^6.1.11",
|
||||||
"axios": "1.7.3",
|
"axios": "1.7.3",
|
||||||
"bech32": "2.0.0",
|
"bech32": "2.0.0",
|
||||||
"buffer": "6.0.3",
|
"buffer": "6.0.3",
|
||||||
@ -32,6 +33,7 @@
|
|||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-countdown": "2.3.5",
|
"react-countdown": "2.3.5",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
"react-helmet": "^6.1.0",
|
||||||
"react-redux": "9.1.2",
|
"react-redux": "9.1.2",
|
||||||
"react-router-dom": "^6.24.1",
|
"react-router-dom": "^6.24.1",
|
||||||
"react-toastify": "10.0.5",
|
"react-toastify": "10.0.5",
|
||||||
@ -1986,14 +1988,12 @@
|
|||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
"version": "15.7.12",
|
"version": "15.7.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
|
||||||
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
|
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
|
||||||
"devOptional": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.3.3",
|
"version": "18.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
|
||||||
"integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
|
"integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
|
||||||
"devOptional": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
@ -2008,6 +2008,15 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-helmet": {
|
||||||
|
"version": "6.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.11.tgz",
|
||||||
|
"integrity": "sha512-0QcdGLddTERotCXo3VFlUSWO3ztraw8nZ6e3zJSgG7apwV5xt+pJUS8ewPBqT4NYB1optGLprNQzFleIY84u/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/react-window": {
|
"node_modules/@types/react-window": {
|
||||||
"version": "1.8.8",
|
"version": "1.8.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
|
||||||
@ -2654,8 +2663,7 @@
|
|||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||||
"devOptional": true
|
|
||||||
},
|
},
|
||||||
"node_modules/d": {
|
"node_modules/d": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -4623,6 +4631,27 @@
|
|||||||
"react": "^18.3.1"
|
"react": "^18.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-fast-compare": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/react-helmet": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"react-fast-compare": "^3.1.1",
|
||||||
|
"react-side-effect": "^2.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
@ -4689,6 +4718,15 @@
|
|||||||
"react-dom": ">=16.8"
|
"react-dom": ">=16.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-side-effect": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.3.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-toastify": {
|
"node_modules/react-toastify": {
|
||||||
"version": "10.0.5",
|
"version": "10.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz",
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"@tiptap/extension-link": "2.6.6",
|
"@tiptap/extension-link": "2.6.6",
|
||||||
"@tiptap/react": "2.6.6",
|
"@tiptap/react": "2.6.6",
|
||||||
"@tiptap/starter-kit": "2.6.6",
|
"@tiptap/starter-kit": "2.6.6",
|
||||||
|
"@types/react-helmet": "^6.1.11",
|
||||||
"axios": "1.7.3",
|
"axios": "1.7.3",
|
||||||
"bech32": "2.0.0",
|
"bech32": "2.0.0",
|
||||||
"buffer": "6.0.3",
|
"buffer": "6.0.3",
|
||||||
@ -34,6 +35,7 @@
|
|||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-countdown": "2.3.5",
|
"react-countdown": "2.3.5",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
"react-helmet": "^6.1.0",
|
||||||
"react-redux": "9.1.2",
|
"react-redux": "9.1.2",
|
||||||
"react-router-dom": "^6.24.1",
|
"react-router-dom": "^6.24.1",
|
||||||
"react-toastify": "10.0.5",
|
"react-toastify": "10.0.5",
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
Game Name,16 by 9 image,Boxart image
|
Game Name,16 by 9 image,Boxart image
|
||||||
Voices of the Void,,https://image.nostr.build/472949882d0756c84d3effd9f641b10c88abd48265f0f01f360937b189d50b54.jpg
|
Voices of the Void,,https://image.nostr.build/472949882d0756c84d3effd9f641b10c88abd48265f0f01f360937b189d50b54.jpg
|
||||||
Shroom and Gloom,,
|
Shroom and Gloom,,
|
|
@ -1,2 +1,2 @@
|
|||||||
Game Name,16 by 9 image,Boxart image
|
Game Name,16 by 9 image,Boxart image
|
||||||
Fire Emblem Engage,,https://image.nostr.build/f9f883f88c7d1abc38b98b0aa2394684e52e10171b621011f348034ab9973476.jpg
|
Fire Emblem Engage,,https://image.nostr.build/f9f883f88c7d1abc38b98b0aa2394684e52e10171b621011f348034ab9973476.jpg
|
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 277 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 687 B After Width: | Height: | Size: 687 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 284 KiB After Width: | Height: | Size: 284 KiB |
@ -419,7 +419,7 @@ export const ModForm = ({ existingModData }: ModFormProps) => {
|
|||||||
We recommend to upload images to https://nostr.build/
|
We recommend to upload images to https://nostr.build/
|
||||||
</p>
|
</p>
|
||||||
{formState.screenshotsUrls.map((url, index) => (
|
{formState.screenshotsUrls.map((url, index) => (
|
||||||
<Fragment key={`screenShot-${url}`}>
|
<Fragment key={`screenShot-${index}`}>
|
||||||
<ScreenshotUrlFields
|
<ScreenshotUrlFields
|
||||||
index={index}
|
index={index}
|
||||||
url={url}
|
url={url}
|
||||||
@ -468,12 +468,12 @@ export const ModForm = ({ existingModData }: ModFormProps) => {
|
|||||||
</div>
|
</div>
|
||||||
<p className='labelDescriptionMain'>
|
<p className='labelDescriptionMain'>
|
||||||
You can upload your game mod to Github, as an example, and keep
|
You can upload your game mod to Github, as an example, and keep
|
||||||
updating it there (another option is catbox.moe). Also, it's advisable that you hash your package as
|
updating it there (another option is catbox.moe). Also, it's advisable
|
||||||
well with your nostr public key.
|
that you hash your package as well with your nostr public key.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{formState.downloadUrls.map((download, index) => (
|
{formState.downloadUrls.map((download, index) => (
|
||||||
<Fragment key={`download-${download.url}`}>
|
<Fragment key={`download-${index}`}>
|
||||||
<DownloadUrlFields
|
<DownloadUrlFields
|
||||||
index={index}
|
index={index}
|
||||||
url={download.url}
|
url={download.url}
|
||||||
|
@ -21,6 +21,7 @@ import {
|
|||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { LoadingSpinner } from './LoadingSpinner'
|
import { LoadingSpinner } from './LoadingSpinner'
|
||||||
import { ZapPopUp } from './Zap'
|
import { ZapPopUp } from './Zap'
|
||||||
|
import placeholder from '../assets/img/DEGMods Placeholder Img.png'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
pubkey: string
|
pubkey: string
|
||||||
@ -240,7 +241,7 @@ const posts: Post[] = [
|
|||||||
name: 'User name',
|
name: 'User name',
|
||||||
link: `feed-note.html`,
|
link: `feed-note.html`,
|
||||||
content: `user text, this is a long string of temporary text that would be replaced with the user post from their short posts`,
|
content: `user text, this is a long string of temporary text that would be replaced with the user post from their short posts`,
|
||||||
imageUrl: '/assets/img/DEGMods%20Placeholder%20Img.png'
|
imageUrl: placeholder
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -110,18 +110,6 @@ export const REACTIONS = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: there should be a corresponding CSV file in public/assets/games folder for each entry in the array
|
|
||||||
export const GAME_FILES = [
|
|
||||||
'Games_Itch.csv',
|
|
||||||
'Games_Nintendo.csv',
|
|
||||||
'Games_Other.csv',
|
|
||||||
'Games_Steam1.csv',
|
|
||||||
'Games_Steam2.csv',
|
|
||||||
'Games_Steam3.csv',
|
|
||||||
'Games_Steam4.csv',
|
|
||||||
'Games_Steam5.csv'
|
|
||||||
]
|
|
||||||
|
|
||||||
export const MAX_MODS_PER_PAGE = 10
|
export const MAX_MODS_PER_PAGE = 10
|
||||||
export const MAX_GAMES_PER_PAGE = 10
|
export const MAX_GAMES_PER_PAGE = 10
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { GAME_FILES } from 'constants.ts'
|
|
||||||
import Papa from 'papaparse'
|
import Papa from 'papaparse'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import { Game } from 'types'
|
import { Game } from 'types'
|
||||||
import { log, LogType } from 'utils'
|
import { log, LogType } from 'utils'
|
||||||
|
import gameFiles from '../utils/games'
|
||||||
|
|
||||||
export const useGames = () => {
|
export const useGames = () => {
|
||||||
const hasProcessedFiles = useRef(false)
|
const hasProcessedFiles = useRef(false)
|
||||||
@ -36,18 +36,19 @@ export const useGames = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Fetch and parse each file
|
// Fetch and parse each file
|
||||||
const promises = GAME_FILES.map(async (filename) => {
|
const promises = Object.values(gameFiles).map(async (importFn) => {
|
||||||
const response = await fetch(`/assets/games/${filename}`)
|
const csvText = await importFn()
|
||||||
const csvText = await response.text()
|
if (typeof csvText === 'string') {
|
||||||
const parsedGames = await parseCSV(csvText)
|
const parsedGames = await parseCSV(csvText as string)
|
||||||
|
|
||||||
// Remove duplicate games based on 'Game Name'
|
// Remove duplicate games based on 'Game Name'
|
||||||
parsedGames.forEach((game) => {
|
parsedGames.forEach((game) => {
|
||||||
if (!gameNames.has(game['Game Name'])) {
|
if (!gameNames.has(game['Game Name'])) {
|
||||||
gameNames.add(game['Game Name'])
|
gameNames.add(game['Game Name'])
|
||||||
uniqueGames.push(game)
|
uniqueGames.push(game)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
await Promise.all(promises)
|
await Promise.all(promises)
|
||||||
|
36
src/layout/head.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Helmet } from 'react-helmet'
|
||||||
|
import thumb from '../assets/img/DEGM Thumb.png'
|
||||||
|
import logoWithCircle from '../assets/img/Logo with circle.png'
|
||||||
|
|
||||||
|
export const Head = () => {
|
||||||
|
return (
|
||||||
|
<Helmet>
|
||||||
|
{/* Open Graph Meta Tags */}
|
||||||
|
<meta property='og:title' content='DEG Mods - Liberating Game Mods' />
|
||||||
|
<meta
|
||||||
|
property='og:description'
|
||||||
|
content='Never get your game mods censored, get banned, lose your history, nor lose the connection between game mod creators and fans. Download your mods freely.'
|
||||||
|
/>
|
||||||
|
<meta property='og:image' content={thumb} />
|
||||||
|
<meta property='og:url' content='https://degmods.com' />
|
||||||
|
<meta property='og:type' content='website' />
|
||||||
|
|
||||||
|
{/* Twitter Card Meta Tags */}
|
||||||
|
<meta name='twitter:card' content='summary_large_image' />
|
||||||
|
<meta name='twitter:title' content='DEG Mods - Liberating Game Mods' />
|
||||||
|
<meta
|
||||||
|
name='twitter:description'
|
||||||
|
content='Never get your game mods censored, get banned, lose your history, nor lose the connection between game mod creators and fans. Download your mods freely.'
|
||||||
|
/>
|
||||||
|
<meta name='twitter:image' content={thumb} />
|
||||||
|
|
||||||
|
{/* Other Meta Tags */}
|
||||||
|
<meta
|
||||||
|
name='description'
|
||||||
|
content='Never get your game mods censored, get banned, lose your history, nor lose the connection between game mod creators and fans. Download your mods freely.'
|
||||||
|
/>
|
||||||
|
|
||||||
|
<link rel='icon' type='image/png' sizes='935x934' href={logoWithCircle} />
|
||||||
|
</Helmet>
|
||||||
|
)
|
||||||
|
}
|
@ -19,6 +19,8 @@ import mainStyles from '../styles//main.module.scss'
|
|||||||
import navStyles from '../styles/nav.module.scss'
|
import navStyles from '../styles/nav.module.scss'
|
||||||
import '../styles/popup.css'
|
import '../styles/popup.css'
|
||||||
import { npubToHex } from '../utils'
|
import { npubToHex } from '../utils'
|
||||||
|
import logo from '../assets/img/DEG Mods Logo With Text.svg'
|
||||||
|
import placeholder from '../assets/img/DEG Mods Default PP.png'
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
@ -81,7 +83,7 @@ export const Header = () => {
|
|||||||
<div className={navStyles.NMTI_Sec_HomeLink_Logo}>
|
<div className={navStyles.NMTI_Sec_HomeLink_Logo}>
|
||||||
<img
|
<img
|
||||||
className={navStyles.NMTI_Sec_HomeLink_LogoImg}
|
className={navStyles.NMTI_Sec_HomeLink_LogoImg}
|
||||||
src='/assets/img/DEG%20Mods%20Logo%20With%20Text.svg'
|
src={logo}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
@ -144,7 +146,7 @@ export const Header = () => {
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
className={navStyles.NMTI_SecInside_LinkImg}
|
className={navStyles.NMTI_SecInside_LinkImg}
|
||||||
src='/assets/img/DEG%20Mods%20Default%20PP.png'
|
src={placeholder}
|
||||||
/>
|
/>
|
||||||
Login
|
Login
|
||||||
</a>
|
</a>
|
||||||
|
@ -2,10 +2,12 @@ import { Outlet } from 'react-router-dom'
|
|||||||
import { Footer } from './footer'
|
import { Footer } from './footer'
|
||||||
import { Header } from './header'
|
import { Header } from './header'
|
||||||
import { SocialNav } from './socialNav'
|
import { SocialNav } from './socialNav'
|
||||||
|
import { Head } from './head'
|
||||||
|
|
||||||
export const Layout = () => {
|
export const Layout = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Head />
|
||||||
<Header />
|
<Header />
|
||||||
<Outlet />
|
<Outlet />
|
||||||
<Footer />
|
<Footer />
|
||||||
|
@ -2,6 +2,8 @@ import { FAQAccordion } from '../components/FAQAccordion'
|
|||||||
import '../styles/about.css'
|
import '../styles/about.css'
|
||||||
import '../styles/FAQ.css'
|
import '../styles/FAQ.css'
|
||||||
import '../styles/styles.css'
|
import '../styles/styles.css'
|
||||||
|
import thumb from '../assets/img/DEGM Thumb.png'
|
||||||
|
import vivian from '../assets/img/vivian james.png'
|
||||||
|
|
||||||
export type FAQItem = {
|
export type FAQItem = {
|
||||||
question: string
|
question: string
|
||||||
@ -14,7 +16,8 @@ const FAQ_ITEMS: FAQItem[] = [
|
|||||||
answer: `We don't handle that directly, but you, as the creator, will.`
|
answer: `We don't handle that directly, but you, as the creator, will.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
question: 'How do you assure security of game mod files that someone downloads?',
|
question:
|
||||||
|
'How do you assure security of game mod files that someone downloads?',
|
||||||
answer: `We don't assure security directly. However, we will provide a reaction
|
answer: `We don't assure security directly. However, we will provide a reaction
|
||||||
system to help users gauge the safety of download links, and mod creators
|
system to help users gauge the safety of download links, and mod creators
|
||||||
are encouraged to include scan links.`
|
are encouraged to include scan links.`
|
||||||
@ -36,12 +39,14 @@ const FAQ_ITEMS: FAQItem[] = [
|
|||||||
Gist: If someone put a gun to your / the team's head, will you censor or ban anyone? No, because we can't.`
|
Gist: If someone put a gun to your / the team's head, will you censor or ban anyone? No, because we can't.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
question: "You can't do anything about any mod or person? Nothing at all? What about the illegal stuff?",
|
question:
|
||||||
|
"You can't do anything about any mod or person? Nothing at all? What about the illegal stuff?",
|
||||||
answer: `Direct removal or banning is not possible. We can only filter or
|
answer: `Direct removal or banning is not possible. We can only filter or
|
||||||
hide content on the site, but it remains accessible on here and elsewhere.`
|
hide content on the site, but it remains accessible on here and elsewhere.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
question: 'Why did you have to add Bitcoin? Why not traditional payment methods like Visa, PayPal, etc?',
|
question:
|
||||||
|
'Why did you have to add Bitcoin? Why not traditional payment methods like Visa, PayPal, etc?',
|
||||||
answer: `For various reasons. With traditional payment methods, not everyone has access to them, they
|
answer: `For various reasons. With traditional payment methods, not everyone has access to them, they
|
||||||
can pressure or threaten us, mod creators, or even gamers to censor or ban, or restrict usage of this site
|
can pressure or threaten us, mod creators, or even gamers to censor or ban, or restrict usage of this site
|
||||||
by holding our funds or stealing them. They can prevent you from tipping on this site or specific mod creators,
|
by holding our funds or stealing them. They can prevent you from tipping on this site or specific mod creators,
|
||||||
@ -70,7 +75,7 @@ const FAQ_ITEMS: FAQItem[] = [
|
|||||||
as such her design is temporary and will be replaced with a design created by an artist (or artists)
|
as such her design is temporary and will be replaced with a design created by an artist (or artists)
|
||||||
when that time comes.)`
|
when that time comes.)`
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
|
|
||||||
export const AboutPage = () => {
|
export const AboutPage = () => {
|
||||||
return (
|
return (
|
||||||
@ -92,7 +97,7 @@ export const AboutPage = () => {
|
|||||||
>
|
>
|
||||||
Liberating Game Mods
|
Liberating Game Mods
|
||||||
</h1>
|
</h1>
|
||||||
<img src='/assets/img/DEGM%20Thumb.png' alt='Thumbnail' />
|
<img src={thumb} alt='Thumbnail' />
|
||||||
<p className='LearnTextPara'>
|
<p className='LearnTextPara'>
|
||||||
Never get your game mods censored, get banned, lose your
|
Never get your game mods censored, get banned, lose your
|
||||||
history, nor lose the connection between creators and fans.
|
history, nor lose the connection between creators and fans.
|
||||||
@ -120,7 +125,11 @@ export const AboutPage = () => {
|
|||||||
imposing their ideals. DEG Mods aims to change that
|
imposing their ideals. DEG Mods aims to change that
|
||||||
narrative by being developed on Nostr, a revolutionary new
|
narrative by being developed on Nostr, a revolutionary new
|
||||||
communications protocol.{' '}
|
communications protocol.{' '}
|
||||||
<a className='linkMain' href='https://nostr.com/' target="_blank">
|
<a
|
||||||
|
className='linkMain'
|
||||||
|
href='https://nostr.com/'
|
||||||
|
target='_blank'
|
||||||
|
>
|
||||||
Learn more about Nostr here.
|
Learn more about Nostr here.
|
||||||
</a>
|
</a>
|
||||||
<br />
|
<br />
|
||||||
@ -171,11 +180,11 @@ export const AboutPage = () => {
|
|||||||
on this platform/site. Pretend its not even there. We're not
|
on this platform/site. Pretend its not even there. We're not
|
||||||
even making any money out of this project/site, in-fact,
|
even making any money out of this project/site, in-fact,
|
||||||
we're running at a loss (unless direct donations/tips covers
|
we're running at a loss (unless direct donations/tips covers
|
||||||
it, and/or we managed to add reasonable monetization systems
|
it, and/or we managed to add reasonable monetization systems
|
||||||
to help cover further development and maintenance costs).
|
to help cover further development and maintenance costs).
|
||||||
This is just a passion project to help free (liberate)
|
This is just a passion project to help free (liberate) game
|
||||||
game mods and their creators, and this part potentially
|
mods and their creators, and this part potentially helps
|
||||||
helps them financially, even those in other countries where
|
them financially, even those in other countries where
|
||||||
"normal" methods of money payment/transfer are not an
|
"normal" methods of money payment/transfer are not an
|
||||||
option. You can just find the mod you want and download it,
|
option. You can just find the mod you want and download it,
|
||||||
or upload the mod you've created, and never even touch
|
or upload the mod you've created, and never even touch
|
||||||
@ -228,10 +237,7 @@ export const AboutPage = () => {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img className='LearnTextCharacterImgRight' src={vivian} />
|
||||||
className='LearnTextCharacterImgRight'
|
|
||||||
src='/assets/img/vivian%20james.png'
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='LearnFAQ'>
|
<div className='LearnFAQ'>
|
||||||
|
@ -3,6 +3,7 @@ import '../styles/filters.css'
|
|||||||
import '../styles/pagination.css'
|
import '../styles/pagination.css'
|
||||||
import '../styles/search.css'
|
import '../styles/search.css'
|
||||||
import '../styles/styles.css'
|
import '../styles/styles.css'
|
||||||
|
import placeholder from '../assets/img/DEGMods Placeholder Img.png'
|
||||||
|
|
||||||
export const BlogsPage = () => {
|
export const BlogsPage = () => {
|
||||||
return (
|
return (
|
||||||
@ -92,14 +93,14 @@ export const BlogsPage = () => {
|
|||||||
|
|
||||||
<div className='IBMSecMain IBMSMListWrapper'>
|
<div className='IBMSecMain IBMSMListWrapper'>
|
||||||
<div className='IBMSMList'>
|
<div className='IBMSMList'>
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import { NDKFilter } from '@nostr-dev-kit/ndk'
|
|||||||
import 'swiper/css'
|
import 'swiper/css'
|
||||||
import 'swiper/css/navigation'
|
import 'swiper/css/navigation'
|
||||||
import 'swiper/css/pagination'
|
import 'swiper/css/pagination'
|
||||||
|
import placeholder from '../assets/img/DEGMods Placeholder Img.png'
|
||||||
|
|
||||||
export const HomePage = () => {
|
export const HomePage = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@ -118,10 +119,10 @@ export const HomePage = () => {
|
|||||||
<h2 className='IBMSMTitleMainHeading'>Blog Posts (WIP)</h2>
|
<h2 className='IBMSMTitleMainHeading'>Blog Posts (WIP)</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className='IBMSMList'>
|
<div className='IBMSMList'>
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='IBMSMAction'>
|
<div className='IBMSMAction'>
|
||||||
|
@ -41,6 +41,7 @@ import {
|
|||||||
import { Comments } from './internal/comment'
|
import { Comments } from './internal/comment'
|
||||||
import { Reactions } from './internal/reactions'
|
import { Reactions } from './internal/reactions'
|
||||||
import { Zap } from './internal/zap'
|
import { Zap } from './internal/zap'
|
||||||
|
import placeholder from '../../assets/img/DEGMods Placeholder Img.png'
|
||||||
|
|
||||||
export const ModPage = () => {
|
export const ModPage = () => {
|
||||||
const { naddr } = useParams()
|
const { naddr } = useParams()
|
||||||
@ -182,9 +183,9 @@ export const ModPage = () => {
|
|||||||
Creator's Blog Posts (WIP)
|
Creator's Blog Posts (WIP)
|
||||||
</h4>
|
</h4>
|
||||||
<div className='IBMSMList IBMSMListAlt'>
|
<div className='IBMSMList IBMSMListAlt'>
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
<BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
|
<BlogCard backgroundLink={placeholder} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,6 +17,8 @@ import {
|
|||||||
import { RelayController } from 'controllers'
|
import { RelayController } from 'controllers'
|
||||||
import { LoadingSpinner } from 'components/LoadingSpinner'
|
import { LoadingSpinner } from 'components/LoadingSpinner'
|
||||||
import { setUser } from 'store/reducers/user'
|
import { setUser } from 'store/reducers/user'
|
||||||
|
import placeholderMod from '../../assets/img/DEGMods Placeholder Img.png'
|
||||||
|
import placeholderPP from '../../assets/img/DEG Mods Default PP.png'
|
||||||
|
|
||||||
type FormState = {
|
type FormState = {
|
||||||
name: string
|
name: string
|
||||||
@ -80,11 +82,9 @@ export const ProfileSettings = () => {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const banner =
|
const banner = formState.banner || placeholderMod
|
||||||
formState.banner || '/assets/img/DEGMods%20Placeholder%20Img.png'
|
|
||||||
|
|
||||||
const picture =
|
const picture = formState.picture || placeholderPP
|
||||||
formState.picture || '/assets/img/DEG%20Mods%20Default%20PP.png'
|
|
||||||
|
|
||||||
const name = formState.displayName || formState.name || 'User name'
|
const name = formState.displayName || formState.name || 'User name'
|
||||||
|
|
||||||
|
5
src/utils/games.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const gameFiles = import.meta.glob('../assets/games/*.csv', {
|
||||||
|
query: '?raw',
|
||||||
|
import: 'default'
|
||||||
|
})
|
||||||
|
export default gameFiles
|
@ -56,7 +56,7 @@ export const isValidUrl = (url: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const isValidImageUrl = (url: string) => {
|
export const isValidImageUrl = (url: string) => {
|
||||||
const regex = /\.(jpeg|jpg|gif|png)$/
|
const regex = /\.(jpeg|jpg|gif|png|ico|bmp|webp|avif|jxl)$/
|
||||||
return regex.test(url)
|
return regex.test(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|