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'
|
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
|
||||
# copy client sources and install dependencies during the image build (container-first)
|
||||
COPY client /client
|
||||
WORKDIR /client
|
||||
WORKDIR /client
|
||||
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
|
||||
RUN rm -f package-lock.json
|
||||
RUN npm install --legacy-peer-deps --no-audit --no-fund
|
||||
RUN npm run build
|
||||
#RUN rm -f package-lock.json
|
||||
#RUN npm install --legacy-peer-deps --no-audit --no-fund
|
||||
#RUN npm run build
|
||||
# return to server working dir for default run
|
||||
WORKDIR /server
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
"name": "peddlers-client",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
@ -23,34 +24,28 @@
|
||||
"react-movable": "^3.0.4",
|
||||
"react-moveable": "^0.31.1",
|
||||
"react-router-dom": "^6.14.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-use-websocket": "^4.8.1",
|
||||
"socket.io-client": "^4.4.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "HTTPS=true react-scripts start",
|
||||
"build": "export $(cat ../.env | xargs) && react-scripts build",
|
||||
"test": "export $(cat ../.env | xargs) && react-scripts test",
|
||||
"eject": "export $(cat ../.env | xargs) && react-scripts eject",
|
||||
"start": "vite --host",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest",
|
||||
"type-check": "tsc --project tsconfig.json --noEmit",
|
||||
"lint": "eslint 'src/**/*.{js,jsx,ts,tsx}' --max-warnings=0",
|
||||
"lint:fix": "eslint 'src/**/*.{js,jsx,ts,tsx}' --fix"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,jsx,ts,tsx}": [
|
||||
"npm run lint:fix"
|
||||
]
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.22",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"typescript": "^5.4.3",
|
||||
"vite": "^5.0.0",
|
||||
"vite-tsconfig-paths": "^4.2.1",
|
||||
"vitest": "^1.0.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@ -63,10 +58,5 @@
|
||||
"last 1 firefox 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
|
||||
// name (e.g. http://peddlers-of-ketran:8930) while still working when run on
|
||||
// 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 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 {
|
||||
display: flex;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 5rem;
|
||||
min-width: 5rem;
|
||||
height: 3.75rem;
|
||||
min-height: 3.75rem;
|
||||
background-color: #444;
|
||||
border-radius: 0.25rem;
|
||||
border: 2px dashed #666; /* Visual indicator for drop zone */
|
||||
}
|
||||
|
||||
.MediaControlSpacer.Medium {
|
||||
@ -15,24 +35,26 @@
|
||||
min-height: 8.625em;
|
||||
}
|
||||
|
||||
|
||||
.MediaControl {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
position: absolute; /* Out of flow */
|
||||
top: 0; /* Start at top of container */
|
||||
left: 0; /* Start at left of container */
|
||||
width: 5rem;
|
||||
height: 3.75rem;
|
||||
min-width: 5rem;
|
||||
min-height: 3.75rem;
|
||||
z-index: 50000;
|
||||
z-index: 1200;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.MediaControl .Video {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: #444;
|
||||
border-radius: 0.25rem;
|
||||
border: 1px solid black;
|
||||
@ -45,37 +67,25 @@
|
||||
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 {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
left: 0.5em;
|
||||
bottom: 0.5em;
|
||||
justify-content: flex-end;
|
||||
gap: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
flex-direction: column;
|
||||
z-index: 1;
|
||||
align-items: flex-start;
|
||||
justify-content: center
|
||||
}
|
||||
|
||||
.MediaControl.Small .Controls {
|
||||
left: 0;
|
||||
bottom: unset;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.MediaControl .Controls > div {
|
||||
display: flex;
|
||||
border-radius: 0.25em;
|
||||
cursor: pointer;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.MediaControl .Controls > div:hover {
|
||||
@ -89,4 +99,4 @@
|
||||
|
||||
.moveable-control-box .moveable-direction {
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,7 @@ services:
|
||||
working_dir: /client
|
||||
volumes:
|
||||
- ./client:/client:rw
|
||||
- ./certs:/certs:ro
|
||||
ports:
|
||||
- 3001:3000
|
||||
environment:
|
||||
@ -47,7 +48,11 @@ services:
|
||||
- HOST=0.0.0.0
|
||||
- WDS_SOCKET_HOST=0.0.0.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"]
|
||||
networks:
|
||||
- peddlers-network
|
||||
|
60
launch.sh
60
launch.sh
@ -3,10 +3,60 @@
|
||||
# Launch script for Peddlers of Ketran
|
||||
# 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
|
||||
echo "Launching in PRODUCTION mode..."
|
||||
docker compose --profile prod up
|
||||
PROFILE="prod"
|
||||
echo "Launching in PRODUCTION mode (profile: $PROFILE)..."
|
||||
else
|
||||
echo "Launching in DEVELOPMENT mode..."
|
||||
docker compose --profile dev up
|
||||
fi
|
||||
PROFILE="dev"
|
||||
echo "Launching in DEVELOPMENT mode (profile: $PROFILE)..."
|
||||
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(/\/+$/, "") + "/";
|
||||
if (basePath == "//") {
|
||||
basePath = "/";
|
||||
|
Loading…
x
Reference in New Issue
Block a user