From 6677936f9738f8a4be92b2b5ab1f2058041d1c72 Mon Sep 17 00:00:00 2001 From: NewHappyRabbit <31893343+NewHappyRabbit@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:51:40 +0200 Subject: [PATCH] All files from resources directory are now copied to build folder so they can be used directly without importing them in files. Added flag selection. --- package-lock.json | 167 +++++++++++++++++++++ package.json | 1 + resources/flags/none.svg | 23 +++ src/client/components/FlagInput.ts | 223 ++++++++++++++++++++++++++--- src/client/index.html | 2 +- webpack.config.js | 10 ++ 6 files changed, 405 insertions(+), 21 deletions(-) create mode 100644 resources/flags/none.svg diff --git a/package-lock.json b/package-lock.json index 84e8d0835..6cd82a35f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,6 +65,7 @@ "binary-base64-loader": "^1.0.0", "chai": "^5.1.1", "concurrently": "^8.2.2", + "copy-webpack-plugin": "^12.0.2", "cross-env": "^7.0.3", "css-loader": "^7.1.2", "file-loader": "^6.2.0", @@ -3996,6 +3997,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -6516,6 +6529,95 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/copy-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/core-js-compat": { "version": "3.38.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", @@ -8707,6 +8809,38 @@ "node": ">=4" } }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/google-auth-library": { "version": "9.14.2", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.2.tgz", @@ -9310,6 +9444,15 @@ ], "license": "BSD-3-Clause" }, + "node_modules/ignore": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/image-q": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", @@ -12193,6 +12336,18 @@ "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "license": "MIT" }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pathval": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", @@ -15092,6 +15247,18 @@ "node": ">=4" } }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unique-filename": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", diff --git a/package.json b/package.json index 33ee294ee..bcf4f563c 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "binary-base64-loader": "^1.0.0", "chai": "^5.1.1", "concurrently": "^8.2.2", + "copy-webpack-plugin": "^12.0.2", "cross-env": "^7.0.3", "css-loader": "^7.1.2", "file-loader": "^6.2.0", diff --git a/resources/flags/none.svg b/resources/flags/none.svg new file mode 100644 index 000000000..8f859572f --- /dev/null +++ b/resources/flags/none.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/src/client/components/FlagInput.ts b/src/client/components/FlagInput.ts index 58257503e..3f7013e24 100644 --- a/src/client/components/FlagInput.ts +++ b/src/client/components/FlagInput.ts @@ -1,25 +1,208 @@ -import { LitElement, html, css } from 'lit'; -import { customElement, property, state } from 'lit/decorators.js'; -import Countries from '../data/countries.json'; +import { LitElement, html, css } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import Countries from "../data/countries.json"; -@customElement('flag-input') +const flagKey: string = "flag"; + +@customElement("flag-input") export class FlagInput extends LitElement { - @state() private flag: string = ''; + @state() private flag: string = this.getStoredFlag(); + @state() private search: string = ""; + @state() private showModal: boolean = false; - static styles = css``; + static styles = css` + .hidden { + display: none; + } - render() { - return html` -
-
- -
- `; - } + .flag-container { + display: flex; + } + + .no-selected-flag { + position: absolute; + left: 8px; + top: 8px; + height: 50px; + border-radius: 0.75rem; + border: none; + background: none; + font-size: 1rem; + cursor: pointer; + } + + .selected-flag { + width: 48px; + cursor: pointer; + position: absolute; + left: 24px; + top: 14px; + border: 1px solid black; + } + + .flag-modal { + display: flex; + flex-direction: column; + gap: 0.5rem; + position: absolute; + top: 60px; + left: 0; + width: 560px; + height: 500px; + background-color: rgb(35 35 35 / 0.8); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); + padding: 10px; + border-radius: 8px; + } + + .flag-search { + height: 2rem; + border-radius: 8px; + border: none; + text-align: center; + font-size: 1.3rem; + } + + .flag-dropdown { + overflow-y: auto; + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 1rem; + } + + .dropdown-item { + opacity: 0.7; + width: calc(100% / 4 - 15px); + text-align: center; + color: white; + cursor: pointer; + border: none; + background: none; + } + + .dropdown-item:hover { + opacity: 1; + } + + .country-flag { + width: 100%; + height: auto; + } + + @media (max-width: 768px) { + .flag-modal { + left: 0px; + width: calc(100% - 16px); + height: 50vh; + } + + .dropdown-item { + width: calc(100% / 3 - 15px); + } + } + `; + + private handleSearch(e: Event) { + this.search = String((e.target as HTMLInputElement).value); + } + + private setFlag(flag: string) { + this.flag = flag; + this.showModal = false; + this.storeFlag(flag); + } + + private getStoredFlag(): string { + const storedFlag = localStorage.getItem(flagKey); + if (storedFlag) { + return storedFlag; + } + return ""; + } + + private storeFlag(flag: string) { + if (flag) { + localStorage.setItem(flagKey, flag); + } + } + + render() { + return html` +
+ ${this.flag === "" + ? html` ` + : html` (this.showModal = true)} + />`} + ${this.showModal + ? html` +
+ +
+ + + ${Countries.filter( + (country) => + country.name + .toLowerCase() + .includes( + this.search.toLowerCase() + ) || + country.code + .toLowerCase() + .includes( + this.search.toLowerCase() + ) + ).map( + (country) => html` + + ` + )} +
+
+ ` + : ""} +
+ `; + } } diff --git a/src/client/index.html b/src/client/index.html index 79eb6d6ea..ec219127d 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -80,7 +80,7 @@ v0.15.0 -
+
diff --git a/webpack.config.js b/webpack.config.js index d5f70181c..ad157f846 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,6 +2,7 @@ import path from 'path'; import { fileURLToPath } from 'url'; import HtmlWebpackPlugin from 'html-webpack-plugin'; import webpack from 'webpack'; +import CopyPlugin from "copy-webpack-plugin"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -100,8 +101,17 @@ export default (env, argv) => { new webpack.DefinePlugin({ 'process.env.GAME_ENV': JSON.stringify(isProduction ? 'prod' : 'dev') }), + new CopyPlugin({ + patterns: [ + { from: "resources", to: path.resolve(__dirname, 'out') }, + ], + options: { + concurrency: 100, + }, + }), ], devServer: isProduction ? {} : { + devMiddleware: { writeToDisk: true }, static: { directory: path.join(__dirname, 'out'), },