diff --git a/CHANGELOG.md b/CHANGELOG.md index 0635ee0..258fa46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,42 @@ # 📈 LIST OF CHANGES FOR WEREWOLVES ASSISTANT WEB +## 1.0.0-beta.1 (2020-08-03) + +### 🚀 New features + +* If the user leaves a playing game, a confirm alert is triggered. +* If the user leaves the game lobby while composition has started, a confirm alert is triggered. +* Timer of 5 minutes added for `elect-sheriff` and `vote` plays. +* Game events like player death, role turn and some effect (like seen or promoted sheriff) are displayed during the game. +* Game summary is available at the end of a game with game results and game history. +* `sitemaps.xml` file added for SEO. + +### 🌟 Enhancements + +* The trophy at the end of a game has a sweet `TADA !` animation. +* When player are voting, the text `vote for` has been UX improved. +* Quit button added to Game Lobby. + +### 🐛 Bug fixes + +* Werewolf side doesn't have an overflow-y anymore. +* User is redirected to home page if he tries to load a game he doesn't own. + +### 📦 Packages + +* `@chenfengyuan/vue-countdown` installed with version `1.1.5`. +* `animate.css` installed with version `4.1.0`. +* `uniqid` installed with version `5.2.0`. +* `@sentry/browser` updated to version `5.20.1`. +* `@sentry/integrations` updated to version `5.20.1`. +* `eslint` updated to version `7.6.0`. +* `sweetalert2` updated to version `9.17.1`. +* `vee-validate` updated to version `3.3.8`. +* `vue-i18n` updated to version `8.20.0`. +* `vue-roller` updated to version `1.12.3`. + +--- + ## 0.2.0 (2020-07-24) ### 🚀 New features diff --git a/package-lock.json b/package-lock.json index b0b1718..d7b04d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "werewolves-assistant-web", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -40,6 +40,11 @@ "regenerator-runtime": "^0.13.4" } }, + "@chenfengyuan/vue-countdown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@chenfengyuan/vue-countdown/-/vue-countdown-1.1.5.tgz", + "integrity": "sha512-BB0taTfJzxsXFUPioREWLKpMDdHOoD8EiSW6lhB3yCdJh3I7jiNQzC8Hw5dPxoPNgZekeEPMQwsdPkjQPyxIeA==" + }, "@cypress/listr-verbose-renderer": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", @@ -229,69 +234,69 @@ } }, "@sentry/browser": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.20.0.tgz", - "integrity": "sha512-xVPL7/RuAPcemfSzXiyPHAt4M+0BfzkdTlN+PZb6frCEo4k6E0UiN6WLsGj/iwa2gXhyfTQXtbTuP+tDuNPEJw==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.20.1.tgz", + "integrity": "sha512-ClykuvrEsMKgAvifx5VHzRjchwYbJFX8YiIicYx+Wr3MXL2jLG6OEfHHJwJeyBL2C3vxd5O0KPK3pGMR9wPMLA==", "requires": { - "@sentry/core": "5.20.0", - "@sentry/types": "5.20.0", - "@sentry/utils": "5.20.0", + "@sentry/core": "5.20.1", + "@sentry/types": "5.20.1", + "@sentry/utils": "5.20.1", "tslib": "^1.9.3" } }, "@sentry/core": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.20.0.tgz", - "integrity": "sha512-fzzWKEolc0O6H/phdDenzKs7JXDSb0sooxVn0QCUkwWSzACALQh+NR/UciOXyhyuoUiqu4zthYQx02qtGqizeQ==", - "requires": { - "@sentry/hub": "5.20.0", - "@sentry/minimal": "5.20.0", - "@sentry/types": "5.20.0", - "@sentry/utils": "5.20.0", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.20.1.tgz", + "integrity": "sha512-gG622/UY2TePruF6iUzgVrbIX5vN8w2cjlWFo1Est8MvCfQsz8agGaLMCAyl5hCGJ6K2qTUZDOlbCNIKoMclxg==", + "requires": { + "@sentry/hub": "5.20.1", + "@sentry/minimal": "5.20.1", + "@sentry/types": "5.20.1", + "@sentry/utils": "5.20.1", "tslib": "^1.9.3" } }, "@sentry/hub": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.20.0.tgz", - "integrity": "sha512-DiU8fpjAAMOgSx5tsTekMtHPCAtSNWSNS91FFkDCqPn6fYG+/aK/hB5kTlJwr+GTM1815+WWrtXP6y2ecSmZuA==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.20.1.tgz", + "integrity": "sha512-Nv5BXf14BEc08acDguW6eSqkAJLVf8wki283FczEvTsQZZuSBHM9cJ5Hnehr6n+mr8wWpYLgUUYM0oXXigUmzQ==", "requires": { - "@sentry/types": "5.20.0", - "@sentry/utils": "5.20.0", + "@sentry/types": "5.20.1", + "@sentry/utils": "5.20.1", "tslib": "^1.9.3" } }, "@sentry/integrations": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-5.20.0.tgz", - "integrity": "sha512-ADL6rBJbwYy4P30zjWiRzmAc+PDqMch2URj+Tj89oVK+tUDQQ9qOM9DD4rBTeidqO2h1ninyZAJ3Vu9UJ/5g9A==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-5.20.1.tgz", + "integrity": "sha512-VpeZHYT8Fvw1J5478MqXXORf3Ftpt34YM4e+sTPuGrmf4Gro7lXdyownqiSaa7kwwNVQEV3zMlRDczVZzXQThw==", "requires": { - "@sentry/types": "5.20.0", - "@sentry/utils": "5.20.0", + "@sentry/types": "5.20.1", + "@sentry/utils": "5.20.1", "tslib": "^1.9.3" } }, "@sentry/minimal": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.20.0.tgz", - "integrity": "sha512-oA+0g7p3bapzjgGKQIkSjcjA85VG1HPmjxBD9wpRvNjmYuVmm80Cl1H/P+xg/hupw/kNmASAX4IOd5Z9pEeboA==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.20.1.tgz", + "integrity": "sha512-2PeJKDTHNsUd1jtSLQBJ6oRI+xrIJrYDQmsyK/qs9D7HqHfs+zNAMUjYseiVeSAFGas5IcNSuZbPRV4BnuoZ0w==", "requires": { - "@sentry/hub": "5.20.0", - "@sentry/types": "5.20.0", + "@sentry/hub": "5.20.1", + "@sentry/types": "5.20.1", "tslib": "^1.9.3" } }, "@sentry/types": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.20.0.tgz", - "integrity": "sha512-/9tiGiXBRsOKM66HeCpt0iSF0vnAIqHzXgC97icNQIstx/ZA8tcLs9540cHDeaN0cyZUyZF1o8ECqcLXGNODWQ==" + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.20.1.tgz", + "integrity": "sha512-OU+i/lcjGpDJv0XkNpsKrI2r1VPp8qX0H6Knq8NuZrlZe3AbvO3jRJJK0pH14xFv8Xok5jbZZpKKoQLxYfxqsw==" }, "@sentry/utils": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.20.0.tgz", - "integrity": "sha512-w0AeAzWEf35h9U9QL/4lgS9MqaTPjeSmQYNU/n4ef3FKr+u8HP68Ra7NZ0adiKgi67Yxr652kWopOLPl7CxvZg==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.20.1.tgz", + "integrity": "sha512-dhK6IdO6g7Q2CoxCbB+q8gwUapDUH5VjraFg0UBzgkrtNhtHLylqmwx0sWQvXCcp14Q/3MuzEbb4euvoh8o8oA==", "requires": { - "@sentry/types": "5.20.0", + "@sentry/types": "5.20.1", "tslib": "^1.9.3" } }, @@ -1198,6 +1203,11 @@ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, + "animate.css": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.0.tgz", + "integrity": "sha512-0aVcfWDeU9ykV6vjn1P67ZSs01jxoUQZCGaYbkk0SIIelIG8kUdLrIkua1+VabHfTtsSivDRMMn0ILPvZum2gw==" + }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", @@ -4363,9 +4373,9 @@ } }, "eslint": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.5.0.tgz", - "integrity": "sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.6.0.tgz", + "integrity": "sha512-QlAManNtqr7sozWm5TF4wIH9gmUm2hE3vNRUvyoYAa4y1l5/jxD/PQStEjBMQtCqZmSep8UxrcecI60hOpe61w==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -4547,12 +4557,6 @@ "type-check": "~0.4.0" } }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -12008,9 +12012,9 @@ } }, "sweetalert2": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-9.17.0.tgz", - "integrity": "sha512-tOby96N1FlTT8Xi7Y7QlTiswNJTySgghmRSyFwb3pO3zdrhsR2PUp4ucmye7a3CTLbLdqjHdszsGlCJ0v6pGaQ==" + "version": "9.17.1", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-9.17.1.tgz", + "integrity": "sha512-D/VE2lT/bKd64/RBglLUtQ+3nsftzjzIiP2iqN6zPzPwf+2djIY+4k8Bg430zxRUn4DkZzyIuU58q3n0J43lvw==" }, "symbol-observable": { "version": "1.0.1", @@ -12481,6 +12485,11 @@ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, + "uniqid": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-5.2.0.tgz", + "integrity": "sha512-LH8zsvwJ/GL6YtNfSOmMCrI9piraAUjBfw2MCvleNE6a4pVKJwXjG2+HWhkVeFcSg+nmaPKbMrMOoxwQluZ1Mg==" + }, "uniqs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", @@ -12736,9 +12745,9 @@ "dev": true }, "vee-validate": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-3.3.7.tgz", - "integrity": "sha512-s0CfIO8U+YSAzn7q+WnNtPignsndWKQlrbp8qbJ/zCw6QMO/OKDxhFXYRdWeNWRbRktVGCkiIaYktQiY/YL3TQ==" + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-3.3.8.tgz", + "integrity": "sha512-1LUGmtwqnu6PvKFq5Ia07GdvWD8uvA6mpxrqHLcHnWp0hkBS05oGsI1GP860gzlT6lSEmDsPN6GiPIoqOkuVNg==" }, "vendors": { "version": "1.0.4", @@ -12830,9 +12839,9 @@ "dev": true }, "vue-i18n": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.18.2.tgz", - "integrity": "sha512-0X5nBTCZAVjlwcrPaYJwNs3iipBBTv0AUHwQUOa8yP3XbQGWKbRHqBb3OhCYtum/IHDD21d/df5Xd2VgyxbxfA==" + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.20.0.tgz", + "integrity": "sha512-ZiAOoeR4d/JtKpbjipx3I80ey7cYG1ki5gQ7HwzWm4YFio9brA15BEYHjalEoBaEfzF5OBEZP+Y2MvAaWnyXXg==" }, "vue-loader": { "version": "15.9.3", @@ -12869,9 +12878,9 @@ "integrity": "sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg==" }, "vue-roller": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/vue-roller/-/vue-roller-1.12.1.tgz", - "integrity": "sha512-YEaCnKRG1zxXSRd/pXCrNPq6Yk4jcptomB3ff7gtCF8PDqgbEvC3QK2NhB8nsmosF5khnX8oiyligjPB/2NXCQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/vue-roller/-/vue-roller-1.12.3.tgz", + "integrity": "sha512-lN9QxU/wE0yaRvxzUEASQZy9kc8xovli3ZuFXr68HnUWRjkfuKk+gMeIDR245KBu60llSZ3C6T7FlNseFcacZQ==", "requires": { "core-js": "^3.6.5", "vue": "^2.6.11", diff --git a/package.json b/package.json index 88d4c24..cbfaf2c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "werewolves-assistant-web", - "version": "0.2.0", + "version": "1.0.0-beta.1", "private": true, "scripts": { "start": "npm run serve", @@ -12,9 +12,11 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "@chenfengyuan/vue-countdown": "^1.1.5", "@fortawesome/fontawesome-free": "^5.14.0", - "@sentry/browser": "^5.20.0", - "@sentry/integrations": "^5.20.0", + "@sentry/browser": "^5.20.1", + "@sentry/integrations": "^5.20.1", + "animate.css": "^4.1.0", "axios": "^0.19.2", "bootstrap": "^4.5.0", "epic-spinners": "^1.1.0", @@ -24,13 +26,14 @@ "popper.js": "^1.16.1", "qs": "^6.9.4", "sass-loader": "^9.0.2", - "sweetalert2": "^9.17.0", + "sweetalert2": "^9.17.1", + "uniqid": "^5.2.0", "v-tooltip": "^2.0.3", - "vee-validate": "^3.3.7", + "vee-validate": "^3.3.8", "vue": "^2.6.11", "vue-flip": "^1.0.2", - "vue-i18n": "^8.18.2", - "vue-roller": "^1.12.1", + "vue-i18n": "^8.20.0", + "vue-roller": "^1.12.3", "vue-router": "^3.2.0", "vue-select": "^3.10.7", "vue-toasted": "^1.1.28", @@ -46,7 +49,7 @@ "@vue/eslint-config-airbnb": "^5.1.0", "@vue/test-utils": "^1.0.3", "chai": "^4.1.2", - "eslint": "^7.5.0", + "eslint": "^7.6.0", "eslint-plugin-import": "^2.22.0", "eslint-plugin-vue": "^6.2.2", "vue-template-compiler": "^2.6.11" diff --git a/public/index.html b/public/index.html index 0c8b617..cd77089 100644 --- a/public/index.html +++ b/public/index.html @@ -1,21 +1,16 @@ - + - - + + <%= htmlWebpackPlugin.options.title %> -
@@ -39,6 +34,5 @@
- \ No newline at end of file diff --git a/public/sitemaps.xml b/public/sitemaps.xml new file mode 100644 index 0000000..ef42605 --- /dev/null +++ b/public/sitemaps.xml @@ -0,0 +1,6 @@ + + + https://werewolves-assistant.antoinezanardi.fr/ + 2020-07-24T13:11:00+00:00 + + \ No newline at end of file diff --git a/src/assets/scss/_tables.scss b/src/assets/scss/_tables.scss new file mode 100644 index 0000000..87419a8 --- /dev/null +++ b/src/assets/scss/_tables.scss @@ -0,0 +1,10 @@ +.table { + &.table-hover { + } + tr { + color: white !important; + td { + border-color: #515151; + } + } +} \ No newline at end of file diff --git a/src/assets/scss/styles.scss b/src/assets/scss/styles.scss index e07724d..2db1739 100644 --- a/src/assets/scss/styles.scss +++ b/src/assets/scss/styles.scss @@ -1,3 +1,4 @@ +@import "../../../node_modules/animate.css/animate.min.css"; @import "../../../node_modules/@fortawesome/fontawesome-free/css/all.min.css"; @import "colors"; @@ -7,6 +8,7 @@ @import "forms"; @import "modal"; @import "sweetalert2"; +@import "tables"; @import "v-tooltip"; @import "vue-flip"; @import "vue-select"; diff --git a/src/assets/svg/attributes/dead.svg b/src/assets/svg/attributes/dead.svg new file mode 100644 index 0000000..62b9657 --- /dev/null +++ b/src/assets/svg/attributes/dead.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/Game.js b/src/classes/Game.js index 727000e..9a7c32b 100644 --- a/src/classes/Game.js +++ b/src/classes/Game.js @@ -77,6 +77,11 @@ class Game { waiting.to === "shoot" || waiting.to === "settle-votes" || waiting.to === "delegate"; } + get isTimedPlay() { + const waiting = this.firstWaiting; + return waiting.to === "elect-sheriff" || waiting.to === "vote"; + } + getPlayerWithRole(role) { return this.players.find(player => player.role.current === role); } diff --git a/src/classes/GameEvent.js b/src/classes/GameEvent.js new file mode 100644 index 0000000..4e5f0e2 --- /dev/null +++ b/src/classes/GameEvent.js @@ -0,0 +1,19 @@ +import uniqId from "uniqid"; +import { getProp } from "@/helpers/functions/Class"; +import Player from "./Player"; + +class GameEvent { + constructor(gameEvent = null) { + this._id = getProp(gameEvent, "_id", uniqId()); + this.type = getProp(gameEvent, "type"); + this.targets = getProp(gameEvent, "targets", [], targets => targets.map(target => ({ + player: new Player(target.player), + potion: { + life: getProp(target, "potion.life"), + death: getProp(target, "potion.death"), + }, + }))); + } +} + +export default GameEvent; \ No newline at end of file diff --git a/src/components/Game/Game.vue b/src/components/Game/Game.vue index fd29057..5ce3dcf 100644 --- a/src/components/Game/Game.vue +++ b/src/components/Game/Game.vue @@ -4,30 +4,32 @@
-
+
- +
diff --git a/src/components/Game/GameContent/GameContent.vue b/src/components/Game/GameContent/GameContent.vue index 4f0cf0d..485a933 100644 --- a/src/components/Game/GameContent/GameContent.vue +++ b/src/components/Game/GameContent/GameContent.vue @@ -1,21 +1,24 @@ \ No newline at end of file diff --git a/src/components/Game/GameContent/GamePlayField/GamePlayField.vue b/src/components/Game/GameContent/GamePlayField/GamePlayField.vue new file mode 100644 index 0000000..06cd051 --- /dev/null +++ b/src/components/Game/GameContent/GamePlayField/GamePlayField.vue @@ -0,0 +1,49 @@ + + + + + \ No newline at end of file diff --git a/src/components/Game/GameContent/GameContentPlayField/DelegatePlayField.vue b/src/components/Game/GameContent/GamePlayField/GamePlayFieldContent/DelegatePlayField.vue similarity index 83% rename from src/components/Game/GameContent/GameContentPlayField/DelegatePlayField.vue rename to src/components/Game/GameContent/GamePlayField/GamePlayFieldContent/DelegatePlayField.vue index bea3858..35828bd 100644 --- a/src/components/Game/GameContent/GameContentPlayField/DelegatePlayField.vue +++ b/src/components/Game/GameContent/GamePlayField/GamePlayFieldContent/DelegatePlayField.vue @@ -12,10 +12,10 @@ \ No newline at end of file diff --git a/src/components/Game/GameEventMonitor/GameEvent/GameEventImage.vue b/src/components/Game/GameEventMonitor/GameEvent/GameEventImage.vue new file mode 100644 index 0000000..efd0277 --- /dev/null +++ b/src/components/Game/GameEventMonitor/GameEvent/GameEventImage.vue @@ -0,0 +1,175 @@ + + + + + \ No newline at end of file diff --git a/src/components/Game/GameEventMonitor/GameEventMonitor.vue b/src/components/Game/GameEventMonitor/GameEventMonitor.vue new file mode 100644 index 0000000..78037fe --- /dev/null +++ b/src/components/Game/GameEventMonitor/GameEventMonitor.vue @@ -0,0 +1,54 @@ + + + + + \ No newline at end of file diff --git a/src/components/Game/GameVillagersSide/GameVillagersSide.vue b/src/components/Game/GameVillagersSide/GameVillagersSide.vue index d6ffd4c..e9a24a9 100644 --- a/src/components/Game/GameVillagersSide/GameVillagersSide.vue +++ b/src/components/Game/GameVillagersSide/GameVillagersSide.vue @@ -1,18 +1,16 @@ + + \ No newline at end of file diff --git a/src/components/shared/Game/Role/RoleText.vue b/src/components/shared/Game/Role/RoleText.vue new file mode 100644 index 0000000..622cbd9 --- /dev/null +++ b/src/components/shared/Game/Role/RoleText.vue @@ -0,0 +1,36 @@ + + + + + \ No newline at end of file diff --git a/src/components/shared/Game/RoleImage.vue b/src/components/shared/Game/RoleImage.vue deleted file mode 100644 index de1f925..0000000 --- a/src/components/shared/Game/RoleImage.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/shared/Game/RolePicker.vue b/src/components/shared/Game/RolePicker.vue index cd50fcb..6f386c8 100644 --- a/src/components/shared/Game/RolePicker.vue +++ b/src/components/shared/Game/RolePicker.vue @@ -55,7 +55,7 @@ export default { roles: "roles", }), roleText() { - return this.hoverOn ? this.$t(`Role.${this.hoverOn}`) : `${this.$t("RolePicker.chooseRole")}`; + return this.hoverOn ? this.$tc(`Role.${this.hoverOn}`, 1) : `${this.$t("RolePicker.chooseRole")}`; }, availableRoles() { return this.roles.filter(({ name }) => name !== this.player.role.current); diff --git a/src/components/shared/Game/Sides/AliveVillagers.vue b/src/components/shared/Game/Sides/AliveVillagers.vue new file mode 100644 index 0000000..863fd64 --- /dev/null +++ b/src/components/shared/Game/Sides/AliveVillagers.vue @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/src/components/shared/Game/Sides/AliveWerewolves.vue b/src/components/shared/Game/Sides/AliveWerewolves.vue new file mode 100644 index 0000000..8ea6c59 --- /dev/null +++ b/src/components/shared/Game/Sides/AliveWerewolves.vue @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/src/helpers/functions/Array.js b/src/helpers/functions/Array.js new file mode 100644 index 0000000..fa1cac7 --- /dev/null +++ b/src/helpers/functions/Array.js @@ -0,0 +1,9 @@ +/** + * @description Insert a value into the array according to the condition. Needs to be called like ...insertIf(condition, value1, value2, value3) + * @param condition + * @param elements List of values to insert + * @returns {*[]} + */ +export function insertIf(condition, ...elements) { + return condition ? elements : []; +} \ No newline at end of file diff --git a/src/helpers/functions/Error.js b/src/helpers/functions/Error.js index dea1aaa..3bae5b9 100644 --- a/src/helpers/functions/Error.js +++ b/src/helpers/functions/Error.js @@ -1 +1 @@ -exports.isAPIError = err => err && err.response && err.response.data && err.response.data.HTTPCode; \ No newline at end of file +exports.isAPIError = err => !!err && !!err.response && !!err.response.data && !!err.response.data.HTTPCode; \ No newline at end of file diff --git a/src/plugins/error/index.js b/src/plugins/error/index.js index d277ed9..d05734f 100644 --- a/src/plugins/error/index.js +++ b/src/plugins/error/index.js @@ -1,5 +1,5 @@ import Vue from "vue"; -import { isAPIError } from "../../helpers/functions/Error"; +import { isAPIError } from "@/helpers/functions/Error"; import i18n from "../vue-i18n"; import Router from "../router"; diff --git a/src/plugins/index.js b/src/plugins/index.js index 0c52919..9e8994f 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -5,6 +5,7 @@ import Router from "./router"; import "./sentry"; import "./v-tooltip"; import "./vee-validate"; +import "./vue-countdown"; import "./vue-flip"; import i18n from "./vue-i18n"; import "./vue-roller"; diff --git a/src/plugins/router/index.js b/src/plugins/router/index.js index bfeb870..bc913d9 100644 --- a/src/plugins/router/index.js +++ b/src/plugins/router/index.js @@ -7,6 +7,22 @@ import Statistics from "../../components/Statistics/Statistics"; Vue.use(VueRouter); +const originalPush = VueRouter.prototype.push; +VueRouter.prototype.push = function push(location, onResolve, onReject) { + if (onResolve || onReject) { + return originalPush.call(this, location, onResolve, onReject); + } + return originalPush.call(this, location).catch(err => err); +}; + +const originalReplace = VueRouter.prototype.replace; +VueRouter.prototype.replace = function replace(query, onResolve, onReject) { + if (onResolve || onReject) { + return originalReplace.call(this, query, onResolve, onReject); + } + return originalReplace.call(this, query).catch(err => err); +}; + const routes = [{ path: "/", name: "Home", diff --git a/src/plugins/vue-countdown/index.js b/src/plugins/vue-countdown/index.js new file mode 100644 index 0000000..238f619 --- /dev/null +++ b/src/plugins/vue-countdown/index.js @@ -0,0 +1,4 @@ +import Vue from "vue"; +import VueCountdown from "@chenfengyuan/vue-countdown"; + +Vue.component("VCountdown", VueCountdown); \ No newline at end of file diff --git a/src/plugins/vue-i18n/fr.json b/src/plugins/vue-i18n/fr.json index 4cd57d5..a47c34d 100644 --- a/src/plugins/vue-i18n/fr.json +++ b/src/plugins/vue-i18n/fr.json @@ -1,11 +1,6 @@ { "NavBar": { - "werewolvesAssistant": "Assistant Loups Garous", - "areYouSureYouWantToQuit": "Êtes-vous sûr de vouloir quitter ?", - "gameCompositionNotFinished": "La composition du jeu n'est pas encore finalisée", - "yourProgressIsSaved": "Votre progression dans le jeu est sauvegardée", - "quit": "Quitter le jeu", - "cancel": "Annuler" + "werewolvesAssistant": "Assistant Loups Garous" }, "Home": { "werewolvesAssistant": "Assistant Loups Garous", @@ -55,7 +50,11 @@ "missingOneWerewolfToStart": "Il manque un loup garou pour commencer la partie", "missingOneVillagerToStart": "Il manque un villageois pour commencer", "allPlayerDontHaveARole": "Certains joueurs n'ont pas de rôle", - "gameCreated": "Partie créée" + "gameCreated": "Partie créée", + "areYouSureYouWantToQuit": "Êtes-vous sûr de vouloir quitter la composition de partie ?", + "gameCompositionNotFinished": "La composition du jeu n'est pas encore finalisée.", + "quit": "Quitter", + "cancel": "Annuler" }, "GameLobbyComposition": { "playerCount": "Aucun joueur | {count} joueur | {count} joueurs", @@ -90,9 +89,13 @@ }, "Game": { "loadingGame": "Chargement de la partie", - "wolves": "Loups garous" + "areYouSureYouWantToQuit": "Êtes-vous sûr de vouloir quitter la partie en cours ?", + "yourProgressIsSaved": "Votre progression est sauvegardée.", + "quit": "Quitter le jeu", + "cancel": "Annuler", + "youDontOwnThisGame": "Cette partie ne vous appartient pas" }, - "GameContentHeader": { + "GamePlayFieldHeader": { "day": "Jour", "night": "Nuit", "waiting": { @@ -124,12 +127,14 @@ } } }, - "GameContentFooter": { + "GamePlayFieldFooter": { "next": "Suivant", "playersHaveVoted": "{votesCount}/{playersCount} joueurs ont voté", "playersTargeted": "{targetsCount}/{min} joueur visé", "minOnePlayerHasToVote": "Minimum 1 joueur doit voter", - "minOnePlayerHasToBeTargeted": "Minimum 1 joueur doit être visé" + "minOnePlayerHasToBeTargeted": "Minimum 1 joueur doit être visé", + "timeForDebating": "Temps pour débattre", + "debateIsOver": "Le débat est terminé, il est temps de voter !" }, "PlayerAttribute": { "attributes": { @@ -143,6 +148,7 @@ } }, "PlayerThumbnail": { + "chooseRole": "Choisir un rôle", "unsetPlayer": "Retirer le joueur" }, "PlayerVote": { @@ -166,14 +172,39 @@ "useDeathPotionOn": "Utiliser la potion de mort sur ..." }, "GameWinners": { - "wonByWerewolves": "Partie gagnée par le seul loup garou | Partie gagnée par les loups garous", + "wonByWerewolves": "Partie gagnée par le seul loup-garou | Partie gagnée par les loups-garous", "wonByVillagers": "Partie gagnée par le seul villageois | Partie gagnée par les villageois", "restartGame": "Recommencer une partie", "quit": "Quitter", "newGame": "Nouvelle partie", "doYouWantToKeepSamePlayers": "Voulez-vous rejouer avec les mêmes joueurs ?", "keepSamePlayers": "Garder les mêmes joueurs", - "fromScratch": "Recommencer du début" + "fromScratch": "Recommencer du début", + "seeGameSummary": "Voir le récapitulatif de partie" + }, + "GameSummaryModal": { + "gameSummary": "Récapitulatif de la partie", + "gameResults": "Résultats de la partie", + "gameHistory": "Historique de la partie", + "villagers": "Villageois", + "werewolves": "Loups-Garous", + "close": "Fermer" + }, + "GameSummaryHistoryLine": { + "day": "Jour", + "night": "Nuit", + "actions": { + "eat": "ont décidé de manger", + "use-potion": "a utilisé une potion sur", + "look": "a vu", + "shoot": "a tiré sur", + "protect": "a protégé", + "mark": "a marqué", + "elect-sheriff": "a élu comme maire", + "vote": "a décidé de pendre", + "delegate": "a légué son rôle de maire à", + "settle-votes": "a tranché pour pendre" + } }, "PlayFieldActionText": { "wantsToLook": "souhaite voir le rôle de", @@ -198,6 +229,34 @@ "cancel": "Annuler", "cancelTarget": "Annuler cette cible" }, + "GameEventMonitor": { + "skip": "Passer" + }, + "GameEvent": { + "next": "Suivant", + "previous": "Précédent", + "messages": { + "welcomeToTheVillage": "Bienvenue à tous dans le village de Thiercelieux !", + "compositionIs": "Ce village de {inhabitantCount} habitants se composent de ", + "looksLifeSomeWerewolvesIntroducedThemselves": "Il semblerait qu'un ou plusieurs loups-garous se soient faufilé dans le village...", + "villagersMurderWerewolves": "Villageois, prenez les fourches et nettoyez votre village de ces canidés !", + "beforeStartingLetsElectSheriff": "Mais avant de vous entretuer, il faut élire le maire de ce village.", + "playerDies": "{player} est mort ! Quelle tragédie...", + "playerRevealsRole": "Il ou elle révèle son rôle aux survivants.", + "playerHasBeenPromotedSheriff": "{player} a été promu maire !", + "sheriffCanMakeASpeech": "Le maire peut, s'il le souhaite, faire un discours poignant sur son élection.", + "nightFalls": "La nuit tombe sur le village de Thiercelieux...", + "inhabitantsFallAsleep": "Les habitants du village s'endorment.", + "dayRises": "Le jour se lève sur le village de Thiercelieux.", + "seerStarts": "La voyante se réveille et va découvrir dans sa boule de cristal le rôle d'un habitant.", + "seerHasSeen": "La voyante a vu", + "werewolvesStart": "Le loup-garou se réveille et va choisir son dîner de ce soir. | Les loups-garous se réveillent et vont choisir leur dîner de ce soir.", + "witchStarts": "La sorcière se réveille et va, si elle le souhaite, utiliser ses potions.", + "guardStarts": "Le salvateur se réveille et va protéger la personne de son choix.", + "ravenStarts": "Le corbeau se réveille et va, s'il le souhaite, marquer de sa plume un des habitants.", + "hunterStarts": "Dans son dernier souffle, le chasseur s'apprête à choisir la cible de sa vengeance." + } + }, "Statistics": { "statistics": "Statistiques", "loadingStatistics": "Chargement des statistiques", @@ -214,14 +273,38 @@ "createGameNow": "Créer une partie maintenant" }, "Role": { + "a": { + "villager": "un villageois", + "werewolf": "un loup-garou", + "seer": "une voyante", + "witch": "une sorcière", + "hunter": "un chasseur", + "guard": "un salvateur", + "raven": "un corbeau" + }, + "the": { + "villager": "le villageois", + "werewolf": "le loup-garou", + "werewolves": "les loups-garous", + "seer": "la voyante", + "witch": "la sorcière", + "hunter": "le chasseur", + "guard": "le salvateur", + "raven": "le corbeau", + "sheriff": "le maire", + "all": "le village" + }, "villager": "Villageois", - "werewolf": "Loup-Garou", + "werewolf": "Loup-Garou | Loups-Garous", "seer": "Voyante", "witch": "Sorcière", "hunter": "Chasseur", "guard": "Salvateur", "raven": "Corbeau" }, + "RoleText": { + "chooseARole": "Choisir un rôle" + }, "Error": { "unauthorized": "Vous ne pouvez pas accéder à cette page", "BAD_REQUEST": "Mauvaise requête serveur",