adding tauri
							
								
								
									
										2
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					src-tauri/
 | 
				
			||||||
 | 
					node_modules/
 | 
				
			||||||
							
								
								
									
										69
									
								
								.hmrc
									
									
									
									
									
								
							
							
						
						@@ -2,7 +2,7 @@
 | 
				
			|||||||
  "path": "G:\\Other\\Development\\Projects\\[ideas]\\domino-client",
 | 
					  "path": "G:\\Other\\Development\\Projects\\[ideas]\\domino-client",
 | 
				
			||||||
  "name": "domino-client",
 | 
					  "name": "domino-client",
 | 
				
			||||||
  "initialVersion": "0.1.4",
 | 
					  "initialVersion": "0.1.4",
 | 
				
			||||||
  "version": "0.1.4",
 | 
					  "version": "0.1.8",
 | 
				
			||||||
  "docker": {
 | 
					  "docker": {
 | 
				
			||||||
    "useRegistry": true,
 | 
					    "useRegistry": true,
 | 
				
			||||||
    "registry": "192.168.1.115:5000",
 | 
					    "registry": "192.168.1.115:5000",
 | 
				
			||||||
@@ -81,5 +81,72 @@
 | 
				
			|||||||
      "type": "git",
 | 
					      "type": "git",
 | 
				
			||||||
      "url": "https://gitea.xintanalabs.net/arhuako/domino-client"
 | 
					      "url": "https://gitea.xintanalabs.net/arhuako/domino-client"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "_backup": {
 | 
				
			||||||
 | 
					    "name": "domino-client",
 | 
				
			||||||
 | 
					    "version": "0.1.7",
 | 
				
			||||||
 | 
					    "private": true,
 | 
				
			||||||
 | 
					    "type": "commonjs",
 | 
				
			||||||
 | 
					    "scripts": {
 | 
				
			||||||
 | 
					      "dev": "vite",
 | 
				
			||||||
 | 
					      "build": "run-p type-check \"build-only {@}\" --",
 | 
				
			||||||
 | 
					      "preview": "vite preview",
 | 
				
			||||||
 | 
					      "test:unit": "vitest",
 | 
				
			||||||
 | 
					      "build-only": "vite build",
 | 
				
			||||||
 | 
					      "type-check": "vue-tsc --build --force",
 | 
				
			||||||
 | 
					      "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
 | 
				
			||||||
 | 
					      "format": "prettier --write src/",
 | 
				
			||||||
 | 
					      "docker-build": "docker build -t 192.168.1.115:5000/arhuako/domino-client:latest .",
 | 
				
			||||||
 | 
					      "docker-tag": "docker tag 192.168.1.115:5000/arhuako/domino-client:latest 192.168.1.115:5000/arhuako/domino-client:0.1.7",
 | 
				
			||||||
 | 
					      "docker-push": "docker push 192.168.1.115:5000/arhuako/domino-client:latest && docker push 192.168.1.115:5000/arhuako/domino-client:0.1.7",
 | 
				
			||||||
 | 
					      "publish": "npm run docker-build && npm run docker-tag && npm run docker-push",
 | 
				
			||||||
 | 
					      "serve": "npm run build-only && http-server ./dist -c-1 -s ",
 | 
				
			||||||
 | 
					      "tauri": "tauri"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "dependencies": {
 | 
				
			||||||
 | 
					      "@pixi/sound": "^6.0.0",
 | 
				
			||||||
 | 
					      "@tauri-apps/api": "^1.6.0",
 | 
				
			||||||
 | 
					      "bulma": "^1.0.1",
 | 
				
			||||||
 | 
					      "colorette": "^2.0.20",
 | 
				
			||||||
 | 
					      "dayjs": "^1.11.11",
 | 
				
			||||||
 | 
					      "pinia": "^2.1.7",
 | 
				
			||||||
 | 
					      "pino": "^9.2.0",
 | 
				
			||||||
 | 
					      "pixi-actions": "^1.1.11",
 | 
				
			||||||
 | 
					      "pixi-filters": "^6.0.4",
 | 
				
			||||||
 | 
					      "pixi.js": "^8.2.1",
 | 
				
			||||||
 | 
					      "socket.io-client": "^4.7.5",
 | 
				
			||||||
 | 
					      "vue": "^3.4.29",
 | 
				
			||||||
 | 
					      "vue-clipboard3": "^2.0.0",
 | 
				
			||||||
 | 
					      "vue-i18n": "^9.13.1",
 | 
				
			||||||
 | 
					      "vue-router": "^4.3.3"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "devDependencies": {
 | 
				
			||||||
 | 
					      "@rushstack/eslint-patch": "^1.8.0",
 | 
				
			||||||
 | 
					      "@tauri-apps/cli": "^1.6.0",
 | 
				
			||||||
 | 
					      "@tsconfig/node20": "^20.1.4",
 | 
				
			||||||
 | 
					      "@types/jsdom": "^21.1.7",
 | 
				
			||||||
 | 
					      "@types/node": "^20.14.5",
 | 
				
			||||||
 | 
					      "@vitejs/plugin-vue": "^5.0.5",
 | 
				
			||||||
 | 
					      "@vue/eslint-config-prettier": "^9.0.0",
 | 
				
			||||||
 | 
					      "@vue/eslint-config-typescript": "^13.0.0",
 | 
				
			||||||
 | 
					      "@vue/test-utils": "^2.4.6",
 | 
				
			||||||
 | 
					      "@vue/tsconfig": "^0.5.1",
 | 
				
			||||||
 | 
					      "eslint": "^8.57.0",
 | 
				
			||||||
 | 
					      "eslint-plugin-vue": "^9.23.0",
 | 
				
			||||||
 | 
					      "http-server": "^14.1.1",
 | 
				
			||||||
 | 
					      "jsdom": "^24.1.0",
 | 
				
			||||||
 | 
					      "npm-run-all2": "^6.2.0",
 | 
				
			||||||
 | 
					      "prettier": "^3.2.5",
 | 
				
			||||||
 | 
					      "sass": "^1.77.6",
 | 
				
			||||||
 | 
					      "typescript": "~5.4.0",
 | 
				
			||||||
 | 
					      "vite": "^5.3.1",
 | 
				
			||||||
 | 
					      "vitest": "^1.6.0",
 | 
				
			||||||
 | 
					      "vue-tsc": "^2.0.21"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "author": "arhuako",
 | 
				
			||||||
 | 
					    "reposityory": {
 | 
				
			||||||
 | 
					      "type": "git",
 | 
				
			||||||
 | 
					      "url": "https://gitea.xintanalabs.net/arhuako/domino-client"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						@@ -1,16 +1,20 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
 | 
					 | 
				
			||||||
All notable changes to this project will be documented in this file.
 | 
					All notable changes to this project will be documented in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Unreleased
 | 
					## Unreleased
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Added
 | 
					## 0.1.8 - 2024-07-18
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 0.1.7 - 2024-07-17
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 0.1.6 - 2024-07-17
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 0.1.5 - 2024-07-17
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
- Initial commit
 | 
					- Initial commit
 | 
				
			||||||
- Match page back button
 | 
					- Match page back button
 | 
				
			||||||
- Team play
 | 
					- Team play
 | 
				
			||||||
- Movement synchronized netween clients and AI players
 | 
					- Movement synchronized netween clients and AI players
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Fixed
 | 
					### Fixed
 | 
				
			||||||
 | 
					 | 
				
			||||||
- Button statuses
 | 
					- Button statuses
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,9 @@ RUN npm install
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# run webpack and the vue-loader
 | 
					# run webpack and the vue-loader
 | 
				
			||||||
RUN npm run build-only
 | 
					RUN npm run build-only
 | 
				
			||||||
 | 
					RUN rm -rf .git
 | 
				
			||||||
 | 
					RUN rm -rf .vscode
 | 
				
			||||||
 | 
					RUN rm -rf .env
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# copy the built app to our served directory
 | 
					# copy the built app to our served directory
 | 
				
			||||||
RUN cp -r dist/* /var/www/html
 | 
					RUN cp -r dist/* /var/www/html
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								Dockerfile.bkp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					FROM node:22-alpine
 | 
				
			||||||
 | 
					WORKDIR /usr/src/app
 | 
				
			||||||
 | 
					COPY package*.json ./
 | 
				
			||||||
 | 
					RUN npm i
 | 
				
			||||||
 | 
					COPY . .
 | 
				
			||||||
 | 
					EXPOSE 8080
 | 
				
			||||||
 | 
					CMD ["npm", "run", "serve"]
 | 
				
			||||||
							
								
								
									
										208
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						@@ -1,14 +1,15 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "domino-client",
 | 
					  "name": "domino-client",
 | 
				
			||||||
  "version": "0.1.0",
 | 
					  "version": "0.1.7",
 | 
				
			||||||
  "lockfileVersion": 3,
 | 
					  "lockfileVersion": 3,
 | 
				
			||||||
  "requires": true,
 | 
					  "requires": true,
 | 
				
			||||||
  "packages": {
 | 
					  "packages": {
 | 
				
			||||||
    "": {
 | 
					    "": {
 | 
				
			||||||
      "name": "domino-client",
 | 
					      "name": "domino-client",
 | 
				
			||||||
      "version": "0.1.0",
 | 
					      "version": "0.1.7",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@pixi/sound": "^6.0.0",
 | 
					        "@pixi/sound": "^6.0.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/api": "^1.6.0",
 | 
				
			||||||
        "bulma": "^1.0.1",
 | 
					        "bulma": "^1.0.1",
 | 
				
			||||||
        "colorette": "^2.0.20",
 | 
					        "colorette": "^2.0.20",
 | 
				
			||||||
        "dayjs": "^1.11.11",
 | 
					        "dayjs": "^1.11.11",
 | 
				
			||||||
@@ -25,6 +26,7 @@
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      "devDependencies": {
 | 
					      "devDependencies": {
 | 
				
			||||||
        "@rushstack/eslint-patch": "^1.8.0",
 | 
					        "@rushstack/eslint-patch": "^1.8.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli": "^1.6.0",
 | 
				
			||||||
        "@tsconfig/node20": "^20.1.4",
 | 
					        "@tsconfig/node20": "^20.1.4",
 | 
				
			||||||
        "@types/jsdom": "^21.1.7",
 | 
					        "@types/jsdom": "^21.1.7",
 | 
				
			||||||
        "@types/node": "^20.14.5",
 | 
					        "@types/node": "^20.14.5",
 | 
				
			||||||
@@ -963,6 +965,208 @@
 | 
				
			|||||||
      "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
 | 
					      "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/api": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-rqI++FWClU5I2UBp4HXFvl+sBWkdigBkxnpJDQUWttNyG7IZP4FwQGhTNL5EOw0vI8i6eSAJ5frLqO7n7jbJdg==",
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 14.6.0",
 | 
				
			||||||
 | 
					        "npm": ">= 6.6.0",
 | 
				
			||||||
 | 
					        "yarn": ">= 1.19.1"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "type": "opencollective",
 | 
				
			||||||
 | 
					        "url": "https://opencollective.com/tauri"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-DBBpBl6GhTzm8ImMbKkfaZ4fDTykWrC7Q5OXP4XqD91recmDEn2LExuvuiiS3HYe7uP8Eb5B9NPHhqJb+Zo7qQ==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "bin": {
 | 
				
			||||||
 | 
					        "tauri": "tauri.js"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "type": "opencollective",
 | 
				
			||||||
 | 
					        "url": "https://opencollective.com/tauri"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "optionalDependencies": {
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-darwin-arm64": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-darwin-x64": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-linux-arm-gnueabihf": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-linux-arm64-gnu": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-linux-arm64-musl": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-linux-x64-gnu": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-linux-x64-musl": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-win32-arm64-msvc": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-win32-ia32-msvc": "1.6.0",
 | 
				
			||||||
 | 
					        "@tauri-apps/cli-win32-x64-msvc": "1.6.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-darwin-arm64": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-SNRwUD9nqGxY47mbY1CGTt/jqyQOU7Ps7Mx/mpgahL0FVUDiCEY/5L9QfEPPhEgccgcelEVn7i6aQHIkHyUtCA==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "arm64"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "darwin"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-darwin-x64": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-g2/uDR/eeH2arvuawA4WwaEOqv/7jDO/ZLNI3JlBjP5Pk8GGb3Kdy0ro1xQzF94mtk2mOnOXa4dMgAet4sUJ1A==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "x64"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "darwin"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-EVwf4oRkQyG8BpSrk0gqO7oA0sDM2MdNDtJpMfleYFEgCxLIOGZKNqaOW3M7U+0Y4qikmG3TtRK+ngc8Ymtrjg==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "arm"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "linux"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-linux-arm64-gnu": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-YdpY17cAySrhK9dX4BUVEmhAxE2o+6skIEFg8iN/xrDwRxhaNPI9I80YXPatUTX54Kx55T5++25VJG9+3iw83A==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "arm64"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "linux"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-linux-arm64-musl": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-4U628tuf2U8pMr4tIBJhEkrFwt+46dwhXrDlpdyWSZtnop5RJAVKHODm0KbWns4xGKfTW1F3r6sSv+2ZxLcISA==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "arm64"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "linux"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-linux-x64-gnu": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-AKRzp76fVUaJyXj5KRJT9bJyhwZyUnRQU0RqIRqOtZCT5yr6qGP8rjtQ7YhCIzWrseBlOllc3Qvbgw3Yl0VQcA==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "x64"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "linux"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-linux-x64-musl": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-0edIdq6aMBTaRMIXddHfyAFL361JqulLLd2Wi2aoOie7DkQ2MYh6gv3hA7NB9gqFwNIGE+xtJ4BkXIP2tSGPlg==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "x64"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "linux"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-win32-arm64-msvc": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-QwWpWk4ubcwJ1rljsRAmINgB2AwkyzZhpYbalA+MmzyYMREcdXWGkyixWbRZgqc6fEWEBmq5UG73qz5eBJiIKg==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "arm64"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "win32"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-win32-ia32-msvc": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-Vtw0yxO9+aEFuhuxQ57ALG43tjECopRimRuKGbtZYDCriB/ty5TrT3QWMdy0dxBkpDTu3Rqsz30sbDzw6tlP3Q==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "ia32"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "win32"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@tauri-apps/cli-win32-x64-msvc": {
 | 
				
			||||||
 | 
					      "version": "1.6.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.6.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-h54FHOvGi7+LIfRchzgZYSCHB1HDlP599vWXQQJ/XnwJY+6Rwr2E5bOe/EhqoG8rbGkfK0xX3KPAvXPbUlmggg==",
 | 
				
			||||||
 | 
					      "cpu": [
 | 
				
			||||||
 | 
					        "x64"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "optional": true,
 | 
				
			||||||
 | 
					      "os": [
 | 
				
			||||||
 | 
					        "win32"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 10"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@tsconfig/node20": {
 | 
					    "node_modules/@tsconfig/node20": {
 | 
				
			||||||
      "version": "20.1.4",
 | 
					      "version": "20.1.4",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "domino-client",
 | 
					  "name": "domino-client",
 | 
				
			||||||
  "version": "0.1.3",
 | 
					  "version": "0.1.8",
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
  "type": "commonjs",
 | 
					  "type": "commonjs",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
@@ -13,13 +13,15 @@
 | 
				
			|||||||
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
 | 
					    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
 | 
				
			||||||
    "format": "prettier --write src/",
 | 
					    "format": "prettier --write src/",
 | 
				
			||||||
    "docker-build": "docker build -t 192.168.1.115:5000/arhuako/domino-client:latest .",
 | 
					    "docker-build": "docker build -t 192.168.1.115:5000/arhuako/domino-client:latest .",
 | 
				
			||||||
    "docker-tag": "docker tag 192.168.1.115:5000/arhuako/domino-client:latest 192.168.1.115:5000/arhuako/domino-client:0.1.4",
 | 
					    "docker-tag": "docker tag 192.168.1.115:5000/arhuako/domino-client:latest 192.168.1.115:5000/arhuako/domino-client:0.1.8",
 | 
				
			||||||
    "docker-push": "docker push 192.168.1.115:5000/arhuako/domino-client:latest && docker push 192.168.1.115:5000/arhuako/domino-client:0.1.4",
 | 
					    "docker-push": "docker push 192.168.1.115:5000/arhuako/domino-client:latest && docker push 192.168.1.115:5000/arhuako/domino-client:0.1.8",
 | 
				
			||||||
    "publish": "npm run docker-build && npm run docker-tag && npm run docker-push",
 | 
					    "publish": "npm run docker-build && npm run docker-tag && npm run docker-push",
 | 
				
			||||||
    "serve": "npm run build-only && http-server ./dist -c-1 -s "
 | 
					    "serve": "npm run build-only && http-server ./dist -c-1 -s ",
 | 
				
			||||||
 | 
					    "tauri": "tauri"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@pixi/sound": "^6.0.0",
 | 
					    "@pixi/sound": "^6.0.0",
 | 
				
			||||||
 | 
					    "@tauri-apps/api": "^1.6.0",
 | 
				
			||||||
    "bulma": "^1.0.1",
 | 
					    "bulma": "^1.0.1",
 | 
				
			||||||
    "colorette": "^2.0.20",
 | 
					    "colorette": "^2.0.20",
 | 
				
			||||||
    "dayjs": "^1.11.11",
 | 
					    "dayjs": "^1.11.11",
 | 
				
			||||||
@@ -36,6 +38,7 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@rushstack/eslint-patch": "^1.8.0",
 | 
					    "@rushstack/eslint-patch": "^1.8.0",
 | 
				
			||||||
 | 
					    "@tauri-apps/cli": "^1.6.0",
 | 
				
			||||||
    "@tsconfig/node20": "^20.1.4",
 | 
					    "@tsconfig/node20": "^20.1.4",
 | 
				
			||||||
    "@types/jsdom": "^21.1.7",
 | 
					    "@types/jsdom": "^21.1.7",
 | 
				
			||||||
    "@types/node": "^20.14.5",
 | 
					    "@types/node": "^20.14.5",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								public/CHANGELOG.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					<h1>Changelog</h1>
 | 
				
			||||||
 | 
					<p>All notable changes to this project will be documented in this file.</p>
 | 
				
			||||||
 | 
					<h2>0.1.8 - 2024-07-18</h2>
 | 
				
			||||||
 | 
					<h2>0.1.7 - 2024-07-17</h2>
 | 
				
			||||||
 | 
					<h2>0.1.6 - 2024-07-17</h2>
 | 
				
			||||||
 | 
					<h2>0.1.5 - 2024-07-17</h2>
 | 
				
			||||||
 | 
					<h3>Added</h3>
 | 
				
			||||||
 | 
					<ul>
 | 
				
			||||||
 | 
					<li>Initial commit</li>
 | 
				
			||||||
 | 
					<li>Match page back button</li>
 | 
				
			||||||
 | 
					<li>Team play</li>
 | 
				
			||||||
 | 
					<li>Movement synchronized netween clients and AI players</li>
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					<h3>Fixed</h3>
 | 
				
			||||||
 | 
					<ul>
 | 
				
			||||||
 | 
					<li>Button statuses</li>
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
							
								
								
									
										3
									
								
								src-tauri/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# Generated by Cargo
 | 
				
			||||||
 | 
					# will have compiled files and executables
 | 
				
			||||||
 | 
					/target/
 | 
				
			||||||
							
								
								
									
										3669
									
								
								src-tauri/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										26
									
								
								src-tauri/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "app"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					description = "A Tauri App"
 | 
				
			||||||
 | 
					authors = ["you"]
 | 
				
			||||||
 | 
					license = ""
 | 
				
			||||||
 | 
					repository = ""
 | 
				
			||||||
 | 
					default-run = "app"
 | 
				
			||||||
 | 
					edition = "2021"
 | 
				
			||||||
 | 
					rust-version = "1.60"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[build-dependencies]
 | 
				
			||||||
 | 
					tauri-build = { version = "1.5.3", features = [] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
 | 
					serde_json = "1.0"
 | 
				
			||||||
 | 
					serde = { version = "1.0", features = ["derive"] }
 | 
				
			||||||
 | 
					tauri = { version = "1.7.0", features = [] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[features]
 | 
				
			||||||
 | 
					# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
 | 
				
			||||||
 | 
					# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes.
 | 
				
			||||||
 | 
					# DO NOT REMOVE!!
 | 
				
			||||||
 | 
					custom-protocol = [ "tauri/custom-protocol" ]
 | 
				
			||||||
							
								
								
									
										3
									
								
								src-tauri/build.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					  tauri_build::build()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/128x128.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/128x128@2x.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 23 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/32x32.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square107x107Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square142x142Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 12 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square150x150Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square284x284Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 25 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square30x30Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square310x310Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 28 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square44x44Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square71x71Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/Square89x89Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/StoreLogo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/icon.icns
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/icon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 37 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src-tauri/icons/icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 49 KiB  | 
							
								
								
									
										8
									
								
								src-tauri/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					// Prevents additional console window on Windows in release, DO NOT REMOVE!!
 | 
				
			||||||
 | 
					#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					  tauri::Builder::default()
 | 
				
			||||||
 | 
					    .run(tauri::generate_context!())
 | 
				
			||||||
 | 
					    .expect("error while running tauri application");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										70
									
								
								src-tauri/tauri.conf.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "$schema": "../node_modules/@tauri-apps/cli/schema.json",
 | 
				
			||||||
 | 
					  "build": {
 | 
				
			||||||
 | 
					    "beforeBuildCommand": "npm run build-only",
 | 
				
			||||||
 | 
					    "beforeDevCommand": "npm run dev",
 | 
				
			||||||
 | 
					    "devPath": "http://localhost:5173",
 | 
				
			||||||
 | 
					    "distDir": "../dist"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "package": {
 | 
				
			||||||
 | 
					    "productName": "domino-client",
 | 
				
			||||||
 | 
					    "version": "0.1.8"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "tauri": {
 | 
				
			||||||
 | 
					    "allowlist": {
 | 
				
			||||||
 | 
					      "all": false
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "bundle": {
 | 
				
			||||||
 | 
					      "active": true,
 | 
				
			||||||
 | 
					      "category": "DeveloperTool",
 | 
				
			||||||
 | 
					      "copyright": "",
 | 
				
			||||||
 | 
					      "deb": {
 | 
				
			||||||
 | 
					        "depends": []
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "externalBin": [],
 | 
				
			||||||
 | 
					      "icon": [
 | 
				
			||||||
 | 
					        "icons/32x32.png",
 | 
				
			||||||
 | 
					        "icons/128x128.png",
 | 
				
			||||||
 | 
					        "icons/128x128@2x.png",
 | 
				
			||||||
 | 
					        "icons/icon.icns",
 | 
				
			||||||
 | 
					        "icons/icon.ico"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "identifier": "net.xintanalabs.domino",
 | 
				
			||||||
 | 
					      "longDescription": "",
 | 
				
			||||||
 | 
					      "macOS": {
 | 
				
			||||||
 | 
					        "entitlements": null,
 | 
				
			||||||
 | 
					        "exceptionDomain": "",
 | 
				
			||||||
 | 
					        "frameworks": [],
 | 
				
			||||||
 | 
					        "providerShortName": null,
 | 
				
			||||||
 | 
					        "signingIdentity": null
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "resources": [],
 | 
				
			||||||
 | 
					      "shortDescription": "",
 | 
				
			||||||
 | 
					      "targets": "all",
 | 
				
			||||||
 | 
					      "windows": {
 | 
				
			||||||
 | 
					        "certificateThumbprint": null,
 | 
				
			||||||
 | 
					        "digestAlgorithm": "sha256",
 | 
				
			||||||
 | 
					        "timestampUrl": ""
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "security": {
 | 
				
			||||||
 | 
					      "csp": null
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "updater": {
 | 
				
			||||||
 | 
					      "active": false
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "windows": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "fullscreen": false,
 | 
				
			||||||
 | 
					        "height": 720,
 | 
				
			||||||
 | 
					        "resizable": true,
 | 
				
			||||||
 | 
					        "title": "Domino",
 | 
				
			||||||
 | 
					        "width": 1280,
 | 
				
			||||||
 | 
					        "minHeight": 720,
 | 
				
			||||||
 | 
					        "minWidth": 1280,
 | 
				
			||||||
 | 
					        "center": true,
 | 
				
			||||||
 | 
					        "decorations": true
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -15,3 +15,9 @@
 | 
				
			|||||||
  --bulma-danger-s: 74%;
 | 
					  --bulma-danger-s: 74%;
 | 
				
			||||||
  --bulma-danger-l: 37%;
 | 
					  --bulma-danger-l: 37%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.tabs li.is-disabled {
 | 
				
			||||||
 | 
					  pointer-events: none;
 | 
				
			||||||
 | 
					  cursor: default;
 | 
				
			||||||
 | 
					  opacity: 0.3;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1,6 @@
 | 
				
			|||||||
@import './base.css';
 | 
					@import './base.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					html {
 | 
				
			||||||
 | 
					  font-size: 16px;
 | 
				
			||||||
 | 
					  overflow: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,7 @@ export interface MatchSessionDto {
 | 
				
			|||||||
  seed: string
 | 
					  seed: string
 | 
				
			||||||
  waitingForPlayers: boolean
 | 
					  waitingForPlayers: boolean
 | 
				
			||||||
  mode: string
 | 
					  mode: string
 | 
				
			||||||
  pointsToWin: number
 | 
					  options: MatchSessionOptions
 | 
				
			||||||
  sessionInProgress: boolean
 | 
					  sessionInProgress: boolean
 | 
				
			||||||
  status: string
 | 
					  status: string
 | 
				
			||||||
  maxPlayers: number
 | 
					  maxPlayers: number
 | 
				
			||||||
@@ -100,15 +100,24 @@ export interface AnimationOptions {
 | 
				
			|||||||
  height?: number
 | 
					  height?: number
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface GameOptions {
 | 
					export interface ScreenOptions {
 | 
				
			||||||
  boardScale?: number
 | 
					  boardScale: number
 | 
				
			||||||
  handScale?: number
 | 
					  handScale: number
 | 
				
			||||||
  width?: number
 | 
					  width: number
 | 
				
			||||||
  height?: number
 | 
					  height: number
 | 
				
			||||||
  background?: string
 | 
					 | 
				
			||||||
  teamed?: boolean
 | 
					 | 
				
			||||||
  pointsToWin?: number
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface MatchSessionOptions {
 | 
				
			||||||
 | 
					  screen?: ScreenOptions
 | 
				
			||||||
 | 
					  seed?: string
 | 
				
			||||||
 | 
					  background: string
 | 
				
			||||||
 | 
					  teamed: boolean
 | 
				
			||||||
 | 
					  winTarget: number
 | 
				
			||||||
 | 
					  winType: 'points' | 'rounds'
 | 
				
			||||||
 | 
					  sessionName: string
 | 
				
			||||||
 | 
					  numPlayers: 1 | 2 | 3 | 4
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface GameSummary {
 | 
					export interface GameSummary {
 | 
				
			||||||
  gameId: string
 | 
					  gameId: string
 | 
				
			||||||
  isBlocked: boolean
 | 
					  isBlocked: boolean
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import type { GameDto, PlayerDto } from '@/common/interfaces'
 | 
					import type { GameDto, MatchSessionOptions, PlayerDto } from '@/common/interfaces'
 | 
				
			||||||
import { onMounted, onUnmounted, ref, inject } from 'vue'
 | 
					import { onMounted, onUnmounted, ref, inject } from 'vue'
 | 
				
			||||||
import { Game } from '@/game/Game'
 | 
					import { Game } from '@/game/Game'
 | 
				
			||||||
import { useGameStore } from '@/stores/game'
 | 
					import { useGameStore } from '@/stores/game'
 | 
				
			||||||
@@ -20,8 +20,9 @@ const { playerState, sessionState } = storeToRefs(gameStore)
 | 
				
			|||||||
const { updateGameState } = gameStore
 | 
					const { updateGameState } = gameStore
 | 
				
			||||||
const { gameOptions } = storeToRefs(gameOptionsStore)
 | 
					const { gameOptions } = storeToRefs(gameOptionsStore)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const minScreenWidth = 800
 | 
					const minScreenWidth = 1280
 | 
				
			||||||
const minScreenHeight = 700
 | 
					const minScreenHeight = 72
 | 
				
			||||||
 | 
					0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let screenWidth = window.innerWidth - 10
 | 
					let screenWidth = window.innerWidth - 10
 | 
				
			||||||
let screenHeight = window.innerHeight - 10
 | 
					let screenHeight = window.innerHeight - 10
 | 
				
			||||||
@@ -29,48 +30,34 @@ let screenHeight = window.innerHeight - 10
 | 
				
			|||||||
if (screenWidth < minScreenWidth) screenWidth = minScreenWidth
 | 
					if (screenWidth < minScreenWidth) screenWidth = minScreenWidth
 | 
				
			||||||
if (screenHeight < minScreenHeight) screenHeight = minScreenHeight
 | 
					if (screenHeight < minScreenHeight) screenHeight = minScreenHeight
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const boardScale = screenWidth > 1200 ? 0.8 : screenWidth > 1200 ? 0.7 : 0.6
 | 
					const minSide = Math.min(screenWidth, screenHeight)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const boardScale = minSide > 1440 ? 1 : minSide > 1080 ? 0.8 : minSide > 720 ? 0.7 : 0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let appEl = ref<HTMLElement | null>(null)
 | 
					let appEl = ref<HTMLElement | null>(null)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const game = new Game(
 | 
					const defaultOptions: MatchSessionOptions = {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    width: screenWidth,
 | 
					 | 
				
			||||||
    height: screenHeight,
 | 
					 | 
				
			||||||
    boardScale,
 | 
					 | 
				
			||||||
    handScale: 1,
 | 
					 | 
				
			||||||
  background: gameOptions.value?.background || 'green',
 | 
					  background: gameOptions.value?.background || 'green',
 | 
				
			||||||
  },
 | 
					  teamed: false,
 | 
				
			||||||
 | 
					  winType: 'points',
 | 
				
			||||||
 | 
					  winTarget: 100,
 | 
				
			||||||
 | 
					  seed: '',
 | 
				
			||||||
 | 
					  sessionName: `Test #${Date.now()}`,
 | 
				
			||||||
 | 
					  numPlayers: 1,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					const gameOptionsValue: MatchSessionOptions = {
 | 
				
			||||||
 | 
					  ...defaultOptions,
 | 
				
			||||||
 | 
					  ...sessionState.value?.options,
 | 
				
			||||||
 | 
					  ...{ screen: { width: screenWidth, height: screenHeight, boardScale: boardScale, handScale: 1 } },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const game = new Game(
 | 
				
			||||||
 | 
					  gameOptionsValue,
 | 
				
			||||||
  socketService,
 | 
					  socketService,
 | 
				
			||||||
  playerState.value?.id || '',
 | 
					  playerState.value?.id || '',
 | 
				
			||||||
  sessionState.value?.id || '',
 | 
					  sessionState.value?.id || '',
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// watch(
 | 
					 | 
				
			||||||
//   () => gameStore.gameState,
 | 
					 | 
				
			||||||
//   async (value: GameDto | undefined) => {
 | 
					 | 
				
			||||||
//     if (value === undefined) return
 | 
					 | 
				
			||||||
//     await game.board?.setState(value)
 | 
					 | 
				
			||||||
//   }
 | 
					 | 
				
			||||||
// )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// watch(
 | 
					 | 
				
			||||||
//   () => gameStore.sessionState,
 | 
					 | 
				
			||||||
//   (value: MatchSessionDto | undefined) => {
 | 
					 | 
				
			||||||
//     if (value === undefined) return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//     // logger.debug('gameSessionState-------------------------------------- :>> ', value)
 | 
					 | 
				
			||||||
//   }
 | 
					 | 
				
			||||||
// )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// watch(
 | 
					 | 
				
			||||||
//   () => gameStore.playerState,
 | 
					 | 
				
			||||||
//   (value: PlayerDto | undefined) => {
 | 
					 | 
				
			||||||
//     if (value === undefined) return
 | 
					 | 
				
			||||||
//     game.hand.update(value as PlayerDto)
 | 
					 | 
				
			||||||
//   }
 | 
					 | 
				
			||||||
// )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
onMounted(async () => {
 | 
					onMounted(async () => {
 | 
				
			||||||
  sessionId = route.params.id as string
 | 
					  sessionId = route.params.id as string
 | 
				
			||||||
  if (appEl.value === null) return
 | 
					  if (appEl.value === null) return
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										211
									
								
								src/components/MatchConfiguration.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,211 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import type { MatchSessionOptions } from '@/common/interfaces'
 | 
				
			||||||
 | 
					import { ref } from 'vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const emit = defineEmits(['createMatch'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let options = ref<MatchSessionOptions>({
 | 
				
			||||||
 | 
					  background: 'green',
 | 
				
			||||||
 | 
					  teamed: false,
 | 
				
			||||||
 | 
					  winType: 'points',
 | 
				
			||||||
 | 
					  winTarget: 100,
 | 
				
			||||||
 | 
					  seed: '',
 | 
				
			||||||
 | 
					  sessionName: `Test #${Date.now()}`,
 | 
				
			||||||
 | 
					  numPlayers: 1,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createMatch() {
 | 
				
			||||||
 | 
					  emit('createMatch', options.value)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div>
 | 
				
			||||||
 | 
					    <div class="grid">
 | 
				
			||||||
 | 
					      <div class="cell">
 | 
				
			||||||
 | 
					        <div class="field">
 | 
				
			||||||
 | 
					          <label class="label">{{ $t('mode') }}</label>
 | 
				
			||||||
 | 
					          <div class="control">
 | 
				
			||||||
 | 
					            <div class="buttons has-addons">
 | 
				
			||||||
 | 
					              <button
 | 
				
			||||||
 | 
					                class="button"
 | 
				
			||||||
 | 
					                :class="{ 'is-primary is-selected': options.numPlayers === 1 }"
 | 
				
			||||||
 | 
					                @click="
 | 
				
			||||||
 | 
					                  () => {
 | 
				
			||||||
 | 
					                    console.log('options :>> ', options)
 | 
				
			||||||
 | 
					                    options.numPlayers = 1
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                "
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                {{ $t('singleplayer') }}
 | 
				
			||||||
 | 
					              </button>
 | 
				
			||||||
 | 
					              <button
 | 
				
			||||||
 | 
					                class="button"
 | 
				
			||||||
 | 
					                :class="{ 'is-primary is-selected': options.numPlayers > 1 }"
 | 
				
			||||||
 | 
					                @click="
 | 
				
			||||||
 | 
					                  () => {
 | 
				
			||||||
 | 
					                    console.log('options :>> ', options)
 | 
				
			||||||
 | 
					                    options.numPlayers = 2
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                "
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                {{ $t('multiplayer') }}
 | 
				
			||||||
 | 
					              </button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="cell">
 | 
				
			||||||
 | 
					        <div class="field" v-if="options.numPlayers > 1">
 | 
				
			||||||
 | 
					          <label class="label">{{ $t('players-number') }}</label>
 | 
				
			||||||
 | 
					          <div class="control">
 | 
				
			||||||
 | 
					            <div class="buttons has-addons">
 | 
				
			||||||
 | 
					              <button
 | 
				
			||||||
 | 
					                class="button is-primary"
 | 
				
			||||||
 | 
					                @click="options.numPlayers--"
 | 
				
			||||||
 | 
					                :disabled="options.numPlayers <= 2"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                -
 | 
				
			||||||
 | 
					              </button>
 | 
				
			||||||
 | 
					              <button class="button is-primary" disabled>{{ options.numPlayers }}</button>
 | 
				
			||||||
 | 
					              <button
 | 
				
			||||||
 | 
					                class="button is-primary"
 | 
				
			||||||
 | 
					                @click="options.numPlayers++"
 | 
				
			||||||
 | 
					                :disabled="options.numPlayers >= 4"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                +
 | 
				
			||||||
 | 
					              </button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="cell">
 | 
				
			||||||
 | 
					        <div class="field" v-if="options.numPlayers > 1">
 | 
				
			||||||
 | 
					          <div class="control">
 | 
				
			||||||
 | 
					            <label for="teamed" class="checkbox">
 | 
				
			||||||
 | 
					              <input v-model="options.teamed" name="teamed" type="checkbox" />
 | 
				
			||||||
 | 
					              {{ $t('crossed-game-teamed') }}
 | 
				
			||||||
 | 
					            </label>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="grid">
 | 
				
			||||||
 | 
					      <div class="cell">
 | 
				
			||||||
 | 
					        <div class="field">
 | 
				
			||||||
 | 
					          <label class="label">{{ $t('session-name') }}</label>
 | 
				
			||||||
 | 
					          <div class="control">
 | 
				
			||||||
 | 
					            <input
 | 
				
			||||||
 | 
					              type="text"
 | 
				
			||||||
 | 
					              class="input"
 | 
				
			||||||
 | 
					              v-model="options.sessionName"
 | 
				
			||||||
 | 
					              placeholder="$t('session-name-placeholder')"
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <!---->
 | 
				
			||||||
 | 
					      <div class="cell">
 | 
				
			||||||
 | 
					        <div class="field">
 | 
				
			||||||
 | 
					          <label class="label">{{ $t('seed') }}</label>
 | 
				
			||||||
 | 
					          <div class="control">
 | 
				
			||||||
 | 
					            <input
 | 
				
			||||||
 | 
					              type="text"
 | 
				
			||||||
 | 
					              class="input"
 | 
				
			||||||
 | 
					              style="margin-bottom: 0"
 | 
				
			||||||
 | 
					              v-model="options.seed"
 | 
				
			||||||
 | 
					              :placeholder="$t('seed-placeholder')"
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <!---->
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="grid">
 | 
				
			||||||
 | 
					      <div class="cell">
 | 
				
			||||||
 | 
					        <div class="field">
 | 
				
			||||||
 | 
					          <label for="background" class="label">{{ $t('background-color') }}</label>
 | 
				
			||||||
 | 
					          <div class="control">
 | 
				
			||||||
 | 
					            <div class="select">
 | 
				
			||||||
 | 
					              <select v-model="options.background" name="background">
 | 
				
			||||||
 | 
					                <option value="wood-1">{{ $t('wood-1') }}</option>
 | 
				
			||||||
 | 
					                <option value="green">{{ $t('green-fabric') }}</option>
 | 
				
			||||||
 | 
					                <option value="gray">{{ $t('gray-fabric') }}</option>
 | 
				
			||||||
 | 
					                <option value="blue">{{ $t('blue-fabric') }}</option>
 | 
				
			||||||
 | 
					                <option value="yellow">{{ $t('yellow-fabric') }}</option>
 | 
				
			||||||
 | 
					                <option value="red">{{ $t('red-fabric') }}</option>
 | 
				
			||||||
 | 
					              </select>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="cell">
 | 
				
			||||||
 | 
					        <div class="field">
 | 
				
			||||||
 | 
					          <label for="winTarget" class="label">{{ $t('win-type') }}</label>
 | 
				
			||||||
 | 
					          <div class="control">
 | 
				
			||||||
 | 
					            <div class="buttons has-addons">
 | 
				
			||||||
 | 
					              <button
 | 
				
			||||||
 | 
					                class="button"
 | 
				
			||||||
 | 
					                :class="{ 'is-primary is-selected': options.winType === 'points' }"
 | 
				
			||||||
 | 
					                @click="
 | 
				
			||||||
 | 
					                  () => {
 | 
				
			||||||
 | 
					                    options.winType = 'points'
 | 
				
			||||||
 | 
					                    options.winTarget = 100
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                "
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                {{ $t('points') }}
 | 
				
			||||||
 | 
					              </button>
 | 
				
			||||||
 | 
					              <button
 | 
				
			||||||
 | 
					                class="button"
 | 
				
			||||||
 | 
					                :class="{ 'is-primary is-selected': options.winType === 'rounds' }"
 | 
				
			||||||
 | 
					                @click="
 | 
				
			||||||
 | 
					                  () => {
 | 
				
			||||||
 | 
					                    options.winType = 'rounds'
 | 
				
			||||||
 | 
					                    options.winTarget = 2
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                "
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                {{ $t('rounds') }}
 | 
				
			||||||
 | 
					              </button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="cell">
 | 
				
			||||||
 | 
					        <div class="field">
 | 
				
			||||||
 | 
					          <label for="winTarget" class="label">{{ $t('points-to-win') }}</label>
 | 
				
			||||||
 | 
					          <div class="control">
 | 
				
			||||||
 | 
					            <div class="select" v-if="options.winType === 'points'">
 | 
				
			||||||
 | 
					              <select v-model="options.winTarget" name="winTarget">
 | 
				
			||||||
 | 
					                <option value="20">{{ $t('n-points', [20]) }}</option>
 | 
				
			||||||
 | 
					                <option value="50">{{ $t('n-points', [50]) }}</option>
 | 
				
			||||||
 | 
					                <option value="80">{{ $t('n-points', [80]) }}</option>
 | 
				
			||||||
 | 
					                <option value="100">{{ $t('n-points', [100]) }}</option>
 | 
				
			||||||
 | 
					                <option value="150">{{ $t('n-points', [150]) }}</option>
 | 
				
			||||||
 | 
					                <option value="200">{{ $t('n-points', [200]) }}</option>
 | 
				
			||||||
 | 
					              </select>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="select" v-if="options.winType === 'rounds'">
 | 
				
			||||||
 | 
					              <select v-model="options.winTarget" name="winTarget">
 | 
				
			||||||
 | 
					                <option value="1">{{ $t('n-of-m-rounds', [1, 1]) }}</option>
 | 
				
			||||||
 | 
					                <option value="2">{{ $t('n-of-m-rounds', [2, 3]) }}</option>
 | 
				
			||||||
 | 
					                <option value="3">{{ $t('n-of-m-rounds', [3, 5]) }}</option>
 | 
				
			||||||
 | 
					                <option value="4">{{ $t('n-of-m-rounds', [4, 7]) }}</option>
 | 
				
			||||||
 | 
					                <option value="5">{{ $t('n-of-m-rounds', [5, 9]) }}</option>
 | 
				
			||||||
 | 
					                <option value="6">{{ $t('n-of-m-rounds', [6, 11]) }}</option>
 | 
				
			||||||
 | 
					              </select>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="buttons mt-6">
 | 
				
			||||||
 | 
					      <button class="button is-primary" @click.prevent="createMatch">
 | 
				
			||||||
 | 
					        {{ $t('create-match-session') }}
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped></style>
 | 
				
			||||||
@@ -1,9 +1,16 @@
 | 
				
			|||||||
import { Application, Assets, Container, EventEmitter, Sprite } from 'pixi.js'
 | 
					import { Application, Assets, Container, EventEmitter, TilingSprite } from 'pixi.js'
 | 
				
			||||||
import { Board } from '@/game/Board'
 | 
					import { Board } from '@/game/Board'
 | 
				
			||||||
import { assets } from '@/game/utilities/assets'
 | 
					import { assets } from '@/game/utilities/assets'
 | 
				
			||||||
import { Tile } from '@/game/Tile'
 | 
					import { Tile } from '@/game/Tile'
 | 
				
			||||||
import { Hand } from '@/game/Hand'
 | 
					import { Hand } from '@/game/Hand'
 | 
				
			||||||
import type { GameDto, MatchSessionDto, Movement, PlayerDto, TileDto } from '@/common/interfaces'
 | 
					import type {
 | 
				
			||||||
 | 
					  GameDto,
 | 
				
			||||||
 | 
					  MatchSessionDto,
 | 
				
			||||||
 | 
					  MatchSessionOptions,
 | 
				
			||||||
 | 
					  Movement,
 | 
				
			||||||
 | 
					  PlayerDto,
 | 
				
			||||||
 | 
					  TileDto,
 | 
				
			||||||
 | 
					} from '@/common/interfaces'
 | 
				
			||||||
import type { SocketIoClientService } from '@/services/SocketIoClientService'
 | 
					import type { SocketIoClientService } from '@/services/SocketIoClientService'
 | 
				
			||||||
import { wait } from '@/common/helpers'
 | 
					import { wait } from '@/common/helpers'
 | 
				
			||||||
import { Actions } from 'pixi-actions'
 | 
					import { Actions } from 'pixi-actions'
 | 
				
			||||||
@@ -31,23 +38,24 @@ export class Game extends EventEmitter {
 | 
				
			|||||||
  private players: PlayerDto[] = []
 | 
					  private players: PlayerDto[] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private options: GameOptions = {
 | 
					    private options: MatchSessionOptions,
 | 
				
			||||||
      boardScale: 1,
 | 
					 | 
				
			||||||
      handScale: 1,
 | 
					 | 
				
			||||||
      width: 1200,
 | 
					 | 
				
			||||||
      height: 800,
 | 
					 | 
				
			||||||
      background: 'bg-green',
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    private socketService: SocketIoClientService,
 | 
					    private socketService: SocketIoClientService,
 | 
				
			||||||
    private playerId: string,
 | 
					    private playerId: string,
 | 
				
			||||||
    private sessionId: string,
 | 
					    private sessionId: string,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    super()
 | 
					    super()
 | 
				
			||||||
 | 
					    this.options.screen = {
 | 
				
			||||||
 | 
					      width: 1280,
 | 
				
			||||||
 | 
					      height: 720,
 | 
				
			||||||
 | 
					      handScale: 1,
 | 
				
			||||||
 | 
					      boardScale: 0.7,
 | 
				
			||||||
 | 
					      ...this.options.screen,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async setup(): Promise<HTMLCanvasElement> {
 | 
					  async setup(): Promise<HTMLCanvasElement> {
 | 
				
			||||||
    const width = this.options.width || 1200
 | 
					    const width = this.options.screen?.width || 1280
 | 
				
			||||||
    const height = this.options.height || 800
 | 
					    const height = this.options.screen?.height || 720
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await this.app.init({ width, height })
 | 
					    await this.app.init({ width, height })
 | 
				
			||||||
    this.app.ticker.add((tick) => Actions.tick(tick.deltaTime / 60))
 | 
					    this.app.ticker.add((tick) => Actions.tick(tick.deltaTime / 60))
 | 
				
			||||||
@@ -65,9 +73,9 @@ export class Game extends EventEmitter {
 | 
				
			|||||||
    ]
 | 
					    ]
 | 
				
			||||||
    this.initPlayers(players)
 | 
					    this.initPlayers(players)
 | 
				
			||||||
    this.players = players
 | 
					    this.players = players
 | 
				
			||||||
    this.gameSummaryView = new GameSummayView(this.app)
 | 
					    this.gameSummaryView = new GameSummayView(this.app, this.options)
 | 
				
			||||||
    this.hand.scale = this.options.handScale
 | 
					    this.hand.scale = this.options.screen?.handScale || 1
 | 
				
			||||||
    this.board.scale = this.options.boardScale
 | 
					    this.board.scale = this.options.screen?.boardScale || 0.7
 | 
				
			||||||
    this.setBoardEvents()
 | 
					    this.setBoardEvents()
 | 
				
			||||||
    this.setHandEvents()
 | 
					    this.setHandEvents()
 | 
				
			||||||
    this.initEventBus()
 | 
					    this.initEventBus()
 | 
				
			||||||
@@ -80,7 +88,7 @@ export class Game extends EventEmitter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  iniialStuff(app: Application) {
 | 
					  iniialStuff(app: Application) {
 | 
				
			||||||
    app.stage.addChild(this.backgroundLayer)
 | 
					    app.stage.addChild(this.backgroundLayer)
 | 
				
			||||||
    const background = new Sprite(Assets.get(`bg-${this.options.background}`))
 | 
					    const background = new TilingSprite(Assets.get(`bg-${this.options.background}`))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.backgroundLayer.addChild(background)
 | 
					    this.backgroundLayer.addChild(background)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import { createButton, createContainer } from '@/common/helpers'
 | 
					import { createButton, createContainer } from '@/common/helpers'
 | 
				
			||||||
import type { GameSummary, MatchSessionDto } from '@/common/interfaces'
 | 
					import type { GameSummary, MatchSessionDto, MatchSessionOptions } from '@/common/interfaces'
 | 
				
			||||||
import { EventEmitter, type Application, type Container } from 'pixi.js'
 | 
					import { EventEmitter, type Application, type Container } from 'pixi.js'
 | 
				
			||||||
import { createText, whiteStyle, yellowStyle } from './utilities/fonts'
 | 
					import { createText, whiteStyle, yellowStyle } from './utilities/fonts'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -12,7 +12,10 @@ export class GameSummayView extends EventEmitter {
 | 
				
			|||||||
  matchState!: MatchSessionDto
 | 
					  matchState!: MatchSessionDto
 | 
				
			||||||
  type: 'round' | 'match' = 'round'
 | 
					  type: 'round' | 'match' = 'round'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(app: Application) {
 | 
					  constructor(
 | 
				
			||||||
 | 
					    app: Application,
 | 
				
			||||||
 | 
					    private options: MatchSessionOptions,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
    super()
 | 
					    super()
 | 
				
			||||||
    this.width = 500
 | 
					    this.width = 500
 | 
				
			||||||
    this.height = 400
 | 
					    this.height = 400
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,10 +28,11 @@ import tile6_4 from '@/assets/images/tiles/6-4.png'
 | 
				
			|||||||
import tile6_5 from '@/assets/images/tiles/6-5.png'
 | 
					import tile6_5 from '@/assets/images/tiles/6-5.png'
 | 
				
			||||||
import tile6_6 from '@/assets/images/tiles/6-6.png'
 | 
					import tile6_6 from '@/assets/images/tiles/6-6.png'
 | 
				
			||||||
import bgWood_1 from '@/assets/images/backgrounds/wood-1.jpg'
 | 
					import bgWood_1 from '@/assets/images/backgrounds/wood-1.jpg'
 | 
				
			||||||
import bg_1 from '@/assets/images/backgrounds/bg-1.png'
 | 
					 | 
				
			||||||
import bg_green from '@/assets/images/backgrounds/bg-green.png'
 | 
					import bg_green from '@/assets/images/backgrounds/bg-green.png'
 | 
				
			||||||
import bg_red from '@/assets/images/backgrounds/bg-red.png'
 | 
					import bg_red from '@/assets/images/backgrounds/bg-red.png'
 | 
				
			||||||
import bg_yellow from '@/assets/images/backgrounds/bg-yellow.png'
 | 
					import bg_yellow from '@/assets/images/backgrounds/bg-yellow.png'
 | 
				
			||||||
 | 
					import bg_blue from '@/assets/images/backgrounds/bg-blue.png'
 | 
				
			||||||
 | 
					import bg_gray from '@/assets/images/backgrounds/bg-1.png'
 | 
				
			||||||
import snd_move_1 from '@/assets/sounds/move-1.mp3'
 | 
					import snd_move_1 from '@/assets/sounds/move-1.mp3'
 | 
				
			||||||
import snd_move_2 from '@/assets/sounds/move-2.mp3'
 | 
					import snd_move_2 from '@/assets/sounds/move-2.mp3'
 | 
				
			||||||
import snd_move_3 from '@/assets/sounds/move-3.mp3'
 | 
					import snd_move_3 from '@/assets/sounds/move-3.mp3'
 | 
				
			||||||
@@ -69,10 +70,11 @@ export const assets = [
 | 
				
			|||||||
  { alias: 'tile-6_5', src: tile6_5 },
 | 
					  { alias: 'tile-6_5', src: tile6_5 },
 | 
				
			||||||
  { alias: 'tile-6_6', src: tile6_6 },
 | 
					  { alias: 'tile-6_6', src: tile6_6 },
 | 
				
			||||||
  { alias: 'bg-wood-1', src: bgWood_1 },
 | 
					  { alias: 'bg-wood-1', src: bgWood_1 },
 | 
				
			||||||
  { alias: 'bg-gray', src: bg_1 },
 | 
					 | 
				
			||||||
  { alias: 'bg-green', src: bg_green },
 | 
					  { alias: 'bg-green', src: bg_green },
 | 
				
			||||||
  { alias: 'bg-red', src: bg_red },
 | 
					  { alias: 'bg-red', src: bg_red },
 | 
				
			||||||
  { alias: 'bg-yellow', src: bg_yellow },
 | 
					  { alias: 'bg-yellow', src: bg_yellow },
 | 
				
			||||||
 | 
					  { alias: 'bg-blue', src: bg_blue },
 | 
				
			||||||
 | 
					  { alias: 'bg-gray', src: bg_gray },
 | 
				
			||||||
  { alias: 'snd-move-1', src: snd_move_1 },
 | 
					  { alias: 'snd-move-1', src: snd_move_1 },
 | 
				
			||||||
  { alias: 'snd-move-2', src: snd_move_2 },
 | 
					  { alias: 'snd-move-2', src: snd_move_2 },
 | 
				
			||||||
  { alias: 'snd-move-3', src: snd_move_3 },
 | 
					  { alias: 'snd-move-3', src: snd_move_3 },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@
 | 
				
			|||||||
  "login-button": "Login",
 | 
					  "login-button": "Login",
 | 
				
			||||||
  "invalid-username-or-password": "Invalid username or password",
 | 
					  "invalid-username-or-password": "Invalid username or password",
 | 
				
			||||||
  "winner": "Winner",
 | 
					  "winner": "Winner",
 | 
				
			||||||
  "points-to-win": "Points to win",
 | 
					  "points-to-win": "Win Target",
 | 
				
			||||||
  "final-scoreboard": "Final Scoreboard",
 | 
					  "final-scoreboard": "Final Scoreboard",
 | 
				
			||||||
  "round-index-1": "Round {0}",
 | 
					  "round-index-1": "Round {0}",
 | 
				
			||||||
  "scoreboard": "Scoreboard",
 | 
					  "scoreboard": "Scoreboard",
 | 
				
			||||||
@@ -26,13 +26,13 @@
 | 
				
			|||||||
  "session-name-placeholder": "Session Name",
 | 
					  "session-name-placeholder": "Session Name",
 | 
				
			||||||
  "seed": "Seed",
 | 
					  "seed": "Seed",
 | 
				
			||||||
  "seed-placeholder": "Type the session seed here!",
 | 
					  "seed-placeholder": "Type the session seed here!",
 | 
				
			||||||
  "background-color": "Background color",
 | 
					  "background-color": "Background",
 | 
				
			||||||
  "green-fabric": "Green Fabric",
 | 
					  "green-fabric": "Green Fabric",
 | 
				
			||||||
  "gray-fabric": "Gray Fabric",
 | 
					  "gray-fabric": "Gray Fabric",
 | 
				
			||||||
  "blue-fabric": "Blue Fabric",
 | 
					  "blue-fabric": "Blue Fabric",
 | 
				
			||||||
  "yellow-fabric": "Yellow Fabric",
 | 
					  "yellow-fabric": "Yellow Fabric",
 | 
				
			||||||
  "red-fabric": "Red Fabric",
 | 
					  "red-fabric": "Red Fabric",
 | 
				
			||||||
  "crossed-game-teamed": "Crossed game ({0})",
 | 
					  "crossed-game-teamed": "Crossed game",
 | 
				
			||||||
  "create-match-session": "Create Match Session",
 | 
					  "create-match-session": "Create Match Session",
 | 
				
			||||||
  "ready": "Ready",
 | 
					  "ready": "Ready",
 | 
				
			||||||
  "unready": "Unready",
 | 
					  "unready": "Unready",
 | 
				
			||||||
@@ -46,5 +46,18 @@
 | 
				
			|||||||
    "player-turn": "{0}'s turn!"
 | 
					    "player-turn": "{0}'s turn!"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "back": "Back",
 | 
					  "back": "Back",
 | 
				
			||||||
  "session-name": "Session Name"
 | 
					  "session-name": "Session Name",
 | 
				
			||||||
 | 
					  "mode": "Mode",
 | 
				
			||||||
 | 
					  "singleplayer": "Singleplayer",
 | 
				
			||||||
 | 
					  "multiplayer": "Multiplayer",
 | 
				
			||||||
 | 
					  "players-number": "Players Number",
 | 
				
			||||||
 | 
					  "wood-1": "Wood",
 | 
				
			||||||
 | 
					  "win-type": "Win unit",
 | 
				
			||||||
 | 
					  "points": "Points",
 | 
				
			||||||
 | 
					  "rounds": "Rounds",
 | 
				
			||||||
 | 
					  "n-points": "{value} Points",
 | 
				
			||||||
 | 
					  "n-of-m-rounds": "{0} of {1} Rounds",
 | 
				
			||||||
 | 
					  "create-session": "Create Session",
 | 
				
			||||||
 | 
					  "join-a-multiplayer-session": "Join a Multiplayer Session",
 | 
				
			||||||
 | 
					  "tournaments": "Tournaments"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
  "password": "Contraseña",
 | 
					  "password": "Contraseña",
 | 
				
			||||||
  "password-placeholder": "Contraseña",
 | 
					  "password-placeholder": "Contraseña",
 | 
				
			||||||
  "invalid-username-or-password": "usuario o contraseña invalido",
 | 
					  "invalid-username-or-password": "usuario o contraseña invalido",
 | 
				
			||||||
  "points-to-win": "Puntos para ganar",
 | 
					  "points-to-win": "Objetivo para ganar",
 | 
				
			||||||
  "round-index-1": "Ronda {0}",
 | 
					  "round-index-1": "Ronda {0}",
 | 
				
			||||||
  "scoreboard": "Marcador",
 | 
					  "scoreboard": "Marcador",
 | 
				
			||||||
  "winner": "Ganador",
 | 
					  "winner": "Ganador",
 | 
				
			||||||
@@ -19,7 +19,7 @@
 | 
				
			|||||||
  "unready": "No preparado",
 | 
					  "unready": "No preparado",
 | 
				
			||||||
  "welcome-to-the-user-username-s-home-page": "Bienvenido a la página de inicio de {0}",
 | 
					  "welcome-to-the-user-username-s-home-page": "Bienvenido a la página de inicio de {0}",
 | 
				
			||||||
  "available-sessions": "Sesiones disponibles",
 | 
					  "available-sessions": "Sesiones disponibles",
 | 
				
			||||||
  "background-color": "Color de fondo",
 | 
					  "background-color": "Fondo",
 | 
				
			||||||
  "blue-fabric": "Tela azul",
 | 
					  "blue-fabric": "Tela azul",
 | 
				
			||||||
  "cancel": "Cancelar",
 | 
					  "cancel": "Cancelar",
 | 
				
			||||||
  "copy": "Copiar",
 | 
					  "copy": "Copiar",
 | 
				
			||||||
@@ -31,7 +31,7 @@
 | 
				
			|||||||
    "your-turn": "¡Tu turno!"
 | 
					    "your-turn": "¡Tu turno!"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "create-match-session": "Crear sesión de partido",
 | 
					  "create-match-session": "Crear sesión de partido",
 | 
				
			||||||
  "crossed-game-teamed": "Juego cruzado ({0})",
 | 
					  "crossed-game-teamed": "Juego cruzado",
 | 
				
			||||||
  "delete": "Borrar",
 | 
					  "delete": "Borrar",
 | 
				
			||||||
  "gray-fabric": "Tela gris",
 | 
					  "gray-fabric": "Tela gris",
 | 
				
			||||||
  "green-fabric": "Tela verde",
 | 
					  "green-fabric": "Tela verde",
 | 
				
			||||||
@@ -46,5 +46,18 @@
 | 
				
			|||||||
  "start": "Comenzar",
 | 
					  "start": "Comenzar",
 | 
				
			||||||
  "yellow-fabric": "Tela amarilla",
 | 
					  "yellow-fabric": "Tela amarilla",
 | 
				
			||||||
  "back": "Volver",
 | 
					  "back": "Volver",
 | 
				
			||||||
  "session-name": "Nombre de la sesión"
 | 
					  "session-name": "Nombre de la sesión",
 | 
				
			||||||
 | 
					  "mode": "Modo",
 | 
				
			||||||
 | 
					  "singleplayer": "Un jugador",
 | 
				
			||||||
 | 
					  "multiplayer": "Multijugador",
 | 
				
			||||||
 | 
					  "players-number": "Número de jugadores",
 | 
				
			||||||
 | 
					  "wood-1": "Madera",
 | 
				
			||||||
 | 
					  "win-type": "Unidad de puntaje",
 | 
				
			||||||
 | 
					  "points": "Puntos",
 | 
				
			||||||
 | 
					  "rounds": "Rondas",
 | 
				
			||||||
 | 
					  "n-points": "{0} puntos",
 | 
				
			||||||
 | 
					  "n-of-m-rounds": "{0} de {1} rondas",
 | 
				
			||||||
 | 
					  "create-session": "Crear sesión",
 | 
				
			||||||
 | 
					  "join-a-multiplayer-session": "Únete a una sesión multijugador",
 | 
				
			||||||
 | 
					  "tournaments": "Torneos"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,20 +2,20 @@ import { createI18n } from 'vue-i18n'
 | 
				
			|||||||
import en from './en.json'
 | 
					import en from './en.json'
 | 
				
			||||||
import es from './es.json'
 | 
					import es from './es.json'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const browserLang = 'pt' //avigator.language.split('-')[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const i18n = createI18n({
 | 
					const i18n = createI18n({
 | 
				
			||||||
  legacy: false,
 | 
					  legacy: false,
 | 
				
			||||||
  locale: 'es',
 | 
					  locale: browserLang,
 | 
				
			||||||
 | 
					  fallbackLocale: 'en',
 | 
				
			||||||
 | 
					  missingWarn: false,
 | 
				
			||||||
 | 
					  fallbackWarn: false,
 | 
				
			||||||
  messages: {
 | 
					  messages: {
 | 
				
			||||||
    en,
 | 
					    en,
 | 
				
			||||||
    es,
 | 
					    es,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// const translate = (key: string, context: any, plural: number = 1) => {
 | 
					 | 
				
			||||||
//   return i18n.global.t(key, plural)
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default i18n
 | 
					export default i18n
 | 
				
			||||||
 | 
					 | 
				
			||||||
const { t } = i18n.global
 | 
					const { t } = i18n.global
 | 
				
			||||||
export { t, t as $t }
 | 
					export { t, t as $t }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,14 @@
 | 
				
			|||||||
import { NetworkService } from './NetworkService'
 | 
					import { NetworkService } from './NetworkService'
 | 
				
			||||||
import { ServiceBase } from './ServiceBase'
 | 
					import { ServiceBase } from './ServiceBase'
 | 
				
			||||||
 | 
					import type { MatchSessionOptions } from '@/common/interfaces'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class GameService extends ServiceBase {
 | 
					export class GameService extends ServiceBase {
 | 
				
			||||||
  private networkService = new NetworkService()
 | 
					  private networkService = new NetworkService()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async createMatchSession(sessionName: string, seed: string, options: any) {
 | 
					  async createMatchSession(options: MatchSessionOptions) {
 | 
				
			||||||
    const response = await this.networkService.post({
 | 
					    const response = await this.networkService.post({
 | 
				
			||||||
      uri: '/game/match',
 | 
					      uri: '/game/match',
 | 
				
			||||||
      body: { sessionName, seed, options },
 | 
					      body: { options },
 | 
				
			||||||
      auth: true,
 | 
					      auth: true,
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    const { sessionId } = response
 | 
					    const { sessionId } = response
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
import type { GameOptions } from '@/common/interfaces'
 | 
					import type { MatchSessionOptions } from '@/common/interfaces'
 | 
				
			||||||
import { defineStore } from 'pinia'
 | 
					import { defineStore } from 'pinia'
 | 
				
			||||||
import { ref } from 'vue'
 | 
					import { ref } from 'vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const useGameOptionsStore = defineStore('gameOptions', () => {
 | 
					export const useGameOptionsStore = defineStore('gameOptions', () => {
 | 
				
			||||||
  const gameOptions = ref<GameOptions>()
 | 
					  const gameOptions = ref<MatchSessionOptions>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return { gameOptions }
 | 
					  return { gameOptions }
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +1,23 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import { inject, onMounted, onUnmounted, ref } from 'vue'
 | 
					import { computed, inject, onMounted, onUnmounted, ref } from 'vue'
 | 
				
			||||||
import { useRouter } from 'vue-router'
 | 
					import { useRouter } from 'vue-router'
 | 
				
			||||||
import { useGameStore } from '@/stores/game'
 | 
					import { useGameStore } from '@/stores/game'
 | 
				
			||||||
import { storeToRefs } from 'pinia'
 | 
					import { storeToRefs } from 'pinia'
 | 
				
			||||||
import type { LoggingService } from '@/services/LoggingService'
 | 
					import type { LoggingService } from '@/services/LoggingService'
 | 
				
			||||||
import type { GameService } from '@/services/GameService'
 | 
					import type { GameService } from '@/services/GameService'
 | 
				
			||||||
import type { MatchSessionDto } from '@/common/interfaces'
 | 
					import type { MatchSessionOptions, MatchSessionDto } from '@/common/interfaces'
 | 
				
			||||||
import { useEventBusStore } from '@/stores/eventBus'
 | 
					import { useEventBusStore } from '@/stores/eventBus'
 | 
				
			||||||
import { useAuthStore } from '@/stores/auth'
 | 
					import { useAuthStore } from '@/stores/auth'
 | 
				
			||||||
import { copyToclipboard } from '@/common/helpers'
 | 
					import { copyToclipboard } from '@/common/helpers'
 | 
				
			||||||
import { useGameOptionsStore } from '@/stores/gameOptions'
 | 
					import { useGameOptionsStore } from '@/stores/gameOptions'
 | 
				
			||||||
 | 
					import MatchConfiguration from '@/components/MatchConfiguration.vue'
 | 
				
			||||||
 | 
					import { useI18n } from 'vue-i18n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let teamedWith = ref<string | undefined>(undefined)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let background = ref<string>('green')
 | 
					 | 
				
			||||||
let teamed = ref<boolean>(false)
 | 
					 | 
				
			||||||
let pointsToWin = ref<number>(100)
 | 
					 | 
				
			||||||
let seed = ref<string>('')
 | 
					 | 
				
			||||||
let sessionName = ref(`Test #${Date.now()}`)
 | 
					 | 
				
			||||||
let matchSessions = ref<MatchSessionDto[]>([])
 | 
					let matchSessions = ref<MatchSessionDto[]>([])
 | 
				
			||||||
let dataInterval: any
 | 
					let dataInterval: any
 | 
				
			||||||
 | 
					let loadingSessions = ref<boolean>(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = useRouter()
 | 
					const router = useRouter()
 | 
				
			||||||
const gameStore = useGameStore()
 | 
					const gameStore = useGameStore()
 | 
				
			||||||
@@ -33,36 +33,18 @@ const { sessionState, isSessionStarted, playerState, amIHost, readyForStart } =
 | 
				
			|||||||
const { user } = storeToRefs(auth)
 | 
					const { user } = storeToRefs(auth)
 | 
				
			||||||
const { gameOptions } = storeToRefs(gameOptionsStore)
 | 
					const { gameOptions } = storeToRefs(gameOptionsStore)
 | 
				
			||||||
const { updateSessionState, updatePlayerState, updateGameState } = gameStore
 | 
					const { updateSessionState, updatePlayerState, updateGameState } = gameStore
 | 
				
			||||||
 | 
					const { t } = useI18n()
 | 
				
			||||||
// function setPlayerReady() {
 | 
					 | 
				
			||||||
//   logger.debug('Starting game')
 | 
					 | 
				
			||||||
//   if (!sessionState.value) {
 | 
					 | 
				
			||||||
//     logger.error('No session found')
 | 
					 | 
				
			||||||
//     return
 | 
					 | 
				
			||||||
//   }
 | 
					 | 
				
			||||||
//   if (!playerState.value) {
 | 
					 | 
				
			||||||
//     logger.error('No player found')
 | 
					 | 
				
			||||||
//     return
 | 
					 | 
				
			||||||
//   }
 | 
					 | 
				
			||||||
//   socketService.sendMessage('client:set-player-ready', {
 | 
					 | 
				
			||||||
//     userId: playerState.value.id,
 | 
					 | 
				
			||||||
//     sessionId: sessionState.value.id
 | 
					 | 
				
			||||||
//   })
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const eventBus = useEventBusStore()
 | 
					const eventBus = useEventBusStore()
 | 
				
			||||||
eventBus.subscribe('window-before-unload', () => {
 | 
					eventBus.subscribe('window-before-unload', () => {
 | 
				
			||||||
  logger.debug('Window before unload')
 | 
					  logger.debug('Window before unload')
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function createMatch() {
 | 
					async function createMatch(options: MatchSessionOptions) {
 | 
				
			||||||
  logger.debug('Creating match')
 | 
					  logger.debug('Creating match')
 | 
				
			||||||
  await socketService.connect()
 | 
					  await socketService.connect()
 | 
				
			||||||
  gameOptions.value = { background: background.value }
 | 
					  gameOptions.value = options
 | 
				
			||||||
  const sessionOptions = {
 | 
					  await gameService.createMatchSession(options)
 | 
				
			||||||
    pointsToWin: pointsToWin.value,
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  const id = await gameService.createMatchSession(sessionName.value, seed.value, sessionOptions)
 | 
					 | 
				
			||||||
  logger.debug('Match created successfully')
 | 
					  logger.debug('Match created successfully')
 | 
				
			||||||
  // router.push({ name: 'match', params: { id } })
 | 
					  // router.push({ name: 'match', params: { id } })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -90,6 +72,7 @@ async function startMatch() {
 | 
				
			|||||||
    await socketService.sendMessageWithAck('client:start-session', {
 | 
					    await socketService.sendMessageWithAck('client:start-session', {
 | 
				
			||||||
      sessionId: sessionId,
 | 
					      sessionId: sessionId,
 | 
				
			||||||
      playerId: playerId,
 | 
					      playerId: playerId,
 | 
				
			||||||
 | 
					      teamedWith: teamedWith.value,
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -97,13 +80,16 @@ async function startMatch() {
 | 
				
			|||||||
async function cancelMatch() {
 | 
					async function cancelMatch() {
 | 
				
			||||||
  logger.debug('Cancelling match')
 | 
					  logger.debug('Cancelling match')
 | 
				
			||||||
  if (sessionState?.value?.id) {
 | 
					  if (sessionState?.value?.id) {
 | 
				
			||||||
 | 
					    if (amIHost.value) {
 | 
				
			||||||
      await gameService.cancelMatchSession(sessionState?.value?.id)
 | 
					      await gameService.cancelMatchSession(sessionState?.value?.id)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      //TODO: await gameService.leaveMatchSession(sessionState?.value?.id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    updateSessionState(undefined)
 | 
					    updateSessionState(undefined)
 | 
				
			||||||
    updatePlayerState(undefined)
 | 
					    updatePlayerState(undefined)
 | 
				
			||||||
    updateGameState(undefined)
 | 
					    updateGameState(undefined)
 | 
				
			||||||
 | 
					    teamedWith.value = undefined
 | 
				
			||||||
    logger.debug('Match cancelled successfully')
 | 
					 | 
				
			||||||
    router.push({ name: 'home' })
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -127,14 +113,28 @@ async function deleteMatch(id: string) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const playersToTeamUpWith = computed(() => {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    sessionState?.value?.players.filter((player) => player.id !== sessionState?.value?.creator) ||
 | 
				
			||||||
 | 
					    []
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const canStart = computed(() => {
 | 
				
			||||||
 | 
					  const players = sessionState?.value?.players || []
 | 
				
			||||||
 | 
					  const options = gameOptions.value
 | 
				
			||||||
 | 
					  const allReady = (players.length || 0) > 0 && players.every((player) => player.ready)
 | 
				
			||||||
 | 
					  return (!options?.teamed && allReady) || (options?.teamed && !!teamedWith.value && allReady)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function loadData() {
 | 
					async function loadData() {
 | 
				
			||||||
  const listResponse = await gameService.listMatchSessions()
 | 
					  const listResponse = await gameService.listMatchSessions()
 | 
				
			||||||
  matchSessions.value = listResponse.data
 | 
					  matchSessions.value = listResponse.data
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
  loadData()
 | 
					  // loadData()
 | 
				
			||||||
  dataInterval = setInterval(loadData, 5000)
 | 
					  // dataInterval = setInterval(loadData, 5000)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onUnmounted(() => {
 | 
					onUnmounted(() => {
 | 
				
			||||||
@@ -142,9 +142,34 @@ onUnmounted(() => {
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function copy(sessionSeed: string) {
 | 
					function copy(sessionSeed: string) {
 | 
				
			||||||
  seed.value = sessionSeed
 | 
					 | 
				
			||||||
  copyToclipboard(sessionSeed)
 | 
					  copyToclipboard(sessionSeed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let tabs = ref<any[]>([
 | 
				
			||||||
 | 
					  { label: t('create-session'), id: 'create-tab', active: true, disabled: false },
 | 
				
			||||||
 | 
					  { label: t('join-a-multiplayer-session'), id: 'join-tab', active: false, disabled: false },
 | 
				
			||||||
 | 
					  { label: t('tournaments'), id: 'torunaments-tab', active: false, disabled: true },
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const selectedTab = computed(() => tabs.value.find((t) => t.active)?.id)
 | 
				
			||||||
 | 
					const isCreateTab = computed(() => selectedTab.value === 'create-tab')
 | 
				
			||||||
 | 
					const isJoinTab = computed(() => selectedTab.value === 'join-tab')
 | 
				
			||||||
 | 
					const isTournamentTab = computed(() => selectedTab.value === 'torunaments-tab')
 | 
				
			||||||
 | 
					async function tabClick(tab: any) {
 | 
				
			||||||
 | 
					  tabs.value.forEach((t) => (t.active = t === tab))
 | 
				
			||||||
 | 
					  if (tab.id === 'join-tab') {
 | 
				
			||||||
 | 
					    loadingSessions.value = true
 | 
				
			||||||
 | 
					    await loadData()
 | 
				
			||||||
 | 
					    dataInterval = setInterval(loadData, 5000)
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    clearInterval(dataInterval)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onCreateMatch(options: MatchSessionOptions) {
 | 
				
			||||||
 | 
					  console.log('Creating match', options)
 | 
				
			||||||
 | 
					  createMatch(options)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
@@ -153,102 +178,27 @@ function copy(sessionSeed: string) {
 | 
				
			|||||||
      <h1 class="title is-2">
 | 
					      <h1 class="title is-2">
 | 
				
			||||||
        {{ $t('welcome-to-the-user-username-s-home-page', [user.username]) }}
 | 
					        {{ $t('welcome-to-the-user-username-s-home-page', [user.username]) }}
 | 
				
			||||||
      </h1>
 | 
					      </h1>
 | 
				
			||||||
 | 
					      <!-- Tabs -->
 | 
				
			||||||
      <div class="block" v-if="!isSessionStarted">
 | 
					      <div class="block" v-if="!isSessionStarted">
 | 
				
			||||||
        <div class="field">
 | 
					        <div class="tabs is-centered">
 | 
				
			||||||
          <label class="label">{{ $t('session-name') }}</label>
 | 
					          <ul>
 | 
				
			||||||
          <div class="control">
 | 
					            <li
 | 
				
			||||||
            <input
 | 
					              v-bind:key="tab.label"
 | 
				
			||||||
              type="text"
 | 
					              v-for="tab in tabs"
 | 
				
			||||||
              class="input"
 | 
					              :class="{ 'is-active': tab.active, 'is-disabled': tab.disabled }"
 | 
				
			||||||
              v-model="sessionName"
 | 
					            >
 | 
				
			||||||
              placeholder="$t('session-name-placeholder')"
 | 
					              <a @click="() => tabClick(tab)">{{ tab.label }}</a>
 | 
				
			||||||
            />
 | 
					            </li>
 | 
				
			||||||
          </div>
 | 
					          </ul>
 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="field">
 | 
					 | 
				
			||||||
          <label class="label">{{ $t('seed') }}</label>
 | 
					 | 
				
			||||||
          <div class="control">
 | 
					 | 
				
			||||||
            <input
 | 
					 | 
				
			||||||
              type="text"
 | 
					 | 
				
			||||||
              class="input"
 | 
					 | 
				
			||||||
              style="margin-bottom: 0"
 | 
					 | 
				
			||||||
              v-model="seed"
 | 
					 | 
				
			||||||
              :placeholder="$t('seed-placeholder')"
 | 
					 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="grid">
 | 
					 | 
				
			||||||
          <div class="cell">
 | 
					 | 
				
			||||||
            <div class="field">
 | 
					 | 
				
			||||||
              <label for="background" class="label">{{ $t('background-color') }}</label>
 | 
					 | 
				
			||||||
              <div class="control">
 | 
					 | 
				
			||||||
                <div class="select">
 | 
					 | 
				
			||||||
                  <select v-model="background" name="background">
 | 
					 | 
				
			||||||
                    <option value="green">{{ $t('green-fabric') }}</option>
 | 
					 | 
				
			||||||
                    <option value="gray">{{ $t('gray-fabric') }}</option>
 | 
					 | 
				
			||||||
                    <option value="blue">{{ $t('blue-fabric') }}</option>
 | 
					 | 
				
			||||||
                    <option value="yellow">{{ $t('yellow-fabric') }}</option>
 | 
					 | 
				
			||||||
                    <option value="red">{{ $t('red-fabric') }}</option>
 | 
					 | 
				
			||||||
                  </select>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
              </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="field">
 | 
					 | 
				
			||||||
              <div class="control">
 | 
					 | 
				
			||||||
                <label for="teamed" class="checkbox">
 | 
					 | 
				
			||||||
                  <input v-model="teamed" name="teamed" type="checkbox" />
 | 
					 | 
				
			||||||
                  {{ $t('crossed-game-teamed', [teamed]) }}
 | 
					 | 
				
			||||||
                </label>
 | 
					 | 
				
			||||||
              </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
          <div class="cell">
 | 
					 | 
				
			||||||
            <div class="field">
 | 
					 | 
				
			||||||
              <label for="pointsToWin" class="label">{{ $t('points-to-win') }}</label>
 | 
					 | 
				
			||||||
              <div class="control">
 | 
					 | 
				
			||||||
                <div class="select">
 | 
					 | 
				
			||||||
                  <select v-model="pointsToWin" name="pointsToWin">
 | 
					 | 
				
			||||||
                    <option value="50">50</option>
 | 
					 | 
				
			||||||
                    <option value="80">80</option>
 | 
					 | 
				
			||||||
                    <option value="100">100</option>
 | 
					 | 
				
			||||||
                    <option value="150">150</option>
 | 
					 | 
				
			||||||
                    <option value="200">200</option>
 | 
					 | 
				
			||||||
                  </select>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
              </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="buttons">
 | 
					 | 
				
			||||||
          <button class="button is-primary" @click.once="createMatch">
 | 
					 | 
				
			||||||
            {{ $t('create-match-session') }}
 | 
					 | 
				
			||||||
          </button>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      <div class="block" v-if="isSessionStarted">
 | 
					 | 
				
			||||||
        <h2 class="title is-4">{{ sessionState?.name }}</h2>
 | 
					 | 
				
			||||||
        <h6 class="title is-size-5">Players</h6>
 | 
					 | 
				
			||||||
        <div v-for="player in sessionState?.players" :key="player.id">
 | 
					 | 
				
			||||||
          <p>{{ player.name }}</p>
 | 
					 | 
				
			||||||
          <p>{{ player.ready ? 'Ready' : 'Not ready' }}</p>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="buttons mt-6">
 | 
					 | 
				
			||||||
          <button class="button" @click="setPlayerReady">
 | 
					 | 
				
			||||||
            <span v-if="!readyForStart">{{ $t('ready') }}</span
 | 
					 | 
				
			||||||
            ><span v-else>{{ $t('unready') }}</span>
 | 
					 | 
				
			||||||
          </button>
 | 
					 | 
				
			||||||
          <button class="button" @click="startMatch" v-if="amIHost && readyForStart">
 | 
					 | 
				
			||||||
            <span>{{ $t('start') }}</span>
 | 
					 | 
				
			||||||
          </button>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          <button class="button" @click="cancelMatch">
 | 
					 | 
				
			||||||
            <span>{{ $t('cancel') }}</span>
 | 
					 | 
				
			||||||
          </button>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					        <!-- Tabs End -->
 | 
				
			||||||
 | 
					        <!-- Match Configuration -->
 | 
				
			||||||
 | 
					        <section class="section" v-if="isCreateTab">
 | 
				
			||||||
 | 
					          <MatchConfiguration @create-match="onCreateMatch" />
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
    <section class="section available-sessions" v-if="!isSessionStarted">
 | 
					        <!-- Match Configuration End -->
 | 
				
			||||||
      <h2 class="title is-4">{{ $t('available-sessions') }}</h2>
 | 
					        <!-- Join a Multiplayer Session -->
 | 
				
			||||||
 | 
					        <section class="section available-sessions" v-if="isJoinTab">
 | 
				
			||||||
          <div class="block">
 | 
					          <div class="block">
 | 
				
			||||||
            <div v-if="matchSessions.length === 0">
 | 
					            <div v-if="matchSessions.length === 0">
 | 
				
			||||||
              <p>{{ $t('no-sessions-available') }}</p>
 | 
					              <p>{{ $t('no-sessions-available') }}</p>
 | 
				
			||||||
@@ -289,6 +239,52 @@ function copy(sessionSeed: string) {
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
 | 
					        <!-- Join a Multiplayer Session End -->
 | 
				
			||||||
 | 
					        <!-- Tournaments -->
 | 
				
			||||||
 | 
					        <section class="section" v-if="isTournamentTab"></section>
 | 
				
			||||||
 | 
					        <!-- Tournaments End -->
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div class="block" v-if="isSessionStarted">
 | 
				
			||||||
 | 
					        <h2 class="title is-4">{{ sessionState?.name }}</h2>
 | 
				
			||||||
 | 
					        <h6 class="title is-size-5">Players</h6>
 | 
				
			||||||
 | 
					        <div v-for="player in sessionState?.players" :key="player.id">
 | 
				
			||||||
 | 
					          <p>{{ player.name }} ({{ player.ready ? 'Ready' : 'Not ready' }})</p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="mt-4" v-if="amIHost && gameOptions?.teamed && playersToTeamUpWith.length > 0">
 | 
				
			||||||
 | 
					          <div class="field">
 | 
				
			||||||
 | 
					            <label for="background" class="label">Team up with</label>
 | 
				
			||||||
 | 
					            <div class="control">
 | 
				
			||||||
 | 
					              <div class="select">
 | 
				
			||||||
 | 
					                <select v-model="teamedWith" name="teamedWidth">
 | 
				
			||||||
 | 
					                  <option v-for="player in playersToTeamUpWith" :key="player.id" :value="player.id">
 | 
				
			||||||
 | 
					                    {{ player.name }}
 | 
				
			||||||
 | 
					                  </option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="buttons mt-6">
 | 
				
			||||||
 | 
					          <button class="button is-dark" @click="setPlayerReady">
 | 
				
			||||||
 | 
					            <span v-if="!readyForStart">{{ $t('ready') }}</span
 | 
				
			||||||
 | 
					            ><span v-else>{{ $t('unready') }}</span>
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					          <button
 | 
				
			||||||
 | 
					            class="button is-success"
 | 
				
			||||||
 | 
					            :disabled="!canStart"
 | 
				
			||||||
 | 
					            @click="startMatch"
 | 
				
			||||||
 | 
					            v-if="amIHost"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <span>{{ $t('start') }}</span>
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <button class="button is-danger" @click="cancelMatch">
 | 
				
			||||||
 | 
					            <span>{{ $t('cancel') }}</span>
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,9 +39,13 @@ onBeforeMount(() => {
 | 
				
			|||||||
        <span class="title is-5">{{ $t('winner') }}</span>
 | 
					        <span class="title is-5">{{ $t('winner') }}</span>
 | 
				
			||||||
        <span class="is-size-5 ml-4">{{ matchSession?.matchWinner?.name }}</span>
 | 
					        <span class="is-size-5 ml-4">{{ matchSession?.matchWinner?.name }}</span>
 | 
				
			||||||
      </p>
 | 
					      </p>
 | 
				
			||||||
 | 
					      <p class="mb-4">
 | 
				
			||||||
 | 
					        <span class="title is-5">{{ $t('win-type') }}</span>
 | 
				
			||||||
 | 
					        <span class="is-size-5 ml-4">{{ matchSession?.options.winType }}</span>
 | 
				
			||||||
 | 
					      </p>
 | 
				
			||||||
      <p class="mb-4">
 | 
					      <p class="mb-4">
 | 
				
			||||||
        <span class="title is-5">{{ $t('points-to-win') }}</span>
 | 
					        <span class="title is-5">{{ $t('points-to-win') }}</span>
 | 
				
			||||||
        <span class="is-size-5 ml-4">{{ matchSession?.pointsToWin }}</span>
 | 
					        <span class="is-size-5 ml-4">{{ matchSession?.options.winTarget }}</span>
 | 
				
			||||||
      </p>
 | 
					      </p>
 | 
				
			||||||
      <h3 class="title is-5">{{ $t('final-scoreboard') }}</h3>
 | 
					      <h3 class="title is-5">{{ $t('final-scoreboard') }}</h3>
 | 
				
			||||||
      <div v-bind:key="$index" v-for="(score, $index) in matchSession?.scoreboard">
 | 
					      <div v-bind:key="$index" v-for="(score, $index) in matchSession?.scoreboard">
 | 
				
			||||||
 
 | 
				
			|||||||