Merge pull request #165 from bra1n/164_fix_voting

fix players being moved or removed during a nomination (closes #164)
This commit is contained in:
Steffen 2021-05-09 22:04:05 +02:00 committed by GitHub
commit bdffdc6b9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 338 additions and 583 deletions

View File

@ -1,53 +1,20 @@
---
###########################
###########################
## Linter GitHub Actions ##
###########################
###########################
name: Lint Code Base name: Lint Code Base
#
# Documentation:
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
#
#############################
# Start the job on all push #
#############################
on: on:
push: push:
branches-ignore: branches: [ main, develop ]
- 'gh-pages'
pull_request: pull_request:
# The branches below must be a subset of the branches above branches: [ main, develop ]
branches: [ main ]
###############
# Set the Job #
###############
jobs: jobs:
build: build:
# Name the Job
name: Lint Code Base name: Lint Code Base
# Set the agent to run on
runs-on: ubuntu-latest runs-on: ubuntu-latest
##################
# Load all steps #
##################
steps: steps:
########################## - uses: actions/checkout@v2
# Checkout the code base # - uses: actions/setup-node@v2
########################## with:
- name: Checkout Code node-version: '14'
uses: actions/checkout@v2 - run: npm install
- run: npm run lint
################################
# Run Linter against code base #
################################
- name: Lint Code Base
uses: docker://github/super-linter:v2.2.0
env:
VALIDATE_ALL_CODEBASE: false
VALIDATE_ANSIBLE: false
DEFAULT_BRANCH: "main"

View File

@ -1,5 +1,7 @@
# Release Notes # Release Notes
- fix players being moved or removed during nomination
- add vue linter
- use "Exile" rather than "Banishment" for exiles - use "Exile" rather than "Banishment" for exiles
- added global animation toggle for better performance - added global animation toggle for better performance
- added record vote history toggle to session menu, and clear vote history button - added record vote history toggle to session menu, and clear vote history button

793
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build ./src/main.js", "build": "vue-cli-service build ./src/main.js",
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint --no-fix --max-warnings=0"
}, },
"main": "App.vue", "main": "App.vue",
"dependencies": { "dependencies": {

View File

@ -327,6 +327,10 @@ export default {
clearPlayers() { clearPlayers() {
if (this.session.isSpectator) return; if (this.session.isSpectator) return;
if (confirm("Are you sure you want to remove all players?")) { if (confirm("Are you sure you want to remove all players?")) {
// abort vote if in progress
if (this.session.nomination) {
this.$store.commit("session/nomination");
}
this.$store.commit("players/clear"); this.$store.commit("players/clear");
} }
}, },

View File

@ -128,11 +128,11 @@
<font-awesome-icon icon="hand-point-right" /> <font-awesome-icon icon="hand-point-right" />
Nomination Nomination
</li> </li>
<li @click="movePlayer()"> <li @click="movePlayer()" :class="{ disabled: session.lockedVote }">
<font-awesome-icon icon="redo-alt" /> <font-awesome-icon icon="redo-alt" />
Move player Move player
</li> </li>
<li @click="swapPlayer()"> <li @click="swapPlayer()" :class="{ disabled: session.lockedVote }">
<font-awesome-icon icon="exchange-alt" /> <font-awesome-icon icon="exchange-alt" />
Swap seats Swap seats
</li> </li>
@ -143,7 +143,7 @@
<font-awesome-icon icon="chair" /> <font-awesome-icon icon="chair" />
Empty seat Empty seat
</li> </li>
<li @click="removePlayer"> <li @click="removePlayer" :class="{ disabled: session.lockedVote }">
<font-awesome-icon icon="times-circle" /> <font-awesome-icon icon="times-circle" />
Remove Remove
</li> </li>
@ -759,7 +759,8 @@ li.move:not(.from) .player .overlay svg.move {
} }
li.disabled { li.disabled {
cursor: default; cursor: not-allowed;
opacity: 0.5;
&:hover { &:hover {
color: white; color: white;
} }

View File

@ -152,20 +152,52 @@ export default {
this.$store.commit("toggleModal", "role"); this.$store.commit("toggleModal", "role");
}, },
removePlayer(playerIndex) { removePlayer(playerIndex) {
if (this.session.isSpectator) return; if (this.session.isSpectator || this.session.lockedVote) return;
if ( if (
confirm( confirm(
`Do you really want to remove ${this.players[playerIndex].name}?` `Do you really want to remove ${this.players[playerIndex].name}?`
) )
) { ) {
const { nomination } = this.session;
if (nomination) {
if (nomination.includes(playerIndex)) {
// abort vote if removed player is either nominator or nominee
this.$store.commit("session/nomination");
} else if (
nomination[0] > playerIndex ||
nomination[1] > playerIndex
) {
// update nomination array if removed player has lower index
this.$store.commit("session/setNomination", [
nomination[0] > playerIndex ? nomination[0] - 1 : nomination[0],
nomination[1] > playerIndex ? nomination[1] - 1 : nomination[1]
]);
}
}
this.$store.commit("players/remove", playerIndex); this.$store.commit("players/remove", playerIndex);
} }
}, },
swapPlayer(from, to) { swapPlayer(from, to) {
if (this.session.isSpectator || this.session.lockedVote) return;
if (to === undefined) { if (to === undefined) {
this.cancel(); this.cancel();
this.swap = from; this.swap = from;
} else { } else {
if (this.session.nomination) {
// update nomination if one of the involved players is swapped
const swapTo = this.players.indexOf(to);
const updatedNomination = this.session.nomination.map(nom => {
if (nom === this.swap) return swapTo;
if (nom === swapTo) return this.swap;
return nom;
});
if (
this.session.nomination[0] !== updatedNomination[0] ||
this.session.nomination[1] !== updatedNomination[1]
) {
this.$store.commit("session/setNomination", updatedNomination);
}
}
this.$store.commit("players/swap", [ this.$store.commit("players/swap", [
this.swap, this.swap,
this.players.indexOf(to) this.players.indexOf(to)
@ -174,10 +206,27 @@ export default {
} }
}, },
movePlayer(from, to) { movePlayer(from, to) {
if (this.session.isSpectator || this.session.lockedVote) return;
if (to === undefined) { if (to === undefined) {
this.cancel(); this.cancel();
this.move = from; this.move = from;
} else { } else {
if (this.session.nomination) {
// update nomination if it is affected by the move
const moveTo = this.players.indexOf(to);
const updatedNomination = this.session.nomination.map(nom => {
if (nom === this.move) return moveTo;
if (nom > this.move && nom <= moveTo) return nom - 1;
if (nom < this.move && nom >= moveTo) return nom + 1;
return nom;
});
if (
this.session.nomination[0] !== updatedNomination[0] ||
this.session.nomination[1] !== updatedNomination[1]
) {
this.$store.commit("session/setNomination", updatedNomination);
}
}
this.$store.commit("players/move", [ this.$store.commit("players/move", [
this.move, this.move,
this.players.indexOf(to) this.players.indexOf(to)
@ -186,6 +235,7 @@ export default {
} }
}, },
nominatePlayer(from, to) { nominatePlayer(from, to) {
if (this.session.isSpectator || this.session.lockedVote) return;
if (to === undefined) { if (to === undefined) {
this.cancel(); this.cancel();
if (from !== this.nominate) { if (from !== this.nominate) {

View File

@ -122,7 +122,7 @@ export default {
const nomination = this.session.nomination[0]; const nomination = this.session.nomination[0];
return { return {
transform: `rotate(${Math.round((nomination / players) * 360)}deg)`, transform: `rotate(${Math.round((nomination / players) * 360)}deg)`,
transitionDuration: this.session.votingSpeed - 0.1 + "s" transitionDuration: this.session.votingSpeed - 100 + "ms"
}; };
}, },
nominee: function() { nominee: function() {

View File

@ -46,6 +46,7 @@ const mutations = {
setPing: set("ping"), setPing: set("ping"),
setVotingSpeed: set("votingSpeed"), setVotingSpeed: set("votingSpeed"),
setVoteInProgress: set("isVoteInProgress"), setVoteInProgress: set("isVoteInProgress"),
setNomination: set("nomination"),
setVoteHistoryAllowed: set("isVoteHistoryAllowed"), setVoteHistoryAllowed: set("isVoteHistoryAllowed"),
claimSeat: set("claimedSeat"), claimSeat: set("claimedSeat"),
distributeRoles: set("isRolesDistributed"), distributeRoles: set("isRolesDistributed"),

View File

@ -664,10 +664,12 @@ class LiveSession {
/** /**
* A player nomination. ST only * A player nomination. ST only
* This also syncs the voting speed to the players. * This also syncs the voting speed to the players.
* @param nomination [nominator, nominee] * Payload can be an object with {nomination} property or just the nomination itself, or undefined.
* @param payload [nominator, nominee]|{nomination}
*/ */
nomination({ nomination } = {}) { nomination(payload) {
if (this._isSpectator) return; if (this._isSpectator) return;
const nomination = payload ? payload.nomination || payload : payload;
const players = this._store.state.players.players; const players = this._store.state.players.players;
if ( if (
!nomination || !nomination ||
@ -842,6 +844,7 @@ export default store => {
} }
break; break;
case "session/nomination": case "session/nomination":
case "session/setNomination":
session.nomination(payload); session.nomination(payload);
break; break;
case "session/setVoteInProgress": case "session/setVoteInProgress":