Weapon stories

This commit is contained in:
DrMint 2023-02-16 09:19:44 +01:00
parent df8a7f820d
commit 7aeb85e4f9
25 changed files with 1578 additions and 362 deletions

302
package-lock.json generated
View File

@ -15,7 +15,7 @@
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"cuid": "^2.1.8", "cuid": "^2.1.8",
"intl-messageformat": "^10.3.0", "intl-messageformat": "^10.3.0",
"isomorphic-dompurify": "^0.26.0", "isomorphic-dompurify": "^1.0.0",
"jotai": "^2.0.1", "jotai": "^2.0.1",
"markdown-to-jsx": "^7.1.9", "markdown-to-jsx": "^7.1.9",
"marked": "^4.2.12", "marked": "^4.2.12",
@ -28,7 +28,7 @@
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hotkeys-hook": "^3.4.7", "react-hotkeys-hook": "^3.4.7",
"react-swipeable": "^7.0.0", "react-swipeable": "^7.0.0",
"react-zoom-pan-pinch": "^2.5.0", "react-zoom-pan-pinch": "^2.6.1",
"string-natural-compare": "^3.0.1", "string-natural-compare": "^3.0.1",
"throttle-debounce": "^5.0.0", "throttle-debounce": "^5.0.0",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
@ -46,25 +46,25 @@
"@types/marked": "^4.0.8", "@types/marked": "^4.0.8",
"@types/node": "18.13.0", "@types/node": "18.13.0",
"@types/nodemailer": "^6.4.7", "@types/nodemailer": "^6.4.7",
"@types/react": "^18.0.27", "@types/react": "^18.0.28",
"@types/react-dom": "^18.0.10", "@types/react-dom": "^18.0.11",
"@types/string-natural-compare": "^3.0.2", "@types/string-natural-compare": "^3.0.2",
"@types/throttle-debounce": "^5.0.0", "@types/throttle-debounce": "^5.0.0",
"@types/turndown": "^5.0.1", "@types/turndown": "^5.0.1",
"@types/ua-parser-js": "^0.7.36", "@types/ua-parser-js": "^0.7.36",
"@typescript-eslint/eslint-plugin": "^5.51.0", "@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.51.0", "@typescript-eslint/parser": "^5.52.0",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",
"eslint": "^8.33.0", "eslint": "^8.34.0",
"eslint-config-next": "13.1.6", "eslint-config-next": "13.1.6",
"eslint-plugin-import": "^2.27.5", "eslint-plugin-import": "^2.27.5",
"graphql": "^16.6.0", "graphql": "^16.6.0",
"graphql-request": "^5.1.0", "graphql-request": "^5.1.0",
"next-sitemap": "^3.1.52", "next-sitemap": "^3.1.52",
"prettier": "^2.8.4", "prettier": "^2.8.4",
"prettier-plugin-tailwindcss": "^0.2.2", "prettier-plugin-tailwindcss": "^0.2.3",
"tailwindcss": "^3.2.6", "tailwindcss": "^3.2.6",
"ts-unused-exports": "^9.0.3", "ts-unused-exports": "^9.0.4",
"typescript": "^4.9.5" "typescript": "^4.9.5"
} }
}, },
@ -3690,9 +3690,9 @@
"dev": true "dev": true
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "18.0.27", "version": "18.0.28",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
@ -3701,9 +3701,9 @@
} }
}, },
"node_modules/@types/react-dom": { "node_modules/@types/react-dom": {
"version": "18.0.10", "version": "18.0.11",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz",
"integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/react": "*" "@types/react": "*"
@ -3760,14 +3760,14 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz",
"integrity": "sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==", "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.51.0", "@typescript-eslint/scope-manager": "5.52.0",
"@typescript-eslint/type-utils": "5.51.0", "@typescript-eslint/type-utils": "5.52.0",
"@typescript-eslint/utils": "5.51.0", "@typescript-eslint/utils": "5.52.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"grapheme-splitter": "^1.0.4", "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
@ -3794,14 +3794,14 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz",
"integrity": "sha512-fEV0R9gGmfpDeRzJXn+fGQKcl0inIeYobmmUWijZh9zA7bxJ8clPhV9up2ZQzATxAiFAECqPQyMDB4o4B81AaA==", "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.51.0", "@typescript-eslint/scope-manager": "5.52.0",
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"@typescript-eslint/typescript-estree": "5.51.0", "@typescript-eslint/typescript-estree": "5.52.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -3821,13 +3821,13 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz",
"integrity": "sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==", "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"@typescript-eslint/visitor-keys": "5.51.0" "@typescript-eslint/visitor-keys": "5.52.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -3838,13 +3838,13 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz",
"integrity": "sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==", "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "5.51.0", "@typescript-eslint/typescript-estree": "5.52.0",
"@typescript-eslint/utils": "5.51.0", "@typescript-eslint/utils": "5.52.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
@ -3865,9 +3865,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz",
"integrity": "sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==", "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -3878,13 +3878,13 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz",
"integrity": "sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==", "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"@typescript-eslint/visitor-keys": "5.51.0", "@typescript-eslint/visitor-keys": "5.52.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -3905,16 +3905,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz",
"integrity": "sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==", "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12", "@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.51.0", "@typescript-eslint/scope-manager": "5.52.0",
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"@typescript-eslint/typescript-estree": "5.51.0", "@typescript-eslint/typescript-estree": "5.52.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
"semver": "^7.3.7" "semver": "^7.3.7"
@ -3953,12 +3953,12 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz",
"integrity": "sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==", "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@ -5297,9 +5297,9 @@
"integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==" "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ=="
}, },
"node_modules/dompurify": { "node_modules/dompurify": {
"version": "2.4.1", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.1.tgz", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.0.tgz",
"integrity": "sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA==" "integrity": "sha512-0g/yr2IJn4nTbxwL785YxS7/AvvgGFJw6LLWP+BzWzB1+BYOqPUT9Hy0rXrZh5HLdHnxH72aDdzvC9SdTjsuaA=="
}, },
"node_modules/dot-case": { "node_modules/dot-case": {
"version": "3.0.4", "version": "3.0.4",
@ -5624,9 +5624,9 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "8.33.0", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.33.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz",
"integrity": "sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==", "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint/eslintrc": "^1.4.1", "@eslint/eslintrc": "^1.4.1",
@ -7467,13 +7467,13 @@
"dev": true "dev": true
}, },
"node_modules/isomorphic-dompurify": { "node_modules/isomorphic-dompurify": {
"version": "0.26.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-0.26.0.tgz", "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-1.0.0.tgz",
"integrity": "sha512-70gPadd/NJPTBuTtM5PsWimmc7S4fcBENzOFMHfBtIPacaygUvI9n63qFkUTc91WDDC9yB68mtmluW9/NhhTJw==", "integrity": "sha512-rxkJ2b2rwsgN/uvtaW+Z2JGfD9CYcixYMj0eTIa4V2hG47VDRMiehtUypi4lkpuwW41UrnOR65Dy0POiH3Lbjg==",
"dependencies": { "dependencies": {
"@types/dompurify": "^2.3.4", "@types/dompurify": "^2.4.0",
"dompurify": "^2.4.1", "dompurify": "^3.0.0",
"jsdom": "^21.0.0" "jsdom": "^21.1.0"
} }
}, },
"node_modules/isomorphic-fetch": { "node_modules/isomorphic-fetch": {
@ -7535,9 +7535,9 @@
} }
}, },
"node_modules/jsdom": { "node_modules/jsdom": {
"version": "21.0.0", "version": "21.1.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.0.0.tgz", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.0.tgz",
"integrity": "sha512-AIw+3ZakSUtDYvhwPwWHiZsUi3zHugpMEKlNPaurviseYoBqo0zBd3zqoUi3LPCNtPFlEP8FiW9MqCZdjb2IYA==", "integrity": "sha512-m0lzlP7qOtthD918nenK3hdItSd2I+V3W9IrBcB36sqDwG+KnUs66IF5GY7laGWUnlM9vTsD0W1QwSEBYWWcJg==",
"dependencies": { "dependencies": {
"abab": "^2.0.6", "abab": "^2.0.6",
"acorn": "^8.8.1", "acorn": "^8.8.1",
@ -8860,14 +8860,15 @@
} }
}, },
"node_modules/prettier-plugin-tailwindcss": { "node_modules/prettier-plugin-tailwindcss": {
"version": "0.2.2", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.2.tgz", "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.3.tgz",
"integrity": "sha512-5RjUbWRe305pUpc48MosoIp6uxZvZxrM6GyOgsbGLTce+ehePKNm7ziW2dLG2air9aXbGuXlHVSQQw4Lbosq3w==", "integrity": "sha512-s2N5Dh7Ao5KTV1mao5ZBnn8EKtUcDPJEkGViZIjI0Ij9TTI5zgTz4IHOxW33jOdjHKa8CSjM88scelUiC5TNRQ==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=12.17.0" "node": ">=12.17.0"
}, },
"peerDependencies": { "peerDependencies": {
"@ianvs/prettier-plugin-sort-imports": "*",
"@prettier/plugin-php": "*", "@prettier/plugin-php": "*",
"@prettier/plugin-pug": "*", "@prettier/plugin-pug": "*",
"@shopify/prettier-plugin-liquid": "*", "@shopify/prettier-plugin-liquid": "*",
@ -8885,6 +8886,9 @@
"prettier-plugin-twig-melody": "*" "prettier-plugin-twig-melody": "*"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@ianvs/prettier-plugin-sort-imports": {
"optional": true
},
"@prettier/plugin-php": { "@prettier/plugin-php": {
"optional": true "optional": true
}, },
@ -9102,9 +9106,9 @@
} }
}, },
"node_modules/react-zoom-pan-pinch": { "node_modules/react-zoom-pan-pinch": {
"version": "2.5.0", "version": "2.6.1",
"resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-2.5.0.tgz", "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-2.6.1.tgz",
"integrity": "sha512-5o3DKACPRNXM5Yr1dfQ5sZsGpstEsam3ih3dNmaDUfpghwD7ENwCVAupbNiBHlJ1Jbowd6o9qamp/2FiWu2Jcg==", "integrity": "sha512-4Cgdnn6OwN4DomY/E9NpAf0TyCtslEgwdYn96ZV/f5LKuw/FE3gcIBJiaKFmMGThDGV0yKN5mzO8noi34+UE4Q==",
"engines": { "engines": {
"node": ">=8", "node": ">=8",
"npm": ">=5" "npm": ">=5"
@ -10042,9 +10046,9 @@
"dev": true "dev": true
}, },
"node_modules/ts-unused-exports": { "node_modules/ts-unused-exports": {
"version": "9.0.3", "version": "9.0.4",
"resolved": "https://registry.npmjs.org/ts-unused-exports/-/ts-unused-exports-9.0.3.tgz", "resolved": "https://registry.npmjs.org/ts-unused-exports/-/ts-unused-exports-9.0.4.tgz",
"integrity": "sha512-LCGLYL0EVdXNj1O/cGfpP2Fx+zfqoV936iMyIhvSVnXk4RUjwmSjMzzCNXI9b1j9PCs946a2TbRMhJh7/XUyUA==", "integrity": "sha512-/PPy0B1zhOJkDTUd1XVyaCqE/yA3IL2FrQ8W5/6cQ2g0kKC/06q8LEoPeXI6ELfI6Bivmv3MMvsUup5u3WH+BQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"chalk": "^4.0.0", "chalk": "^4.0.0",
@ -13538,9 +13542,9 @@
"dev": true "dev": true
}, },
"@types/react": { "@types/react": {
"version": "18.0.27", "version": "18.0.28",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
@ -13549,9 +13553,9 @@
} }
}, },
"@types/react-dom": { "@types/react-dom": {
"version": "18.0.10", "version": "18.0.11",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz",
"integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/react": "*" "@types/react": "*"
@ -13608,14 +13612,14 @@
} }
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz",
"integrity": "sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==", "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.51.0", "@typescript-eslint/scope-manager": "5.52.0",
"@typescript-eslint/type-utils": "5.51.0", "@typescript-eslint/type-utils": "5.52.0",
"@typescript-eslint/utils": "5.51.0", "@typescript-eslint/utils": "5.52.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"grapheme-splitter": "^1.0.4", "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
@ -13626,53 +13630,53 @@
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz",
"integrity": "sha512-fEV0R9gGmfpDeRzJXn+fGQKcl0inIeYobmmUWijZh9zA7bxJ8clPhV9up2ZQzATxAiFAECqPQyMDB4o4B81AaA==", "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.51.0", "@typescript-eslint/scope-manager": "5.52.0",
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"@typescript-eslint/typescript-estree": "5.51.0", "@typescript-eslint/typescript-estree": "5.52.0",
"debug": "^4.3.4" "debug": "^4.3.4"
} }
}, },
"@typescript-eslint/scope-manager": { "@typescript-eslint/scope-manager": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz",
"integrity": "sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==", "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"@typescript-eslint/visitor-keys": "5.51.0" "@typescript-eslint/visitor-keys": "5.52.0"
} }
}, },
"@typescript-eslint/type-utils": { "@typescript-eslint/type-utils": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz",
"integrity": "sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==", "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/typescript-estree": "5.51.0", "@typescript-eslint/typescript-estree": "5.52.0",
"@typescript-eslint/utils": "5.51.0", "@typescript-eslint/utils": "5.52.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz",
"integrity": "sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==", "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz",
"integrity": "sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==", "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"@typescript-eslint/visitor-keys": "5.51.0", "@typescript-eslint/visitor-keys": "5.52.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -13681,16 +13685,16 @@
} }
}, },
"@typescript-eslint/utils": { "@typescript-eslint/utils": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz",
"integrity": "sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==", "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12", "@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.51.0", "@typescript-eslint/scope-manager": "5.52.0",
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"@typescript-eslint/typescript-estree": "5.51.0", "@typescript-eslint/typescript-estree": "5.52.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
"semver": "^7.3.7" "semver": "^7.3.7"
@ -13715,12 +13719,12 @@
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "5.51.0", "version": "5.52.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.51.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz",
"integrity": "sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==", "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.51.0", "@typescript-eslint/types": "5.52.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
} }
}, },
@ -14738,9 +14742,9 @@
"integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==" "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ=="
}, },
"dompurify": { "dompurify": {
"version": "2.4.1", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.1.tgz", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.0.tgz",
"integrity": "sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA==" "integrity": "sha512-0g/yr2IJn4nTbxwL785YxS7/AvvgGFJw6LLWP+BzWzB1+BYOqPUT9Hy0rXrZh5HLdHnxH72aDdzvC9SdTjsuaA=="
}, },
"dot-case": { "dot-case": {
"version": "3.0.4", "version": "3.0.4",
@ -15001,9 +15005,9 @@
} }
}, },
"eslint": { "eslint": {
"version": "8.33.0", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.33.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz",
"integrity": "sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==", "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@eslint/eslintrc": "^1.4.1", "@eslint/eslintrc": "^1.4.1",
@ -16358,13 +16362,13 @@
"dev": true "dev": true
}, },
"isomorphic-dompurify": { "isomorphic-dompurify": {
"version": "0.26.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-0.26.0.tgz", "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-1.0.0.tgz",
"integrity": "sha512-70gPadd/NJPTBuTtM5PsWimmc7S4fcBENzOFMHfBtIPacaygUvI9n63qFkUTc91WDDC9yB68mtmluW9/NhhTJw==", "integrity": "sha512-rxkJ2b2rwsgN/uvtaW+Z2JGfD9CYcixYMj0eTIa4V2hG47VDRMiehtUypi4lkpuwW41UrnOR65Dy0POiH3Lbjg==",
"requires": { "requires": {
"@types/dompurify": "^2.3.4", "@types/dompurify": "^2.4.0",
"dompurify": "^2.4.1", "dompurify": "^3.0.0",
"jsdom": "^21.0.0" "jsdom": "^21.1.0"
} }
}, },
"isomorphic-fetch": { "isomorphic-fetch": {
@ -16411,9 +16415,9 @@
} }
}, },
"jsdom": { "jsdom": {
"version": "21.0.0", "version": "21.1.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.0.0.tgz", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.0.tgz",
"integrity": "sha512-AIw+3ZakSUtDYvhwPwWHiZsUi3zHugpMEKlNPaurviseYoBqo0zBd3zqoUi3LPCNtPFlEP8FiW9MqCZdjb2IYA==", "integrity": "sha512-m0lzlP7qOtthD918nenK3hdItSd2I+V3W9IrBcB36sqDwG+KnUs66IF5GY7laGWUnlM9vTsD0W1QwSEBYWWcJg==",
"requires": { "requires": {
"abab": "^2.0.6", "abab": "^2.0.6",
"acorn": "^8.8.1", "acorn": "^8.8.1",
@ -17352,9 +17356,9 @@
"dev": true "dev": true
}, },
"prettier-plugin-tailwindcss": { "prettier-plugin-tailwindcss": {
"version": "0.2.2", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.2.tgz", "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.3.tgz",
"integrity": "sha512-5RjUbWRe305pUpc48MosoIp6uxZvZxrM6GyOgsbGLTce+ehePKNm7ziW2dLG2air9aXbGuXlHVSQQw4Lbosq3w==", "integrity": "sha512-s2N5Dh7Ao5KTV1mao5ZBnn8EKtUcDPJEkGViZIjI0Ij9TTI5zgTz4IHOxW33jOdjHKa8CSjM88scelUiC5TNRQ==",
"dev": true, "dev": true,
"requires": {} "requires": {}
}, },
@ -17484,9 +17488,9 @@
"requires": {} "requires": {}
}, },
"react-zoom-pan-pinch": { "react-zoom-pan-pinch": {
"version": "2.5.0", "version": "2.6.1",
"resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-2.5.0.tgz", "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-2.6.1.tgz",
"integrity": "sha512-5o3DKACPRNXM5Yr1dfQ5sZsGpstEsam3ih3dNmaDUfpghwD7ENwCVAupbNiBHlJ1Jbowd6o9qamp/2FiWu2Jcg==", "integrity": "sha512-4Cgdnn6OwN4DomY/E9NpAf0TyCtslEgwdYn96ZV/f5LKuw/FE3gcIBJiaKFmMGThDGV0yKN5mzO8noi34+UE4Q==",
"requires": {} "requires": {}
}, },
"read-cache": { "read-cache": {
@ -18202,9 +18206,9 @@
} }
}, },
"ts-unused-exports": { "ts-unused-exports": {
"version": "9.0.3", "version": "9.0.4",
"resolved": "https://registry.npmjs.org/ts-unused-exports/-/ts-unused-exports-9.0.3.tgz", "resolved": "https://registry.npmjs.org/ts-unused-exports/-/ts-unused-exports-9.0.4.tgz",
"integrity": "sha512-LCGLYL0EVdXNj1O/cGfpP2Fx+zfqoV936iMyIhvSVnXk4RUjwmSjMzzCNXI9b1j9PCs946a2TbRMhJh7/XUyUA==", "integrity": "sha512-/PPy0B1zhOJkDTUd1XVyaCqE/yA3IL2FrQ8W5/6cQ2g0kKC/06q8LEoPeXI6ELfI6Bivmv3MMvsUup5u3WH+BQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^4.0.0", "chalk": "^4.0.0",

View File

@ -27,7 +27,7 @@
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"cuid": "^2.1.8", "cuid": "^2.1.8",
"intl-messageformat": "^10.3.0", "intl-messageformat": "^10.3.0",
"isomorphic-dompurify": "^0.26.0", "isomorphic-dompurify": "^1.0.0",
"jotai": "^2.0.1", "jotai": "^2.0.1",
"markdown-to-jsx": "^7.1.9", "markdown-to-jsx": "^7.1.9",
"marked": "^4.2.12", "marked": "^4.2.12",
@ -40,7 +40,7 @@
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hotkeys-hook": "^3.4.7", "react-hotkeys-hook": "^3.4.7",
"react-swipeable": "^7.0.0", "react-swipeable": "^7.0.0",
"react-zoom-pan-pinch": "^2.5.0", "react-zoom-pan-pinch": "^2.6.1",
"string-natural-compare": "^3.0.1", "string-natural-compare": "^3.0.1",
"throttle-debounce": "^5.0.0", "throttle-debounce": "^5.0.0",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
@ -58,25 +58,25 @@
"@types/marked": "^4.0.8", "@types/marked": "^4.0.8",
"@types/node": "18.13.0", "@types/node": "18.13.0",
"@types/nodemailer": "^6.4.7", "@types/nodemailer": "^6.4.7",
"@types/react": "^18.0.27", "@types/react": "^18.0.28",
"@types/react-dom": "^18.0.10", "@types/react-dom": "^18.0.11",
"@types/string-natural-compare": "^3.0.2", "@types/string-natural-compare": "^3.0.2",
"@types/throttle-debounce": "^5.0.0", "@types/throttle-debounce": "^5.0.0",
"@types/turndown": "^5.0.1", "@types/turndown": "^5.0.1",
"@types/ua-parser-js": "^0.7.36", "@types/ua-parser-js": "^0.7.36",
"@typescript-eslint/eslint-plugin": "^5.51.0", "@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.51.0", "@typescript-eslint/parser": "^5.52.0",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",
"eslint": "^8.33.0", "eslint": "^8.34.0",
"eslint-config-next": "13.1.6", "eslint-config-next": "13.1.6",
"eslint-plugin-import": "^2.27.5", "eslint-plugin-import": "^2.27.5",
"graphql": "^16.6.0", "graphql": "^16.6.0",
"graphql-request": "^5.1.0", "graphql-request": "^5.1.0",
"next-sitemap": "^3.1.52", "next-sitemap": "^3.1.52",
"prettier": "^2.8.4", "prettier": "^2.8.4",
"prettier-plugin-tailwindcss": "^0.2.2", "prettier-plugin-tailwindcss": "^0.2.3",
"tailwindcss": "^3.2.6", "tailwindcss": "^3.2.6",
"ts-unused-exports": "^9.0.3", "ts-unused-exports": "^9.0.4",
"typescript": "^4.9.5" "typescript": "^4.9.5"
}, },
"overrides": { "overrides": {

View File

@ -180,7 +180,11 @@
"definition_x": "Definition {x}", "definition_x": "Definition {x}",
"subitem_of_x": "Subitem of {x}", "subitem_of_x": "Subitem of {x}",
"variant_of_x": "Variant of {x}", "variant_of_x": "Variant of {x}",
"dark_mode_extension_warning": "This website offers a light and dark theme. If you are using a \"dark mode\" browser extension, make sure to disable it for an optimal experience." "dark_mode_extension_warning": "This website offers a light and dark theme. If you are using a \"dark mode\" browser extension, make sure to disable it for an optimal experience.",
"weapon": "{ count, plural, =0 {No weapons} one {Weapon} other {Weapons} }",
"weapons_description": "A list of all the weapons across all of the games. All distinguished weapons come with an “account.” Its a document with various details like how the weapon was forged and how its been used in the past.",
"level_x": "Level {x}",
"story_x": "Story {x}"
} }
}, },
{ {
@ -362,7 +366,11 @@
"definition_x": "Définition {x}", "definition_x": "Définition {x}",
"subitem_of_x": "Sous-item de {x}", "subitem_of_x": "Sous-item de {x}",
"variant_of_x": "Variante de {x}", "variant_of_x": "Variante de {x}",
"dark_mode_extension_warning": "Ce site web propose un thème clair et un thème sombre. Si vous utilisez une extension de navigateur qui simule un thème sombre, veillez à la désactiver pour une expérience optimale." "dark_mode_extension_warning": "Ce site web propose un thème clair et un thème sombre. Si vous utilisez une extension de navigateur qui simule un thème sombre, veillez à la désactiver pour une expérience optimale.",
"weapon": null,
"weapons_description": null,
"level_x": null,
"story_x": null
} }
}, },
{ {
@ -544,7 +552,11 @@
"definition_x": null, "definition_x": null,
"subitem_of_x": null, "subitem_of_x": null,
"variant_of_x": null, "variant_of_x": null,
"dark_mode_extension_warning": null "dark_mode_extension_warning": null,
"weapon": null,
"weapons_description": null,
"level_x": null,
"story_x": null
} }
}, },
{ {
@ -726,7 +738,11 @@
"definition_x": null, "definition_x": null,
"subitem_of_x": null, "subitem_of_x": null,
"variant_of_x": null, "variant_of_x": null,
"dark_mode_extension_warning": null "dark_mode_extension_warning": null,
"weapon": null,
"weapons_description": null,
"level_x": null,
"story_x": null
} }
}, },
{ {
@ -908,7 +924,11 @@
"definition_x": null, "definition_x": null,
"subitem_of_x": null, "subitem_of_x": null,
"variant_of_x": null, "variant_of_x": null,
"dark_mode_extension_warning": null "dark_mode_extension_warning": null,
"weapon": null,
"weapons_description": null,
"level_x": null,
"story_x": null
} }
} }
] ]

