Moved away from deprecated CRA and using Vite
This commit is contained in:
parent
f35eb4bdda
commit
e2d00d5887
2
.env
2
.env
@ -1,2 +1,2 @@
|
|||||||
REACT_APP_basePath="/ketr.ketran"
|
VITE_basePath="/ketr.ketran"
|
||||||
NODE_CONFIG_ENV='production'
|
NODE_CONFIG_ENV='production'
|
10
Dockerfile
10
Dockerfile
@ -34,13 +34,13 @@ RUN npm run build
|
|||||||
# prepare client deps in the image so lint/type-check can run inside the container
|
# prepare client deps in the image so lint/type-check can run inside the container
|
||||||
# copy client sources and install dependencies during the image build (container-first)
|
# copy client sources and install dependencies during the image build (container-first)
|
||||||
COPY client /client
|
COPY client /client
|
||||||
WORKDIR /client
|
WORKDIR /client
|
||||||
ENV PUBLIC_URL="/ketr.ketran"
|
ENV PUBLIC_URL="/ketr.ketran"
|
||||||
ENV REACT_APP_API_BASE=""
|
ENV VITE_API_BASE=""
|
||||||
# prefer npm ci when lockfile present, otherwise fall back to npm install
|
# prefer npm ci when lockfile present, otherwise fall back to npm install
|
||||||
RUN rm -f package-lock.json
|
#RUN rm -f package-lock.json
|
||||||
RUN npm install --legacy-peer-deps --no-audit --no-fund
|
#RUN npm install --legacy-peer-deps --no-audit --no-fund
|
||||||
RUN npm run build
|
#RUN npm run build
|
||||||
# return to server working dir for default run
|
# return to server working dir for default run
|
||||||
WORKDIR /server
|
WORKDIR /server
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "peddlers-client",
|
"name": "peddlers-client",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
@ -23,34 +24,28 @@
|
|||||||
"react-movable": "^3.0.4",
|
"react-movable": "^3.0.4",
|
||||||
"react-moveable": "^0.31.1",
|
"react-moveable": "^0.31.1",
|
||||||
"react-router-dom": "^6.14.1",
|
"react-router-dom": "^6.14.1",
|
||||||
"react-scripts": "5.0.1",
|
"react-use-websocket": "^4.8.1",
|
||||||
"socket.io-client": "^4.4.1",
|
"socket.io-client": "^4.4.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "HTTPS=true react-scripts start",
|
"start": "vite --host",
|
||||||
"build": "export $(cat ../.env | xargs) && react-scripts build",
|
"build": "tsc && vite build",
|
||||||
"test": "export $(cat ../.env | xargs) && react-scripts test",
|
"preview": "vite preview",
|
||||||
"eject": "export $(cat ../.env | xargs) && react-scripts eject",
|
"test": "vitest",
|
||||||
"type-check": "tsc --project tsconfig.json --noEmit",
|
"type-check": "tsc --project tsconfig.json --noEmit",
|
||||||
"lint": "eslint 'src/**/*.{js,jsx,ts,tsx}' --max-warnings=0",
|
"lint": "eslint 'src/**/*.{js,jsx,ts,tsx}' --max-warnings=0",
|
||||||
"lint:fix": "eslint 'src/**/*.{js,jsx,ts,tsx}' --fix"
|
"lint:fix": "eslint 'src/**/*.{js,jsx,ts,tsx}' --fix"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"devDependencies": {
|
||||||
"src/**/*.{js,jsx,ts,tsx}": [
|
"@types/react": "^18.2.22",
|
||||||
"npm run lint:fix"
|
"@types/react-dom": "^18.2.7",
|
||||||
]
|
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||||
},
|
"@vitejs/plugin-react": "^4.0.0",
|
||||||
"husky": {
|
"typescript": "^5.4.3",
|
||||||
"hooks": {
|
"vite": "^5.0.0",
|
||||||
"pre-commit": "lint-staged"
|
"vite-tsconfig-paths": "^4.2.1",
|
||||||
}
|
"vitest": "^1.0.0"
|
||||||
},
|
|
||||||
"eslintConfig": {
|
|
||||||
"extends": [
|
|
||||||
"react-app",
|
|
||||||
"react-app/jest"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
@ -63,10 +58,5 @@
|
|||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.2.22",
|
|
||||||
"@types/react-dom": "^18.2.7",
|
|
||||||
"typescript": "^5.3.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,45 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
|
||||||
|
|
||||||
<base href="%PUBLIC_URL%"/>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<meta name="theme-color" content="#000000" />
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
content="Play Peddlers of Ketran!"
|
|
||||||
/>
|
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
|
||||||
<!--
|
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
|
||||||
-->
|
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
||||||
<!--
|
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
|
||||||
|
|
||||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
|
||||||
-->
|
|
||||||
<title>Peddlers of Ketran</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
|
||||||
This HTML file is a template.
|
|
||||||
If you open it directly in the browser, you will see an empty page.
|
|
||||||
|
|
||||||
You can add webfonts, meta tags, or analytics to this file.
|
|
||||||
The build step will place the bundled scripts into the <body> tag.
|
|
||||||
|
|
||||||
To begin the development, run `npm start` or `yarn start`.
|
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
|
||||||
-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -15,7 +15,7 @@ function debounce<T extends (...args: any[]) => void>(fn: T, ms: number): T {
|
|||||||
// the client running in a container to talk to the server by docker service
|
// the client running in a container to talk to the server by docker service
|
||||||
// name (e.g. http://peddlers-of-ketran:8930) while still working when run on
|
// name (e.g. http://peddlers-of-ketran:8930) while still working when run on
|
||||||
// the host where PUBLIC_URL may be appropriate.
|
// the host where PUBLIC_URL may be appropriate.
|
||||||
const envApiBase = process.env.REACT_APP_API_BASE;
|
const envApiBase = process.env.VITE_API_BASE;
|
||||||
const publicBase = process.env.PUBLIC_URL || '';
|
const publicBase = process.env.PUBLIC_URL || '';
|
||||||
|
|
||||||
const base = envApiBase || publicBase;
|
const base = envApiBase || publicBase;
|
||||||
|
@ -1,11 +1,31 @@
|
|||||||
|
.Video {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.8s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Video.fade-in {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.MediaControlContainer {
|
||||||
|
position: relative; /* CRITICAL: This creates the positioning context */
|
||||||
|
display: inline-block;
|
||||||
|
width: max-content; /* Ensure container sizes to content */
|
||||||
|
height: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
.MediaControlSpacer {
|
.MediaControlSpacer {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
width: 5rem;
|
width: 5rem;
|
||||||
min-width: 5rem;
|
min-width: 5rem;
|
||||||
height: 3.75rem;
|
height: 3.75rem;
|
||||||
min-height: 3.75rem;
|
min-height: 3.75rem;
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
|
border: 2px dashed #666; /* Visual indicator for drop zone */
|
||||||
}
|
}
|
||||||
|
|
||||||
.MediaControlSpacer.Medium {
|
.MediaControlSpacer.Medium {
|
||||||
@ -15,24 +35,26 @@
|
|||||||
min-height: 8.625em;
|
min-height: 8.625em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.MediaControl {
|
.MediaControl {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: fixed;
|
position: absolute; /* Out of flow */
|
||||||
flex-direction: row;
|
top: 0; /* Start at top of container */
|
||||||
justify-content: flex-end;
|
left: 0; /* Start at left of container */
|
||||||
align-items: center;
|
|
||||||
width: 5rem;
|
width: 5rem;
|
||||||
height: 3.75rem;
|
height: 3.75rem;
|
||||||
min-width: 5rem;
|
min-width: 5rem;
|
||||||
min-height: 3.75rem;
|
min-height: 3.75rem;
|
||||||
z-index: 50000;
|
z-index: 1200;
|
||||||
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MediaControl .Video {
|
.MediaControl .Video {
|
||||||
position: relative;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
@ -45,37 +67,25 @@
|
|||||||
min-height: 8.625em;
|
min-height: 8.625em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MediaControl > div {
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin-right: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.MediaControl .Controls {
|
.MediaControl .Controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0.5em;
|
gap: 0;
|
||||||
bottom: 0.5em;
|
left: 0;
|
||||||
justify-content: flex-end;
|
bottom: 0;
|
||||||
|
flex-direction: column;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center
|
||||||
}
|
}
|
||||||
|
|
||||||
.MediaControl.Small .Controls {
|
.MediaControl.Small .Controls {
|
||||||
left: 0;
|
|
||||||
bottom: unset;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MediaControl .Controls > div {
|
.MediaControl .Controls > div {
|
||||||
display: flex;
|
|
||||||
border-radius: 0.25em;
|
border-radius: 0.25em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0.25em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.MediaControl .Controls > div:hover {
|
.MediaControl .Controls > div:hover {
|
||||||
@ -89,4 +99,4 @@
|
|||||||
|
|
||||||
.moveable-control-box .moveable-direction {
|
.moveable-control-box .moveable-direction {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,7 @@ services:
|
|||||||
working_dir: /client
|
working_dir: /client
|
||||||
volumes:
|
volumes:
|
||||||
- ./client:/client:rw
|
- ./client:/client:rw
|
||||||
|
- ./certs:/certs:ro
|
||||||
ports:
|
ports:
|
||||||
- 3001:3000
|
- 3001:3000
|
||||||
environment:
|
environment:
|
||||||
@ -47,7 +48,11 @@ services:
|
|||||||
- HOST=0.0.0.0
|
- HOST=0.0.0.0
|
||||||
- WDS_SOCKET_HOST=0.0.0.0
|
- WDS_SOCKET_HOST=0.0.0.0
|
||||||
- WDS_SOCKET_PORT=0
|
- WDS_SOCKET_PORT=0
|
||||||
- REACT_APP_API_BASE=/ketr.ketran
|
- VITE_API_BASE=/ketr.ketran
|
||||||
|
# Provide paths to TLS key/cert inside the container so Vite can present
|
||||||
|
# a certificate for the external hostname (e.g. battle-linux.ketrenos.com).
|
||||||
|
- VITE_HTTPS_KEY=/certs/battle.key
|
||||||
|
- VITE_HTTPS_CERT=/certs/battle.crt
|
||||||
command: ["bash", "-c", "cd /client && npm install --legacy-peer-deps --silent --no-audit --no-fund && npm start"]
|
command: ["bash", "-c", "cd /client && npm install --legacy-peer-deps --silent --no-audit --no-fund && npm start"]
|
||||||
networks:
|
networks:
|
||||||
- peddlers-network
|
- peddlers-network
|
||||||
|
60
launch.sh
60
launch.sh
@ -3,10 +3,60 @@
|
|||||||
# Launch script for Peddlers of Ketran
|
# Launch script for Peddlers of Ketran
|
||||||
# Set PRODUCTION=1 for production mode, PRODUCTION=0 or unset for development mode
|
# Set PRODUCTION=1 for production mode, PRODUCTION=0 or unset for development mode
|
||||||
|
|
||||||
|
# Default values
|
||||||
|
PRODUCTION=${PRODUCTION:-0}
|
||||||
|
COMMAND="up"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--production)
|
||||||
|
PRODUCTION=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
up|down|restart)
|
||||||
|
COMMAND="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help|help)
|
||||||
|
echo "Usage: $0 [--production] [up|down|restart]"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown argument: $1"
|
||||||
|
echo "Usage: $0 [--production] [up|down|restart]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
export PRODUCTION
|
||||||
|
|
||||||
if [ "$PRODUCTION" = "1" ]; then
|
if [ "$PRODUCTION" = "1" ]; then
|
||||||
echo "Launching in PRODUCTION mode..."
|
PROFILE="prod"
|
||||||
docker compose --profile prod up
|
echo "Launching in PRODUCTION mode (profile: $PROFILE)..."
|
||||||
else
|
else
|
||||||
echo "Launching in DEVELOPMENT mode..."
|
PROFILE="dev"
|
||||||
docker compose --profile dev up
|
echo "Launching in DEVELOPMENT mode (profile: $PROFILE)..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case "$COMMAND" in
|
||||||
|
up)
|
||||||
|
echo "Bringing containers up (detached)..."
|
||||||
|
docker compose --profile "$PROFILE" up -d
|
||||||
|
;;
|
||||||
|
down)
|
||||||
|
echo "Bringing containers down..."
|
||||||
|
docker compose --profile "$PROFILE" down
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
echo "Restarting containers..."
|
||||||
|
docker compose --profile "$PROFILE" down
|
||||||
|
docker compose --profile "$PROFILE" up -d
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown command: $COMMAND"
|
||||||
|
echo "Usage: $0 [--production] [up|down|restart]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
@ -1,4 +1,4 @@
|
|||||||
let basePath = process.env.REACT_APP_basePath || "";
|
let basePath = process.env.VITE_basePath || "";
|
||||||
basePath = "/" + basePath.replace(/^\/+/, "").replace(/\/+$/, "") + "/";
|
basePath = "/" + basePath.replace(/^\/+/, "").replace(/\/+$/, "") + "/";
|
||||||
if (basePath == "//") {
|
if (basePath == "//") {
|
||||||
basePath = "/";
|
basePath = "/";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user