diff --git a/index.html b/index.html
index 8997335..96e638d 100644
--- a/index.html
+++ b/index.html
@@ -1,120 +1,20 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- sandspiel
-
-
-
-
-
-
-
-
-
+ sandspiel
+
-
-
-
-
-
-
-
-
diff --git a/js/app.js b/js/app.js
index d3202b9..49473d2 100644
--- a/js/app.js
+++ b/js/app.js
@@ -1,63 +1,6 @@
import React from "react";
import ReactDOM from "react-dom";
-import { BrowserRouter as Router, Route, Link } from "react-router-dom";
-import Info from "./components/info";
import { Index } from "./components/ui";
-import Browse from "./components/browse";
-import Admin from "./components/admin";
-import Menu from "./components/menu";
-import SignInScreen from "./components/signin";
-import BenchmarkRunner from "./components/benchmarkRunner";
-let sizeMap = [2, 5, 10, 18, 30, 45];
-
-function BrowseRouter({ match, location }) {
- return (
-
- );
-}
-
-function AdminRouter({ match, location }) {
- return (
-
- );
-}
-
-function SigninRouter({ match, location }) {
- return (
-
- );
-}
-
-function AppRouter() {
- return (
-
-
- (
-
- )}
- />
-
-
-
-
-
-
- );
-}
-
-ReactDOM.render(, document.getElementById("ui"));
-
-export { sizeMap };
+ReactDOM.render(, document.getElementById("ui"));
diff --git a/js/components/ui.js b/js/components/ui.js
index 10d1bd6..f3dd7ef 100644
--- a/js/components/ui.js
+++ b/js/components/ui.js
@@ -1,19 +1,12 @@
import React from "react";
-import { Link } from "react-router-dom";
-import * as Sentry from "@sentry/browser";
import * as wasm from "../../crate/pkg/sandtable_bg.wasm";
import { Species } from "../../crate/pkg/sandtable";
const memory = wasm.memory;
import { height, universe, width, reset } from "../index.js";
-import { snapshot, pallette } from "../render.js";
-import { functions, storage } from "../api.js";
-import SignInButton from "./signinButton.js";
+import { pallette } from "../render.js";
import { svgToImageData, rgbaToSpecies } from "../convertSVG";
-import { fetchVotedIds } from "../votes.js";
-
-import Menu from "./menu";
window.species = Species;
let pallette_data = pallette();
@@ -64,82 +57,23 @@ class Index extends React.Component {
super(props);
this.state = {
- submissionMenuOpen: false,
paused: false,
- submitting: false,
size: 2,
- dataURL: {},
- currentSubmission: null,
selectedElement: Species.Water,
};
window.UI = this;
- //if we start in the background, pause;
- if (
- this.props.location.pathname !== "/" &&
- this.props.location.pathname !== "/school"
- ) {
- window.setTimeout(() => this.pause(), 50);
- }
-
- this.load();
- }
-
- componentDidMount() {
- this.unregisterAuthObserver = firebase.auth().onAuthStateChanged((user) => {
- if (user && this.state.currentSubmission) {
- this.checkLiked(this.state.currentSubmission.id);
- }
- });
}
- componentWillUnmount() {
- if (this.unregisterAuthObserver) {
- this.unregisterAuthObserver();
- }
- }
-
- // Marks the loaded submission as liked if the signed-in user already voted.
- checkLiked(id) {
- fetchVotedIds([id]).then((voted) => {
- const { currentSubmission } = this.state;
- if (voted.has(id) && currentSubmission && currentSubmission.id === id) {
- this.setState({
- currentSubmission: { ...currentSubmission, liked: true },
- });
- }
- });
- }
-
- componentDidUpdate(prevProps) {
- if (
- this.props.location.pathname === "/" &&
- prevProps.location.pathname !== "/" &&
- this.state.currentSubmission
- ) {
- window.location = `#${this.state.currentSubmission.id}`;
- return;
- }
- if (
- this.props.location.pathname !== "/" &&
- prevProps.location.pathname == "/"
- ) {
- this.pause();
- }
- if (
- prevProps.location.hash === "" ||
- prevProps.location.hash != this.props.location.hash
- ) {
- this.load();
- }
- }
togglePause() {
window.paused = !this.state.paused;
this.setState({ paused: !this.state.paused });
}
+
play() {
window.paused = false;
this.setState({ paused: false });
}
+
pause() {
window.paused = true;
this.setState({ paused: true });
@@ -151,147 +85,13 @@ class Index extends React.Component {
size,
});
}
+
reset() {
if (window.confirm("Are you sure you want to reset?")) {
this.play();
- window.location = "#";
- this.setState({ currentSubmission: null });
reset();
}
}
- menu() {
- this.pause();
- this.setState({ submissionMenuOpen: true });
- }
-
- closeMenu() {
- this.play();
- this.setState({ submissionMenuOpen: false });
- }
- upload() {
- let dataURL = snapshot(universe);
- const cells = new Uint8Array(
- memory.buffer,
- universe.cells(),
- width * height * 4
- );
-
- // Create canvas
- let canvas = document.createElement("canvas"),
- context = canvas.getContext("2d"),
- imgData = context.createImageData(width, height);
-
- canvas.height = height;
- canvas.width = width;
-
- // fill imgData with data from cells
- // transpose for historical compatability
- for (let x = 0; x < width; x++) {
- for (let y = 0; y < height; y++) {
- let cell_index = (y + x * height) * 4;
- let img_index = (x + y * width) * 4;
- for (var i = 0; i < 4; i++) {
- if (i % 4 == 3) {
- imgData.data[img_index + i] = 255;
- } else {
- imgData.data[img_index + i] = cells[cell_index + i];
- }
- }
- }
- }
- // put data to context at (0, 0)
- context.putImageData(imgData, 0, 0);
-
- let cellData = canvas.toDataURL("image/png");
-
- this.pause();
- this.setState({
- data: { dataURL, cells: cellData },
- submissionMenuOpen: true,
- });
- }
- rateLimited() {
- var postList = JSON.parse(localStorage.getItem("postList") || "[]");
- postList = postList.filter((post) => Date.now() - 1000 * 60 * 5 < post);
-
- if (postList.length >= 3) {
- Sentry.captureMessage("RATELIMIT");
- return true;
- }
- return false;
- }
- submit() {
- let { title = "", data, currentSubmission } = this.state;
-
- let { dataURL, cells } = data;
- let { currentUser } = firebase.auth();
- if (!currentUser) {
- window.alert("Please sign in to post!");
- return;
- }
- title = title.replace(
- "[profile]",
- `https://sandspiel.club/browse/search/?user=${currentUser.uid}`
- );
-
- let payload = {
- title,
- image: dataURL,
- parent_id: currentSubmission?.data?.id,
- cells,
- };
-
- const recordPost = () => {
- var postList = JSON.parse(localStorage.getItem("postList") || "[]");
- postList = postList.filter((post) => Date.now() - 1000 * 60 * 3 < post);
- postList.push(Date.now());
- localStorage.setItem("postList", JSON.stringify(postList));
- };
-
- const errorMessages = {
- 202: "This exact creation has already been posted.",
- 301: "Please verify your email address before posting.",
- 302: "Too many posts from your network today. Try again later.",
- 400: "This creation couldn't be validated. Try uploading again.",
- 401: "Your account has been banned from posting.",
- 418: "That title isn't allowed. Please choose another.",
- 429: "You're posting too fast. Wait a few minutes and try again.",
- };
-
- this.setState({ submitting: true });
- currentUser
- .getIdToken()
- .then((token) =>
- fetch(functions._url("api/creations"), {
- method: "POST",
- body: JSON.stringify(payload), // data can be `string` or {object}!
- headers: {
- "Content-Type": "application/json",
- Authorization: "Bearer " + token,
- },
- })
- )
- .then((res) => {
- if (!res.ok) {
- throw new Error(
- errorMessages[res.status] ||
- `Upload failed (HTTP ${res.status}). Please try again.`
- );
- }
- return res.json();
- })
- .then((response) => {
- console.log("Success:", JSON.stringify(response));
- recordPost();
- this.setState({ submissionMenuOpen: false, submitting: false });
- this.play();
- })
- .catch((error) => {
- console.error("Error:", error);
- window.alert(error.message || "Upload failed. Please try again.");
- this.setState({ submitting: false });
- });
- }
async loadSVG(svgString) {
const imgData = await svgToImageData(svgString);
@@ -323,150 +123,8 @@ class Index extends React.Component {
this.pause();
}
- load() {
- let { location } = this.props;
- let id = location.hash.replace(/#/, "");
- if (id === "") {
- return;
- }
-
- if (this.state.currentSubmission && this.state.currentSubmission.id == id) {
- return;
- }
-
- fetch(functions._url(`api/creations/${id}`), {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- },
- })
- .then((res) => {
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
- return res.json();
- })
- .then((data) => {
- if (!data || !data.id) throw new Error("submission not found");
- storage
- .refFromURL(
- `gs://sandtable-8d0f7.appspot.com/creations/${data.id}.data.png`
- )
- .getDownloadURL()
- .then((dlurl) => {
- fetch(dlurl, {
- method: "GET",
- })
- .then((res) => res.blob())
- .then((blob) => {
- this.setState({ currentSubmission: { id, data } });
- this.checkLiked(id);
-
- var url = URL.createObjectURL(blob);
- var img = new Image();
- img.src = url;
- img.onload = () => {
- var canvas = document.createElement("canvas");
- canvas.width = width;
- canvas.height = height;
- var ctx = canvas.getContext("2d");
-
- ctx.translate(canvas.width / 2, canvas.height / 2);
- ctx.rotate((-90 * Math.PI) / 180);
- ctx.scale(-1, 1.0);
- ctx.translate(-canvas.width / 2, -canvas.height / 2);
-
- ctx.drawImage(img, 0, 0);
- var imgData = ctx.getImageData(
- 0,
- 0,
- canvas.width,
- canvas.height
- );
-
- const cellsData = new Uint8Array(
- memory.buffer,
- universe.cells(),
- width * height * 4
- );
-
- reset();
- window.stopboot = true;
-
- for (var i = 0; i < width * height * 4; i++) {
- cellsData[i] = imgData.data[i];
- }
- universe.flush_undos();
- universe.push_undo();
- this.pause();
- };
- })
- .catch((error) => console.error("Error:", error));
- })
- .catch((error) => console.error("Error:", error));
- })
- .catch((error) => {
- console.error("Error:", error);
- });
- }
- incScore() {
- let { currentSubmission } = this.state;
- if (!currentSubmission || currentSubmission.liked) return;
- let { id } = currentSubmission;
- const { currentUser } = firebase.auth();
- if (!currentUser) {
- window.alert("Please sign in to vote!");
- return;
- }
- if (!currentUser.emailVerified) {
- window.alert(`Please verify your email ${currentUser.email} to vote!`);
- return;
- }
- // creations/:id/vote
- currentUser
- .getIdToken()
- .then((token) =>
- fetch(functions._url(`api/creations/${id}/vote`), {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- Authorization: "Bearer " + token,
- },
- })
- )
- .then((res) => {
- if (res.status === 301) {
- // already voted: just reflect that
- if (this.state.currentSubmission?.id === id) {
- this.setState({
- currentSubmission: { ...this.state.currentSubmission, liked: true },
- });
- }
- return null;
- }
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
- return res.json();
- })
- .then((data) => {
- if (data && this.state.currentSubmission?.id === id) {
- this.setState({
- currentSubmission: {
- ...this.state.currentSubmission,
- data,
- liked: true,
- },
- });
- }
- })
- .catch((e) => {
- console.error(e);
- });
- }
-
render() {
- let { size, paused, selectedElement, currentSubmission } = this.state;
- let hash =
- currentSubmission && currentSubmission.id
- ? `#${currentSubmission.id}`
- : "";
+ let { size, paused, selectedElement } = this.state;
return (
);
}
diff --git a/js/index.js b/js/index.js
index 22a8793..0882dbb 100644
--- a/js/index.js
+++ b/js/index.js
@@ -1,24 +1,6 @@
-import * as Sentry from "@sentry/browser";
-import { Integrations } from "@sentry/tracing";
-import { Wasm as WasmIntegration } from "@sentry/wasm";
import { boot } from "./boot";
-if (!window.location.host.startsWith("localhost")) {
- Sentry.init({
- dsn: "https://4bf8c3ab764f40569d573fc4021efe40@o40136.ingest.sentry.io/1331284",
-
- // Alternatively, use `process.env.npm_package_version` for a dynamic release version
- // if your build tool supports it.
- integrations: [new Integrations.BrowserTracing(), new WasmIntegration()],
-
- // Set tracesSampleRate to 1.0 to capture 100%
- // of transactions for performance monitoring.
- // We recommend adjusting this value in production
- tracesSampleRate: 0.01,
- });
-}
-
-import "./api";
import { Universe } from "../crate/pkg";
+import * as wasm from "../crate/pkg/sandtable_bg.wasm";
import { startWebGL } from "./render";
import { fps } from "./fps";
@@ -27,49 +9,7 @@ import {} from "./app";
import { startFluid } from "./fluid";
import {} from "./layout";
-const isBench = window.location.pathname === "/bench";
-if (window.safari) {
- history.pushState(null, null, location.href);
- window.onpopstate = function (event) {
- history.go(1);
- };
-}
-
-function mobileAndTabletcheck() {
- var check = false;
- (function (a) {
- if (
- /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(
- a
- ) ||
- /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
- a.substr(0, 4)
- )
- )
- check = true;
- })(navigator.userAgent || navigator.vendor || window.opera);
- return check;
-}
-
-if (mobileAndTabletcheck()) {
- window.onbeforeunload = function () {
- return true;
- };
-}
-
-if ("serviceWorker" in navigator) {
- window.addEventListener("load", () => {
- navigator.serviceWorker
- .register("/service-worker.js")
- .then((registration) => {
- console.log("SW registered: ", registration);
- fetch("index.html"); // refresh cache (?)
- })
- .catch((registrationError) => {
- console.log("SW registration failed: ", registrationError);
- });
- });
-}
+const isBench = false;
let n = 300;
const universe = isBench ? window.u : Universe.new(n, n);
@@ -82,7 +22,7 @@ const canvas2 = document.getElementById("fluid-canvas");
canvas.height = n * Math.ceil(window.devicePixelRatio);
canvas.width = n * Math.ceil(window.devicePixelRatio);
-document.getElementById("background").addEventListener("touchmove", (e) => {
+canvas.addEventListener("touchmove", (e) => {
if (!window.paused) {
if (e.cancelable) {
e.preventDefault();
@@ -140,5 +80,29 @@ document.addEventListener("paste", function (event) {
}
});
-(adsbygoogle = window.adsbygoogle || []).push({});
+// For the page that embeds this one (wasmga.me): the board as bytes, to keep
+// and to load back, and a reset without asking.
+const cells = () =>
+ new Uint8Array(wasm.memory.buffer, universe.cells(), width * height * 4);
+window.wg = {
+ snapshot: () => cells().slice(),
+ restore(bytes) {
+ if (bytes.length !== width * height * 4) return false;
+ reset();
+ window.stopboot = true;
+ cells().set(bytes);
+ universe.flush_undos();
+ universe.push_undo();
+ return true;
+ },
+ clear() {
+ window.stopboot = true;
+ reset();
+ },
+ setPaused(paused) {
+ if (paused) window.UI.pause();
+ else window.UI.play();
+ },
+};
+
export { canvas, width, height, universe, reset };
diff --git a/js/layout.js b/js/layout.js
index ac72c17..a928c86 100644
--- a/js/layout.js
+++ b/js/layout.js
@@ -1,3 +1,6 @@
+// Fits the board and the buttons into the window: the buttons beside the
+// board when there's room for them, else in one row above it that scrolls
+// sideways.
let resize = () => {
const canvas = document.getElementById("sand-canvas");
const canvas2 = document.getElementById("fluid-canvas");
@@ -5,50 +8,26 @@ let resize = () => {
if (!canvas || !canvas2 || !ui) return;
- let screen_width = window.innerWidth;
- let uiheight = 50;
- let screen_height = window.innerHeight - uiheight;
-
- let canvasStyle = "";
- let uiStyle = "";
- let adStyle = "display:none;";
-
- if (screen_width > screen_height) {
- if (screen_width - window.innerHeight < 400) {
- // landscape compressed
- canvasStyle = `height: ${window.innerHeight}px; margin:3px`;
- uiStyle = `width: ${
- screen_width - window.innerHeight - 12
- }px; margin: 2px;`;
- } else {
- // landscape wide
- canvasStyle = `
- height: ${window.innerHeight}px;
- width:${window.innerHeight}px;
- margin:0;
- left: auto;
- right: 206px`;
- uiStyle = `width: 200px; margin: 2px;`;
- adStyle = `width: ${
- screen_width - window.innerHeight - (206 + 150)
- }px; margin: 1px;`;
- }
+ const w = window.innerWidth;
+ const h = window.innerHeight;
+ let side;
+ if (w - h >= 180) {
+ ui.className = "";
+ ui.style = `width: ${w - h - 8}px; margin: 2px;`;
+ side = h;
+ canvas.style = canvas2.style = `height: ${side}px; width: ${side}px; left: 0; right: auto;`;
} else {
- //portrait (mobile)
- canvasStyle = `width: ${screen_width}px; bottom:3px;`;
- uiStyle = "";
+ ui.className = "row";
+ ui.style = "";
+ side = Math.max(60, Math.min(w, h - ui.offsetHeight - 2));
+ canvas.style = canvas2.style = `height: ${side}px; width: ${side}px;`;
}
- ui.style = uiStyle;
- canvas.style = canvasStyle;
- canvas2.style = canvasStyle;
- const adSlot = document.getElementsByClassName("adslot_1")[0];
- if (adSlot) adSlot.style = adStyle;
};
-if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', resize);
+if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", resize);
} else {
resize();
}
-window.addEventListener("deviceorientation", resize, true);
window.addEventListener("resize", resize);
+new ResizeObserver(resize).observe(document.getElementById("ui"));
diff --git a/js/styles.css b/js/styles.css
index 309c533..2ab8465 100644
--- a/js/styles.css
+++ b/js/styles.css
@@ -431,3 +431,17 @@ img {
.reversed {
transform: rotate(180deg);
}
+
+#ui.row {
+ float: none;
+ flex-wrap: nowrap;
+ overflow-x: auto;
+ scrollbar-width: none;
+}
+#ui.row button {
+ flex-shrink: 0;
+}
+#ui.row .sizes {
+ display: flex;
+ flex-shrink: 0;
+}
diff --git a/package.json b/package.json
index 8860e0c..e2bccac 100644
--- a/package.json
+++ b/package.json
@@ -4,9 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
- "build": "webpack --mode=production",
- "start": "webpack-dev-server --host 0.0.0.0",
- "deploy": "webpack --mode=production && gh-pages -d dist"
+ "build": "webpack --mode=production"
},
"repository": {
"type": "git",
@@ -25,44 +23,29 @@
"@babel/plugin-syntax-dynamic-import": "^7.7.4",
"@babel/preset-env": "^7.7.7",
"@babel/preset-react": "^7.7.4",
- "@wasm-tool/wasm-pack-plugin": "0.2.1",
"babel-loader": "^8.0.6",
"copy-webpack-plugin": "^12.0.2",
"glslify": "^6.4.1",
"glslify-loader": "^1.0.2",
"html-webpack-plugin": "^5.6.5",
- "http-server": "^0.11.1",
"raw-loader": "^1.0.0",
"webpack": "^5.104.1",
- "webpack-cli": "^5.1.4",
- "webpack-dev-server": "^5.2.3",
- "workbox-webpack-plugin": "^7.4.0"
+ "webpack-cli": "^5.1.4"
},
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.7.4",
"@babel/plugin-transform-runtime": "^7.13.15",
- "@sentry/browser": "^6.2.5",
- "@sentry/react": "^7.28.1",
- "@sentry/tracing": "^6.2.5",
- "@sentry/wasm": "^6.2.5",
+ "@babel/runtime": "^7.29.10",
"classnames": "^2.2.6",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^5.0.2",
"dat.gui": "^0.7.5",
- "firebase": "^8.2.8",
- "firebase-admin": "^9.3.0",
- "firebase-tools": "^15.29.0",
- "gh-pages": "^2.1.1",
"glsl-hsv2rgb": "^1.0.0",
"glsl-noise": "0.0.0",
"glsl-random": "0.0.5",
"react": "^16.12.0",
"react-dom": "^16.12.0",
- "react-firebaseui": "4.1.0",
- "react-router-dom": "^5.1.2",
- "react-youtube": "^9.0.2",
"regl": "^1.3.13",
- "style-loader": "^2.0.0",
- "timeago.js": "^3.0.2"
+ "style-loader": "^2.0.0"
}
}
diff --git a/webpack.config.js b/webpack.config.js
index 28c87ab..ca0fda7 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,62 +2,27 @@ const path = require("path");
const dist = path.resolve(__dirname, "dist");
const CopyWebpackPlugin = require("copy-webpack-plugin");
-const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
-const { GenerateSW } = require("workbox-webpack-plugin");
module.exports = (env, argv) => {
const isProduction = argv.mode === "production";
const plugins = [
new CleanWebpackPlugin(),
- new WasmPackPlugin({
- crateDirectory: path.resolve(__dirname, "crate"),
- extraArgs: "--target bundler",
- }),
new CopyWebpackPlugin({
- patterns: [
- "js/styles.css",
- "manifest.json",
- { from: "assets/*" },
- ],
+ patterns: ["js/styles.css"],
}),
new HtmlWebpackPlugin({ template: "index.html" }),
];
- // Only add service worker in production to avoid watch mode warnings
- if (isProduction) {
- plugins.push(
- new GenerateSW({
- navigateFallback: "index.html",
- runtimeCaching: [
- {
- urlPattern: /\.html$/,
- handler: "StaleWhileRevalidate",
- },
- {
- urlPattern: /\.(?:png|jpg|jpeg|svg)$/,
- handler: "CacheFirst",
- options: {
- cacheName: "images",
- expiration: {
- maxEntries: 300,
- },
- },
- },
- ],
- })
- );
- }
-
return {
entry: "./js/bootstrap.js",
output: {
path: dist,
- filename: "[name].[contenthash].js",
- publicPath: "/",
+ filename: "[name].js",
+ publicPath: "",
},
devServer: {
static: dist,
@@ -68,7 +33,7 @@ module.exports = (env, argv) => {
asyncWebAssembly: true,
},
mode: isProduction ? "production" : "development",
- devtool: "source-map",
+ devtool: false,
plugins,
module: {
rules: [