View File

@ -1,3 +1,4 @@
import { useHotkeys } from "react-hotkeys-hook";
import { Ico } from "components/Ico"; import { Ico } from "components/Ico";
import { PageSelector } from "components/Inputs/PageSelector"; import { PageSelector } from "components/Inputs/PageSelector";
import { atoms } from "contexts/atoms"; import { atoms } from "contexts/atoms";
@ -21,8 +22,14 @@ export const Paginator = ({
children, children,
}: Props): JSX.Element => { }: Props): JSX.Element => {
useScrollTopOnChange(Ids.ContentPanel, [page]); useScrollTopOnChange(Ids.ContentPanel, [page]);
useHotkeys("left", () => onPageChange(page - 1), { enabled: page > 1 }, [page]);
useHotkeys("right", () => onPageChange(page + 1), { enabled: page < (totalNumberOfPages ?? 0) }, [
page,
]);
if (totalNumberOfPages === 0) return <DefaultRenderWhenEmpty />; if (totalNumberOfPages === 0) return <DefaultRenderWhenEmpty />;
if (isUndefined(totalNumberOfPages) || totalNumberOfPages < 2) return <>{children}</>; if (isUndefined(totalNumberOfPages) || totalNumberOfPages < 2) return <>{children}</>;
return ( return (
<> <>
<PageSelector <PageSelector
@ -50,6 +57,7 @@ export const Paginator = ({
const DefaultRenderWhenEmpty = () => { const DefaultRenderWhenEmpty = () => {
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout); const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
const { format } = useFormat(); const { format } = useFormat();
return ( return (
<div className="grid h-full place-content-center"> <div className="grid h-full place-content-center">
<div <div

View File

@ -216,18 +216,12 @@ export const Markdawn = ({ className, text: rawText }: MarkdawnProps): JSX.Eleme
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
interface TableOfContentsProps { interface TableOfContentsProps {
text: string; toc: TocInterface;
title?: string;
onContentClicked?: MouseEventHandler<HTMLAnchorElement>; onContentClicked?: MouseEventHandler<HTMLAnchorElement>;
} }
export const TableOfContents = ({ export const TableOfContents = ({ toc, onContentClicked }: TableOfContentsProps): JSX.Element => {
text,
title,
onContentClicked,
}: TableOfContentsProps): JSX.Element => {
const { format } = useFormat(); const { format } = useFormat();
const toc = getTocFromMarkdawn(preprocessMarkDawn(text), title);
return ( return (
<> <>
@ -435,7 +429,14 @@ const markdawnHeadersParser = (
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
const getTocFromMarkdawn = (text: string, title?: string): TocInterface => { export const getTocFromMarkdawn = (
markdawn: string | null | undefined,
title?: string
): TocInterface | undefined => {
if (isUndefined(markdawn)) return undefined;
const text = preprocessMarkDawn(markdawn);
const toc: TocInterface = { const toc: TocInterface = {
title: title ?? "Return to top", title: title ?? "Return to top",
slug: slugify(title), slug: slugify(title),
@ -522,5 +523,6 @@ const getTocFromMarkdawn = (text: string, title?: string): TocInterface => {
} }
}); });
if (toc.children.length === 0) return undefined;
return toc; return toc;
}; };

View File

@ -14,6 +14,7 @@ import {
MeiliLibraryItem, MeiliLibraryItem,
MeiliPost, MeiliPost,
MeiliVideo, MeiliVideo,
MeiliWeapon,
MeiliWikiPage, MeiliWikiPage,
} from "shared/meilisearch-graphql-typings/meiliTypes"; } from "shared/meilisearch-graphql-typings/meiliTypes";
import { getVideoThumbnailURL } from "helpers/videos"; import { getVideoThumbnailURL } from "helpers/videos";
@ -43,6 +44,7 @@ export const SearchPopup = (): JSX.Element => {
const [videos, setVideos] = useState<CustomSearchResponse<MeiliVideo>>(); const [videos, setVideos] = useState<CustomSearchResponse<MeiliVideo>>();
const [posts, setPosts] = useState<CustomSearchResponse<MeiliPost>>(); const [posts, setPosts] = useState<CustomSearchResponse<MeiliPost>>();
const [wikiPages, setWikiPages] = useState<CustomSearchResponse<MeiliWikiPage>>(); const [wikiPages, setWikiPages] = useState<CustomSearchResponse<MeiliWikiPage>>();
const [weapons, setWeapons] = useState<CustomSearchResponse<MeiliWeapon>>();
useEffect(() => { useEffect(() => {
const fetchLibraryItems = async () => { const fetchLibraryItems = async () => {
@ -129,6 +131,25 @@ export const SearchPopup = (): JSX.Element => {
setPosts(searchResult); setPosts(searchResult);
}; };
const fetchWeapons = async () => {
const searchResult = await meiliSearch(MeiliIndices.WEAPON, query, {
limit: SEARCH_LIMIT,
attributesToRetrieve: ["*"],
attributesToHighlight: ["translations.description", "translations.names"],
attributesToCrop: ["translations.description"],
sort: ["slug:asc"],
});
searchResult.hits = searchResult.hits.map((item) => {
if (Object.keys(item._matchesPosition).some((match) => match.startsWith("translations"))) {
item._formatted.translations = filterDefined(item._formatted.translations).filter(
(translation) => JSON.stringify(translation).includes("</mark>")
);
}
return item;
});
setWeapons(searchResult);
};
const fetchWikiPages = async () => { const fetchWikiPages = async () => {
const searchResult = await meiliSearch(MeiliIndices.WIKI_PAGE, query, { const searchResult = await meiliSearch(MeiliIndices.WIKI_PAGE, query, {
limit: SEARCH_LIMIT, limit: SEARCH_LIMIT,
@ -160,12 +181,14 @@ export const SearchPopup = (): JSX.Element => {
setContents(undefined); setContents(undefined);
setVideos(undefined); setVideos(undefined);
setPosts(undefined); setPosts(undefined);
setWeapons(undefined);
} else { } else {
fetchWikiPages(); fetchWikiPages();
fetchLibraryItems(); fetchLibraryItems();
fetchContents(); fetchContents();
fetchVideos(); fetchVideos();
fetchPosts(); fetchPosts();
fetchWeapons();
} }
}, [query]); }, [query]);
@ -411,6 +434,48 @@ export const SearchPopup = (): JSX.Element => {
</div> </div>
</SearchResultSection> </SearchResultSection>
)} )}
{isDefined(weapons) && (
<SearchResultSection
title={format("weapon", { count: Infinity })}
icon="shield"
href={`/wiki/weapons?page=1&query=${query}`}
totalHits={weapons.estimatedTotalHits}>
<div className="flex flex-wrap items-start gap-x-6 gap-y-8">
{weapons.hits.map((item) => (
<TranslatedPreviewCard
key={item.id}
className="w-56"
href={"/"}
translations={filterHasAttributes(item._formatted.translations, [
"language.data.attributes.code",
] as const).map(
({ description, language, names: [primaryName, ...aliases] }) => ({
language: language.data.attributes.code,
title: primaryName,
subtitle: aliases.join("・"),
description: containsHighlight(description) ? description : undefined,
})
)}
fallback={{ title: prettySlug(item.slug) }}
thumbnail={item.thumbnail?.data?.attributes}
thumbnailAspectRatio="1/1"
thumbnailForceAspectRatio
thumbnailFitMethod="contain"
keepInfoVisible
topChips={
item.type?.data?.attributes?.slug
? [prettySlug(item.type.data.attributes.slug)]
: undefined
}
bottomChips={filterHasAttributes(item.categories, [
"attributes.short",
] as const).map((category) => category.attributes.short)}
/>
))}
</div>
</SearchResultSection>
)}
</div> </div>
</Popup> </Popup>
); );
@ -442,7 +507,7 @@ const SearchResultSection = ({
className="grid grid-cols-[auto_1fr] place-items-center gap-6 px-6 py-4" className="grid grid-cols-[auto_1fr] place-items-center gap-6 px-6 py-4"
href={href} href={href}
onClick={() => setSearchOpened(false)}> onClick={() => setSearchOpened(false)}>
<Ico icon={icon} className="!text-3xl" isFilled /> <Ico icon={icon} className="!text-3xl" isFilled={false} />
<div> <div>
<p className="font-headers text-lg">{title}</p> <p className="font-headers text-lg">{title}</p>
{isDefined(totalHits) && totalHits > SEARCH_LIMIT && ( {isDefined(totalHits) && totalHits > SEARCH_LIMIT && (

View File

@ -2,7 +2,7 @@ import { Fragment, useCallback } from "react";
import { AppLayout, AppLayoutRequired } from "./AppLayout"; import { AppLayout, AppLayoutRequired } from "./AppLayout";
import { Chip } from "./Chip"; import { Chip } from "./Chip";
import { HorizontalLine } from "./HorizontalLine"; import { HorizontalLine } from "./HorizontalLine";
import { Markdawn, TableOfContents } from "./Markdown/Markdawn"; import { getTocFromMarkdawn, Markdawn, TableOfContents } from "./Markdown/Markdawn";
import { ReturnButton } from "./PanelComponents/ReturnButton"; import { ReturnButton } from "./PanelComponents/ReturnButton";
import { ContentPanel } from "./Containers/ContentPanel"; import { ContentPanel } from "./Containers/ContentPanel";
import { SubPanel } from "./Containers/SubPanel"; import { SubPanel } from "./Containers/SubPanel";
@ -70,56 +70,55 @@ export const PostPage = ({
const title = selectedTranslation?.title ?? prettySlug(post.slug); const title = selectedTranslation?.title ?? prettySlug(post.slug);
const excerpt = selectedTranslation?.excerpt ?? ""; const excerpt = selectedTranslation?.excerpt ?? "";
const subPanel = ( const toc = getTocFromMarkdawn(body, title);
<SubPanel>
<ElementsSeparator>
{[
returnHref && returnTitle && !is1ColumnLayout && (
<ReturnButton href={returnHref} title={returnTitle} />
),
displayCredits && ( const subPanelElems = [
<> returnHref && returnTitle && !is1ColumnLayout && (
{selectedTranslation && ( <ReturnButton href={returnHref} title={returnTitle} />
<div className="grid grid-flow-col place-content-center place-items-center gap-2"> ),
<p className="font-headers font-bold">{format("status")}:</p>
<ToolTip displayCredits && (
content={formatStatusDescription(selectedTranslation.status)} <>
maxWidth={"20rem"}> {selectedTranslation && (
<Chip text={selectedTranslation.status} /> <div className="grid grid-flow-col place-content-center place-items-center gap-2">
</ToolTip> <p className="font-headers font-bold">{format("status")}:</p>
</div>
<ToolTip
content={formatStatusDescription(selectedTranslation.status)}
maxWidth={"20rem"}>
<Chip text={selectedTranslation.status} />
</ToolTip>
</div>
)}
{post.authors && post.authors.data.length > 0 && (
<div>
<p className="font-headers font-bold">{"Authors"}:</p>
<div className="grid place-content-center place-items-center gap-2">
{filterHasAttributes(post.authors.data, ["id", "attributes"] as const).map(
(author) => (
<Fragment key={author.id}>
<RecorderChip recorder={author.attributes} />
</Fragment>
)
)} )}
</div>
</div>
)}
</>
),
{post.authors && post.authors.data.length > 0 && ( displayToc && isDefined(toc) && (
<div> <TableOfContents toc={toc} onContentClicked={() => setSubPanelOpened(false)} />
<p className="font-headers font-bold">{"Authors"}:</p> ),
<div className="grid place-content-center place-items-center gap-2"> ];
{filterHasAttributes(post.authors.data, ["id", "attributes"] as const).map(
(author) => (
<Fragment key={author.id}>
<RecorderChip recorder={author.attributes} />
</Fragment>
)
)}
</div>
</div>
)}
</>
),
displayToc && ( const subPanel =
<TableOfContents subPanelElems.filter(Boolean).length > 0 ? (
text={body} <SubPanel>
title={title} <ElementsSeparator>{subPanelElems}</ElementsSeparator>
onContentClicked={() => setSubPanelOpened(false)} </SubPanel>
/> ) : undefined;
),
]}
</ElementsSeparator>
</SubPanel>
);
const contentPanel = ( const contentPanel = (
<ContentPanel> <ContentPanel>

View File

@ -24,6 +24,7 @@ interface Props {
thumbnail?: UploadImageFragment | string | null | undefined; thumbnail?: UploadImageFragment | string | null | undefined;
thumbnailAspectRatio?: string; thumbnailAspectRatio?: string;
thumbnailForceAspectRatio?: boolean; thumbnailForceAspectRatio?: boolean;
thumbnailFitMethod?: "contain" | "cover";
thumbnailRounded?: boolean; thumbnailRounded?: boolean;
href: string; href: string;
pre_title?: string | null | undefined; pre_title?: string | null | undefined;
@ -60,6 +61,7 @@ export const PreviewCard = ({
thumbnail, thumbnail,
thumbnailAspectRatio = "4/3", thumbnailAspectRatio = "4/3",
thumbnailForceAspectRatio = false, thumbnailForceAspectRatio = false,
thumbnailFitMethod = "cover",
thumbnailRounded = true, thumbnailRounded = true,
pre_title, pre_title,
title, title,
@ -133,7 +135,12 @@ export const PreviewCard = ({
thumbnailRounded, thumbnailRounded,
cIf(keepInfoVisible, "rounded-t-md", "rounded-md notHoverable:rounded-b-none") cIf(keepInfoVisible, "rounded-t-md", "rounded-md notHoverable:rounded-b-none")
), ),
cIf(thumbnailForceAspectRatio, "h-full w-full object-cover") cIf(thumbnailForceAspectRatio, "h-full w-full"),
cIf(
thumbnailForceAspectRatio && thumbnailFitMethod === "contain",
"object-contain",
"object-cover"
)
)} )}
src={thumbnail} src={thumbnail}
quality={ImageQuality.Medium} quality={ImageQuality.Medium}

View File

@ -179,4 +179,8 @@ export interface ICUParams {
subitem_of_x: { x: Date | boolean | number | string }; subitem_of_x: { x: Date | boolean | number | string };
variant_of_x: { x: Date | boolean | number | string }; variant_of_x: { x: Date | boolean | number | string };
dark_mode_extension_warning: never; dark_mode_extension_warning: never;
weapon: { count: number };
weapons_description: never;
level_x: { x: Date | boolean | number | string };
story_x: { x: Date | boolean | number | string };
} }

View File

@ -0,0 +1,92 @@
query getWeapon($slug: String, $language_code: String) {
weaponStories(filters: { slug: { eq: $slug } }) {
data {
attributes {
...sharedWeaponFragment
stories(pagination: { limit: -1 }) {
id
categories(pagination: { limit: -1 }) {
data {
id
attributes {
name
short
}
}
}
translations(pagination: { limit: -1 }) {
id
description
level_1
level_2
level_3
level_4
status
language {
data {
attributes {
code
}
}
}
}
}
weapon_group {
data {
attributes {
slug
weapons(pagination: { limit: -1 }, filters: { slug: { ne: $slug } }) {
data {
id
attributes {
...sharedWeaponFragment
}
}
}
}
}
}
}
}
}
}
fragment sharedWeaponFragment on WeaponStory {
type {
data {
id
attributes {
slug
translations(filters: { language: { code: { eq: $language_code } } }) {
name
language {
data {
attributes {
code
}
}
}
}
}
}
}
name(pagination: { limit: -1 }) {
id
name
language {
data {
attributes {
code
}
}
}
}
slug
thumbnail {
data {
attributes {
...uploadImage
}
}
}
}

View File

@ -0,0 +1,10 @@
query getWeaponsSlugs {
weaponStories(pagination: { limit: -1 }) {
data {
id
attributes {
slug
}
}
}
}

View File

@ -186,6 +186,10 @@ query localDataGetWebsiteInterfaces {
subitem_of_x subitem_of_x
variant_of_x variant_of_x
dark_mode_extension_warning dark_mode_extension_warning
weapon
weapons_description
level_x
story_x
} }
} }
} }

View File

@ -59,7 +59,13 @@ export const useFormat = (): {
if (isDefinedAndNotEmpty(result)) { if (isDefinedAndNotEmpty(result)) {
return result; return result;
} }
return new IntlMessageFormat(fallbackLangui[key] ?? "").format(processedValues).toString(); const fallback = new IntlMessageFormat(fallbackLangui[key] ?? "")
.format(processedValues)
.toString();
if (isDefinedAndNotEmpty(fallback)) {
return fallback;
}
return key;
}, },
[langui, fallbackLangui] [langui, fallbackLangui]
); );

View File

@ -17,10 +17,10 @@ interface ReaderSettings extends FilterSettings {
const DEFAULT_READER_SETTINGS: ReaderSettings = { const DEFAULT_READER_SETTINGS: ReaderSettings = {
bookFold: true, bookFold: true,
lighting: true, lighting: false,
paperTexture: true, paperTexture: true,
teint: 0.1, teint: 0.1,
dropShadow: true, dropShadow: false,
pageQuality: ImageQuality.Large, pageQuality: ImageQuality.Large,
isSidePagesEnabled: true, isSidePagesEnabled: true,
}; };

View File

@ -4,7 +4,7 @@ import naturalCompare from "string-natural-compare";
import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Chip } from "components/Chip"; import { Chip } from "components/Chip";
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs"; import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
import { Markdawn, TableOfContents } from "components/Markdown/Markdawn"; import { getTocFromMarkdawn, Markdawn, TableOfContents } from "components/Markdown/Markdawn";
import { TranslatedReturnButton } from "components/PanelComponents/ReturnButton"; import { TranslatedReturnButton } from "components/PanelComponents/ReturnButton";
import { ContentPanel } from "components/Containers/ContentPanel"; import { ContentPanel } from "components/Containers/ContentPanel";
import { SubPanel } from "components/Containers/SubPanel"; import { SubPanel } from "components/Containers/SubPanel";
@ -91,6 +91,15 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
}, },
}; };
const toc = getTocFromMarkdawn(
selectedTranslation?.text_set?.text,
prettyInlineTitle(
selectedTranslation?.pre_title,
selectedTranslation?.title,
selectedTranslation?.subtitle
)
);
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
<ElementsSeparator> <ElementsSeparator>
@ -191,17 +200,7 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
</div> </div>
), ),
selectedTranslation?.text_set?.text && ( toc && <TableOfContents toc={toc} onContentClicked={() => setSubPanelOpened(false)} />,
<TableOfContents
text={selectedTranslation.text_set.text}
title={prettyInlineTitle(
selectedTranslation.pre_title,
selectedTranslation.title,
selectedTranslation.subtitle
)}
onContentClicked={() => setSubPanelOpened(false)}
/>
),
content.ranged_contents?.data && content.ranged_contents.data.length > 0 && ( content.ranged_contents?.data && content.ranged_contents.data.length > 0 && (
<div> <div>

View File

@ -3,12 +3,13 @@ import { useCallback, useRef, useState } from "react";
import TurndownService from "turndown"; import TurndownService from "turndown";
import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Button } from "components/Inputs/Button"; import { Button } from "components/Inputs/Button";
import { Markdawn, TableOfContents } from "components/Markdown/Markdawn"; import { getTocFromMarkdawn, Markdawn, TableOfContents } from "components/Markdown/Markdawn";
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel"; import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { Popup } from "components/Containers/Popup"; import { Popup } from "components/Containers/Popup";
import { ToolTip } from "components/ToolTip"; import { ToolTip } from "components/ToolTip";
import { getOpenGraph } from "helpers/openGraph"; import { getOpenGraph } from "helpers/openGraph";
import { getFormat } from "helpers/i18n"; import { getFormat } from "helpers/i18n";
import { isDefined } from "helpers/asserts";
/* /*
* *
@ -155,6 +156,8 @@ const Editor = (props: Props): JSX.Element => {
[transformationWrapper] [transformationWrapper]
); );
const toc = getTocFromMarkdawn(markdown);
const contentPanel = ( const contentPanel = (
<ContentPanel width={ContentPanelWidthSizes.Full}> <ContentPanel width={ContentPanelWidthSizes.Full}>
<Popup isVisible={converterOpened} onCloseRequest={() => setConverterOpened(false)}> <Popup isVisible={converterOpened} onCloseRequest={() => setConverterOpened(false)}>
@ -388,9 +391,11 @@ const Editor = (props: Props): JSX.Element => {
</div> </div>
</div> </div>
<div className="mt-8"> {isDefined(toc) && (
<TableOfContents text={markdown} /> <div className="mt-8">
</div> <TableOfContents toc={toc} />
</div>
)}
</ContentPanel> </ContentPanel>
); );

View File

@ -47,13 +47,13 @@ import { useSmartLanguage } from "hooks/useSmartLanguage";
import { getOpenGraph } from "helpers/openGraph"; import { getOpenGraph } from "helpers/openGraph";
import { getDescription } from "helpers/description"; import { getDescription } from "helpers/description";
import { useIntersectionList } from "hooks/useIntersectionList"; import { useIntersectionList } from "hooks/useIntersectionList";
import { HorizontalLine } from "components/HorizontalLine";
import { Ids } from "types/ids"; import { Ids } from "types/ids";
import { atoms } from "contexts/atoms"; import { atoms } from "contexts/atoms";
import { useAtomGetter, useAtomSetter } from "helpers/atoms"; import { useAtomGetter, useAtomSetter } from "helpers/atoms";
import { Link } from "components/Inputs/Link"; import { Link } from "components/Inputs/Link";
import { useFormat } from "hooks/useFormat"; import { useFormat } from "hooks/useFormat";
import { getFormat } from "helpers/i18n"; import { getFormat } from "helpers/i18n";
import { ElementsSeparator } from "helpers/component";
/* /*
* *
@ -99,59 +99,69 @@ const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => {
(content) => content.attributes?.scan_set && content.attributes.scan_set.length > 0 (content) => content.attributes?.scan_set && content.attributes.scan_set.length > 0
); );
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
<ReturnButton href="/library/" title={format("library")} displayOnlyOn="3ColumnsLayout" /> <ElementsSeparator>
{[
is3ColumnsLayout && (
<ReturnButton
key="ReturnButton"
href="/library/"
title={format("library")}
displayOnlyOn="3ColumnsLayout"
/>
),
<div className="grid gap-4" key="NavOption">
<NavOption
title={format("summary")}
url={`#${intersectionIds[0]}`}
border
active={currentIntersection === 0}
onClick={closeSubPanel}
/>
<HorizontalLine /> {item.gallery && item.gallery.data.length > 0 && (
<NavOption
title={format("gallery")}
url={`#${intersectionIds[1]}`}
border
active={currentIntersection === 1}
onClick={closeSubPanel}
/>
)}
<div className="grid gap-4"> <NavOption
<NavOption title={format("details")}
title={format("summary")} url={`#${intersectionIds[2]}`}
url={`#${intersectionIds[0]}`} border
border active={currentIntersection === 2}
active={currentIntersection === 0} onClick={closeSubPanel}
onClick={closeSubPanel} />
/>
{item.gallery && item.gallery.data.length > 0 && ( {item.subitems && item.subitems.data.length > 0 && (
<NavOption <NavOption
title={format("gallery")} title={format(isVariantSet ? "variant" : "subitem", { count: Infinity })}
url={`#${intersectionIds[1]}`} url={`#${intersectionIds[3]}`}
border border
active={currentIntersection === 1} active={currentIntersection === 3}
onClick={closeSubPanel} onClick={closeSubPanel}
/> />
)} )}
<NavOption {item.contents && item.contents.data.length > 0 && (
title={format("details")} <NavOption
url={`#${intersectionIds[2]}`} title={format("contents")}
border url={`#${intersectionIds[4]}`}
active={currentIntersection === 2} border
onClick={closeSubPanel} active={currentIntersection === 4}
/> onClick={closeSubPanel}
/>
{item.subitems && item.subitems.data.length > 0 && ( )}
<NavOption </div>,
title={format(isVariantSet ? "variant" : "subitem", { count: Infinity })} ]}
url={`#${intersectionIds[3]}`} </ElementsSeparator>
border
active={currentIntersection === 3}
onClick={closeSubPanel}
/>
)}
{item.contents && item.contents.data.length > 0 && (
<NavOption
title={format("contents")}
url={`#${intersectionIds[4]}`}
border
active={currentIntersection === 4}
onClick={closeSubPanel}
/>
)}
</div>
</SubPanel> </SubPanel>
); );

View File

@ -129,6 +129,7 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
placeholder={format("search_title")} placeholder={format("search_title")}
value={query} value={query}
onChange={(name) => { onChange={(name) => {
setPage(1);
setQuery(name); setQuery(name);
if (isDefinedAndNotEmpty(name)) { if (isDefinedAndNotEmpty(name)) {
sendAnalytics("News", "Change search term"); sendAnalytics("News", "Change search term");

View File

@ -1,5 +1,5 @@
import { GetStaticProps } from "next"; import { GetStaticProps } from "next";
import { Fragment, useCallback } from "react"; import { Fragment, useCallback, useMemo } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { InsetBox } from "components/Containers/InsetBox"; import { InsetBox } from "components/Containers/InsetBox";
@ -27,6 +27,8 @@ import { useIntersectionList } from "hooks/useIntersectionList";
import { HorizontalLine } from "components/HorizontalLine"; import { HorizontalLine } from "components/HorizontalLine";
import { useFormat } from "hooks/useFormat"; import { useFormat } from "hooks/useFormat";
import { getFormat } from "helpers/i18n"; import { getFormat } from "helpers/i18n";
import { useAtomSetter } from "helpers/atoms";
import { atoms } from "contexts/atoms";
/* /*
* *
@ -40,8 +42,14 @@ interface Props extends AppLayoutRequired {
const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props): JSX.Element => { const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props): JSX.Element => {
const { format } = useFormat(); const { format } = useFormat();
const ids = filterHasAttributes(chronologyEras, ["attributes"] as const).map( const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
(era) => era.attributes.slug const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
const ids = useMemo(
() =>
filterHasAttributes(chronologyEras, ["attributes"] as const).map(
(era) => era.attributes.slug
),
[chronologyEras]
); );
const currentIntersection = useIntersectionList(ids); const currentIntersection = useIntersectionList(ids);
@ -69,6 +77,7 @@ const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props):
url={`#${era.attributes.slug}`} url={`#${era.attributes.slug}`}
border border
active={currentIntersection === index} active={currentIntersection === index}
onClick={closeSubPanel}
/> />
</Fragment> </Fragment>
))} ))}

View File

@ -1,5 +1,5 @@
import { GetStaticProps } from "next"; import { GetStaticProps } from "next";
import { useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { useBoolean } from "usehooks-ts"; import { useBoolean } from "usehooks-ts";
import { z } from "zod"; import { z } from "zod";
import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { AppLayout, AppLayoutRequired } from "components/AppLayout";
@ -24,6 +24,8 @@ import { containsHighlight, CustomSearchResponse, meiliSearch } from "helpers/se
import { Paginator } from "components/Containers/Paginator"; import { Paginator } from "components/Containers/Paginator";
import { useFormat } from "hooks/useFormat"; import { useFormat } from "hooks/useFormat";
import { getFormat } from "helpers/i18n"; import { getFormat } from "helpers/i18n";
import { useAtomSetter } from "helpers/atoms";
import { atoms } from "contexts/atoms";
/* /*
* *
@ -50,6 +52,8 @@ interface Props extends AppLayoutRequired {}
const Wiki = (props: Props): JSX.Element => { const Wiki = (props: Props): JSX.Element => {
const hoverable = useDeviceSupportsHover(); const hoverable = useDeviceSupportsHover();
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
const { format } = useFormat(); const { format } = useFormat();
const router = useTypedRouter(queryParamSchema); const router = useTypedRouter(queryParamSchema);
const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query); const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
@ -151,7 +155,18 @@ const Wiki = (props: Props): JSX.Element => {
<p className="mb-4 font-headers text-xl font-bold">{format("special_pages")}</p> <p className="mb-4 font-headers text-xl font-bold">{format("special_pages")}</p>
<NavOption title={format("chronology")} url="/wiki/chronology" border /> <NavOption
title={format("chronology")}
url="/wiki/chronology"
onClick={closeSubPanel}
border
/>
<NavOption
title={format("weapon", { count: Infinity })}
url="/wiki/weapons"
onClick={closeSubPanel}
border
/>
</SubPanel> </SubPanel>
); );

View File

@ -0,0 +1,297 @@
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
import { Fragment, useCallback, useMemo } from "react";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { getReadySdk } from "graphql/sdk";
import { filterDefined, filterHasAttributes, isDefinedAndNotEmpty } from "helpers/asserts";
import { getFormat } from "helpers/i18n";
import { getOpenGraph } from "helpers/openGraph";
import { ContentPanel } from "components/Containers/ContentPanel";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
import { useFormat } from "hooks/useFormat";
import { SubPanel } from "components/Containers/SubPanel";
import { ThumbnailHeader } from "components/ThumbnailHeader";
import { getDefaultPreferredLanguages } from "helpers/locales";
import { prettySlug } from "helpers/formatters";
import { useSmartLanguage } from "hooks/useSmartLanguage";
import { Weapon, WeaponGroupPreview, WeaponStoryWithTranslations } from "types/types";
import { InsetBox } from "components/Containers/InsetBox";
import { Chip } from "components/Chip";
import { Markdawn } from "components/Markdown/Markdawn";
import { NavOption } from "components/PanelComponents/NavOption";
import { HorizontalLine } from "components/HorizontalLine";
import { useIntersectionList } from "hooks/useIntersectionList";
import { ElementsSeparator } from "helpers/component";
import { useAtomGetter } from "helpers/atoms";
import { atoms } from "contexts/atoms";
import { TranslatedPreviewCard } from "components/PreviewCard";
/*
*
* PAGE
*/
interface Props extends AppLayoutRequired {
weapon: Weapon;
primaryName: string;
aliases: string[];
}
interface WeaponPreviewProps {
weapon: WeaponGroupPreview;
}
const WeaponPreview = ({ weapon }: WeaponPreviewProps): JSX.Element => (
<TranslatedPreviewCard
href={`/wiki/weapons/${weapon.slug}`}
translations={filterHasAttributes(weapon.name, ["language.data.attributes.code"] as const).map(
({ name, language }) => ({
language: language.data.attributes.code,
title: name,
})
)}
fallback={{ title: prettySlug(weapon.slug) }}
thumbnail={weapon.thumbnail?.data?.attributes}
thumbnailAspectRatio="1/1"
thumbnailForceAspectRatio
thumbnailFitMethod="contain"
keepInfoVisible
topChips={
weapon.type?.data?.attributes?.slug
? [prettySlug(weapon.type.data.attributes.slug)]
: undefined
}
/>
);
const WeaponPage = ({ weapon, primaryName, aliases, ...otherProps }: Props): JSX.Element => {
const { format } = useFormat();
const intersectionIds = useMemo(
() => filterDefined(weapon.stories).map(({ id }) => `story-${id}`),
[weapon.stories]
);
const currentIntersection = useIntersectionList(intersectionIds);
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
const subPanel = (
<SubPanel>
<ElementsSeparator>
{[
is3ColumnsLayout && (
<ReturnButton
key="return-button"
href="/wiki/weapons"
title={format("weapon", { count: Infinity })}
/>
),
<Fragment key="nav-options">
{intersectionIds.map((id, index) => (
<NavOption
key={index}
url={`#${id}`}
title={`Story ${index + 1}`}
subtitle={weapon.stories?.[index]?.categories?.data
.map((category) => category.attributes?.name)
.join("・")}
active={currentIntersection === index}
border
/>
))}
</Fragment>,
weapon.weapon_group?.data?.attributes?.weapons?.data && (
<>
<h3>Weapon group</h3>
<p className="mb-8">{`${
weapon.weapon_group.data.attributes.weapons.data.length
} other weapons part of the ${prettySlug(
weapon.weapon_group.data.attributes.slug
)}'s group`}</p>
<div className="grid gap-8">
{filterHasAttributes(weapon.weapon_group.data.attributes.weapons.data, [
"attributes",
] as const).map((groupWeapon) => (
<WeaponPreview key={groupWeapon.id} weapon={groupWeapon.attributes} />
))}
</div>
</>
),
]}
</ElementsSeparator>
</SubPanel>
);
const contentPanel = (
<ContentPanel>
<ReturnButton
href="/wiki/weapons"
title={format("weapon", { count: Infinity })}
displayOnlyOn="1ColumnLayout"
className="mb-10"
/>
<ThumbnailHeader
title={primaryName}
subtitle={aliases.join("・")}
thumbnail={weapon.thumbnail?.data?.attributes}
/>
<HorizontalLine className="mb-12" />
<div className="grid gap-8">
<ElementsSeparator>
{filterHasAttributes(weapon.stories, ["translations"] as const).map((story, index) => (
<WeaponStory
key={story.id}
id={intersectionIds[index]}
story={story}
storyNumber={index + 1}
/>
))}
</ElementsSeparator>
</div>
</ContentPanel>
);
return <AppLayout contentPanel={contentPanel} subPanel={subPanel} {...otherProps} />;
};
export default WeaponPage;
/*
*
* NEXT DATA FETCHING
*/
export const getStaticProps: GetStaticProps = async (context) => {
const sdk = getReadySdk();
const { format } = getFormat(context.locale);
const slug = context.params?.slug ? context.params.slug.toString() : "";
const weaponResp = await sdk.getWeapon({
slug: slug,
language_code: context.locale ?? "en",
});
const weapon = weaponResp.weaponStories?.data[0]?.attributes;
if (!weapon?.stories || !context.locale || !context.locales) {
return { notFound: true };
}
const names = weapon.name;
const preferredLanguages = getDefaultPreferredLanguages(context.locale, context.locales);
const [primaryName, ...aliases] = getFilteredNames(names, preferredLanguages);
const props: Props = {
primaryName: primaryName ?? prettySlug(slug),
aliases,
// eslint-disable-next-line id-denylist
weapon,
openGraph: getOpenGraph(format, undefined, undefined, weapon.thumbnail?.data?.attributes),
};
return {
props: props,
};
};
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
export const getStaticPaths: GetStaticPaths = async (context) => {
const sdk = getReadySdk();
const weapons = await sdk.getWeaponsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
filterHasAttributes(weapons.weaponStories?.data, ["attributes"] as const).map((item) => {
context.locales?.map((local) => {
paths.push({
params: { slug: item.attributes.slug },
locale: local,
});
});
});
return {
paths,
fallback: "blocking",
};
};
/*
*
* PRIVATE COMPONENTS
*/
interface WeaponStoryProps {
story: WeaponStoryWithTranslations;
storyNumber: number;
id?: string;
}
const WeaponStory = ({ story, storyNumber, id }: WeaponStoryProps): JSX.Element => {
const { format } = useFormat();
const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({
items: story.translations,
languageExtractor: useCallback(
(item: WeaponStoryProps["story"]["translations"][number]) =>
item?.language?.data?.attributes?.code,
[]
),
});
if (!selectedTranslation) return <></>;
return (
<InsetBox id={id} className="formatted">
<h2 className="!mt-4 !mb-4">{format("story_x", { x: storyNumber })}</h2>
{languageSwitcherProps.locales.size > 1 && <LanguageSwitcher {...languageSwitcherProps} />}
{story.categories && story.categories.data.length > 0 && (
<div className="mb-12 flex flex-row flex-wrap place-content-center gap-2">
{filterHasAttributes(story.categories.data, ["attributes.name"] as const).map(
(category) => (
<Chip key={category.id} text={category.attributes.name} />
)
)}
</div>
)}
{isDefinedAndNotEmpty(selectedTranslation.description) && (
<div className="mb-8">
<h3>{format("description")}</h3>
{selectedTranslation.description}
</div>
)}
<h3>{format("level_x", { x: 1 })}</h3>
<Markdawn text={selectedTranslation.level_1 ?? "To be added"} />
<h3>{format("level_x", { x: 2 })}</h3>
<Markdawn text={selectedTranslation.level_2 ?? "To be added"} />
<h3>{format("level_x", { x: 3 })}</h3>
<Markdawn text={selectedTranslation.level_3 ?? "To be added"} />
<h3>{format("level_x", { x: 4 })}</h3>
<Markdawn text={selectedTranslation.level_4 ?? "To be added"} />
</InsetBox>
);
};
/*
*
* PRIVATE METHODS
*/
export const getFilteredNames = (
names: Props["weapon"]["name"],
preferredLanguages: string[]
): string[] => {
for (const language of preferredLanguages) {
const filteredNames = filterHasAttributes(names, ["name"] as const).filter(
(name) => name.language?.data?.attributes?.code === language
);
if (filteredNames.length > 0) {
return filteredNames.map((name) => name.name);
}
}
return [];
};

View File

@ -0,0 +1,237 @@
import { GetStaticProps } from "next";
import { z } from "zod";
import { useEffect, useState } from "react";
import { useBoolean } from "usehooks-ts";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { getFormat } from "helpers/i18n";
import { getOpenGraph } from "helpers/openGraph";
import { SubPanel } from "components/Containers/SubPanel";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
import { TextInput } from "components/Inputs/TextInput";
import { useTypedRouter } from "hooks/useTypedRouter";
import { useFormat } from "hooks/useFormat";
import {
filterDefined,
filterHasAttributes,
isDefined,
isDefinedAndNotEmpty,
} from "helpers/asserts";
import { sendAnalytics } from "helpers/analytics";
import { Button } from "components/Inputs/Button";
import { HorizontalLine } from "components/HorizontalLine";
import { containsHighlight, CustomSearchResponse, meiliSearch } from "helpers/search";
import { MeiliIndices, MeiliWeapon } from "shared/meilisearch-graphql-typings/meiliTypes";
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { Paginator } from "components/Containers/Paginator";
import { TranslatedPreviewCard } from "components/PreviewCard";
import { prettySlug } from "helpers/formatters";
import { useDeviceSupportsHover } from "hooks/useMediaQuery";
import { WithLabel } from "components/Inputs/WithLabel";
import { Switch } from "components/Inputs/Switch";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
/*
*
* CONSTANTS
*/
const DEFAULT_FILTERS_STATE = {
query: "",
keepInfoVisible: true,
page: 1,
};
const queryParamSchema = z.object({
query: z.coerce.string().optional(),
page: z.coerce.number().positive().optional(),
});
/*
*
* PAGE
*/
interface Props extends AppLayoutRequired {}
const Weapons = (props: Props): JSX.Element => {
const { format } = useFormat();
const hoverable = useDeviceSupportsHover();
const router = useTypedRouter(queryParamSchema);
const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
const [page, setPage] = useState<number>(router.query.page ?? DEFAULT_FILTERS_STATE.page);
const {
value: keepInfoVisible,
toggle: toggleKeepInfoVisible,
setValue: setKeepInfoVisible,
} = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible);
const [weapons, setWeapons] = useState<CustomSearchResponse<MeiliWeapon>>();
useEffect(() => {
const fetchPosts = async () => {
const searchResult = await meiliSearch(MeiliIndices.WEAPON, query, {
hitsPerPage: 25,
page,
attributesToRetrieve: ["*"],
attributesToHighlight: ["translations.description", "translations.names"],
attributesToCrop: ["translations.description"],
sort: ["slug:asc"],
});
searchResult.hits = searchResult.hits.map((item) => {
if (Object.keys(item._matchesPosition).some((match) => match.startsWith("translations"))) {
item._formatted.translations = filterDefined(item._formatted.translations).filter(
(translation) => JSON.stringify(translation).includes("</mark>")
);
}
return item;
});
setWeapons(searchResult);
};
fetchPosts();
}, [query, page]);
useEffect(() => {
if (router.isReady)
router.updateQuery({
page,
query,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [page, query, router.isReady]);
useEffect(() => {
if (router.isReady) {
if (isDefined(router.query.page)) setPage(router.query.page);
if (isDefined(router.query.query)) setQuery(router.query.query);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router.isReady]);
const subPanel = (
<SubPanel>
<ReturnButton
href="/wiki"
title={format("wiki")}
displayOnlyOn="3ColumnsLayout"
className="mb-10"
/>
<PanelHeader
icon="shield"
title={format("weapon", { count: Infinity })}
description={format("weapons_description")}
/>
<HorizontalLine />
<TextInput
className="mb-6 w-full"
placeholder={format("search_title")}
value={query}
onChange={(name) => {
setPage(1);
setQuery(name);
if (isDefinedAndNotEmpty(name)) {
sendAnalytics("Weapons", "Change search term");
} else {
sendAnalytics("Weapons", "Clear search term");
}
}}
/>
{hoverable && (
<WithLabel label={format("always_show_info")}>
<Switch
value={keepInfoVisible}
onClick={() => {
toggleKeepInfoVisible();
sendAnalytics("Weapons", `Always ${keepInfoVisible ? "hide" : "show"} info`);
}}
/>
</WithLabel>
)}
<Button
className="mt-8"
text={format("reset_all_filters")}
icon="settings_backup_restore"
onClick={() => {
setQuery(DEFAULT_FILTERS_STATE.query);
setKeepInfoVisible(DEFAULT_FILTERS_STATE.keepInfoVisible);
sendAnalytics("Weapons", "Reset all filters");
}}
/>
</SubPanel>
);
const contentPanel = (
<ContentPanel width={ContentPanelWidthSizes.Full}>
<ReturnButton
href="/wiki"
title={format("wiki")}
displayOnlyOn="1ColumnLayout"
className="mb-10"
/>
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={weapons?.totalPages}>
<div
className="grid grid-cols-[repeat(auto-fill,_minmax(12rem,1fr))] items-start
gap-x-6 gap-y-8">
{weapons?.hits.map((item) => (
<TranslatedPreviewCard
key={item.id}
href={`/wiki/weapons/${item.slug}`}
translations={filterHasAttributes(item._formatted.translations, [
"language.data.attributes.code",
] as const).map(({ description, language, names: [primaryName, ...aliases] }) => ({
language: language.data.attributes.code,
title: primaryName,
subtitle: aliases.join("・"),
description: containsHighlight(description) ? description : undefined,
}))}
fallback={{ title: prettySlug(item.slug) }}
thumbnail={item.thumbnail?.data?.attributes}
thumbnailAspectRatio="1/1"
thumbnailForceAspectRatio
thumbnailFitMethod="contain"
keepInfoVisible={keepInfoVisible}
topChips={
item.type?.data?.attributes?.slug
? [prettySlug(item.type.data.attributes.slug)]
: undefined
}
bottomChips={filterHasAttributes(item.categories, ["attributes.short"] as const).map(
(category) => category.attributes.short
)}
/>
))}
</div>
</Paginator>
</ContentPanel>
);
return (
<>
<AppLayout contentPanel={contentPanel} subPanel={subPanel} {...props} />
</>
);
};
export default Weapons;
/*
*
* NEXT DATA FETCHING
*/
export const getStaticProps: GetStaticProps = (context) => {
const { format } = getFormat(context.locale);
const props: Props = {
openGraph: getOpenGraph(format, format("weapon", { count: Infinity })),
};
return {
props: props,
};
};

View File

@ -4715,7 +4715,7 @@ export type WeaponStory = {
__typename?: "WeaponStory"; __typename?: "WeaponStory";
createdAt?: Maybe<Scalars["DateTime"]>; createdAt?: Maybe<Scalars["DateTime"]>;
name?: Maybe<Array<Maybe<ComponentTranslationsWeaponStory>>>; name?: Maybe<Array<Maybe<ComponentTranslationsWeaponStory>>>;
slug?: Maybe<Scalars["String"]>; slug: Scalars["String"];
stories?: Maybe<Array<Maybe<ComponentCollectionsComponentWeaponStory>>>; stories?: Maybe<Array<Maybe<ComponentCollectionsComponentWeaponStory>>>;
thumbnail?: Maybe<UploadFileEntityResponse>; thumbnail?: Maybe<UploadFileEntityResponse>;
type?: Maybe<WeaponStoryTypeEntityResponse>; type?: Maybe<WeaponStoryTypeEntityResponse>;
@ -4772,10 +4772,18 @@ export type WeaponStoryGroup = {
__typename?: "WeaponStoryGroup"; __typename?: "WeaponStoryGroup";
createdAt?: Maybe<Scalars["DateTime"]>; createdAt?: Maybe<Scalars["DateTime"]>;
slug: Scalars["String"]; slug: Scalars["String"];
subgroup_of?: Maybe<WeaponStoryGroupEntityResponse>;
subgroups?: Maybe<WeaponStoryGroupRelationResponseCollection>;
updatedAt?: Maybe<Scalars["DateTime"]>; updatedAt?: Maybe<Scalars["DateTime"]>;
weapons?: Maybe<WeaponStoryRelationResponseCollection>; weapons?: Maybe<WeaponStoryRelationResponseCollection>;
}; };
export type WeaponStoryGroupSubgroupsArgs = {
filters?: InputMaybe<WeaponStoryGroupFiltersInput>;
pagination?: InputMaybe<PaginationArg>;
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
};
export type WeaponStoryGroupWeaponsArgs = { export type WeaponStoryGroupWeaponsArgs = {
filters?: InputMaybe<WeaponStoryFiltersInput>; filters?: InputMaybe<WeaponStoryFiltersInput>;
pagination?: InputMaybe<PaginationArg>; pagination?: InputMaybe<PaginationArg>;
@ -4806,15 +4814,24 @@ export type WeaponStoryGroupFiltersInput = {
not?: InputMaybe<WeaponStoryGroupFiltersInput>; not?: InputMaybe<WeaponStoryGroupFiltersInput>;
or?: InputMaybe<Array<InputMaybe<WeaponStoryGroupFiltersInput>>>; or?: InputMaybe<Array<InputMaybe<WeaponStoryGroupFiltersInput>>>;
slug?: InputMaybe<StringFilterInput>; slug?: InputMaybe<StringFilterInput>;
subgroup_of?: InputMaybe<WeaponStoryGroupFiltersInput>;
subgroups?: InputMaybe<WeaponStoryGroupFiltersInput>;
updatedAt?: InputMaybe<DateTimeFilterInput>; updatedAt?: InputMaybe<DateTimeFilterInput>;
weapons?: InputMaybe<WeaponStoryFiltersInput>; weapons?: InputMaybe<WeaponStoryFiltersInput>;
}; };
export type WeaponStoryGroupInput = { export type WeaponStoryGroupInput = {
slug?: InputMaybe<Scalars["String"]>; slug?: InputMaybe<Scalars["String"]>;
subgroup_of?: InputMaybe<Scalars["ID"]>;
subgroups?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
weapons?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>; weapons?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
}; };
export type WeaponStoryGroupRelationResponseCollection = {
__typename?: "WeaponStoryGroupRelationResponseCollection";
data: Array<WeaponStoryGroupEntity>;
};
export type WeaponStoryInput = { export type WeaponStoryInput = {
name?: InputMaybe<Array<InputMaybe<ComponentTranslationsWeaponStoryInput>>>; name?: InputMaybe<Array<InputMaybe<ComponentTranslationsWeaponStoryInput>>>;
slug?: InputMaybe<Scalars["String"]>; slug?: InputMaybe<Scalars["String"]>;
@ -4962,7 +4979,6 @@ export type WebsiteInterface = {
binding?: Maybe<Scalars["String"]>; binding?: Maybe<Scalars["String"]>;
book_fold?: Maybe<Scalars["String"]>; book_fold?: Maybe<Scalars["String"]>;
calculated?: Maybe<Scalars["String"]>; calculated?: Maybe<Scalars["String"]>;
categories?: Maybe<Scalars["String"]>;
category?: Maybe<Scalars["String"]>; category?: Maybe<Scalars["String"]>;
change_language?: Maybe<Scalars["String"]>; change_language?: Maybe<Scalars["String"]>;
channel?: Maybe<Scalars["String"]>; channel?: Maybe<Scalars["String"]>;
@ -4984,8 +5000,9 @@ export type WebsiteInterface = {
createdAt?: Maybe<Scalars["DateTime"]>; createdAt?: Maybe<Scalars["DateTime"]>;
currency?: Maybe<Scalars["String"]>; currency?: Maybe<Scalars["String"]>;
dark?: Maybe<Scalars["String"]>; dark?: Maybe<Scalars["String"]>;
dark_mode_extension_warning?: Maybe<Scalars["String"]>;
default_description?: Maybe<Scalars["String"]>; default_description?: Maybe<Scalars["String"]>;
definition?: Maybe<Scalars["String"]>; definition_x?: Maybe<Scalars["String"]>;
description?: Maybe<Scalars["String"]>; description?: Maybe<Scalars["String"]>;
details?: Maybe<Scalars["String"]>; details?: Maybe<Scalars["String"]>;
display_all_items?: Maybe<Scalars["String"]>; display_all_items?: Maybe<Scalars["String"]>;
@ -5001,7 +5018,6 @@ export type WebsiteInterface = {
font_size?: Maybe<Scalars["String"]>; font_size?: Maybe<Scalars["String"]>;
front_matter?: Maybe<Scalars["String"]>; front_matter?: Maybe<Scalars["String"]>;
gallery?: Maybe<Scalars["String"]>; gallery?: Maybe<Scalars["String"]>;
gallery_description?: Maybe<Scalars["String"]>;
game?: Maybe<Scalars["String"]>; game?: Maybe<Scalars["String"]>;
group?: Maybe<Scalars["String"]>; group?: Maybe<Scalars["String"]>;
group_by?: Maybe<Scalars["String"]>; group_by?: Maybe<Scalars["String"]>;
@ -5011,10 +5027,7 @@ export type WebsiteInterface = {
incomplete?: Maybe<Scalars["String"]>; incomplete?: Maybe<Scalars["String"]>;
item?: Maybe<Scalars["String"]>; item?: Maybe<Scalars["String"]>;
item_not_available?: Maybe<Scalars["String"]>; item_not_available?: Maybe<Scalars["String"]>;
items?: Maybe<Scalars["String"]>;
language?: Maybe<Scalars["String"]>; language?: Maybe<Scalars["String"]>;
language_switch_message?: Maybe<Scalars["String"]>;
languages?: Maybe<Scalars["String"]>;
least_popular?: Maybe<Scalars["String"]>; least_popular?: Maybe<Scalars["String"]>;
left_to_right?: Maybe<Scalars["String"]>; left_to_right?: Maybe<Scalars["String"]>;
legality?: Maybe<Scalars["String"]>; legality?: Maybe<Scalars["String"]>;
@ -5026,9 +5039,6 @@ export type WebsiteInterface = {
lighting?: Maybe<Scalars["String"]>; lighting?: Maybe<Scalars["String"]>;
listen_content?: Maybe<Scalars["String"]>; listen_content?: Maybe<Scalars["String"]>;
longest?: Maybe<Scalars["String"]>; longest?: Maybe<Scalars["String"]>;
members?: Maybe<Scalars["String"]>;
merch?: Maybe<Scalars["String"]>;
merch_description?: Maybe<Scalars["String"]>;
message?: Maybe<Scalars["String"]>; message?: Maybe<Scalars["String"]>;
most_popular?: Maybe<Scalars["String"]>; most_popular?: Maybe<Scalars["String"]>;
name?: Maybe<Scalars["String"]>; name?: Maybe<Scalars["String"]>;
@ -5036,11 +5046,8 @@ export type WebsiteInterface = {
news?: Maybe<Scalars["String"]>; news?: Maybe<Scalars["String"]>;
news_description?: Maybe<Scalars["String"]>; news_description?: Maybe<Scalars["String"]>;
night_reader?: Maybe<Scalars["String"]>; night_reader?: Maybe<Scalars["String"]>;
no_category?: Maybe<Scalars["String"]>;
no_results_message?: Maybe<Scalars["String"]>; no_results_message?: Maybe<Scalars["String"]>;
no_source_warning?: Maybe<Scalars["String"]>; no_source_warning?: Maybe<Scalars["String"]>;
no_type?: Maybe<Scalars["String"]>;
no_year?: Maybe<Scalars["String"]>;
notes?: Maybe<Scalars["String"]>; notes?: Maybe<Scalars["String"]>;
oldest?: Maybe<Scalars["String"]>; oldest?: Maybe<Scalars["String"]>;
only_display_items_i_have?: Maybe<Scalars["String"]>; only_display_items_i_have?: Maybe<Scalars["String"]>;
@ -5055,7 +5062,6 @@ export type WebsiteInterface = {
page?: Maybe<Scalars["String"]>; page?: Maybe<Scalars["String"]>;
page_not_found?: Maybe<Scalars["String"]>; page_not_found?: Maybe<Scalars["String"]>;
page_order?: Maybe<Scalars["String"]>; page_order?: Maybe<Scalars["String"]>;
pages?: Maybe<Scalars["String"]>;
paper_texture?: Maybe<Scalars["String"]>; paper_texture?: Maybe<Scalars["String"]>;
paperback?: Maybe<Scalars["String"]>; paperback?: Maybe<Scalars["String"]>;
player_name?: Maybe<Scalars["String"]>; player_name?: Maybe<Scalars["String"]>;
@ -5074,9 +5080,7 @@ export type WebsiteInterface = {
response_email_success?: Maybe<Scalars["String"]>; response_email_success?: Maybe<Scalars["String"]>;
response_invalid_code?: Maybe<Scalars["String"]>; response_invalid_code?: Maybe<Scalars["String"]>;
response_invalid_email?: Maybe<Scalars["String"]>; response_invalid_email?: Maybe<Scalars["String"]>;
result?: Maybe<Scalars["String"]>; return_to_x?: Maybe<Scalars["String"]>;
results?: Maybe<Scalars["String"]>;
return_to?: Maybe<Scalars["String"]>;
review?: Maybe<Scalars["String"]>; review?: Maybe<Scalars["String"]>;
right_to_left?: Maybe<Scalars["String"]>; right_to_left?: Maybe<Scalars["String"]>;
scan?: Maybe<Scalars["String"]>; scan?: Maybe<Scalars["String"]>;
@ -5095,6 +5099,7 @@ export type WebsiteInterface = {
show_primary_items?: Maybe<Scalars["String"]>; show_primary_items?: Maybe<Scalars["String"]>;
show_secondary_items?: Maybe<Scalars["String"]>; show_secondary_items?: Maybe<Scalars["String"]>;
show_subitems?: Maybe<Scalars["String"]>; show_subitems?: Maybe<Scalars["String"]>;
showing_x_out_of_y_results?: Maybe<Scalars["String"]>;
side_pages?: Maybe<Scalars["String"]>; side_pages?: Maybe<Scalars["String"]>;
single_page_view?: Maybe<Scalars["String"]>; single_page_view?: Maybe<Scalars["String"]>;
size?: Maybe<Scalars["String"]>; size?: Maybe<Scalars["String"]>;
@ -5107,8 +5112,7 @@ export type WebsiteInterface = {
status_incomplete?: Maybe<Scalars["String"]>; status_incomplete?: Maybe<Scalars["String"]>;
status_review?: Maybe<Scalars["String"]>; status_review?: Maybe<Scalars["String"]>;
subitem?: Maybe<Scalars["String"]>; subitem?: Maybe<Scalars["String"]>;
subitem_of?: Maybe<Scalars["String"]>; subitem_of_x?: Maybe<Scalars["String"]>;
subitems?: Maybe<Scalars["String"]>;
subscribers?: Maybe<Scalars["String"]>; subscribers?: Maybe<Scalars["String"]>;
summary?: Maybe<Scalars["String"]>; summary?: Maybe<Scalars["String"]>;
switch_to_folder_view?: Maybe<Scalars["String"]>; switch_to_folder_view?: Maybe<Scalars["String"]>;
@ -5128,8 +5132,7 @@ export type WebsiteInterface = {
ui_language?: Maybe<LanguageEntityResponse>; ui_language?: Maybe<LanguageEntityResponse>;
updatedAt?: Maybe<Scalars["DateTime"]>; updatedAt?: Maybe<Scalars["DateTime"]>;
variant?: Maybe<Scalars["String"]>; variant?: Maybe<Scalars["String"]>;
variant_of?: Maybe<Scalars["String"]>; variant_of_x?: Maybe<Scalars["String"]>;
variants?: Maybe<Scalars["String"]>;
video?: Maybe<Scalars["String"]>; video?: Maybe<Scalars["String"]>;
videos?: Maybe<Scalars["String"]>; videos?: Maybe<Scalars["String"]>;
view_on?: Maybe<Scalars["String"]>; view_on?: Maybe<Scalars["String"]>;
@ -5140,6 +5143,7 @@ export type WebsiteInterface = {
wiki?: Maybe<Scalars["String"]>; wiki?: Maybe<Scalars["String"]>;
wiki_description?: Maybe<Scalars["String"]>; wiki_description?: Maybe<Scalars["String"]>;
wiki_short_description?: Maybe<Scalars["String"]>; wiki_short_description?: Maybe<Scalars["String"]>;
x_results?: Maybe<Scalars["String"]>;
}; };
export type WebsiteInterfaceEntity = { export type WebsiteInterfaceEntity = {
@ -5176,7 +5180,6 @@ export type WebsiteInterfaceFiltersInput = {
binding?: InputMaybe<StringFilterInput>; binding?: InputMaybe<StringFilterInput>;
book_fold?: InputMaybe<StringFilterInput>; book_fold?: InputMaybe<StringFilterInput>;
calculated?: InputMaybe<StringFilterInput>; calculated?: InputMaybe<StringFilterInput>;
categories?: InputMaybe<StringFilterInput>;
category?: InputMaybe<StringFilterInput>; category?: InputMaybe<StringFilterInput>;
change_language?: InputMaybe<StringFilterInput>; change_language?: InputMaybe<StringFilterInput>;
channel?: InputMaybe<StringFilterInput>; channel?: InputMaybe<StringFilterInput>;
@ -5198,8 +5201,9 @@ export type WebsiteInterfaceFiltersInput = {
createdAt?: InputMaybe<DateTimeFilterInput>; createdAt?: InputMaybe<DateTimeFilterInput>;
currency?: InputMaybe<StringFilterInput>; currency?: InputMaybe<StringFilterInput>;
dark?: InputMaybe<StringFilterInput>; dark?: InputMaybe<StringFilterInput>;
dark_mode_extension_warning?: InputMaybe<StringFilterInput>;
default_description?: InputMaybe<StringFilterInput>; default_description?: InputMaybe<StringFilterInput>;
definition?: InputMaybe<StringFilterInput>; definition_x?: InputMaybe<StringFilterInput>;
description?: InputMaybe<StringFilterInput>; description?: InputMaybe<StringFilterInput>;
details?: InputMaybe<StringFilterInput>; details?: InputMaybe<StringFilterInput>;
display_all_items?: InputMaybe<StringFilterInput>; display_all_items?: InputMaybe<StringFilterInput>;
@ -5215,7 +5219,6 @@ export type WebsiteInterfaceFiltersInput = {
font_size?: InputMaybe<StringFilterInput>; font_size?: InputMaybe<StringFilterInput>;
front_matter?: InputMaybe<StringFilterInput>; front_matter?: InputMaybe<StringFilterInput>;
gallery?: InputMaybe<StringFilterInput>; gallery?: InputMaybe<StringFilterInput>;
gallery_description?: InputMaybe<StringFilterInput>;
game?: InputMaybe<StringFilterInput>; game?: InputMaybe<StringFilterInput>;
group?: InputMaybe<StringFilterInput>; group?: InputMaybe<StringFilterInput>;
group_by?: InputMaybe<StringFilterInput>; group_by?: InputMaybe<StringFilterInput>;
@ -5226,10 +5229,7 @@ export type WebsiteInterfaceFiltersInput = {
incomplete?: InputMaybe<StringFilterInput>; incomplete?: InputMaybe<StringFilterInput>;
item?: InputMaybe<StringFilterInput>; item?: InputMaybe<StringFilterInput>;
item_not_available?: InputMaybe<StringFilterInput>; item_not_available?: InputMaybe<StringFilterInput>;
items?: InputMaybe<StringFilterInput>;
language?: InputMaybe<StringFilterInput>; language?: InputMaybe<StringFilterInput>;
language_switch_message?: InputMaybe<StringFilterInput>;
languages?: InputMaybe<StringFilterInput>;
least_popular?: InputMaybe<StringFilterInput>; least_popular?: InputMaybe<StringFilterInput>;
left_to_right?: InputMaybe<StringFilterInput>; left_to_right?: InputMaybe<StringFilterInput>;
legality?: InputMaybe<StringFilterInput>; legality?: InputMaybe<StringFilterInput>;
@ -5241,9 +5241,6 @@ export type WebsiteInterfaceFiltersInput = {
lighting?: InputMaybe<StringFilterInput>; lighting?: InputMaybe<StringFilterInput>;
listen_content?: InputMaybe<StringFilterInput>; listen_content?: InputMaybe<StringFilterInput>;
longest?: InputMaybe<StringFilterInput>; longest?: InputMaybe<StringFilterInput>;
members?: InputMaybe<StringFilterInput>;
merch?: InputMaybe<StringFilterInput>;
merch_description?: InputMaybe<StringFilterInput>;
message?: InputMaybe<StringFilterInput>; message?: InputMaybe<StringFilterInput>;
most_popular?: InputMaybe<StringFilterInput>; most_popular?: InputMaybe<StringFilterInput>;
name?: InputMaybe<StringFilterInput>; name?: InputMaybe<StringFilterInput>;
@ -5251,11 +5248,8 @@ export type WebsiteInterfaceFiltersInput = {
news?: InputMaybe<StringFilterInput>; news?: InputMaybe<StringFilterInput>;
news_description?: InputMaybe<StringFilterInput>; news_description?: InputMaybe<StringFilterInput>;
night_reader?: InputMaybe<StringFilterInput>; night_reader?: InputMaybe<StringFilterInput>;
no_category?: InputMaybe<StringFilterInput>;
no_results_message?: InputMaybe<StringFilterInput>; no_results_message?: InputMaybe<StringFilterInput>;
no_source_warning?: InputMaybe<StringFilterInput>; no_source_warning?: InputMaybe<StringFilterInput>;
no_type?: InputMaybe<StringFilterInput>;
no_year?: InputMaybe<StringFilterInput>;
not?: InputMaybe<WebsiteInterfaceFiltersInput>; not?: InputMaybe<WebsiteInterfaceFiltersInput>;
notes?: InputMaybe<StringFilterInput>; notes?: InputMaybe<StringFilterInput>;
oldest?: InputMaybe<StringFilterInput>; oldest?: InputMaybe<StringFilterInput>;
@ -5272,7 +5266,6 @@ export type WebsiteInterfaceFiltersInput = {
page?: InputMaybe<StringFilterInput>; page?: InputMaybe<StringFilterInput>;
page_not_found?: InputMaybe<StringFilterInput>; page_not_found?: InputMaybe<StringFilterInput>;
page_order?: InputMaybe<StringFilterInput>; page_order?: InputMaybe<StringFilterInput>;
pages?: InputMaybe<StringFilterInput>;
paper_texture?: InputMaybe<StringFilterInput>; paper_texture?: InputMaybe<StringFilterInput>;
paperback?: InputMaybe<StringFilterInput>; paperback?: InputMaybe<StringFilterInput>;
player_name?: InputMaybe<StringFilterInput>; player_name?: InputMaybe<StringFilterInput>;
@ -5291,9 +5284,7 @@ export type WebsiteInterfaceFiltersInput = {
response_email_success?: InputMaybe<StringFilterInput>; response_email_success?: InputMaybe<StringFilterInput>;
response_invalid_code?: InputMaybe<StringFilterInput>; response_invalid_code?: InputMaybe<StringFilterInput>;
response_invalid_email?: InputMaybe<StringFilterInput>; response_invalid_email?: InputMaybe<StringFilterInput>;
result?: InputMaybe<StringFilterInput>; return_to_x?: InputMaybe<StringFilterInput>;
results?: InputMaybe<StringFilterInput>;
return_to?: InputMaybe<StringFilterInput>;
review?: InputMaybe<StringFilterInput>; review?: InputMaybe<StringFilterInput>;
right_to_left?: InputMaybe<StringFilterInput>; right_to_left?: InputMaybe<StringFilterInput>;
scan?: InputMaybe<StringFilterInput>; scan?: InputMaybe<StringFilterInput>;
@ -5312,6 +5303,7 @@ export type WebsiteInterfaceFiltersInput = {
show_primary_items?: InputMaybe<StringFilterInput>; show_primary_items?: InputMaybe<StringFilterInput>;
show_secondary_items?: InputMaybe<StringFilterInput>; show_secondary_items?: InputMaybe<StringFilterInput>;
show_subitems?: InputMaybe<StringFilterInput>; show_subitems?: InputMaybe<StringFilterInput>;
showing_x_out_of_y_results?: InputMaybe<StringFilterInput>;
side_pages?: InputMaybe<StringFilterInput>; side_pages?: InputMaybe<StringFilterInput>;
single_page_view?: InputMaybe<StringFilterInput>; single_page_view?: InputMaybe<StringFilterInput>;
size?: InputMaybe<StringFilterInput>; size?: InputMaybe<StringFilterInput>;
@ -5324,8 +5316,7 @@ export type WebsiteInterfaceFiltersInput = {
status_incomplete?: InputMaybe<StringFilterInput>; status_incomplete?: InputMaybe<StringFilterInput>;
status_review?: InputMaybe<StringFilterInput>; status_review?: InputMaybe<StringFilterInput>;
subitem?: InputMaybe<StringFilterInput>; subitem?: InputMaybe<StringFilterInput>;
subitem_of?: InputMaybe<StringFilterInput>; subitem_of_x?: InputMaybe<StringFilterInput>;
subitems?: InputMaybe<StringFilterInput>;
subscribers?: InputMaybe<StringFilterInput>; subscribers?: InputMaybe<StringFilterInput>;
summary?: InputMaybe<StringFilterInput>; summary?: InputMaybe<StringFilterInput>;
switch_to_folder_view?: InputMaybe<StringFilterInput>; switch_to_folder_view?: InputMaybe<StringFilterInput>;
@ -5345,8 +5336,7 @@ export type WebsiteInterfaceFiltersInput = {
ui_language?: InputMaybe<LanguageFiltersInput>; ui_language?: InputMaybe<LanguageFiltersInput>;
updatedAt?: InputMaybe<DateTimeFilterInput>; updatedAt?: InputMaybe<DateTimeFilterInput>;
variant?: InputMaybe<StringFilterInput>; variant?: InputMaybe<StringFilterInput>;
variant_of?: InputMaybe<StringFilterInput>; variant_of_x?: InputMaybe<StringFilterInput>;
variants?: InputMaybe<StringFilterInput>;
video?: InputMaybe<StringFilterInput>; video?: InputMaybe<StringFilterInput>;
videos?: InputMaybe<StringFilterInput>; videos?: InputMaybe<StringFilterInput>;
view_on?: InputMaybe<StringFilterInput>; view_on?: InputMaybe<StringFilterInput>;
@ -5357,6 +5347,7 @@ export type WebsiteInterfaceFiltersInput = {
wiki?: InputMaybe<StringFilterInput>; wiki?: InputMaybe<StringFilterInput>;
wiki_description?: InputMaybe<StringFilterInput>; wiki_description?: InputMaybe<StringFilterInput>;
wiki_short_description?: InputMaybe<StringFilterInput>; wiki_short_description?: InputMaybe<StringFilterInput>;
x_results?: InputMaybe<StringFilterInput>;
}; };
export type WebsiteInterfaceInput = { export type WebsiteInterfaceInput = {
@ -5375,7 +5366,6 @@ export type WebsiteInterfaceInput = {
binding?: InputMaybe<Scalars["String"]>; binding?: InputMaybe<Scalars["String"]>;
book_fold?: InputMaybe<Scalars["String"]>; book_fold?: InputMaybe<Scalars["String"]>;
calculated?: InputMaybe<Scalars["String"]>; calculated?: InputMaybe<Scalars["String"]>;
categories?: InputMaybe<Scalars["String"]>;
category?: InputMaybe<Scalars["String"]>; category?: InputMaybe<Scalars["String"]>;
change_language?: InputMaybe<Scalars["String"]>; change_language?: InputMaybe<Scalars["String"]>;
channel?: InputMaybe<Scalars["String"]>; channel?: InputMaybe<Scalars["String"]>;
@ -5396,8 +5386,9 @@ export type WebsiteInterfaceInput = {
cover?: InputMaybe<Scalars["String"]>; cover?: InputMaybe<Scalars["String"]>;
currency?: InputMaybe<Scalars["String"]>; currency?: InputMaybe<Scalars["String"]>;
dark?: InputMaybe<Scalars["String"]>; dark?: InputMaybe<Scalars["String"]>;
dark_mode_extension_warning?: InputMaybe<Scalars["String"]>;
default_description?: InputMaybe<Scalars["String"]>; default_description?: InputMaybe<Scalars["String"]>;
definition?: InputMaybe<Scalars["String"]>; definition_x?: InputMaybe<Scalars["String"]>;
description?: InputMaybe<Scalars["String"]>; description?: InputMaybe<Scalars["String"]>;
details?: InputMaybe<Scalars["String"]>; details?: InputMaybe<Scalars["String"]>;
display_all_items?: InputMaybe<Scalars["String"]>; display_all_items?: InputMaybe<Scalars["String"]>;
@ -5413,7 +5404,6 @@ export type WebsiteInterfaceInput = {
font_size?: InputMaybe<Scalars["String"]>; font_size?: InputMaybe<Scalars["String"]>;
front_matter?: InputMaybe<Scalars["String"]>; front_matter?: InputMaybe<Scalars["String"]>;
gallery?: InputMaybe<Scalars["String"]>; gallery?: InputMaybe<Scalars["String"]>;
gallery_description?: InputMaybe<Scalars["String"]>;
game?: InputMaybe<Scalars["String"]>; game?: InputMaybe<Scalars["String"]>;
group?: InputMaybe<Scalars["String"]>; group?: InputMaybe<Scalars["String"]>;
group_by?: InputMaybe<Scalars["String"]>; group_by?: InputMaybe<Scalars["String"]>;
@ -5423,10 +5413,7 @@ export type WebsiteInterfaceInput = {
incomplete?: InputMaybe<Scalars["String"]>; incomplete?: InputMaybe<Scalars["String"]>;
item?: InputMaybe<Scalars["String"]>; item?: InputMaybe<Scalars["String"]>;
item_not_available?: InputMaybe<Scalars["String"]>; item_not_available?: InputMaybe<Scalars["String"]>;
items?: InputMaybe<Scalars["String"]>;
language?: InputMaybe<Scalars["String"]>; language?: InputMaybe<Scalars["String"]>;
language_switch_message?: InputMaybe<Scalars["String"]>;
languages?: InputMaybe<Scalars["String"]>;
least_popular?: InputMaybe<Scalars["String"]>; least_popular?: InputMaybe<Scalars["String"]>;
left_to_right?: InputMaybe<Scalars["String"]>; left_to_right?: InputMaybe<Scalars["String"]>;
legality?: InputMaybe<Scalars["String"]>; legality?: InputMaybe<Scalars["String"]>;
@ -5438,9 +5425,6 @@ export type WebsiteInterfaceInput = {
lighting?: InputMaybe<Scalars["String"]>; lighting?: InputMaybe<Scalars["String"]>;
listen_content?: InputMaybe<Scalars["String"]>; listen_content?: InputMaybe<Scalars["String"]>;
longest?: InputMaybe<Scalars["String"]>; longest?: InputMaybe<Scalars["String"]>;
members?: InputMaybe<Scalars["String"]>;
merch?: InputMaybe<Scalars["String"]>;
merch_description?: InputMaybe<Scalars["String"]>;
message?: InputMaybe<Scalars["String"]>; message?: InputMaybe<Scalars["String"]>;
most_popular?: InputMaybe<Scalars["String"]>; most_popular?: InputMaybe<Scalars["String"]>;
name?: InputMaybe<Scalars["String"]>; name?: InputMaybe<Scalars["String"]>;
@ -5448,11 +5432,8 @@ export type WebsiteInterfaceInput = {
news?: InputMaybe<Scalars["String"]>; news?: InputMaybe<Scalars["String"]>;
news_description?: InputMaybe<Scalars["String"]>; news_description?: InputMaybe<Scalars["String"]>;
night_reader?: InputMaybe<Scalars["String"]>; night_reader?: InputMaybe<Scalars["String"]>;
no_category?: InputMaybe<Scalars["String"]>;
no_results_message?: InputMaybe<Scalars["String"]>; no_results_message?: InputMaybe<Scalars["String"]>;
no_source_warning?: InputMaybe<Scalars["String"]>; no_source_warning?: InputMaybe<Scalars["String"]>;
no_type?: InputMaybe<Scalars["String"]>;
no_year?: InputMaybe<Scalars["String"]>;
notes?: InputMaybe<Scalars["String"]>; notes?: InputMaybe<Scalars["String"]>;
oldest?: InputMaybe<Scalars["String"]>; oldest?: InputMaybe<Scalars["String"]>;
only_display_items_i_have?: InputMaybe<Scalars["String"]>; only_display_items_i_have?: InputMaybe<Scalars["String"]>;
@ -5467,7 +5448,6 @@ export type WebsiteInterfaceInput = {
page?: InputMaybe<Scalars["String"]>; page?: InputMaybe<Scalars["String"]>;
page_not_found?: InputMaybe<Scalars["String"]>; page_not_found?: InputMaybe<Scalars["String"]>;
page_order?: InputMaybe<Scalars["String"]>; page_order?: InputMaybe<Scalars["String"]>;
pages?: InputMaybe<Scalars["String"]>;
paper_texture?: InputMaybe<Scalars["String"]>; paper_texture?: InputMaybe<Scalars["String"]>;
paperback?: InputMaybe<Scalars["String"]>; paperback?: InputMaybe<Scalars["String"]>;
player_name?: InputMaybe<Scalars["String"]>; player_name?: InputMaybe<Scalars["String"]>;
@ -5486,9 +5466,7 @@ export type WebsiteInterfaceInput = {
response_email_success?: InputMaybe<Scalars["String"]>; response_email_success?: InputMaybe<Scalars["String"]>;
response_invalid_code?: InputMaybe<Scalars["String"]>; response_invalid_code?: InputMaybe<Scalars["String"]>;
response_invalid_email?: InputMaybe<Scalars["String"]>; response_invalid_email?: InputMaybe<Scalars["String"]>;
result?: InputMaybe<Scalars["String"]>; return_to_x?: InputMaybe<Scalars["String"]>;
results?: InputMaybe<Scalars["String"]>;
return_to?: InputMaybe<Scalars["String"]>;
review?: InputMaybe<Scalars["String"]>; review?: InputMaybe<Scalars["String"]>;
right_to_left?: InputMaybe<Scalars["String"]>; right_to_left?: InputMaybe<Scalars["String"]>;
scan?: InputMaybe<Scalars["String"]>; scan?: InputMaybe<Scalars["String"]>;
@ -5507,6 +5485,7 @@ export type WebsiteInterfaceInput = {
show_primary_items?: InputMaybe<Scalars["String"]>; show_primary_items?: InputMaybe<Scalars["String"]>;
show_secondary_items?: InputMaybe<Scalars["String"]>; show_secondary_items?: InputMaybe<Scalars["String"]>;
show_subitems?: InputMaybe<Scalars["String"]>; show_subitems?: InputMaybe<Scalars["String"]>;
showing_x_out_of_y_results?: InputMaybe<Scalars["String"]>;
side_pages?: InputMaybe<Scalars["String"]>; side_pages?: InputMaybe<Scalars["String"]>;
single_page_view?: InputMaybe<Scalars["String"]>; single_page_view?: InputMaybe<Scalars["String"]>;
size?: InputMaybe<Scalars["String"]>; size?: InputMaybe<Scalars["String"]>;
@ -5519,8 +5498,7 @@ export type WebsiteInterfaceInput = {
status_incomplete?: InputMaybe<Scalars["String"]>; status_incomplete?: InputMaybe<Scalars["String"]>;
status_review?: InputMaybe<Scalars["String"]>; status_review?: InputMaybe<Scalars["String"]>;
subitem?: InputMaybe<Scalars["String"]>; subitem?: InputMaybe<Scalars["String"]>;
subitem_of?: InputMaybe<Scalars["String"]>; subitem_of_x?: InputMaybe<Scalars["String"]>;
subitems?: InputMaybe<Scalars["String"]>;
subscribers?: InputMaybe<Scalars["String"]>; subscribers?: InputMaybe<Scalars["String"]>;
summary?: InputMaybe<Scalars["String"]>; summary?: InputMaybe<Scalars["String"]>;
switch_to_folder_view?: InputMaybe<Scalars["String"]>; switch_to_folder_view?: InputMaybe<Scalars["String"]>;
@ -5539,8 +5517,7 @@ export type WebsiteInterfaceInput = {
typesetters?: InputMaybe<Scalars["String"]>; typesetters?: InputMaybe<Scalars["String"]>;
ui_language?: InputMaybe<Scalars["ID"]>; ui_language?: InputMaybe<Scalars["ID"]>;
variant?: InputMaybe<Scalars["String"]>; variant?: InputMaybe<Scalars["String"]>;
variant_of?: InputMaybe<Scalars["String"]>; variant_of_x?: InputMaybe<Scalars["String"]>;
variants?: InputMaybe<Scalars["String"]>;
video?: InputMaybe<Scalars["String"]>; video?: InputMaybe<Scalars["String"]>;
videos?: InputMaybe<Scalars["String"]>; videos?: InputMaybe<Scalars["String"]>;
view_on?: InputMaybe<Scalars["String"]>; view_on?: InputMaybe<Scalars["String"]>;
@ -5551,6 +5528,7 @@ export type WebsiteInterfaceInput = {
wiki?: InputMaybe<Scalars["String"]>; wiki?: InputMaybe<Scalars["String"]>;
wiki_description?: InputMaybe<Scalars["String"]>; wiki_description?: InputMaybe<Scalars["String"]>;
wiki_short_description?: InputMaybe<Scalars["String"]>; wiki_short_description?: InputMaybe<Scalars["String"]>;
x_results?: InputMaybe<Scalars["String"]>;
}; };
export type WikiPage = { export type WikiPage = {
@ -6005,6 +5983,88 @@ export type VideoAttributesFragment = {
} | null; } | null;
}; };
export type WeaponAttributesFragment = {
__typename?: "WeaponStory";
slug: string;
thumbnail?: {
__typename?: "UploadFileEntityResponse";
data?: {
__typename?: "UploadFileEntity";
attributes?: {
__typename?: "UploadFile";
name: string;
alternativeText?: string | null;
caption?: string | null;
width?: number | null;
height?: number | null;
url: string;
} | null;
} | null;
} | null;
type?: {
__typename?: "WeaponStoryTypeEntityResponse";
data?: {
__typename?: "WeaponStoryTypeEntity";
id?: string | null;
attributes?: {
__typename?: "WeaponStoryType";
slug: string;
translations?: Array<{
__typename?: "ComponentTranslationsWeaponStoryType";
name?: string | null;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
} | null;
} | null;
} | null;
name?: Array<{
__typename?: "ComponentTranslationsWeaponStory";
id: string;
name?: string | null;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
stories?: Array<{
__typename?: "ComponentCollectionsComponentWeaponStory";
id: string;
categories?: {
__typename?: "CategoryRelationResponseCollection";
data: Array<{
__typename?: "CategoryEntity";
id?: string | null;
attributes?: { __typename?: "Category"; short: string } | null;
}>;
} | null;
translations?: Array<{
__typename?: "ComponentTranslationsWeaponStoryStory";
description?: string | null;
level_1?: string | null;
level_2?: string | null;
level_3?: string | null;
level_4?: string | null;
status: Enum_Componenttranslationsweaponstorystory_Status;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
} | null> | null;
};
export type WikiPageAttributesFragment = { export type WikiPageAttributesFragment = {
__typename?: "WikiPage"; __typename?: "WikiPage";
slug: string; slug: string;
@ -6804,6 +6864,196 @@ export type GetVideosQuery = {
} | null; } | null;
}; };
export type GetWeaponQueryVariables = Exact<{
id?: InputMaybe<Scalars["ID"]>;
}>;
export type GetWeaponQuery = {
__typename?: "Query";
weaponStory?: {
__typename?: "WeaponStoryEntityResponse";
data?: {
__typename?: "WeaponStoryEntity";
id?: string | null;
attributes?: {
__typename?: "WeaponStory";
slug: string;
thumbnail?: {
__typename?: "UploadFileEntityResponse";
data?: {
__typename?: "UploadFileEntity";
attributes?: {
__typename?: "UploadFile";
name: string;
alternativeText?: string | null;
caption?: string | null;
width?: number | null;
height?: number | null;
url: string;
} | null;
} | null;
} | null;
type?: {
__typename?: "WeaponStoryTypeEntityResponse";
data?: {
__typename?: "WeaponStoryTypeEntity";
id?: string | null;
attributes?: {
__typename?: "WeaponStoryType";
slug: string;
translations?: Array<{
__typename?: "ComponentTranslationsWeaponStoryType";
name?: string | null;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
} | null;
} | null;
} | null;
name?: Array<{
__typename?: "ComponentTranslationsWeaponStory";
id: string;
name?: string | null;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
stories?: Array<{
__typename?: "ComponentCollectionsComponentWeaponStory";
id: string;
categories?: {
__typename?: "CategoryRelationResponseCollection";
data: Array<{
__typename?: "CategoryEntity";
id?: string | null;
attributes?: { __typename?: "Category"; short: string } | null;
}>;
} | null;
translations?: Array<{
__typename?: "ComponentTranslationsWeaponStoryStory";
description?: string | null;
level_1?: string | null;
level_2?: string | null;
level_3?: string | null;
level_4?: string | null;
status: Enum_Componenttranslationsweaponstorystory_Status;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
} | null> | null;
} | null;
} | null;
} | null;
};
export type GetWeaponsQueryVariables = Exact<{ [key: string]: never }>;
export type GetWeaponsQuery = {
__typename?: "Query";
weaponStories?: {
__typename?: "WeaponStoryEntityResponseCollection";
data: Array<{
__typename?: "WeaponStoryEntity";
id?: string | null;
attributes?: {
__typename?: "WeaponStory";
slug: string;
thumbnail?: {
__typename?: "UploadFileEntityResponse";
data?: {
__typename?: "UploadFileEntity";
attributes?: {
__typename?: "UploadFile";
name: string;
alternativeText?: string | null;
caption?: string | null;
width?: number | null;
height?: number | null;
url: string;
} | null;
} | null;
} | null;
type?: {
__typename?: "WeaponStoryTypeEntityResponse";
data?: {
__typename?: "WeaponStoryTypeEntity";
id?: string | null;
attributes?: {
__typename?: "WeaponStoryType";
slug: string;
translations?: Array<{
__typename?: "ComponentTranslationsWeaponStoryType";
name?: string | null;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
} | null;
} | null;
} | null;
name?: Array<{
__typename?: "ComponentTranslationsWeaponStory";
id: string;
name?: string | null;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
stories?: Array<{
__typename?: "ComponentCollectionsComponentWeaponStory";
id: string;
categories?: {
__typename?: "CategoryRelationResponseCollection";
data: Array<{
__typename?: "CategoryEntity";
id?: string | null;
attributes?: { __typename?: "Category"; short: string } | null;
}>;
} | null;
translations?: Array<{
__typename?: "ComponentTranslationsWeaponStoryStory";
description?: string | null;
level_1?: string | null;
level_2?: string | null;
level_3?: string | null;
level_4?: string | null;
status: Enum_Componenttranslationsweaponstorystory_Status;
language?: {
__typename?: "LanguageEntityResponse";
data?: {
__typename?: "LanguageEntity";
attributes?: { __typename?: "Language"; code: string } | null;
} | null;
} | null;
} | null> | null;
} | null> | null;
} | null;
}>;
} | null;
};
export type GetWikiPageQueryVariables = Exact<{ export type GetWikiPageQueryVariables = Exact<{
id?: InputMaybe<Scalars["ID"]>; id?: InputMaybe<Scalars["ID"]>;
}>; }>;
@ -7289,6 +7539,74 @@ export const VideoAttributesFragmentDoc = gql`
duration duration
} }
`; `;
export const WeaponAttributesFragmentDoc = gql`
fragment weaponAttributes on WeaponStory {
thumbnail {
data {
attributes {
...uploadImage
}
}
}
type {
data {
id
attributes {
slug
translations(filters: { language: { code: { eq: "en" } } }) {
name
language {
data {
attributes {
code
}
}
}
}
}
}
}
name(pagination: { limit: -1 }) {
id
name
language {
data {
attributes {
code
}
}
}
}
slug
stories(pagination: { limit: -1 }) {
id
categories(pagination: { limit: -1 }) {
data {
id
attributes {
short
}
}
}
translations(pagination: { limit: -1 }) {
description
level_1
level_2
level_3
level_4
status
language {
data {
attributes {
code
}
}
}
}
}
}
${UploadImageFragmentDoc}
`;
export const WikiPageAttributesFragmentDoc = gql` export const WikiPageAttributesFragmentDoc = gql`
fragment wikiPageAttributes on WikiPage { fragment wikiPageAttributes on WikiPage {
slug slug
@ -7462,6 +7780,32 @@ export const GetVideosDocument = gql`
} }
${VideoAttributesFragmentDoc} ${VideoAttributesFragmentDoc}
`; `;
export const GetWeaponDocument = gql`
query getWeapon($id: ID) {
weaponStory(id: $id) {
data {
id
attributes {
...weaponAttributes
}
}
}
}
${WeaponAttributesFragmentDoc}
`;
export const GetWeaponsDocument = gql`
query getWeapons {
weaponStories(pagination: { limit: -1 }) {
data {
id
attributes {
...weaponAttributes
}
}
}
}
${WeaponAttributesFragmentDoc}
`;
export const GetWikiPageDocument = gql` export const GetWikiPageDocument = gql`
query getWikiPage($id: ID) { query getWikiPage($id: ID) {
wikiPage(id: $id) { wikiPage(id: $id) {
@ -7611,6 +7955,34 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
"query" "query"
); );
}, },
getWeapon(
variables?: GetWeaponQueryVariables,
requestHeaders?: Dom.RequestInit["headers"]
): Promise<GetWeaponQuery> {
return withWrapper(
(wrappedRequestHeaders) =>
client.request<GetWeaponQuery>(GetWeaponDocument, variables, {
...requestHeaders,
...wrappedRequestHeaders,
}),
"getWeapon",
"query"
);
},
getWeapons(
variables?: GetWeaponsQueryVariables,
requestHeaders?: Dom.RequestInit["headers"]
): Promise<GetWeaponsQuery> {
return withWrapper(
(wrappedRequestHeaders) =>
client.request<GetWeaponsQuery>(GetWeaponsDocument, variables, {
...requestHeaders,
...wrappedRequestHeaders,
}),
"getWeapons",
"query"
);
},
getWikiPage( getWikiPage(
variables?: GetWikiPageQueryVariables, variables?: GetWikiPageQueryVariables,
requestHeaders?: Dom.RequestInit["headers"] requestHeaders?: Dom.RequestInit["headers"]

View File

@ -4,10 +4,12 @@ import {
GetLibraryItemQuery, GetLibraryItemQuery,
GetPostQuery, GetPostQuery,
GetVideoQuery, GetVideoQuery,
GetWeaponQuery,
GetWikiPageQuery, GetWikiPageQuery,
LibraryItemAttributesFragment, LibraryItemAttributesFragment,
PostAttributesFragment, PostAttributesFragment,
VideoAttributesFragment, VideoAttributesFragment,
WeaponAttributesFragment,
WikiPageAttributesFragment, WikiPageAttributesFragment,
} from "./generated"; } from "./generated";
@ -24,7 +26,7 @@ export interface MeiliContent
id: string; id: string;
translations: (Omit< translations: (Omit<
NonNullable<NonNullable<ContentAttributesFragment["translations"]>[number]>, NonNullable<NonNullable<ContentAttributesFragment["translations"]>[number]>,
"text_set" | "description" "description" | "text_set"
> & { > & {
displayable_description?: string | null; displayable_description?: string | null;
})[]; })[];
@ -52,35 +54,60 @@ export interface MeiliWikiPage extends Omit<WikiPageAttributesFragment, "transla
})[]; })[];
} }
type WeaponAttributesTranslation = NonNullable<
NonNullable<
NonNullable<NonNullable<WeaponAttributesFragment["stories"]>[number]>["translations"]
>[number]
>;
export interface MeiliWeapon extends Omit<WeaponAttributesFragment, "name" | "stories"> {
id: string;
categories: NonNullable<
NonNullable<NonNullable<WeaponAttributesFragment["stories"]>[number]>["categories"]
>["data"];
translations: {
id: NonNullable<NonNullable<WeaponAttributesFragment["stories"]>[number]>["id"];
names: string[];
description: string;
language: WeaponAttributesTranslation["language"];
}[];
}
export enum MeiliIndices { export enum MeiliIndices {
LIBRARY_ITEM = "library-item", LIBRARY_ITEM = "library-item",
CONTENT = "content", CONTENT = "content",
VIDEOS = "video", VIDEOS = "video",
POST = "post", POST = "post",
WIKI_PAGE = "wiki-page", WIKI_PAGE = "wiki-page",
WEAPON = "weapon-story",
} }
export type MeiliDocumentsType = export type MeiliDocumentsType =
| {
index: MeiliIndices.LIBRARY_ITEM;
documents: MeiliLibraryItem;
strapi: GetLibraryItemQuery["libraryItem"];
}
| { | {
index: MeiliIndices.CONTENT; index: MeiliIndices.CONTENT;
documents: MeiliContent; documents: MeiliContent;
strapi: GetContentQuery["content"]; strapi: GetContentQuery["content"];
} }
| { | {
index: MeiliIndices.VIDEOS; index: MeiliIndices.LIBRARY_ITEM;
documents: MeiliVideo; documents: MeiliLibraryItem;
strapi: GetVideoQuery["video"]; strapi: GetLibraryItemQuery["libraryItem"];
} }
| { | {
index: MeiliIndices.POST; index: MeiliIndices.POST;
documents: MeiliPost; documents: MeiliPost;
strapi: GetPostQuery["post"]; strapi: GetPostQuery["post"];
} }
| {
index: MeiliIndices.VIDEOS;
documents: MeiliVideo;
strapi: GetVideoQuery["video"];
}
| {
index: MeiliIndices.WEAPON;
documents: MeiliWeapon;
strapi: GetWeaponQuery["weaponStory"];
}
| { | {
index: MeiliIndices.WIKI_PAGE; index: MeiliIndices.WIKI_PAGE;
documents: MeiliWikiPage; documents: MeiliWikiPage;

View File

@ -2,6 +2,7 @@ import {
GetChronicleQuery, GetChronicleQuery,
GetContentTextQuery, GetContentTextQuery,
GetPostQuery, GetPostQuery,
GetWeaponQuery,
GetWikiPageQuery, GetWikiPageQuery,
} from "graphql/generated"; } from "graphql/generated";
@ -45,6 +46,28 @@ export interface ChronicleWithTranslations extends Omit<Chronicle, "translations
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
export type Weapon = NonNullable<
NonNullable<NonNullable<GetWeaponQuery["weaponStories"]>["data"][number]>["attributes"]
>;
type WeaponStory = NonNullable<NonNullable<Weapon["stories"]>[number]>;
export interface WeaponStoryWithTranslations extends Omit<WeaponStory, "translations"> {
translations: NonNullable<NonNullable<WeaponStory>["translations"]>;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
export type WeaponGroupPreview = NonNullable<
NonNullable<
NonNullable<
NonNullable<NonNullable<NonNullable<Weapon["weapon_group"]>["data"]>["attributes"]>["weapons"]
>["data"][number]["attributes"]
>
>;
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
export enum LibraryItemUserStatus { export enum LibraryItemUserStatus {
None = 0, None = 0,
Want = 1, Want = 1,