0.1.12
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -29,4 +29,4 @@ coverage
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
*.tsbuildinfo
 | 
					*.tsbuildinfo
 | 
				
			||||||
.history
 | 
					.history
 | 
				
			||||||
.env
 | 
					.env*
 | 
				
			||||||
							
								
								
									
										8
									
								
								.hmrc
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								.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.8",
 | 
					  "version": "0.1.12",
 | 
				
			||||||
  "docker": {
 | 
					  "docker": {
 | 
				
			||||||
    "useRegistry": true,
 | 
					    "useRegistry": true,
 | 
				
			||||||
    "registry": "192.168.1.115:5000",
 | 
					    "registry": "192.168.1.115:5000",
 | 
				
			||||||
@@ -84,7 +84,7 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "_backup": {
 | 
					  "_backup": {
 | 
				
			||||||
    "name": "domino-client",
 | 
					    "name": "domino-client",
 | 
				
			||||||
    "version": "0.1.7",
 | 
					    "version": "0.1.11",
 | 
				
			||||||
    "private": true,
 | 
					    "private": true,
 | 
				
			||||||
    "type": "commonjs",
 | 
					    "type": "commonjs",
 | 
				
			||||||
    "scripts": {
 | 
					    "scripts": {
 | 
				
			||||||
@@ -97,8 +97,8 @@
 | 
				
			|||||||
      "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.7",
 | 
					      "docker-tag": "docker tag 192.168.1.115:5000/arhuako/domino-client:latest 192.168.1.115:5000/arhuako/domino-client:0.1.11",
 | 
				
			||||||
      "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",
 | 
					      "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.11",
 | 
				
			||||||
      "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"
 | 
					      "tauri": "tauri"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Unreleased
 | 
					## Unreleased
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 0.1.12 - 2024-07-22
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					- I18n translations
 | 
				
			||||||
 | 
					- Win conditions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- Multiplayer join button not accessible
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 0.1.10 - 2024-07-20
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					- Updater
 | 
				
			||||||
 | 
					- Refresh authentication when expires
 | 
				
			||||||
 | 
					- Match summary page phase 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 0.1.9 - 2024-07-19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 0.1.8 - 2024-07-18
 | 
					## 0.1.8 - 2024-07-18
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 0.1.7 - 2024-07-17
 | 
					## 0.1.7 - 2024-07-17
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -1,12 +1,12 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "domino-client",
 | 
					  "name": "domino-client",
 | 
				
			||||||
  "version": "0.1.7",
 | 
					  "version": "0.1.8",
 | 
				
			||||||
  "lockfileVersion": 3,
 | 
					  "lockfileVersion": 3,
 | 
				
			||||||
  "requires": true,
 | 
					  "requires": true,
 | 
				
			||||||
  "packages": {
 | 
					  "packages": {
 | 
				
			||||||
    "": {
 | 
					    "": {
 | 
				
			||||||
      "name": "domino-client",
 | 
					      "name": "domino-client",
 | 
				
			||||||
      "version": "0.1.7",
 | 
					      "version": "0.1.8",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@pixi/sound": "^6.0.0",
 | 
					        "@pixi/sound": "^6.0.0",
 | 
				
			||||||
        "@tauri-apps/api": "^1.6.0",
 | 
					        "@tauri-apps/api": "^1.6.0",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "domino-client",
 | 
					  "name": "domino-client",
 | 
				
			||||||
  "version": "0.1.8",
 | 
					  "version": "0.1.12",
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
  "type": "commonjs",
 | 
					  "type": "commonjs",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
@@ -13,8 +13,8 @@
 | 
				
			|||||||
    "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.8",
 | 
					    "docker-tag": "docker tag 192.168.1.115:5000/arhuako/domino-client:latest 192.168.1.115:5000/arhuako/domino-client:0.1.12",
 | 
				
			||||||
    "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",
 | 
					    "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.12",
 | 
				
			||||||
    "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"
 | 
					    "tauri": "tauri"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,23 @@
 | 
				
			|||||||
<h1>Changelog</h1>
 | 
					<h1>Changelog</h1>
 | 
				
			||||||
<p>All notable changes to this project will be documented in this file.</p>
 | 
					<p>All notable changes to this project will be documented in this file.</p>
 | 
				
			||||||
 | 
					<h2>0.1.12 - 2024-07-22</h2>
 | 
				
			||||||
 | 
					<h3>Added</h3>
 | 
				
			||||||
 | 
					<ul>
 | 
				
			||||||
 | 
					<li>I18n translations</li>
 | 
				
			||||||
 | 
					<li>Win conditions</li>
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					<h3>Fixed</h3>
 | 
				
			||||||
 | 
					<ul>
 | 
				
			||||||
 | 
					<li>Multiplayer join button not accessible</li>
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					<h2>0.1.10 - 2024-07-20</h2>
 | 
				
			||||||
 | 
					<h3>Added</h3>
 | 
				
			||||||
 | 
					<ul>
 | 
				
			||||||
 | 
					<li>Updater</li>
 | 
				
			||||||
 | 
					<li>Refresh authentication when expires</li>
 | 
				
			||||||
 | 
					<li>Match summary page phase 1</li>
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					<h2>0.1.9 - 2024-07-19</h2>
 | 
				
			||||||
<h2>0.1.8 - 2024-07-18</h2>
 | 
					<h2>0.1.8 - 2024-07-18</h2>
 | 
				
			||||||
<h2>0.1.7 - 2024-07-17</h2>
 | 
					<h2>0.1.7 - 2024-07-17</h2>
 | 
				
			||||||
<h2>0.1.6 - 2024-07-17</h2>
 | 
					<h2>0.1.6 - 2024-07-17</h2>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										511
									
								
								src-tauri/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										511
									
								
								src-tauri/Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -216,6 +216,9 @@ name = "bytes"
 | 
				
			|||||||
version = "1.6.1"
 | 
					version = "1.6.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"
 | 
					checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "cairo-rs"
 | 
					name = "cairo-rs"
 | 
				
			||||||
@@ -630,7 +633,7 @@ dependencies = [
 | 
				
			|||||||
 "rustc_version",
 | 
					 "rustc_version",
 | 
				
			||||||
 "toml 0.8.15",
 | 
					 "toml 0.8.15",
 | 
				
			||||||
 "vswhom",
 | 
					 "vswhom",
 | 
				
			||||||
 "winreg",
 | 
					 "winreg 0.52.0",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -794,6 +797,12 @@ dependencies = [
 | 
				
			|||||||
 "syn 2.0.71",
 | 
					 "syn 2.0.71",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "futures-sink"
 | 
				
			||||||
 | 
					version = "0.3.30"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "futures-task"
 | 
					name = "futures-task"
 | 
				
			||||||
version = "0.3.30"
 | 
					version = "0.3.30"
 | 
				
			||||||
@@ -807,8 +816,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			|||||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
 | 
					checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "futures-core",
 | 
					 "futures-core",
 | 
				
			||||||
 | 
					 "futures-io",
 | 
				
			||||||
 "futures-macro",
 | 
					 "futures-macro",
 | 
				
			||||||
 | 
					 "futures-sink",
 | 
				
			||||||
 "futures-task",
 | 
					 "futures-task",
 | 
				
			||||||
 | 
					 "memchr",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "pin-utils",
 | 
					 "pin-utils",
 | 
				
			||||||
 "slab",
 | 
					 "slab",
 | 
				
			||||||
@@ -1120,6 +1132,25 @@ dependencies = [
 | 
				
			|||||||
 "syn 1.0.109",
 | 
					 "syn 1.0.109",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "h2"
 | 
				
			||||||
 | 
					version = "0.3.26"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "fnv",
 | 
				
			||||||
 | 
					 "futures-core",
 | 
				
			||||||
 | 
					 "futures-sink",
 | 
				
			||||||
 | 
					 "futures-util",
 | 
				
			||||||
 | 
					 "http",
 | 
				
			||||||
 | 
					 "indexmap 2.2.6",
 | 
				
			||||||
 | 
					 "slab",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
 | 
					 "tokio-util",
 | 
				
			||||||
 | 
					 "tracing",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "hashbrown"
 | 
					name = "hashbrown"
 | 
				
			||||||
version = "0.12.3"
 | 
					version = "0.12.3"
 | 
				
			||||||
@@ -1190,12 +1221,72 @@ dependencies = [
 | 
				
			|||||||
 "itoa 1.0.11",
 | 
					 "itoa 1.0.11",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "http-body"
 | 
				
			||||||
 | 
					version = "0.4.6"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "http",
 | 
				
			||||||
 | 
					 "pin-project-lite",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "http-range"
 | 
					name = "http-range"
 | 
				
			||||||
version = "0.1.5"
 | 
					version = "0.1.5"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
 | 
					checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "httparse"
 | 
				
			||||||
 | 
					version = "1.9.4"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "httpdate"
 | 
				
			||||||
 | 
					version = "1.0.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "hyper"
 | 
				
			||||||
 | 
					version = "0.14.30"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "futures-channel",
 | 
				
			||||||
 | 
					 "futures-core",
 | 
				
			||||||
 | 
					 "futures-util",
 | 
				
			||||||
 | 
					 "h2",
 | 
				
			||||||
 | 
					 "http",
 | 
				
			||||||
 | 
					 "http-body",
 | 
				
			||||||
 | 
					 "httparse",
 | 
				
			||||||
 | 
					 "httpdate",
 | 
				
			||||||
 | 
					 "itoa 1.0.11",
 | 
				
			||||||
 | 
					 "pin-project-lite",
 | 
				
			||||||
 | 
					 "socket2",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
 | 
					 "tower-service",
 | 
				
			||||||
 | 
					 "tracing",
 | 
				
			||||||
 | 
					 "want",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "hyper-tls"
 | 
				
			||||||
 | 
					version = "0.5.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "hyper",
 | 
				
			||||||
 | 
					 "native-tls",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
 | 
					 "tokio-native-tls",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "iana-time-zone"
 | 
					name = "iana-time-zone"
 | 
				
			||||||
version = "0.1.60"
 | 
					version = "0.1.60"
 | 
				
			||||||
@@ -1313,6 +1404,12 @@ dependencies = [
 | 
				
			|||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "ipnet"
 | 
				
			||||||
 | 
					version = "2.9.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "itoa"
 | 
					name = "itoa"
 | 
				
			||||||
version = "0.4.8"
 | 
					version = "0.4.8"
 | 
				
			||||||
@@ -1519,6 +1616,18 @@ dependencies = [
 | 
				
			|||||||
 "autocfg",
 | 
					 "autocfg",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "mime"
 | 
				
			||||||
 | 
					version = "0.3.17"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "minisign-verify"
 | 
				
			||||||
 | 
					version = "0.2.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "miniz_oxide"
 | 
					name = "miniz_oxide"
 | 
				
			||||||
version = "0.7.4"
 | 
					version = "0.7.4"
 | 
				
			||||||
@@ -1529,6 +1638,34 @@ dependencies = [
 | 
				
			|||||||
 "simd-adler32",
 | 
					 "simd-adler32",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "mio"
 | 
				
			||||||
 | 
					version = "0.8.11"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "wasi 0.11.0+wasi-snapshot-preview1",
 | 
				
			||||||
 | 
					 "windows-sys 0.48.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "native-tls"
 | 
				
			||||||
 | 
					version = "0.2.12"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "log",
 | 
				
			||||||
 | 
					 "openssl",
 | 
				
			||||||
 | 
					 "openssl-probe",
 | 
				
			||||||
 | 
					 "openssl-sys",
 | 
				
			||||||
 | 
					 "schannel",
 | 
				
			||||||
 | 
					 "security-framework",
 | 
				
			||||||
 | 
					 "security-framework-sys",
 | 
				
			||||||
 | 
					 "tempfile",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ndk"
 | 
					name = "ndk"
 | 
				
			||||||
version = "0.6.0"
 | 
					version = "0.6.0"
 | 
				
			||||||
@@ -1635,6 +1772,17 @@ dependencies = [
 | 
				
			|||||||
 "objc_exception",
 | 
					 "objc_exception",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "objc-foundation"
 | 
				
			||||||
 | 
					version = "0.1.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "block",
 | 
				
			||||||
 | 
					 "objc",
 | 
				
			||||||
 | 
					 "objc_id",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "objc_exception"
 | 
					name = "objc_exception"
 | 
				
			||||||
version = "0.1.2"
 | 
					version = "0.1.2"
 | 
				
			||||||
@@ -1668,6 +1816,50 @@ version = "1.19.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
 | 
					checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "openssl"
 | 
				
			||||||
 | 
					version = "0.10.64"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bitflags 2.6.0",
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					 "foreign-types",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "once_cell",
 | 
				
			||||||
 | 
					 "openssl-macros",
 | 
				
			||||||
 | 
					 "openssl-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "openssl-macros"
 | 
				
			||||||
 | 
					version = "0.1.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "syn 2.0.71",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "openssl-probe"
 | 
				
			||||||
 | 
					version = "0.1.5"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "openssl-sys"
 | 
				
			||||||
 | 
					version = "0.9.102"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cc",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "pkg-config",
 | 
				
			||||||
 | 
					 "vcpkg",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "overload"
 | 
					name = "overload"
 | 
				
			||||||
version = "0.1.1"
 | 
					version = "0.1.1"
 | 
				
			||||||
@@ -2151,6 +2343,72 @@ version = "0.8.4"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
 | 
					checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "reqwest"
 | 
				
			||||||
 | 
					version = "0.11.27"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "base64 0.21.7",
 | 
				
			||||||
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "encoding_rs",
 | 
				
			||||||
 | 
					 "futures-core",
 | 
				
			||||||
 | 
					 "futures-util",
 | 
				
			||||||
 | 
					 "h2",
 | 
				
			||||||
 | 
					 "http",
 | 
				
			||||||
 | 
					 "http-body",
 | 
				
			||||||
 | 
					 "hyper",
 | 
				
			||||||
 | 
					 "hyper-tls",
 | 
				
			||||||
 | 
					 "ipnet",
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "log",
 | 
				
			||||||
 | 
					 "mime",
 | 
				
			||||||
 | 
					 "native-tls",
 | 
				
			||||||
 | 
					 "once_cell",
 | 
				
			||||||
 | 
					 "percent-encoding",
 | 
				
			||||||
 | 
					 "pin-project-lite",
 | 
				
			||||||
 | 
					 "rustls-pemfile",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					 "serde_json",
 | 
				
			||||||
 | 
					 "serde_urlencoded",
 | 
				
			||||||
 | 
					 "sync_wrapper",
 | 
				
			||||||
 | 
					 "system-configuration",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
 | 
					 "tokio-native-tls",
 | 
				
			||||||
 | 
					 "tokio-util",
 | 
				
			||||||
 | 
					 "tower-service",
 | 
				
			||||||
 | 
					 "url",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					 "wasm-bindgen-futures",
 | 
				
			||||||
 | 
					 "wasm-streams",
 | 
				
			||||||
 | 
					 "web-sys",
 | 
				
			||||||
 | 
					 "winreg 0.50.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rfd"
 | 
				
			||||||
 | 
					version = "0.10.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "0149778bd99b6959285b0933288206090c50e2327f47a9c463bfdbf45c8823ea"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "block",
 | 
				
			||||||
 | 
					 "dispatch",
 | 
				
			||||||
 | 
					 "glib-sys",
 | 
				
			||||||
 | 
					 "gobject-sys",
 | 
				
			||||||
 | 
					 "gtk-sys",
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "lazy_static",
 | 
				
			||||||
 | 
					 "log",
 | 
				
			||||||
 | 
					 "objc",
 | 
				
			||||||
 | 
					 "objc-foundation",
 | 
				
			||||||
 | 
					 "objc_id",
 | 
				
			||||||
 | 
					 "raw-window-handle",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					 "wasm-bindgen-futures",
 | 
				
			||||||
 | 
					 "web-sys",
 | 
				
			||||||
 | 
					 "windows 0.37.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "rustc-demangle"
 | 
					name = "rustc-demangle"
 | 
				
			||||||
version = "0.1.24"
 | 
					version = "0.1.24"
 | 
				
			||||||
@@ -2179,6 +2437,15 @@ dependencies = [
 | 
				
			|||||||
 "windows-sys 0.52.0",
 | 
					 "windows-sys 0.52.0",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rustls-pemfile"
 | 
				
			||||||
 | 
					version = "1.0.4"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "base64 0.21.7",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "rustversion"
 | 
					name = "rustversion"
 | 
				
			||||||
version = "1.0.17"
 | 
					version = "1.0.17"
 | 
				
			||||||
@@ -2200,6 +2467,15 @@ dependencies = [
 | 
				
			|||||||
 "winapi-util",
 | 
					 "winapi-util",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "schannel"
 | 
				
			||||||
 | 
					version = "0.1.23"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "windows-sys 0.52.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "scoped-tls"
 | 
					name = "scoped-tls"
 | 
				
			||||||
version = "1.0.1"
 | 
					version = "1.0.1"
 | 
				
			||||||
@@ -2212,6 +2488,29 @@ version = "1.2.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 | 
					checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "security-framework"
 | 
				
			||||||
 | 
					version = "2.11.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bitflags 2.6.0",
 | 
				
			||||||
 | 
					 "core-foundation",
 | 
				
			||||||
 | 
					 "core-foundation-sys",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "security-framework-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "security-framework-sys"
 | 
				
			||||||
 | 
					version = "2.11.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "core-foundation-sys",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "selectors"
 | 
					name = "selectors"
 | 
				
			||||||
version = "0.22.0"
 | 
					version = "0.22.0"
 | 
				
			||||||
@@ -2293,6 +2592,18 @@ dependencies = [
 | 
				
			|||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "serde_urlencoded"
 | 
				
			||||||
 | 
					version = "0.7.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "form_urlencoded",
 | 
				
			||||||
 | 
					 "itoa 1.0.11",
 | 
				
			||||||
 | 
					 "ryu",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde_with"
 | 
					name = "serde_with"
 | 
				
			||||||
version = "3.9.0"
 | 
					version = "3.9.0"
 | 
				
			||||||
@@ -2402,6 +2713,16 @@ version = "1.13.2"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
 | 
					checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "socket2"
 | 
				
			||||||
 | 
					version = "0.5.7"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "windows-sys 0.52.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "soup2"
 | 
					name = "soup2"
 | 
				
			||||||
version = "0.2.1"
 | 
					version = "0.2.1"
 | 
				
			||||||
@@ -2499,6 +2820,33 @@ dependencies = [
 | 
				
			|||||||
 "unicode-ident",
 | 
					 "unicode-ident",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "sync_wrapper"
 | 
				
			||||||
 | 
					version = "0.1.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "system-configuration"
 | 
				
			||||||
 | 
					version = "0.5.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bitflags 1.3.2",
 | 
				
			||||||
 | 
					 "core-foundation",
 | 
				
			||||||
 | 
					 "system-configuration-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "system-configuration-sys"
 | 
				
			||||||
 | 
					version = "0.5.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "core-foundation-sys",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "system-deps"
 | 
					name = "system-deps"
 | 
				
			||||||
version = "5.0.0"
 | 
					version = "5.0.0"
 | 
				
			||||||
@@ -2607,6 +2955,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			|||||||
checksum = "336bc661a3f3250853fa83c6e5245449ed1c26dce5dcb28bdee7efedf6278806"
 | 
					checksum = "336bc661a3f3250853fa83c6e5245449ed1c26dce5dcb28bdee7efedf6278806"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "anyhow",
 | 
					 "anyhow",
 | 
				
			||||||
 | 
					 "base64 0.21.7",
 | 
				
			||||||
 | 
					 "bytes",
 | 
				
			||||||
 "cocoa",
 | 
					 "cocoa",
 | 
				
			||||||
 "dirs-next",
 | 
					 "dirs-next",
 | 
				
			||||||
 "dunce",
 | 
					 "dunce",
 | 
				
			||||||
@@ -2621,11 +2971,15 @@ dependencies = [
 | 
				
			|||||||
 "heck 0.5.0",
 | 
					 "heck 0.5.0",
 | 
				
			||||||
 "http",
 | 
					 "http",
 | 
				
			||||||
 "ignore",
 | 
					 "ignore",
 | 
				
			||||||
 | 
					 "indexmap 1.9.3",
 | 
				
			||||||
 | 
					 "minisign-verify",
 | 
				
			||||||
 "objc",
 | 
					 "objc",
 | 
				
			||||||
 "once_cell",
 | 
					 "once_cell",
 | 
				
			||||||
 "percent-encoding",
 | 
					 "percent-encoding",
 | 
				
			||||||
 "rand 0.8.5",
 | 
					 "rand 0.8.5",
 | 
				
			||||||
 "raw-window-handle",
 | 
					 "raw-window-handle",
 | 
				
			||||||
 | 
					 "reqwest",
 | 
				
			||||||
 | 
					 "rfd",
 | 
				
			||||||
 "semver",
 | 
					 "semver",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
@@ -2639,12 +2993,14 @@ dependencies = [
 | 
				
			|||||||
 "tauri-utils",
 | 
					 "tauri-utils",
 | 
				
			||||||
 "tempfile",
 | 
					 "tempfile",
 | 
				
			||||||
 "thiserror",
 | 
					 "thiserror",
 | 
				
			||||||
 | 
					 "time",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
 "url",
 | 
					 "url",
 | 
				
			||||||
 "uuid",
 | 
					 "uuid",
 | 
				
			||||||
 "webkit2gtk",
 | 
					 "webkit2gtk",
 | 
				
			||||||
 "webview2-com",
 | 
					 "webview2-com",
 | 
				
			||||||
 "windows 0.39.0",
 | 
					 "windows 0.39.0",
 | 
				
			||||||
 | 
					 "zip",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -2899,8 +3255,35 @@ checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df"
 | 
				
			|||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "backtrace",
 | 
					 "backtrace",
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "mio",
 | 
				
			||||||
 "num_cpus",
 | 
					 "num_cpus",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 | 
					 "socket2",
 | 
				
			||||||
 | 
					 "windows-sys 0.48.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "tokio-native-tls"
 | 
				
			||||||
 | 
					version = "0.3.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "native-tls",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "tokio-util"
 | 
				
			||||||
 | 
					version = "0.7.11"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "futures-core",
 | 
				
			||||||
 | 
					 "futures-sink",
 | 
				
			||||||
 | 
					 "pin-project-lite",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -2971,6 +3354,12 @@ dependencies = [
 | 
				
			|||||||
 "winnow 0.6.13",
 | 
					 "winnow 0.6.13",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "tower-service"
 | 
				
			||||||
 | 
					version = "0.3.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tracing"
 | 
					name = "tracing"
 | 
				
			||||||
version = "0.1.40"
 | 
					version = "0.1.40"
 | 
				
			||||||
@@ -3032,6 +3421,12 @@ dependencies = [
 | 
				
			|||||||
 "tracing-log",
 | 
					 "tracing-log",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "try-lock"
 | 
				
			||||||
 | 
					version = "0.2.5"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "typenum"
 | 
					name = "typenum"
 | 
				
			||||||
version = "1.17.0"
 | 
					version = "1.17.0"
 | 
				
			||||||
@@ -3098,6 +3493,12 @@ version = "0.1.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
 | 
					checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "vcpkg"
 | 
				
			||||||
 | 
					version = "0.2.15"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "version-compare"
 | 
					name = "version-compare"
 | 
				
			||||||
version = "0.0.11"
 | 
					version = "0.0.11"
 | 
				
			||||||
@@ -3146,6 +3547,15 @@ dependencies = [
 | 
				
			|||||||
 "winapi-util",
 | 
					 "winapi-util",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "want"
 | 
				
			||||||
 | 
					version = "0.3.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "try-lock",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "wasi"
 | 
					name = "wasi"
 | 
				
			||||||
version = "0.9.0+wasi-snapshot-preview1"
 | 
					version = "0.9.0+wasi-snapshot-preview1"
 | 
				
			||||||
@@ -3183,6 +3593,18 @@ dependencies = [
 | 
				
			|||||||
 "wasm-bindgen-shared",
 | 
					 "wasm-bindgen-shared",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "wasm-bindgen-futures"
 | 
				
			||||||
 | 
					version = "0.4.42"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					 "web-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "wasm-bindgen-macro"
 | 
					name = "wasm-bindgen-macro"
 | 
				
			||||||
version = "0.2.92"
 | 
					version = "0.2.92"
 | 
				
			||||||
@@ -3212,6 +3634,29 @@ version = "0.2.92"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
 | 
					checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "wasm-streams"
 | 
				
			||||||
 | 
					version = "0.4.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "futures-util",
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					 "wasm-bindgen-futures",
 | 
				
			||||||
 | 
					 "web-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "web-sys"
 | 
				
			||||||
 | 
					version = "0.3.69"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "webkit2gtk"
 | 
					name = "webkit2gtk"
 | 
				
			||||||
version = "0.18.2"
 | 
					version = "0.18.2"
 | 
				
			||||||
@@ -3328,6 +3773,19 @@ version = "0.4.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
					checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "windows"
 | 
				
			||||||
 | 
					version = "0.37.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "windows_aarch64_msvc 0.37.0",
 | 
				
			||||||
 | 
					 "windows_i686_gnu 0.37.0",
 | 
				
			||||||
 | 
					 "windows_i686_msvc 0.37.0",
 | 
				
			||||||
 | 
					 "windows_x86_64_gnu 0.37.0",
 | 
				
			||||||
 | 
					 "windows_x86_64_msvc 0.37.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows"
 | 
					name = "windows"
 | 
				
			||||||
version = "0.39.0"
 | 
					version = "0.39.0"
 | 
				
			||||||
@@ -3462,6 +3920,12 @@ version = "0.52.6"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 | 
					checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "windows_aarch64_msvc"
 | 
				
			||||||
 | 
					version = "0.37.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows_aarch64_msvc"
 | 
					name = "windows_aarch64_msvc"
 | 
				
			||||||
version = "0.39.0"
 | 
					version = "0.39.0"
 | 
				
			||||||
@@ -3480,6 +3944,12 @@ version = "0.52.6"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 | 
					checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "windows_i686_gnu"
 | 
				
			||||||
 | 
					version = "0.37.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows_i686_gnu"
 | 
					name = "windows_i686_gnu"
 | 
				
			||||||
version = "0.39.0"
 | 
					version = "0.39.0"
 | 
				
			||||||
@@ -3504,6 +3974,12 @@ version = "0.52.6"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 | 
					checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "windows_i686_msvc"
 | 
				
			||||||
 | 
					version = "0.37.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows_i686_msvc"
 | 
					name = "windows_i686_msvc"
 | 
				
			||||||
version = "0.39.0"
 | 
					version = "0.39.0"
 | 
				
			||||||
@@ -3522,6 +3998,12 @@ version = "0.52.6"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 | 
					checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "windows_x86_64_gnu"
 | 
				
			||||||
 | 
					version = "0.37.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows_x86_64_gnu"
 | 
					name = "windows_x86_64_gnu"
 | 
				
			||||||
version = "0.39.0"
 | 
					version = "0.39.0"
 | 
				
			||||||
@@ -3552,6 +4034,12 @@ version = "0.52.6"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 | 
					checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "windows_x86_64_msvc"
 | 
				
			||||||
 | 
					version = "0.37.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows_x86_64_msvc"
 | 
					name = "windows_x86_64_msvc"
 | 
				
			||||||
version = "0.39.0"
 | 
					version = "0.39.0"
 | 
				
			||||||
@@ -3588,6 +4076,16 @@ dependencies = [
 | 
				
			|||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "winreg"
 | 
				
			||||||
 | 
					version = "0.50.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					 "windows-sys 0.48.0",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "winreg"
 | 
					name = "winreg"
 | 
				
			||||||
version = "0.52.0"
 | 
					version = "0.52.0"
 | 
				
			||||||
@@ -3667,3 +4165,14 @@ dependencies = [
 | 
				
			|||||||
 "linux-raw-sys",
 | 
					 "linux-raw-sys",
 | 
				
			||||||
 "rustix",
 | 
					 "rustix",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "zip"
 | 
				
			||||||
 | 
					version = "0.6.6"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "byteorder",
 | 
				
			||||||
 | 
					 "crc32fast",
 | 
				
			||||||
 | 
					 "crossbeam-utils",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ tauri-build = { version = "1.5.3", features = [] }
 | 
				
			|||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
serde_json = "1.0"
 | 
					serde_json = "1.0"
 | 
				
			||||||
serde = { version = "1.0", features = ["derive"] }
 | 
					serde = { version = "1.0", features = ["derive"] }
 | 
				
			||||||
tauri = { version = "1.7.0", features = [] }
 | 
					tauri = { version = "1.7.0", features = [ "fs-all", "path-all", "updater"] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[features]
 | 
					[features]
 | 
				
			||||||
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
 | 
					# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,11 +8,26 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "package": {
 | 
					  "package": {
 | 
				
			||||||
    "productName": "domino-client",
 | 
					    "productName": "domino-client",
 | 
				
			||||||
    "version": "0.1.8"
 | 
					    "version": "0.1.11"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "tauri": {
 | 
					  "tauri": {
 | 
				
			||||||
    "allowlist": {
 | 
					    "allowlist": {
 | 
				
			||||||
      "all": false
 | 
					      "path": {
 | 
				
			||||||
 | 
					        "all": true
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "fs": {
 | 
				
			||||||
 | 
					        "copyFile": true,
 | 
				
			||||||
 | 
					        "createDir": true,
 | 
				
			||||||
 | 
					        "exists": true,
 | 
				
			||||||
 | 
					        "readDir": true,
 | 
				
			||||||
 | 
					        "readFile": true,
 | 
				
			||||||
 | 
					        "removeDir": true,
 | 
				
			||||||
 | 
					        "removeFile": true,
 | 
				
			||||||
 | 
					        "renameFile": true,
 | 
				
			||||||
 | 
					        "scope": ["$APPDATA/*", "$APP/*"],
 | 
				
			||||||
 | 
					        "writeFile": true,
 | 
				
			||||||
 | 
					        "all": true
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "bundle": {
 | 
					    "bundle": {
 | 
				
			||||||
      "active": true,
 | 
					      "active": true,
 | 
				
			||||||
@@ -51,14 +66,19 @@
 | 
				
			|||||||
      "csp": null
 | 
					      "csp": null
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "updater": {
 | 
					    "updater": {
 | 
				
			||||||
      "active": false
 | 
					      "active": true,
 | 
				
			||||||
 | 
					      "dialog": true,
 | 
				
			||||||
 | 
					      "endpoints": [
 | 
				
			||||||
 | 
					        "https://domserv.xintanalabs.net/api/updater/{{target}}/{{arch}}/{{current_version}}"
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDQwRTBDNUU1QzIyNEYzQUQKUldTdDh5VEM1Y1hnUVA2M01pcEZMbVltVUpuMlhpN09Rc3BnN1A3NC9BOGs5OE92MndRZzVXSm4K"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "windows": [
 | 
					    "windows": [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        "fullscreen": false,
 | 
					        "fullscreen": false,
 | 
				
			||||||
        "height": 720,
 | 
					        "height": 720,
 | 
				
			||||||
        "resizable": true,
 | 
					        "resizable": true,
 | 
				
			||||||
        "title": "Domino",
 | 
					        "title": "Domino v0.1.11",
 | 
				
			||||||
        "width": 1280,
 | 
					        "width": 1280,
 | 
				
			||||||
        "minHeight": 720,
 | 
					        "minHeight": 720,
 | 
				
			||||||
        "minWidth": 1280,
 | 
					        "minWidth": 1280,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,8 +57,6 @@ onUnmounted(() => {
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template><RouterView /></template>
 | 
				
			||||||
  <RouterView />
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style scoped></style>
 | 
					<style scoped></style>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -111,3 +111,34 @@ export function copyToclipboard(value: string) {
 | 
				
			|||||||
  const { toClipboard } = useClipboard()
 | 
					  const { toClipboard } = useClipboard()
 | 
				
			||||||
  toClipboard(value)
 | 
					  toClipboard(value)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function transposeMatrix(matrix: any[][]): any[][] {
 | 
				
			||||||
 | 
					  // Get the number of rows and columns
 | 
				
			||||||
 | 
					  const numRows = matrix.length
 | 
				
			||||||
 | 
					  const numCols = matrix[0].length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create a new matrix with transposed dimensions
 | 
				
			||||||
 | 
					  const transposed = Array.from({ length: numCols }, () => Array(numRows).fill(null))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Transpose the matrix
 | 
				
			||||||
 | 
					  for (let row = 0; row < numRows; row++) {
 | 
				
			||||||
 | 
					    for (let col = 0; col < numCols; col++) {
 | 
				
			||||||
 | 
					      transposed[col][row] = matrix[row][col]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return transposed
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function createStringMatrix(
 | 
				
			||||||
 | 
					  rows: number,
 | 
				
			||||||
 | 
					  cols: number,
 | 
				
			||||||
 | 
					  initialValue: string = '',
 | 
				
			||||||
 | 
					): string[][] {
 | 
				
			||||||
 | 
					  // Create an array of arrays (matrix)
 | 
				
			||||||
 | 
					  const matrix: string[][] = Array.from({ length: rows }, () =>
 | 
				
			||||||
 | 
					    Array.from({ length: cols }, () => initialValue),
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return matrix
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import type { MatchSessionOptions } from '@/common/interfaces'
 | 
					import type { MatchSessionOptions } from '@/common/interfaces'
 | 
				
			||||||
import { ref } from 'vue'
 | 
					import { computed, ref } from 'vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const emit = defineEmits(['createMatch'])
 | 
					const emit = defineEmits(['createMatch', 'startSingleMatch'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let options = ref<MatchSessionOptions>({
 | 
					let options = ref<MatchSessionOptions>({
 | 
				
			||||||
  background: 'green',
 | 
					  background: 'green',
 | 
				
			||||||
@@ -14,9 +14,42 @@ let options = ref<MatchSessionOptions>({
 | 
				
			|||||||
  numPlayers: 1,
 | 
					  numPlayers: 1,
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const winTargetPointsList = [20, 50, 80, 100, 150, 200]
 | 
				
			||||||
 | 
					const winTargetRoundsList = [1, 2, 3, 4, 5, 6]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const backgroundOptiopnList = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'green-fabric',
 | 
				
			||||||
 | 
					    value: 'green',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'gray-fabric',
 | 
				
			||||||
 | 
					    value: 'gray',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'blue-fabric',
 | 
				
			||||||
 | 
					    value: 'blue',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'yellow-fabric',
 | 
				
			||||||
 | 
					    value: 'yellow',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: 'red-fabric',
 | 
				
			||||||
 | 
					    value: 'red',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const isSinglePlayer = computed(() => options.value.numPlayers === 1)
 | 
				
			||||||
 | 
					const isMultiPlayer = computed(() => options.value.numPlayers > 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createMatch() {
 | 
					function createMatch() {
 | 
				
			||||||
  emit('createMatch', options.value)
 | 
					  emit('createMatch', options.value)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function startSingleMatch() {
 | 
				
			||||||
 | 
					  emit('startSingleMatch', options.value)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
@@ -29,7 +62,7 @@ function createMatch() {
 | 
				
			|||||||
            <div class="buttons has-addons">
 | 
					            <div class="buttons has-addons">
 | 
				
			||||||
              <button
 | 
					              <button
 | 
				
			||||||
                class="button"
 | 
					                class="button"
 | 
				
			||||||
                :class="{ 'is-primary is-selected': options.numPlayers === 1 }"
 | 
					                :class="{ 'is-primary is-selected': isSinglePlayer }"
 | 
				
			||||||
                @click="
 | 
					                @click="
 | 
				
			||||||
                  () => {
 | 
					                  () => {
 | 
				
			||||||
                    console.log('options :>> ', options)
 | 
					                    console.log('options :>> ', options)
 | 
				
			||||||
@@ -41,7 +74,7 @@ function createMatch() {
 | 
				
			|||||||
              </button>
 | 
					              </button>
 | 
				
			||||||
              <button
 | 
					              <button
 | 
				
			||||||
                class="button"
 | 
					                class="button"
 | 
				
			||||||
                :class="{ 'is-primary is-selected': options.numPlayers > 1 }"
 | 
					                :class="{ 'is-primary is-selected': isMultiPlayer }"
 | 
				
			||||||
                @click="
 | 
					                @click="
 | 
				
			||||||
                  () => {
 | 
					                  () => {
 | 
				
			||||||
                    console.log('options :>> ', options)
 | 
					                    console.log('options :>> ', options)
 | 
				
			||||||
@@ -56,7 +89,7 @@ function createMatch() {
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="cell">
 | 
					      <div class="cell">
 | 
				
			||||||
        <div class="field" v-if="options.numPlayers > 1">
 | 
					        <div class="field" v-if="isMultiPlayer">
 | 
				
			||||||
          <label class="label">{{ $t('players-number') }}</label>
 | 
					          <label class="label">{{ $t('players-number') }}</label>
 | 
				
			||||||
          <div class="control">
 | 
					          <div class="control">
 | 
				
			||||||
            <div class="buttons has-addons">
 | 
					            <div class="buttons has-addons">
 | 
				
			||||||
@@ -80,7 +113,7 @@ function createMatch() {
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="cell">
 | 
					      <div class="cell">
 | 
				
			||||||
        <div class="field" v-if="options.numPlayers > 1">
 | 
					        <div class="field" v-if="isMultiPlayer">
 | 
				
			||||||
          <div class="control">
 | 
					          <div class="control">
 | 
				
			||||||
            <label for="teamed" class="checkbox">
 | 
					            <label for="teamed" class="checkbox">
 | 
				
			||||||
              <input v-model="options.teamed" name="teamed" type="checkbox" />
 | 
					              <input v-model="options.teamed" name="teamed" type="checkbox" />
 | 
				
			||||||
@@ -128,12 +161,13 @@ function createMatch() {
 | 
				
			|||||||
          <div class="control">
 | 
					          <div class="control">
 | 
				
			||||||
            <div class="select">
 | 
					            <div class="select">
 | 
				
			||||||
              <select v-model="options.background" name="background">
 | 
					              <select v-model="options.background" name="background">
 | 
				
			||||||
                <option value="wood-1">{{ $t('wood-1') }}</option>
 | 
					                <option
 | 
				
			||||||
                <option value="green">{{ $t('green-fabric') }}</option>
 | 
					                  v-bind:key="option.value"
 | 
				
			||||||
                <option value="gray">{{ $t('gray-fabric') }}</option>
 | 
					                  v-for="option in backgroundOptiopnList"
 | 
				
			||||||
                <option value="blue">{{ $t('blue-fabric') }}</option>
 | 
					                  :value="option.value"
 | 
				
			||||||
                <option value="yellow">{{ $t('yellow-fabric') }}</option>
 | 
					                >
 | 
				
			||||||
                <option value="red">{{ $t('red-fabric') }}</option>
 | 
					                  {{ $t(option.label) }}
 | 
				
			||||||
 | 
					                </option>
 | 
				
			||||||
              </select>
 | 
					              </select>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
@@ -178,22 +212,24 @@ function createMatch() {
 | 
				
			|||||||
          <div class="control">
 | 
					          <div class="control">
 | 
				
			||||||
            <div class="select" v-if="options.winType === 'points'">
 | 
					            <div class="select" v-if="options.winType === 'points'">
 | 
				
			||||||
              <select v-model="options.winTarget" name="winTarget">
 | 
					              <select v-model="options.winTarget" name="winTarget">
 | 
				
			||||||
                <option value="20">{{ $t('n-points', [20]) }}</option>
 | 
					                <option
 | 
				
			||||||
                <option value="50">{{ $t('n-points', [50]) }}</option>
 | 
					                  v-bind:key="winTarget"
 | 
				
			||||||
                <option value="80">{{ $t('n-points', [80]) }}</option>
 | 
					                  v-for="winTarget in winTargetPointsList"
 | 
				
			||||||
                <option value="100">{{ $t('n-points', [100]) }}</option>
 | 
					                  :value="winTarget"
 | 
				
			||||||
                <option value="150">{{ $t('n-points', [150]) }}</option>
 | 
					                >
 | 
				
			||||||
                <option value="200">{{ $t('n-points', [200]) }}</option>
 | 
					                  {{ $t('n-points', winTarget) }}
 | 
				
			||||||
 | 
					                </option>
 | 
				
			||||||
              </select>
 | 
					              </select>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div class="select" v-if="options.winType === 'rounds'">
 | 
					            <div class="select" v-if="options.winType === 'rounds'">
 | 
				
			||||||
              <select v-model="options.winTarget" name="winTarget">
 | 
					              <select v-model="options.winTarget" name="winTarget">
 | 
				
			||||||
                <option value="1">{{ $t('n-of-m-rounds', [1, 1]) }}</option>
 | 
					                <option
 | 
				
			||||||
                <option value="2">{{ $t('n-of-m-rounds', [2, 3]) }}</option>
 | 
					                  v-bind:key="winTarget"
 | 
				
			||||||
                <option value="3">{{ $t('n-of-m-rounds', [3, 5]) }}</option>
 | 
					                  v-for="winTarget in winTargetRoundsList"
 | 
				
			||||||
                <option value="4">{{ $t('n-of-m-rounds', [4, 7]) }}</option>
 | 
					                  :value="winTarget"
 | 
				
			||||||
                <option value="5">{{ $t('n-of-m-rounds', [5, 9]) }}</option>
 | 
					                >
 | 
				
			||||||
                <option value="6">{{ $t('n-of-m-rounds', [6, 11]) }}</option>
 | 
					                  {{ $t('n-of-m-rounds', [winTarget, winTarget * 2 - 1]) }}
 | 
				
			||||||
 | 
					                </option>
 | 
				
			||||||
              </select>
 | 
					              </select>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
@@ -201,9 +237,12 @@ function createMatch() {
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="buttons mt-6">
 | 
					    <div class="buttons mt-6">
 | 
				
			||||||
      <button class="button is-primary" @click.prevent="createMatch">
 | 
					      <button class="button is-primary" @click.prevent="createMatch" v-if="isMultiPlayer">
 | 
				
			||||||
        {{ $t('create-match-session') }}
 | 
					        {{ $t('create-match-session') }}
 | 
				
			||||||
      </button>
 | 
					      </button>
 | 
				
			||||||
 | 
					      <button class="button is-primary" @click.prevent="startSingleMatch" v-if="isSinglePlayer">
 | 
				
			||||||
 | 
					        {{ $t('start-game') }}
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								src/components/ScoreboardComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/components/ScoreboardComponent.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <h3 class="title is-5">{{ title }}</h3>
 | 
				
			||||||
 | 
					  <div v-if="scoreboard">
 | 
				
			||||||
 | 
					    <div v-bind:key="$index" v-for="(score, $index) in sortedScoreboard">
 | 
				
			||||||
 | 
					      <p class="">
 | 
				
			||||||
 | 
					        <span class="title is-5">{{ score.name }}</span>
 | 
				
			||||||
 | 
					        <span class="is-size-5 ml-4">{{ score.score }}</span>
 | 
				
			||||||
 | 
					      </p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { computed } from 'vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { title, scoreboard } = defineProps(['scoreboard', 'title'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const sortedScoreboard = computed(() => {
 | 
				
			||||||
 | 
					  const copy = [...(scoreboard || [])]
 | 
				
			||||||
 | 
					  return copy.sort((a, b) => b.score - a.score)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped></style>
 | 
				
			||||||
							
								
								
									
										77
									
								
								src/components/ScoreboardTableComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/components/ScoreboardTableComponent.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { createStringMatrix } from '@/common/helpers'
 | 
				
			||||||
 | 
					import { computed } from 'vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps(['games', 'finalScore', 'winner'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const playerNames = computed<any[]>(() =>
 | 
				
			||||||
 | 
					  (props.finalScore || []).map((score: any) => {
 | 
				
			||||||
 | 
					    const type = score.name === props.winner.name ? 'winner-name' : 'name'
 | 
				
			||||||
 | 
					    return { type, value: score.name }
 | 
				
			||||||
 | 
					  }),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					const totals = computed<any[]>(() =>
 | 
				
			||||||
 | 
					  props.finalScore.map((score: any) => {
 | 
				
			||||||
 | 
					    const type = score.name === props.winner.name ? 'winner-final-score' : 'final-score'
 | 
				
			||||||
 | 
					    return { type, value: `${score.score}` }
 | 
				
			||||||
 | 
					  }),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					const matrix = computed<any[][]>(() => {
 | 
				
			||||||
 | 
					  if (props.games === undefined) {
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const m = props.games.map((game: any) => {
 | 
				
			||||||
 | 
					    const winner = game.winner.name
 | 
				
			||||||
 | 
					    return game.players.map((player: any) => {
 | 
				
			||||||
 | 
					      const type = player.name === winner ? 'winner-score' : 'score'
 | 
				
			||||||
 | 
					      return { type, value: `${player.score}` }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  m.unshift(playerNames.value)
 | 
				
			||||||
 | 
					  m.push(totals.value)
 | 
				
			||||||
 | 
					  const rows = m.length
 | 
				
			||||||
 | 
					  const cols = m[0].length
 | 
				
			||||||
 | 
					  const t: any[][] = createStringMatrix(cols, rows)
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    for (let row = 0; row < m.length; row++) {
 | 
				
			||||||
 | 
					      for (let col = 0; col < m[0].length; col++) {
 | 
				
			||||||
 | 
					        t[col][row] = m[row][col]
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.error('error :>> ', error)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return t
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getCellClasses(value: any) {
 | 
				
			||||||
 | 
					  const { type } = value
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    'has-text-weight-bold':
 | 
				
			||||||
 | 
					      type === 'name' ||
 | 
				
			||||||
 | 
					      type === 'final-score' ||
 | 
				
			||||||
 | 
					      type === 'winner-final-score' ||
 | 
				
			||||||
 | 
					      type === 'winner-name',
 | 
				
			||||||
 | 
					    'has-text-primary':
 | 
				
			||||||
 | 
					      type === 'winner-score' || type === 'winner-name' || type === 'winner-final-score',
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <table class="table is-striped is-fullwidth is-hoverable">
 | 
				
			||||||
 | 
					    <thead>
 | 
				
			||||||
 | 
					      <th>{{ $t('player') }}</th>
 | 
				
			||||||
 | 
					      <th v-for="(game, $index) in games" :key="game">{{ $t('round-index', [$index]) }}</th>
 | 
				
			||||||
 | 
					      <th>{{ $t('final-score') }}</th>
 | 
				
			||||||
 | 
					    </thead>
 | 
				
			||||||
 | 
					    <tbody>
 | 
				
			||||||
 | 
					      <tr v-for="(row, $index) in matrix" :key="$index">
 | 
				
			||||||
 | 
					        <td :class="getCellClasses(col)" v-for="(col, $index) in row" :key="$index">
 | 
				
			||||||
 | 
					          {{ col.value }}
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					      </tr>
 | 
				
			||||||
 | 
					    </tbody>
 | 
				
			||||||
 | 
					  </table>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped></style>
 | 
				
			||||||
@@ -1,24 +1,33 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import { useRouter } from 'vue-router'
 | 
					import { useRouter } from 'vue-router'
 | 
				
			||||||
import { RouterLink, RouterView } from 'vue-router'
 | 
					import { RouterView } from 'vue-router'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = useRouter()
 | 
					const router = useRouter()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					  navbar: Boolean,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
  name: 'AuthenticatedLayout'
 | 
					  name: 'AuthenticatedLayout',
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function logout() {
 | 
					function logout() {
 | 
				
			||||||
  localStorage.removeItem('isLoggedIn')
 | 
					 | 
				
			||||||
  router.push({ name: 'landing' })
 | 
					  router.push({ name: 'landing' })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="authenticated-layout">
 | 
					  <div class="authenticated-layout">
 | 
				
			||||||
    <header>
 | 
					    <header v-if="props.navbar">
 | 
				
			||||||
      <nav>
 | 
					      <nav class="navbar">
 | 
				
			||||||
        <!-- <button @click="logout">Logout</button> -->
 | 
					        <div class="navbar-end">
 | 
				
			||||||
 | 
					          <div class="navbar-item">
 | 
				
			||||||
 | 
					            <div class="buttons">
 | 
				
			||||||
 | 
					              <button class="button is-primary" @click="logout">Logout</button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
      </nav>
 | 
					      </nav>
 | 
				
			||||||
    </header>
 | 
					    </header>
 | 
				
			||||||
    <main>
 | 
					    <main>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -162,6 +162,7 @@ export class Board extends EventEmitter {
 | 
				
			|||||||
      this.nextTile = tile
 | 
					      this.nextTile = tile
 | 
				
			||||||
      lastMove.tile = tile.toPlain()
 | 
					      lastMove.tile = tile.toPlain()
 | 
				
			||||||
      this.movements.push(lastMove)
 | 
					      this.movements.push(lastMove)
 | 
				
			||||||
 | 
					      console.log('this.movements :>> ', this.movements)
 | 
				
			||||||
      await this.addTile(tile, lastMove)
 | 
					      await this.addTile(tile, lastMove)
 | 
				
			||||||
      this.setFreeEnd(lastMove)
 | 
					      this.setFreeEnd(lastMove)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,14 +17,8 @@ import { Actions } from 'pixi-actions'
 | 
				
			|||||||
import { OtherHand } from './OtherHand'
 | 
					import { OtherHand } from './OtherHand'
 | 
				
			||||||
import { GameSummayView } from './GameSummayView'
 | 
					import { GameSummayView } from './GameSummayView'
 | 
				
			||||||
import Config from './Config'
 | 
					import Config from './Config'
 | 
				
			||||||
 | 
					import { createText, grayStyle } from './utilities/fonts'
 | 
				
			||||||
interface GameOptions {
 | 
					import { t } from '@/i18n'
 | 
				
			||||||
  boardScale: number
 | 
					 | 
				
			||||||
  handScale: number
 | 
					 | 
				
			||||||
  width: number
 | 
					 | 
				
			||||||
  height: number
 | 
					 | 
				
			||||||
  background: string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Game extends EventEmitter {
 | 
					export class Game extends EventEmitter {
 | 
				
			||||||
  public board!: Board
 | 
					  public board!: Board
 | 
				
			||||||
@@ -91,6 +85,25 @@ export class Game extends EventEmitter {
 | 
				
			|||||||
    const background = new TilingSprite(Assets.get(`bg-${this.options.background}`))
 | 
					    const background = new TilingSprite(Assets.get(`bg-${this.options.background}`))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.backgroundLayer.addChild(background)
 | 
					    this.backgroundLayer.addChild(background)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const actor = this.options.teamed ? t('team') : t('player')
 | 
				
			||||||
 | 
					    const type =
 | 
				
			||||||
 | 
					      this.options.winType === 'points'
 | 
				
			||||||
 | 
					        ? t('n-points', this.options.winTarget)
 | 
				
			||||||
 | 
					        : t('n-rounds', this.options.winTarget)
 | 
				
			||||||
 | 
					    const helptext = t('first-actor-to-win-this-options-wintarget-this-options-wintype', [
 | 
				
			||||||
 | 
					      actor.toLowerCase(),
 | 
				
			||||||
 | 
					      type.toLowerCase(),
 | 
				
			||||||
 | 
					    ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.backgroundLayer.addChild(
 | 
				
			||||||
 | 
					      createText({
 | 
				
			||||||
 | 
					        text: `${helptext}`,
 | 
				
			||||||
 | 
					        x: this.app.canvas.width / 2,
 | 
				
			||||||
 | 
					        y: 120,
 | 
				
			||||||
 | 
					        style: grayStyle(14, 'lighter', false),
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  initPlayers(players: PlayerDto[]) {
 | 
					  initPlayers(players: PlayerDto[]) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ import { createButton, createContainer } from '@/common/helpers'
 | 
				
			|||||||
import type { GameSummary, MatchSessionDto, MatchSessionOptions } 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'
 | 
				
			||||||
 | 
					import { t } from '@/i18n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class GameSummayView extends EventEmitter {
 | 
					export class GameSummayView extends EventEmitter {
 | 
				
			||||||
  public width: number
 | 
					  public width: number
 | 
				
			||||||
@@ -59,7 +60,7 @@ export class GameSummayView extends EventEmitter {
 | 
				
			|||||||
    let line = y + 12
 | 
					    let line = y + 12
 | 
				
			||||||
    this.layer.addChild(
 | 
					    this.layer.addChild(
 | 
				
			||||||
      createText({
 | 
					      createText({
 | 
				
			||||||
        text: `Winner: ${this.gameSummary.winner.name}`,
 | 
					        text: t('winner-name', [this.gameSummary.winner.name]),
 | 
				
			||||||
        x: this.width / 2,
 | 
					        x: this.width / 2,
 | 
				
			||||||
        y: line,
 | 
					        y: line,
 | 
				
			||||||
        style: whiteStyle(20),
 | 
					        style: whiteStyle(20),
 | 
				
			||||||
@@ -70,7 +71,7 @@ export class GameSummayView extends EventEmitter {
 | 
				
			|||||||
      line += 30
 | 
					      line += 30
 | 
				
			||||||
      this.layer.addChild(
 | 
					      this.layer.addChild(
 | 
				
			||||||
        createText({
 | 
					        createText({
 | 
				
			||||||
          text: '(Blocked)',
 | 
					          text: `(${t('blocked')})`,
 | 
				
			||||||
          x: this.width / 2,
 | 
					          x: this.width / 2,
 | 
				
			||||||
          y: line,
 | 
					          y: line,
 | 
				
			||||||
          style: whiteStyle(),
 | 
					          style: whiteStyle(),
 | 
				
			||||||
@@ -78,15 +79,29 @@ export class GameSummayView extends EventEmitter {
 | 
				
			|||||||
      )
 | 
					      )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    line += 30
 | 
					    if (this.options.winType === 'points') {
 | 
				
			||||||
    this.layer.addChild(
 | 
					      line += 30
 | 
				
			||||||
      createText({
 | 
					      this.layer.addChild(
 | 
				
			||||||
        text: `Points this round: ${this.gameSummary.winner.score}`,
 | 
					        createText({
 | 
				
			||||||
        x: this.width / 2,
 | 
					          text: `Points this round: ${this.gameSummary.winner.score}`,
 | 
				
			||||||
        y: line,
 | 
					          // text: `Points this round: ${this.gameSummary.winner.score}, needed to win: ${this.options.winTarget}`,
 | 
				
			||||||
        style: whiteStyle(20),
 | 
					          x: this.width / 2,
 | 
				
			||||||
      }),
 | 
					          y: line,
 | 
				
			||||||
    )
 | 
					          style: whiteStyle(20),
 | 
				
			||||||
 | 
					        }),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // } else if (this.options.winType === 'rounds') {
 | 
				
			||||||
 | 
					    //   line += 30
 | 
				
			||||||
 | 
					    //   this.layer.addChild(
 | 
				
			||||||
 | 
					    //     createText({
 | 
				
			||||||
 | 
					    //       text: `Rounds needed to win: ${this.options.winTarget}`,
 | 
				
			||||||
 | 
					    //       x: this.width / 2,
 | 
				
			||||||
 | 
					    //       y: line,
 | 
				
			||||||
 | 
					    //       style: whiteStyle(20),
 | 
				
			||||||
 | 
					    //     }),
 | 
				
			||||||
 | 
					    //   )
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
    return line + 16
 | 
					    return line + 16
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -159,7 +174,7 @@ export class GameSummayView extends EventEmitter {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render() {
 | 
					  render() {
 | 
				
			||||||
    const title: string = this.type === 'round' ? 'Round Summary' : 'Match Finished!'
 | 
					    const title: string = this.type === 'round' ? t('round-summary') : t('match-finished')
 | 
				
			||||||
    this.layer.removeChildren()
 | 
					    this.layer.removeChildren()
 | 
				
			||||||
    let y = this.renderTitle(30, title.toUpperCase())
 | 
					    let y = this.renderTitle(30, title.toUpperCase())
 | 
				
			||||||
    y = this.renderWinner(y)
 | 
					    y = this.renderWinner(y)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,19 +57,19 @@ export const scoreText = new TextStyle({
 | 
				
			|||||||
function getStyle(styleOptions: TextStyleOptions = {}) {
 | 
					function getStyle(styleOptions: TextStyleOptions = {}) {
 | 
				
			||||||
  const {
 | 
					  const {
 | 
				
			||||||
    fill = 0xa2a2a2,
 | 
					    fill = 0xa2a2a2,
 | 
				
			||||||
    stroke = 0x565656,
 | 
					 | 
				
			||||||
    fontSize = 15,
 | 
					    fontSize = 15,
 | 
				
			||||||
    fontFamily = 'Arial, Helvetica, sans-serif',
 | 
					    fontFamily = 'Arial, Helvetica, sans-serif',
 | 
				
			||||||
    fontWeight = 'normal',
 | 
					    fontWeight = 'normal',
 | 
				
			||||||
    fontStyle = 'normal',
 | 
					    fontStyle = 'normal',
 | 
				
			||||||
    dropShadow,
 | 
					    dropShadow,
 | 
				
			||||||
    letterSpacing = 1,
 | 
					    letterSpacing = 1,
 | 
				
			||||||
 | 
					    stroke,
 | 
				
			||||||
  } = styleOptions
 | 
					  } = styleOptions
 | 
				
			||||||
  const style = new TextStyle({
 | 
					  const style = new TextStyle({
 | 
				
			||||||
    fill,
 | 
					    fill,
 | 
				
			||||||
    fontFamily,
 | 
					    fontFamily,
 | 
				
			||||||
    letterSpacing,
 | 
					    letterSpacing,
 | 
				
			||||||
    stroke,
 | 
					    stroke: stroke ? stroke : undefined,
 | 
				
			||||||
    fontSize,
 | 
					    fontSize,
 | 
				
			||||||
    fontStyle,
 | 
					    fontStyle,
 | 
				
			||||||
    fontWeight: fontWeight as any,
 | 
					    fontWeight: fontWeight as any,
 | 
				
			||||||
@@ -78,6 +78,20 @@ function getStyle(styleOptions: TextStyleOptions = {}) {
 | 
				
			|||||||
  return style
 | 
					  return style
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const styleFactory = (fill: number) => {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    fontSize: number = 15,
 | 
				
			||||||
 | 
					    fontWeight: TextStyleFontWeight = 'normal',
 | 
				
			||||||
 | 
					    dropShadow: boolean = false,
 | 
				
			||||||
 | 
					  ) =>
 | 
				
			||||||
 | 
					    getStyle({
 | 
				
			||||||
 | 
					      fill,
 | 
				
			||||||
 | 
					      fontSize,
 | 
				
			||||||
 | 
					      fontWeight,
 | 
				
			||||||
 | 
					      dropShadow,
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const whiteStyle = (
 | 
					export const whiteStyle = (
 | 
				
			||||||
  fontSize: number = 15,
 | 
					  fontSize: number = 15,
 | 
				
			||||||
  fontWeight: TextStyleFontWeight = 'normal',
 | 
					  fontWeight: TextStyleFontWeight = 'normal',
 | 
				
			||||||
@@ -101,6 +115,8 @@ export const yellowStyle = (
 | 
				
			|||||||
    dropShadow,
 | 
					    dropShadow,
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const grayStyle = styleFactory(0x444444)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface TextOptions {
 | 
					interface TextOptions {
 | 
				
			||||||
  text: string
 | 
					  text: string
 | 
				
			||||||
  x: number
 | 
					  x: number
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,9 +55,20 @@
 | 
				
			|||||||
  "win-type": "Win unit",
 | 
					  "win-type": "Win unit",
 | 
				
			||||||
  "points": "Points",
 | 
					  "points": "Points",
 | 
				
			||||||
  "rounds": "Rounds",
 | 
					  "rounds": "Rounds",
 | 
				
			||||||
  "n-points": "{value} Points",
 | 
					  "n-points": "{count} Points",
 | 
				
			||||||
 | 
					  "n-rounds": "One Round|{count} Rounds",
 | 
				
			||||||
  "n-of-m-rounds": "{0} of {1} Rounds",
 | 
					  "n-of-m-rounds": "{0} of {1} Rounds",
 | 
				
			||||||
  "create-session": "Create Session",
 | 
					  "create-session": "Create Session",
 | 
				
			||||||
  "join-a-multiplayer-session": "Join a Multiplayer Session",
 | 
					  "join-a-multiplayer-session": "Join a Multiplayer Session (No sessions)|Join a Multiplayer Session ({count})|Join a Multiplayer Session ({count})",
 | 
				
			||||||
  "tournaments": "Tournaments"
 | 
					  "tournaments": "Tournaments",
 | 
				
			||||||
 | 
					  "start-game": "Start Game",
 | 
				
			||||||
 | 
					  "player": "Player",
 | 
				
			||||||
 | 
					  "final-score": "Final Score",
 | 
				
			||||||
 | 
					  "round-index": "Round #{0}",
 | 
				
			||||||
 | 
					  "first-actor-to-win-this-options-wintarget-this-options-wintype": "First {0} to win {1}",
 | 
				
			||||||
 | 
					  "team": "team",
 | 
				
			||||||
 | 
					  "winner-name": "Winner: {0}",
 | 
				
			||||||
 | 
					  "blocked": "Blocked",
 | 
				
			||||||
 | 
					  "round-summary": "Round Summary",
 | 
				
			||||||
 | 
					  "match-finished": "Match Finished"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,9 +55,20 @@
 | 
				
			|||||||
  "win-type": "Unidad de puntaje",
 | 
					  "win-type": "Unidad de puntaje",
 | 
				
			||||||
  "points": "Puntos",
 | 
					  "points": "Puntos",
 | 
				
			||||||
  "rounds": "Rondas",
 | 
					  "rounds": "Rondas",
 | 
				
			||||||
  "n-points": "{0} puntos",
 | 
					  "n-points": "{count} puntos",
 | 
				
			||||||
  "n-of-m-rounds": "{0} de {1} rondas",
 | 
					  "n-of-m-rounds": "{0} de {1} rondas",
 | 
				
			||||||
  "create-session": "Crear sesión",
 | 
					  "create-session": "Crear sesión",
 | 
				
			||||||
  "join-a-multiplayer-session": "Únete a una sesión multijugador",
 | 
					  "join-a-multiplayer-session": "Únete a una sesión multijugador|Únete a una sesión multijugador ({count})|Únete a una sesión multijugador ({count})",
 | 
				
			||||||
  "tournaments": "Torneos"
 | 
					  "tournaments": "Torneos",
 | 
				
			||||||
 | 
					  "start-game": "Empezar la partida",
 | 
				
			||||||
 | 
					  "player": "Jugador",
 | 
				
			||||||
 | 
					  "final-score": "Puntuación final",
 | 
				
			||||||
 | 
					  "round-index": "Juego #{0}",
 | 
				
			||||||
 | 
					  "first-actor-to-win-this-options-wintarget-this-options-wintype": "Primer {0} en ganar {1}",
 | 
				
			||||||
 | 
					  "n-rounds": "Una ronda|{count} rondas",
 | 
				
			||||||
 | 
					  "winner-name": "Ganador: {0}",
 | 
				
			||||||
 | 
					  "blocked": "Cerrado",
 | 
				
			||||||
 | 
					  "round-summary": "Resumen de la ronda",
 | 
				
			||||||
 | 
					  "match-finished": "Partida terminado",
 | 
				
			||||||
 | 
					  "team": "equipo"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ import { SocketIoClientService } from '@/services/SocketIoClientService'
 | 
				
			|||||||
import { LoggingService } from '@/services/LoggingService'
 | 
					import { LoggingService } from '@/services/LoggingService'
 | 
				
			||||||
import { AuthenticationService } from './services/AuthenticationService'
 | 
					import { AuthenticationService } from './services/AuthenticationService'
 | 
				
			||||||
import { GameService } from './services/GameService'
 | 
					import { GameService } from './services/GameService'
 | 
				
			||||||
 | 
					import { PersistenceService } from './services/PersistenceService'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const app = createApp(App)
 | 
					const app = createApp(App)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,5 +24,6 @@ app.provide('socket', new SocketIoClientService(import.meta.env.VITE_SOCKET_URL)
 | 
				
			|||||||
app.provide('logger', new LoggingService())
 | 
					app.provide('logger', new LoggingService())
 | 
				
			||||||
app.provide('auth', new AuthenticationService())
 | 
					app.provide('auth', new AuthenticationService())
 | 
				
			||||||
app.provide('game', new GameService())
 | 
					app.provide('game', new GameService())
 | 
				
			||||||
 | 
					PersistenceService.getInstance()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.mount('#app')
 | 
					app.mount('#app')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,9 @@ import AuthenticatedLayout from '@/components/layouts/AuthenticatedLayout.vue'
 | 
				
			|||||||
import UnauthenticatedLayout from '@/components/layouts/UnauthenticatedLayout.vue'
 | 
					import UnauthenticatedLayout from '@/components/layouts/UnauthenticatedLayout.vue'
 | 
				
			||||||
import HomeView from '@/views/HomeView.vue'
 | 
					import HomeView from '@/views/HomeView.vue'
 | 
				
			||||||
import LandingView from '@/views/LandingView.vue'
 | 
					import LandingView from '@/views/LandingView.vue'
 | 
				
			||||||
 | 
					import { PersistenceService } from '@/services/PersistenceService'
 | 
				
			||||||
 | 
					import { useAuthStore } from '@/stores/auth'
 | 
				
			||||||
 | 
					import { storeToRefs } from 'pinia'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = createRouter({
 | 
					const router = createRouter({
 | 
				
			||||||
  history: createWebHistory(import.meta.env.BASE_URL),
 | 
					  history: createWebHistory(import.meta.env.BASE_URL),
 | 
				
			||||||
@@ -19,6 +22,7 @@ const router = createRouter({
 | 
				
			|||||||
      ],
 | 
					      ],
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      props: { navbar: true },
 | 
				
			||||||
      path: '/home',
 | 
					      path: '/home',
 | 
				
			||||||
      component: AuthenticatedLayout,
 | 
					      component: AuthenticatedLayout,
 | 
				
			||||||
      children: [
 | 
					      children: [
 | 
				
			||||||
@@ -37,6 +41,7 @@ const router = createRouter({
 | 
				
			|||||||
      // component: () => import('../views/AboutView.vue')
 | 
					      // component: () => import('../views/AboutView.vue')
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      props: { navbar: true },
 | 
				
			||||||
      path: '/match/:id',
 | 
					      path: '/match/:id',
 | 
				
			||||||
      component: AuthenticatedLayout,
 | 
					      component: AuthenticatedLayout,
 | 
				
			||||||
      children: [
 | 
					      children: [
 | 
				
			||||||
@@ -51,6 +56,7 @@ const router = createRouter({
 | 
				
			|||||||
      ],
 | 
					      ],
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      props: { navbar: false },
 | 
				
			||||||
      path: '/game/:id',
 | 
					      path: '/game/:id',
 | 
				
			||||||
      component: AuthenticatedLayout,
 | 
					      component: AuthenticatedLayout,
 | 
				
			||||||
      children: [
 | 
					      children: [
 | 
				
			||||||
@@ -68,8 +74,13 @@ const router = createRouter({
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.beforeEach((to, from, next) => {
 | 
					router.beforeEach((to, from, next) => {
 | 
				
			||||||
  const isLoggedIn = !!sessionStorage.getItem('token')
 | 
					  const auth = useAuthStore()
 | 
				
			||||||
  if (to.matched.some((record) => record.meta.requiresAuth) && !isLoggedIn) {
 | 
					  const { user } = storeToRefs(auth)
 | 
				
			||||||
 | 
					  console.log('user.value :>> ', user.value)
 | 
				
			||||||
 | 
					  const isLoggedIn = user.value === undefined ? false : true
 | 
				
			||||||
 | 
					  if (to.name === 'landing' && isLoggedIn) {
 | 
				
			||||||
 | 
					    next({ name: 'home' })
 | 
				
			||||||
 | 
					  } else if (to.matched.some((record) => record.meta.requiresAuth) && !isLoggedIn) {
 | 
				
			||||||
    next({ name: 'landing' })
 | 
					    next({ name: 'landing' })
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    next()
 | 
					    next()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,9 +3,12 @@ import { useAuthStore } from '@/stores/auth'
 | 
				
			|||||||
import { storeToRefs } from 'pinia'
 | 
					import { storeToRefs } from 'pinia'
 | 
				
			||||||
import { NetworkService } from '@/services/NetworkService'
 | 
					import { NetworkService } from '@/services/NetworkService'
 | 
				
			||||||
import dayjs from 'dayjs'
 | 
					import dayjs from 'dayjs'
 | 
				
			||||||
 | 
					import { PersistenceService } from './PersistenceService'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class AuthenticationService extends ServiceBase {
 | 
					export class AuthenticationService extends ServiceBase {
 | 
				
			||||||
  private networkService = new NetworkService()
 | 
					  private networkService = new NetworkService()
 | 
				
			||||||
 | 
					  private auth = useAuthStore()
 | 
				
			||||||
 | 
					  private persistanceService: PersistenceService = PersistenceService.getInstance()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isAuthenticated() {
 | 
					  isAuthenticated() {
 | 
				
			||||||
    const auth = useAuthStore()
 | 
					    const auth = useAuthStore()
 | 
				
			||||||
@@ -14,17 +17,13 @@ export class AuthenticationService extends ServiceBase {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async login(username: string, password: string) {
 | 
					  async login(username: string, password: string) {
 | 
				
			||||||
    try {
 | 
					    const response = await this.networkService.post({
 | 
				
			||||||
      const res = await this.networkService.post({
 | 
					      uri: '/login',
 | 
				
			||||||
        uri: '/login',
 | 
					      body: { username, password },
 | 
				
			||||||
        body: { username, password }
 | 
					    })
 | 
				
			||||||
      })
 | 
					    const { token, refreshToken } = response
 | 
				
			||||||
      const { token } = res
 | 
					    this.persist(token, refreshToken)
 | 
				
			||||||
      this.persist(token)
 | 
					    return token
 | 
				
			||||||
      return token
 | 
					 | 
				
			||||||
    } catch (error) {
 | 
					 | 
				
			||||||
      console.error(error)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async logout() {
 | 
					  async logout() {
 | 
				
			||||||
@@ -32,20 +31,32 @@ export class AuthenticationService extends ServiceBase {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private removePersistence() {
 | 
					  private removePersistence() {
 | 
				
			||||||
    const auth = useAuthStore()
 | 
					    const { clearUser, clearToken, clearRefreshToken } = this.auth
 | 
				
			||||||
    const { setJwt, setUser } = auth
 | 
					    clearToken()
 | 
				
			||||||
    setJwt(undefined)
 | 
					    clearUser()
 | 
				
			||||||
    setUser(undefined)
 | 
					    clearRefreshToken()
 | 
				
			||||||
    sessionStorage.removeItem('token')
 | 
					    this.persistanceService.saveToken('')
 | 
				
			||||||
 | 
					    this.persistanceService.saveRefreshToken('')
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private persist(jwt: string) {
 | 
					  async persist(jwt: string, refreshJwt?: string) {
 | 
				
			||||||
    const auth = useAuthStore()
 | 
					    const { setToken, setUser, setRefreshToken } = this.auth
 | 
				
			||||||
    const { setJwt, setUser } = auth
 | 
					 | 
				
			||||||
    const loggedUser = this.parseJwt(jwt)
 | 
					    const loggedUser = this.parseJwt(jwt)
 | 
				
			||||||
    setJwt(jwt)
 | 
					    setToken(jwt)
 | 
				
			||||||
    setUser(loggedUser)
 | 
					    setUser(loggedUser)
 | 
				
			||||||
    sessionStorage.setItem('token', jwt)
 | 
					    try {
 | 
				
			||||||
 | 
					      await this.persistanceService.saveToken(jwt)
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					      this.logger.error(error, 'Error saving token')
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (refreshJwt) {
 | 
				
			||||||
 | 
					      setRefreshToken(refreshJwt)
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        await this.persistanceService.saveRefreshToken(refreshJwt)
 | 
				
			||||||
 | 
					      } catch (error) {
 | 
				
			||||||
 | 
					        this.logger.error(error, 'Error saving refresh token')
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private parseJwt(token: string) {
 | 
					  private parseJwt(token: string) {
 | 
				
			||||||
@@ -57,9 +68,14 @@ export class AuthenticationService extends ServiceBase {
 | 
				
			|||||||
    return JSON.parse(window.atob(base64))
 | 
					    return JSON.parse(window.atob(base64))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fromStorage() {
 | 
					  async fromStorage() {
 | 
				
			||||||
    const token = sessionStorage.getItem('token')
 | 
					    console.log('fromStorage')
 | 
				
			||||||
    if (token) {
 | 
					    const auth = useAuthStore()
 | 
				
			||||||
 | 
					    const { setToken, setUser } = auth
 | 
				
			||||||
 | 
					    const token = await this.persistanceService.readToken()
 | 
				
			||||||
 | 
					    const refreshToken = await this.persistanceService.readRefreshToken()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (token && refreshToken) {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        const parsed = this.parseJwt(token)
 | 
					        const parsed = this.parseJwt(token)
 | 
				
			||||||
        const isAfter = dayjs().isAfter(parsed.exp * 1000)
 | 
					        const isAfter = dayjs().isAfter(parsed.exp * 1000)
 | 
				
			||||||
@@ -67,7 +83,8 @@ export class AuthenticationService extends ServiceBase {
 | 
				
			|||||||
          this.removePersistence()
 | 
					          this.removePersistence()
 | 
				
			||||||
          return
 | 
					          return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.persist(token)
 | 
					        setToken(token)
 | 
				
			||||||
 | 
					        setUser(parsed)
 | 
				
			||||||
        this.logger.debug('Token loaded from storage', parsed)
 | 
					        this.logger.debug('Token loaded from storage', parsed)
 | 
				
			||||||
      } catch (error) {
 | 
					      } catch (error) {
 | 
				
			||||||
        this.logger.error(error, 'Error parsing token')
 | 
					        this.logger.error(error, 'Error parsing token')
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								src/services/LocalStorageService.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/services/LocalStorageService.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					import type { StorageInterface } from './StorageInterface'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class LocalStorageService implements StorageInterface {
 | 
				
			||||||
 | 
					  async saveUserDataText(fileName: string, content: any) {
 | 
				
			||||||
 | 
					    localStorage.setItem(`net.xintanalabs.domino.${fileName}`, content)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async saveUserDataJson(fileName: string, content: any) {
 | 
				
			||||||
 | 
					    localStorage.setItem(`net.xintanalabs.domino.${fileName}`, JSON.stringify(content))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async saveConfigData(content: any) {
 | 
				
			||||||
 | 
					    localStorage.setItem('net.xintanalabs.domino.config', JSON.stringify(content))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readUserDataText(fileName: string) {
 | 
				
			||||||
 | 
					    const content: string | null = localStorage.getItem(`net.xintanalabs.domino.${fileName}`)
 | 
				
			||||||
 | 
					    return content || ''
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readUserDataJson(fileName: string) {
 | 
				
			||||||
 | 
					    const content: string | null = localStorage.getItem(`net.xintanalabs.domino.${fileName}`)
 | 
				
			||||||
 | 
					    return JSON.parse(content || 'null')
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readConfigData() {
 | 
				
			||||||
 | 
					    const content: string | null = localStorage.getItem('net.xintanalabs.domino.config')
 | 
				
			||||||
 | 
					    return JSON.parse(content || '{}')
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
import { useAuthStore } from '@/stores/auth'
 | 
					import { useAuthStore } from '@/stores/auth'
 | 
				
			||||||
import { storeToRefs } from 'pinia'
 | 
					import { storeToRefs } from 'pinia'
 | 
				
			||||||
 | 
					import type { AuthenticationService } from './AuthenticationService'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface RequestOptions {
 | 
					interface RequestOptions {
 | 
				
			||||||
  uri: string
 | 
					  uri: string
 | 
				
			||||||
@@ -45,12 +46,20 @@ export class NetworkService {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    const fetchOptions = this.getFetchOptions(options)
 | 
					    const fetchOptions = this.getFetchOptions(options)
 | 
				
			||||||
    const urlParams = this.getURLParams(params)
 | 
					    const urlParams = this.getURLParams(params)
 | 
				
			||||||
    const res = await fetch(`${this.API_URL}${uri}${urlParams}`, fetchOptions)
 | 
					    let response = await fetch(`${this.API_URL}${uri}${urlParams}`, fetchOptions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!res.ok) {
 | 
					    if (response.status === 401) {
 | 
				
			||||||
 | 
					      const newAccessToken = await this.refresh()
 | 
				
			||||||
 | 
					      if (newAccessToken) {
 | 
				
			||||||
 | 
					        fetchOptions.headers.Authorization = newAccessToken
 | 
				
			||||||
 | 
					        response = await fetch(`${this.API_URL}${uri}${urlParams}`, fetchOptions)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!response.ok) {
 | 
				
			||||||
      throw new Error('Network response was not ok')
 | 
					      throw new Error('Network response was not ok')
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const text = await res.text()
 | 
					    const text = await response.text()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (text === '') {
 | 
					    if (text === '') {
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
@@ -59,6 +68,18 @@ export class NetworkService {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async refresh() {
 | 
				
			||||||
 | 
					    const { refreshToken } = storeToRefs(this.auth)
 | 
				
			||||||
 | 
					    const { setToken } = this.auth
 | 
				
			||||||
 | 
					    const response = await await this.post({
 | 
				
			||||||
 | 
					      uri: '/refresh',
 | 
				
			||||||
 | 
					      body: { token: refreshToken.value },
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    const { token } = response
 | 
				
			||||||
 | 
					    setToken(token)
 | 
				
			||||||
 | 
					    return token
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getURLParams(params: any) {
 | 
					  getURLParams(params: any) {
 | 
				
			||||||
    if (!params) {
 | 
					    if (!params) {
 | 
				
			||||||
      return ''
 | 
					      return ''
 | 
				
			||||||
@@ -72,7 +93,7 @@ export class NetworkService {
 | 
				
			|||||||
    const { body, auth, method = 'GET' } = opts
 | 
					    const { body, auth, method = 'GET' } = opts
 | 
				
			||||||
    const options: any = {
 | 
					    const options: any = {
 | 
				
			||||||
      method,
 | 
					      method,
 | 
				
			||||||
      headers: this.getHeaders({ auth })
 | 
					      headers: this.getHeaders({ auth }),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!['GET', 'HEAD'].includes(method) && body) {
 | 
					    if (!['GET', 'HEAD'].includes(method) && body) {
 | 
				
			||||||
      options.body = typeof body === 'string' ? body : JSON.stringify(body)
 | 
					      options.body = typeof body === 'string' ? body : JSON.stringify(body)
 | 
				
			||||||
@@ -84,7 +105,7 @@ export class NetworkService {
 | 
				
			|||||||
  getHeaders({ auth = true }): any {
 | 
					  getHeaders({ auth = true }): any {
 | 
				
			||||||
    const { jwt } = storeToRefs(this.auth)
 | 
					    const { jwt } = storeToRefs(this.auth)
 | 
				
			||||||
    const headers: any = {
 | 
					    const headers: any = {
 | 
				
			||||||
      'Content-Type': 'application/json'
 | 
					      'Content-Type': 'application/json',
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (auth) {
 | 
					    if (auth) {
 | 
				
			||||||
      headers.Authorization = jwt.value
 | 
					      headers.Authorization = jwt.value
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								src/services/PersistenceService.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/services/PersistenceService.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					import { LocalStorageService } from './LocalStorageService'
 | 
				
			||||||
 | 
					import type { StorageInterface } from './StorageInterface'
 | 
				
			||||||
 | 
					import { TauriFileStorageService } from './TauriFileStorageService'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class PersistenceService {
 | 
				
			||||||
 | 
					  private static instance: PersistenceService
 | 
				
			||||||
 | 
					  private isTauri: boolean = false
 | 
				
			||||||
 | 
					  private storage: StorageInterface
 | 
				
			||||||
 | 
					  private constructor() {
 | 
				
			||||||
 | 
					    this.isTauri = window.__TAURI_METADATA__ ? true : false
 | 
				
			||||||
 | 
					    this.storage = this.isTauri ? new TauriFileStorageService() : new LocalStorageService()
 | 
				
			||||||
 | 
					    console.log('PersistenceService created', this.isTauri)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getInstance(): PersistenceService {
 | 
				
			||||||
 | 
					    if (!PersistenceService.instance) {
 | 
				
			||||||
 | 
					      PersistenceService.instance = new PersistenceService()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return PersistenceService.instance
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async saveToken(token: string) {
 | 
				
			||||||
 | 
					    await this.storage.saveUserDataText('token', token)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async saveRefreshToken(refreshToken: string) {
 | 
				
			||||||
 | 
					    await this.storage.saveUserDataText('refreshToken', refreshToken)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readToken(): Promise<string> {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const token = await this.storage.readUserDataText('token')
 | 
				
			||||||
 | 
					      return token
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					      console.error(error)
 | 
				
			||||||
 | 
					      return ''
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readRefreshToken() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const refreshToken = await this.storage.readUserDataText('refreshToken')
 | 
				
			||||||
 | 
					      return refreshToken
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					      console.error(error)
 | 
				
			||||||
 | 
					      return ''
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async saveConfig(config: any) {
 | 
				
			||||||
 | 
					    await this.storage.saveConfigData(config)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readConfig() {
 | 
				
			||||||
 | 
					    const config = await this.storage.readConfigData()
 | 
				
			||||||
 | 
					    return config
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								src/services/StorageInterface.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/services/StorageInterface.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					export interface StorageInterface {
 | 
				
			||||||
 | 
					  saveUserDataText(fileName: string, content: any): Promise<void>
 | 
				
			||||||
 | 
					  saveUserDataJson(fileName: string, content: any): Promise<void>
 | 
				
			||||||
 | 
					  saveConfigData(content: any): Promise<void>
 | 
				
			||||||
 | 
					  readUserDataText(fileName: string): Promise<string>
 | 
				
			||||||
 | 
					  readUserDataJson(fileName: string): Promise<any>
 | 
				
			||||||
 | 
					  readConfigData(): Promise<any>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										94
									
								
								src/services/TauriFileStorageService.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/services/TauriFileStorageService.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					import { appConfigDir, appLocalDataDir, appCacheDir, appDataDir, join } from '@tauri-apps/api/path'
 | 
				
			||||||
 | 
					import { writeTextFile, readTextFile, exists, createDir } from '@tauri-apps/api/fs'
 | 
				
			||||||
 | 
					import type { StorageInterface } from './StorageInterface'
 | 
				
			||||||
 | 
					import { ServiceBase } from './ServiceBase'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class TauriFileStorageService extends ServiceBase implements StorageInterface {
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    super()
 | 
				
			||||||
 | 
					    this.showDirs()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async showDirs() {
 | 
				
			||||||
 | 
					    this.logger.debug(`=> appConfigDir ${await appConfigDir()}`)
 | 
				
			||||||
 | 
					    this.logger.debug(`=> appLocalDataDir ${await appLocalDataDir()}`)
 | 
				
			||||||
 | 
					    this.logger.debug(`=> appCacheDir ${await appCacheDir()}`)
 | 
				
			||||||
 | 
					    this.logger.debug(`=> appDataDir ${await appDataDir()}`)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async saveUserDataText(fileName: string, content: any) {
 | 
				
			||||||
 | 
					    const userAppDir = await appDataDir()
 | 
				
			||||||
 | 
					    await this.ensureDirExists(userAppDir)
 | 
				
			||||||
 | 
					    const filePath = await join(userAppDir, fileName + '.txt')
 | 
				
			||||||
 | 
					    await this.write(filePath, content, false)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async saveUserDataJson(fileName: string, content: any) {
 | 
				
			||||||
 | 
					    const userAppDir = await appDataDir()
 | 
				
			||||||
 | 
					    await this.ensureDirExists(userAppDir)
 | 
				
			||||||
 | 
					    const filePath = await join(userAppDir, fileName + '.json')
 | 
				
			||||||
 | 
					    await this.write(filePath, content, true)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readUserDataText(fileName: string) {
 | 
				
			||||||
 | 
					    const userAppDir = await appDataDir()
 | 
				
			||||||
 | 
					    await this.ensureDirExists(userAppDir)
 | 
				
			||||||
 | 
					    const filePath = await join(userAppDir, fileName + '.txt')
 | 
				
			||||||
 | 
					    const content = await this.read(filePath, false)
 | 
				
			||||||
 | 
					    return content
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readUserDataJson(fileName: string) {
 | 
				
			||||||
 | 
					    const userAppDir = await appDataDir()
 | 
				
			||||||
 | 
					    await this.ensureDirExists(userAppDir)
 | 
				
			||||||
 | 
					    const filePath = await join(userAppDir, fileName + '.json')
 | 
				
			||||||
 | 
					    const content = await this.read(filePath, true)
 | 
				
			||||||
 | 
					    return content
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async saveConfigData(content: any) {
 | 
				
			||||||
 | 
					    const userAppDir = await appConfigDir()
 | 
				
			||||||
 | 
					    await this.ensureDirExists(userAppDir)
 | 
				
			||||||
 | 
					    const filePath = await join(userAppDir, 'config.json')
 | 
				
			||||||
 | 
					    await this.write(filePath, content)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async readConfigData() {
 | 
				
			||||||
 | 
					    const userAppDir = await appConfigDir()
 | 
				
			||||||
 | 
					    await this.ensureDirExists(userAppDir)
 | 
				
			||||||
 | 
					    const filePath = await join(userAppDir, 'config.json')
 | 
				
			||||||
 | 
					    const content = await this.read(filePath, true)
 | 
				
			||||||
 | 
					    return content
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async ensureDirExists(dir: string) {
 | 
				
			||||||
 | 
					    const dirExists = await exists(dir)
 | 
				
			||||||
 | 
					    if (!dirExists) {
 | 
				
			||||||
 | 
					      await createDir(dir)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async write(filePath: string, content: any, json: boolean = false) {
 | 
				
			||||||
 | 
					    this.logger.trace(`write ${filePath}`, content)
 | 
				
			||||||
 | 
					    if (json) {
 | 
				
			||||||
 | 
					      return writeTextFile(filePath, JSON.stringify(content, null, 2))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return writeTextFile(filePath, content)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async read(filePath: string, json: boolean = false) {
 | 
				
			||||||
 | 
					    let content = null
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      if (await exists(filePath)) {
 | 
				
			||||||
 | 
					        content = await readTextFile(filePath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (json) {
 | 
				
			||||||
 | 
					          content = JSON.parse(content as string)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					      this.logger.error(error)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return content
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,15 +3,42 @@ import { computed, ref } from 'vue'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const useAuthStore = defineStore('auth', () => {
 | 
					export const useAuthStore = defineStore('auth', () => {
 | 
				
			||||||
  const jwt = ref<string | undefined>(undefined)
 | 
					  const jwt = ref<string | undefined>(undefined)
 | 
				
			||||||
 | 
					  const refreshJwt = ref<string | undefined>(undefined)
 | 
				
			||||||
  const user = ref<any | undefined>(undefined)
 | 
					  const user = ref<any | undefined>(undefined)
 | 
				
			||||||
  const roles = ref<string[]>([])
 | 
					  const roles = ref<string[]>([])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const isLoggedIn = computed(() => jwt.value !== undefined)
 | 
					  const isLoggedIn = computed(() => jwt.value !== undefined)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function setJwt(token: string | undefined) {
 | 
					  const token = computed(() => {
 | 
				
			||||||
 | 
					    if (jwt.value) {
 | 
				
			||||||
 | 
					      return jwt.value
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return sessionStorage.getItem('token')
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const refreshToken = computed(() => {
 | 
				
			||||||
 | 
					    if (refreshJwt.value) {
 | 
				
			||||||
 | 
					      return refreshJwt.value
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return sessionStorage.getItem('token_refresh')
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function setToken(token: string | undefined) {
 | 
				
			||||||
    jwt.value = token
 | 
					    jwt.value = token
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function clearToken() {
 | 
				
			||||||
 | 
					    jwt.value = undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function setRefreshToken(token: string | undefined) {
 | 
				
			||||||
 | 
					    refreshJwt.value = token
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function clearRefreshToken() {
 | 
				
			||||||
 | 
					    refreshJwt.value = undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function setUser(userIn: any | undefined) {
 | 
					  function setUser(userIn: any | undefined) {
 | 
				
			||||||
    user.value = userIn
 | 
					    user.value = userIn
 | 
				
			||||||
    setRoles(userIn?.roles ?? [])
 | 
					    setRoles(userIn?.roles ?? [])
 | 
				
			||||||
@@ -21,13 +48,23 @@ export const useAuthStore = defineStore('auth', () => {
 | 
				
			|||||||
    roles.value = rolesIn
 | 
					    roles.value = rolesIn
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function clearUser() {
 | 
				
			||||||
 | 
					    user.value = undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    jwt,
 | 
					    jwt,
 | 
				
			||||||
    user,
 | 
					    user,
 | 
				
			||||||
    roles,
 | 
					    roles,
 | 
				
			||||||
    isLoggedIn,
 | 
					    isLoggedIn,
 | 
				
			||||||
    setJwt,
 | 
					    token,
 | 
				
			||||||
 | 
					    refreshToken,
 | 
				
			||||||
 | 
					    setToken,
 | 
				
			||||||
 | 
					    clearToken,
 | 
				
			||||||
 | 
					    setRefreshToken,
 | 
				
			||||||
 | 
					    clearRefreshToken,
 | 
				
			||||||
    setUser,
 | 
					    setUser,
 | 
				
			||||||
    setRoles
 | 
					    clearUser,
 | 
				
			||||||
 | 
					    setRoles,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ import { useRouter } from 'vue-router'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const { toClipboard } = useClipboard()
 | 
					const { toClipboard } = useClipboard()
 | 
				
			||||||
const gameStore = useGameStore()
 | 
					const gameStore = useGameStore()
 | 
				
			||||||
const { moveToMake, canMakeMove, sessionState, gameState, playerState } = storeToRefs(gameStore)
 | 
					const { moveToMake, canMakeMove, sessionState, playerState } = storeToRefs(gameStore)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(async () => {
 | 
					onMounted(async () => {
 | 
				
			||||||
  // startMatch()
 | 
					  // startMatch()
 | 
				
			||||||
@@ -39,7 +39,7 @@ function copySeed() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="block">
 | 
					  <div class="block">
 | 
				
			||||||
    <section class="block info">
 | 
					    <!-- <section class="block info">
 | 
				
			||||||
      <p>Running: {{ sessionState?.sessionInProgress }}</p>
 | 
					      <p>Running: {{ sessionState?.sessionInProgress }}</p>
 | 
				
			||||||
      <p>Seed: {{ sessionState?.seed }}</p>
 | 
					      <p>Seed: {{ sessionState?.seed }}</p>
 | 
				
			||||||
      <p>
 | 
					      <p>
 | 
				
			||||||
@@ -50,7 +50,7 @@ function copySeed() {
 | 
				
			|||||||
      <p>Score: {{ sessionState?.scoreboard }}</p>
 | 
					      <p>Score: {{ sessionState?.scoreboard }}</p>
 | 
				
			||||||
      <p v-if="sessionState?.id">SessionID: {{ sessionState.id }}</p>
 | 
					      <p v-if="sessionState?.id">SessionID: {{ sessionState.id }}</p>
 | 
				
			||||||
      <p>PlayerID: {{ playerState?.id }}</p>
 | 
					      <p>PlayerID: {{ playerState?.id }}</p>
 | 
				
			||||||
    </section>
 | 
					    </section> -->
 | 
				
			||||||
    <section class="block">
 | 
					    <section class="block">
 | 
				
			||||||
      <div class="game-container">
 | 
					      <div class="game-container">
 | 
				
			||||||
        <GameComponent :playerId="playerState?.id" :canMakeMove="canMakeMove" @move="makeMove" />
 | 
					        <GameComponent :playerId="playerState?.id" :canMakeMove="canMakeMove" @move="makeMove" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ import type { GameService } from '@/services/GameService'
 | 
				
			|||||||
import type { MatchSessionOptions, 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, wait } from '@/common/helpers'
 | 
				
			||||||
import { useGameOptionsStore } from '@/stores/gameOptions'
 | 
					import { useGameOptionsStore } from '@/stores/gameOptions'
 | 
				
			||||||
import MatchConfiguration from '@/components/MatchConfiguration.vue'
 | 
					import MatchConfiguration from '@/components/MatchConfiguration.vue'
 | 
				
			||||||
import { useI18n } from 'vue-i18n'
 | 
					import { useI18n } from 'vue-i18n'
 | 
				
			||||||
@@ -127,14 +127,20 @@ const canStart = computed(() => {
 | 
				
			|||||||
  return (!options?.teamed && allReady) || (options?.teamed && !!teamedWith.value && allReady)
 | 
					  return (!options?.teamed && allReady) || (options?.teamed && !!teamedWith.value && allReady)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const isMultiplayer = computed(
 | 
				
			||||||
 | 
					  () => (sessionState?.value?.options?.numPlayers || gameOptions.value?.numPlayers || 0) > 1,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function loadData() {
 | 
					async function loadData() {
 | 
				
			||||||
 | 
					  loadingSessions.value = true
 | 
				
			||||||
  const listResponse = await gameService.listMatchSessions()
 | 
					  const listResponse = await gameService.listMatchSessions()
 | 
				
			||||||
 | 
					  loadingSessions.value = false
 | 
				
			||||||
  matchSessions.value = listResponse.data
 | 
					  matchSessions.value = listResponse.data
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
  // loadData()
 | 
					  loadData()
 | 
				
			||||||
  // dataInterval = setInterval(loadData, 5000)
 | 
					  dataInterval = setInterval(loadData, 5000)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onUnmounted(() => {
 | 
					onUnmounted(() => {
 | 
				
			||||||
@@ -145,31 +151,34 @@ function copy(sessionSeed: string) {
 | 
				
			|||||||
  copyToclipboard(sessionSeed)
 | 
					  copyToclipboard(sessionSeed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let tabs = ref<any[]>([
 | 
					let selectedTab = ref('create-tab')
 | 
				
			||||||
  { 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 isCreateTab = computed(() => selectedTab.value === 'create-tab')
 | 
				
			||||||
const isJoinTab = computed(() => selectedTab.value === 'join-tab')
 | 
					const isJoinTab = computed(() => selectedTab.value === 'join-tab')
 | 
				
			||||||
const isTournamentTab = computed(() => selectedTab.value === 'torunaments-tab')
 | 
					const isTournamentTab = computed(() => selectedTab.value === 'torunaments-tab')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const tabs = computed<any[]>((): any => [
 | 
				
			||||||
 | 
					  { label: t('create-session'), id: 'create-tab', disabled: false },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: t('join-a-multiplayer-session', matchSessions.value.length),
 | 
				
			||||||
 | 
					    id: 'join-tab',
 | 
				
			||||||
 | 
					    disabled: matchSessions.value.length <= 0,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { label: t('tournaments'), id: 'torunaments-tab', disabled: true },
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function tabClick(tab: any) {
 | 
					async function tabClick(tab: any) {
 | 
				
			||||||
  tabs.value.forEach((t) => (t.active = t === tab))
 | 
					  selectedTab.value = tab.id
 | 
				
			||||||
  if (tab.id === 'join-tab') {
 | 
					 | 
				
			||||||
    loadingSessions.value = true
 | 
					 | 
				
			||||||
    await loadData()
 | 
					 | 
				
			||||||
    dataInterval = setInterval(loadData, 5000)
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    clearInterval(dataInterval)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onCreateMatch(options: MatchSessionOptions) {
 | 
					function onCreateMatch(options: MatchSessionOptions) {
 | 
				
			||||||
  console.log('Creating match', options)
 | 
					 | 
				
			||||||
  createMatch(options)
 | 
					  createMatch(options)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function onStartSingleMatch(options: MatchSessionOptions) {
 | 
				
			||||||
 | 
					  await createMatch(options)
 | 
				
			||||||
 | 
					  await wait(1000)
 | 
				
			||||||
 | 
					  startMatch()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
@@ -185,7 +194,7 @@ function onCreateMatch(options: MatchSessionOptions) {
 | 
				
			|||||||
            <li
 | 
					            <li
 | 
				
			||||||
              v-bind:key="tab.label"
 | 
					              v-bind:key="tab.label"
 | 
				
			||||||
              v-for="tab in tabs"
 | 
					              v-for="tab in tabs"
 | 
				
			||||||
              :class="{ 'is-active': tab.active, 'is-disabled': tab.disabled }"
 | 
					              :class="{ 'is-active': selectedTab === tab.id, 'is-disabled': tab.disabled }"
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
              <a @click="() => tabClick(tab)">{{ tab.label }}</a>
 | 
					              <a @click="() => tabClick(tab)">{{ tab.label }}</a>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
@@ -194,7 +203,10 @@ function onCreateMatch(options: MatchSessionOptions) {
 | 
				
			|||||||
        <!-- Tabs End -->
 | 
					        <!-- Tabs End -->
 | 
				
			||||||
        <!-- Match Configuration -->
 | 
					        <!-- Match Configuration -->
 | 
				
			||||||
        <section class="section" v-if="isCreateTab">
 | 
					        <section class="section" v-if="isCreateTab">
 | 
				
			||||||
          <MatchConfiguration @create-match="onCreateMatch" />
 | 
					          <MatchConfiguration
 | 
				
			||||||
 | 
					            @create-match="onCreateMatch"
 | 
				
			||||||
 | 
					            @start-single-match="onStartSingleMatch"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
        <!-- Match Configuration End -->
 | 
					        <!-- Match Configuration End -->
 | 
				
			||||||
        <!-- Join a Multiplayer Session -->
 | 
					        <!-- Join a Multiplayer Session -->
 | 
				
			||||||
@@ -244,8 +256,7 @@ function onCreateMatch(options: MatchSessionOptions) {
 | 
				
			|||||||
        <section class="section" v-if="isTournamentTab"></section>
 | 
					        <section class="section" v-if="isTournamentTab"></section>
 | 
				
			||||||
        <!-- Tournaments End -->
 | 
					        <!-- Tournaments End -->
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="block" v-if="isSessionStarted && isMultiplayer">
 | 
				
			||||||
      <div class="block" v-if="isSessionStarted">
 | 
					 | 
				
			||||||
        <h2 class="title is-4">{{ sessionState?.name }}</h2>
 | 
					        <h2 class="title is-4">{{ sessionState?.name }}</h2>
 | 
				
			||||||
        <h6 class="title is-size-5">Players</h6>
 | 
					        <h6 class="title is-size-5">Players</h6>
 | 
				
			||||||
        <div v-for="player in sessionState?.players" :key="player.id">
 | 
					        <div v-for="player in sessionState?.players" :key="player.id">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,11 +3,14 @@ import { AuthenticationService } from '@/services/AuthenticationService'
 | 
				
			|||||||
import { inject, ref } from 'vue'
 | 
					import { inject, ref } from 'vue'
 | 
				
			||||||
import { useRouter } from 'vue-router'
 | 
					import { useRouter } from 'vue-router'
 | 
				
			||||||
import { useI18n } from 'vue-i18n'
 | 
					import { useI18n } from 'vue-i18n'
 | 
				
			||||||
 | 
					import { emit, listen } from '@tauri-apps/api/event'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = useRouter()
 | 
					const router = useRouter()
 | 
				
			||||||
const username = ref('')
 | 
					const username = ref('')
 | 
				
			||||||
const password = ref('')
 | 
					const password = ref('')
 | 
				
			||||||
 | 
					const errorLogin = ref(false)
 | 
				
			||||||
const { t } = useI18n()
 | 
					const { t } = useI18n()
 | 
				
			||||||
 | 
					const isTauri = window.__TAURI_METADATA__ ? true : false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const authService = inject<AuthenticationService>('auth')
 | 
					const authService = inject<AuthenticationService>('auth')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,7 +19,7 @@ async function login() {
 | 
				
			|||||||
    await authService?.login(username.value, password.value)
 | 
					    await authService?.login(username.value, password.value)
 | 
				
			||||||
    router.push({ name: 'home' })
 | 
					    router.push({ name: 'home' })
 | 
				
			||||||
  } catch (error) {
 | 
					  } catch (error) {
 | 
				
			||||||
    alert(t('invalid-username-or-password'))
 | 
					    errorLogin.value = true
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // if (username.value === 'admin' && password.value === 'password') {
 | 
					  // if (username.value === 'admin' && password.value === 'password') {
 | 
				
			||||||
  // localStorage.setItem('token', 'true')
 | 
					  // localStorage.setItem('token', 'true')
 | 
				
			||||||
@@ -25,11 +28,43 @@ async function login() {
 | 
				
			|||||||
  //   alert('Invalid username or password')
 | 
					  //   alert('Invalid username or password')
 | 
				
			||||||
  // }
 | 
					  // }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// // Listen for update available event
 | 
				
			||||||
 | 
					// listen('tauri://update-available', () => {
 | 
				
			||||||
 | 
					//   console.log('Update is available!')
 | 
				
			||||||
 | 
					//   // You can show a dialog or notify the user here
 | 
				
			||||||
 | 
					// })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// // Listen for update not available event
 | 
				
			||||||
 | 
					// listen('tauri://update-not-available', () => {
 | 
				
			||||||
 | 
					//   console.log('No update available.')
 | 
				
			||||||
 | 
					// })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// // Listen for update download progress
 | 
				
			||||||
 | 
					// listen('tauri://update-download-progress', (event) => {
 | 
				
			||||||
 | 
					//   console.log('Update download progress:', event.payload)
 | 
				
			||||||
 | 
					//   // You can update a progress bar here
 | 
				
			||||||
 | 
					// })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// // Listen for update download finished
 | 
				
			||||||
 | 
					// listen('tauri://update-download-finished', () => {
 | 
				
			||||||
 | 
					//   console.log('Update download finished.')
 | 
				
			||||||
 | 
					//   // You can notify the user to restart the app
 | 
				
			||||||
 | 
					// })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function checkForUpdates() {
 | 
				
			||||||
 | 
					  emit('tauri://update')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="login">
 | 
					  <div class="login">
 | 
				
			||||||
    <h1 class="title">{{ $t('login') }}</h1>
 | 
					    <h1 class="title">{{ $t('login') }}</h1>
 | 
				
			||||||
 | 
					    <div class="message is-danger">
 | 
				
			||||||
 | 
					      <div class="message-body" v-if="errorLogin">
 | 
				
			||||||
 | 
					        {{ $t('invalid-username-or-password') }}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
    <form class="form" @submit.prevent="login">
 | 
					    <form class="form" @submit.prevent="login">
 | 
				
			||||||
      <div class="field">
 | 
					      <div class="field">
 | 
				
			||||||
        <label class="label">{{ $t('username') }}</label>
 | 
					        <label class="label">{{ $t('username') }}</label>
 | 
				
			||||||
@@ -63,5 +98,6 @@ async function login() {
 | 
				
			|||||||
        </div> -->
 | 
					        </div> -->
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </form>
 | 
					    </form>
 | 
				
			||||||
 | 
					    <a href="#" @click="checkForUpdates" v-if="isTauri">Update</a>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,14 +2,17 @@
 | 
				
			|||||||
import type { MatchSessionDto } from '@/common/interfaces'
 | 
					import type { MatchSessionDto } from '@/common/interfaces'
 | 
				
			||||||
import type { GameService } from '@/services/GameService'
 | 
					import type { GameService } from '@/services/GameService'
 | 
				
			||||||
import type { LoggingService } from '@/services/LoggingService'
 | 
					import type { LoggingService } from '@/services/LoggingService'
 | 
				
			||||||
 | 
					import ScoreboardTableComponent from '@/components/ScoreboardTableComponent.vue'
 | 
				
			||||||
import { inject, onBeforeMount, ref, toRaw } from 'vue'
 | 
					import { inject, onBeforeMount, ref, toRaw } from 'vue'
 | 
				
			||||||
import { useRoute, useRouter } from 'vue-router'
 | 
					import { useRoute, useRouter } from 'vue-router'
 | 
				
			||||||
 | 
					import { useGameStore } from '@/stores/game'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const route = useRoute()
 | 
					const route = useRoute()
 | 
				
			||||||
const router = useRouter()
 | 
					const router = useRouter()
 | 
				
			||||||
 | 
					const gameStore = useGameStore()
 | 
				
			||||||
const gameService: GameService = inject<GameService>('game') as GameService
 | 
					const gameService: GameService = inject<GameService>('game') as GameService
 | 
				
			||||||
const logger: LoggingService = inject<LoggingService>('logger') as LoggingService
 | 
					const logger: LoggingService = inject<LoggingService>('logger') as LoggingService
 | 
				
			||||||
 | 
					const { updateSessionState } = gameStore
 | 
				
			||||||
let sessionId: string
 | 
					let sessionId: string
 | 
				
			||||||
let matchSession = ref<MatchSessionDto | undefined>(undefined)
 | 
					let matchSession = ref<MatchSessionDto | undefined>(undefined)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,57 +31,45 @@ onBeforeMount(() => {
 | 
				
			|||||||
    router.push({ name: 'home' })
 | 
					    router.push({ name: 'home' })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function gotoHome() {
 | 
				
			||||||
 | 
					  updateSessionState(undefined)
 | 
				
			||||||
 | 
					  router.push({ name: 'home' })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="container">
 | 
					  <div class="container">
 | 
				
			||||||
    <h1 class="title is-1">{{ $t('match-page') }}</h1>
 | 
					    <h1 class="title is-1">{{ $t('match-page') }}</h1>
 | 
				
			||||||
    <h2 class="title is-3">{{ matchSession?.name }}</h2>
 | 
					    <h2 class="title is-3">{{ matchSession?.name }}</h2>
 | 
				
			||||||
    <div class="block mt-6">
 | 
					
 | 
				
			||||||
      <p class="mb-4">
 | 
					    <div class="level">
 | 
				
			||||||
        <span class="title is-5">{{ $t('winner') }}</span>
 | 
					      <div class="level-item has-text-centered">
 | 
				
			||||||
        <span class="is-size-5 ml-4">{{ matchSession?.matchWinner?.name }}</span>
 | 
					        <div>
 | 
				
			||||||
      </p>
 | 
					          <p class="heading">{{ $t('winner') }}</p>
 | 
				
			||||||
      <p class="mb-4">
 | 
					          <p class="title is-size-3">{{ matchSession?.matchWinner?.name }}</p>
 | 
				
			||||||
        <span class="title is-5">{{ $t('win-type') }}</span>
 | 
					        </div>
 | 
				
			||||||
        <span class="is-size-5 ml-4">{{ matchSession?.options.winType }}</span>
 | 
					 | 
				
			||||||
      </p>
 | 
					 | 
				
			||||||
      <p class="mb-4">
 | 
					 | 
				
			||||||
        <span class="title is-5">{{ $t('points-to-win') }}</span>
 | 
					 | 
				
			||||||
        <span class="is-size-5 ml-4">{{ matchSession?.options.winTarget }}</span>
 | 
					 | 
				
			||||||
      </p>
 | 
					 | 
				
			||||||
      <h3 class="title is-5">{{ $t('final-scoreboard') }}</h3>
 | 
					 | 
				
			||||||
      <div v-bind:key="$index" v-for="(score, $index) in matchSession?.scoreboard">
 | 
					 | 
				
			||||||
        <p class="">
 | 
					 | 
				
			||||||
          <span class="title is-5">{{ score.name }}</span>
 | 
					 | 
				
			||||||
          <span class="is-size-5 ml-4">{{ score.score }}</span>
 | 
					 | 
				
			||||||
        </p>
 | 
					 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					      <div class="level-item has-text-centered">
 | 
				
			||||||
    <div class="grid">
 | 
					        <div>
 | 
				
			||||||
      <div
 | 
					          <p class="heading">{{ $t('win-type') }}</p>
 | 
				
			||||||
        class="cell"
 | 
					          <p class="title">{{ matchSession?.options.winType }}</p>
 | 
				
			||||||
        v-bind:key="$index"
 | 
					        </div>
 | 
				
			||||||
        v-for="(summary, $index) in matchSession?.gameSummaries"
 | 
					      </div>
 | 
				
			||||||
      >
 | 
					      <div class="level-item has-text-centered">
 | 
				
			||||||
        <div class="block mt-6">
 | 
					        <div>
 | 
				
			||||||
          <h3 class="title is-5">{{ $t('round-index-1', [$index + 1]) }}</h3>
 | 
					          <p class="heading">{{ $t('points-to-win') }}</p>
 | 
				
			||||||
          <p class="mb-4">
 | 
					          <p class="title">{{ matchSession?.options.winTarget }}</p>
 | 
				
			||||||
            <span class="title is-5">{{ $t('winner') }}</span>
 | 
					 | 
				
			||||||
            <span class="is-size-5 ml-4">{{ summary.winner?.name }}</span>
 | 
					 | 
				
			||||||
          </p>
 | 
					 | 
				
			||||||
          <h4 class="title is-6">{{ $t('scoreboard') }}</h4>
 | 
					 | 
				
			||||||
          <div v-bind:key="$index" v-for="(gameScore, $index) in summary.score">
 | 
					 | 
				
			||||||
            <p class="">
 | 
					 | 
				
			||||||
              <span class="title is-5">{{ gameScore.name }}</span>
 | 
					 | 
				
			||||||
              <span class="is-size-5 ml-4">{{ gameScore.score }}</span>
 | 
					 | 
				
			||||||
            </p>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <ScoreboardTableComponent
 | 
				
			||||||
 | 
					      :games="matchSession?.gameSummaries"
 | 
				
			||||||
 | 
					      :final-score="matchSession?.scoreboard"
 | 
				
			||||||
 | 
					      :winner="matchSession?.matchWinner"
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
    <div class="buttons">
 | 
					    <div class="buttons">
 | 
				
			||||||
      <button class="button is-primary" @click="router.push({ name: 'home' })">
 | 
					      <button class="button is-primary" @click="gotoHome">
 | 
				
			||||||
        {{ $t('back') }}
 | 
					        {{ $t('back') }}
 | 
				
			||||||
      </button>
 | 
					      </button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "extends": "@vue/tsconfig/tsconfig.dom.json",
 | 
					  "extends": "@vue/tsconfig/tsconfig.dom.json",
 | 
				
			||||||
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
 | 
					  "include": ["types/env.d.ts", "src/**/*", "src/**/*.vue"],
 | 
				
			||||||
  "exclude": ["src/**/__tests__/*"],
 | 
					  "exclude": ["src/**/__tests__/*"],
 | 
				
			||||||
  "compilerOptions": {
 | 
					  "compilerOptions": {
 | 
				
			||||||
    "composite": true,
 | 
					    "composite": true,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
    "types": ["vite/client"]
 | 
					    "types": ["vite/client"]
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "files": [],
 | 
					  "files": [],
 | 
				
			||||||
 | 
					  "typeRoots": ["./src/types"],
 | 
				
			||||||
  "references": [
 | 
					  "references": [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "path": "./tsconfig.node.json"
 | 
					      "path": "./tsconfig.node.json"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										0
									
								
								env.d.ts → types/env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								env.d.ts → types/env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
								
								
									
										4
									
								
								type.d.ts → types/type.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								type.d.ts → types/type.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -3,3 +3,7 @@ declare module 'socket.io' {
 | 
				
			|||||||
    data: any
 | 
					    data: any
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare interface Window {
 | 
				
			||||||
 | 
					  __TAURI__: any
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user