mirror of
				https://github.com/bra1n/townsquare.git
				synced 2025-10-21 16:55:12 +00:00 
			
		
		
		
	Merge branch 'develop' into 164_fix_voting
This commit is contained in:
		
						commit
						ed8bcb6b30
					
				
					 16 changed files with 203 additions and 74 deletions
				
			
		
							
								
								
									
										1
									
								
								.github/workflows/changelog-check.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/changelog-check.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -4,6 +4,7 @@ on: | |||
|     types: [assigned, opened, synchronize, reopened, labeled, unlabeled] | ||||
|     branches: | ||||
|       - main | ||||
|       - develop | ||||
| jobs: | ||||
|   build: | ||||
|     name: Check Actions | ||||
|  |  | |||
							
								
								
									
										4
									
								
								.github/workflows/codeql-analysis.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/codeql-analysis.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -13,10 +13,10 @@ name: "CodeQL" | |||
| 
 | ||||
| on: | ||||
|   push: | ||||
|     branches: [ main ] | ||||
|     branches: [ main, develop ] | ||||
|   pull_request: | ||||
|     # The branches below must be a subset of the branches above | ||||
|     branches: [ main ] | ||||
|     branches: [ main, develop ] | ||||
|   schedule: | ||||
|     - cron: '27 22 * * 1' | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,6 +2,12 @@ | |||
| 
 | ||||
| - fix players being moved or removed during nomination | ||||
| - add vue linter | ||||
| - use "Exile" rather than "Banishment" for exiles | ||||
| - added global animation toggle for better performance | ||||
| - added record vote history toggle to session menu, and clear vote history button | ||||
| - add support for custom Fabled characters | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| ### Version 2.12.0 | ||||
| - tweak reference sheet to better fit screen in single column layout | ||||
|  |  | |||
|  | @ -19,6 +19,9 @@ Before submitting your contribution, please make sure to take a moment and read | |||
| 
 | ||||
| - The `main` branch is what is currently deployed to the website. All development should be done in dedicated branches. | ||||
| 
 | ||||
| - The `develop` branch contains the changes that will be deployed to main next. In order to prepare a release, development | ||||
|   branches should have their Pull Request against `develop` and only releases should be merged from `develop` into `main`.  | ||||
| 
 | ||||
| - Work in the `src` folder and **DO NOT** checkin `dist` in the commits. | ||||
| 
 | ||||
| - It's OK to have multiple small commits as you work on the PR - GitHub will automatically squash it before merging. | ||||
|  | @ -30,6 +33,9 @@ Before submitting your contribution, please make sure to take a moment and read | |||
| - If fixing a bug: | ||||
|   - If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `update entities encoding/decoding (fix #3899)`. | ||||
|   - Provide a detailed description of the bug in the PR. Live demo preferred. | ||||
|    | ||||
| - You'll need to update the `CHANGELOG.md` with a description of your changes before you open a pull request and your code | ||||
|   should pass the lint check. | ||||
| 
 | ||||
| ## Development Setup | ||||
| 
 | ||||
|  |  | |||
|  | @ -96,7 +96,8 @@ For base game characters, it is sufficient to only provide the ID, similar to wh | |||
| - **remindersGlobal**: global reminder tokens that will always be available, no matter if the character is assigned to a player or not | ||||
| - **setup**: whether this token affects setup (orange leaf), like the Drunk or Baron | ||||
| - **name**: the displayed name of this character | ||||
| - **team**: the team of the character, has to be one of `townsfolk`, `outsider`, `minion`, `demon` or `traveler` | ||||
| - **team**: the team of the character, has to be one of `townsfolk`, `outsider`, `minion`, `demon`, `traveler` or `fabled`<br> | ||||
|   _Note_: if you create a custom Fabled character, it will be automatically added to the game when the custom script is loaded | ||||
| - **ability**: the displayed ability text of the character | ||||
| 
 | ||||
| ## [Code of Conduct](CODE_OF_CONDUCT.md) | ||||
|  |  | |||
							
								
								
									
										4
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							|  | @ -1,11 +1,11 @@ | |||
| { | ||||
|   "name": "townsquare", | ||||
|   "version": "2.12.0", | ||||
|   "version": "2.13.0", | ||||
|   "lockfileVersion": 2, | ||||
|   "requires": true, | ||||
|   "packages": { | ||||
|     "": { | ||||
|       "version": "2.12.0", | ||||
|       "version": "2.13.0", | ||||
|       "license": "GPL-3.0", | ||||
|       "dependencies": { | ||||
|         "@fortawesome/fontawesome-svg-core": "^1.2.32", | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| { | ||||
|   "name": "townsquare", | ||||
|   "version": "2.12.0", | ||||
|   "version": "2.13.0", | ||||
|   "description": "Blood on the Clocktower Town Square", | ||||
|   "author": "Steffen Baumgart", | ||||
|   "scripts": { | ||||
|  |  | |||
							
								
								
									
										15
									
								
								src/App.vue
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/App.vue
									
										
									
									
									
								
							|  | @ -3,7 +3,10 @@ | |||
|     id="app" | ||||
|     @keyup="keyup" | ||||
|     tabindex="-1" | ||||
|     :class="{ night: grimoire.isNight }" | ||||
|     :class="{ | ||||
|       night: grimoire.isNight, | ||||
|       static: grimoire.isStatic | ||||
|     }" | ||||
|     :style="{ | ||||
|       backgroundImage: grimoire.background | ||||
|         ? `url('${grimoire.background}')` | ||||
|  | @ -110,7 +113,7 @@ export default { | |||
|           this.$store.commit("toggleModal", "roles"); | ||||
|           break; | ||||
|         case "v": | ||||
|           if (this.session.voteHistory.length) { | ||||
|           if (this.session.voteHistory.length || !this.session.isSpectator) { | ||||
|             this.$store.commit("toggleModal", "voteHistory"); | ||||
|           } | ||||
|           break; | ||||
|  | @ -202,6 +205,14 @@ ul { | |||
|   align-items: center; | ||||
|   align-content: center; | ||||
|   justify-content: center; | ||||
| 
 | ||||
|   // disable all animations | ||||
|   &.static *, | ||||
|   &.static *:after, | ||||
|   &.static *:before { | ||||
|     transition: none !important; | ||||
|     animation: none !important; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #version { | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								src/assets/icons/fabled.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/assets/icons/fabled.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 136 KiB | 
|  | @ -60,13 +60,14 @@ | |||
|           </li> | ||||
|           <li @click="toggleNightOrder" v-if="players.length"> | ||||
|             Night order | ||||
|             <em | ||||
|               ><font-awesome-icon | ||||
|             <em> | ||||
|               <font-awesome-icon | ||||
|                 :icon="[ | ||||
|                   'fas', | ||||
|                   grimoire.isNightOrder ? 'check-square' : 'square' | ||||
|                 ]" | ||||
|             /></em> | ||||
|               /> | ||||
|             </em> | ||||
|           </li> | ||||
|           <li v-if="players.length"> | ||||
|             Zoom | ||||
|  | @ -82,6 +83,10 @@ | |||
|               /> | ||||
|             </em> | ||||
|           </li> | ||||
|           <li @click="setBackground"> | ||||
|             Background image | ||||
|             <em><font-awesome-icon icon="image"/></em> | ||||
|           </li> | ||||
|           <li v-if="!edition.isOfficial" @click="imageOptIn"> | ||||
|             <small>Show Custom Images</small> | ||||
|             <em | ||||
|  | @ -92,9 +97,12 @@ | |||
|                 ]" | ||||
|             /></em> | ||||
|           </li> | ||||
|           <li @click="setBackground"> | ||||
|             Background image | ||||
|             <em><font-awesome-icon icon="image"/></em> | ||||
|           <li @click="toggleStatic"> | ||||
|             Disable Animations | ||||
|             <em | ||||
|               ><font-awesome-icon | ||||
|                 :icon="['fas', grimoire.isStatic ? 'check-square' : 'square']" | ||||
|             /></em> | ||||
|           </li> | ||||
|           <li @click="toggleMuted"> | ||||
|             Mute Sounds | ||||
|  | @ -131,10 +139,10 @@ | |||
|               <em><font-awesome-icon icon="theater-masks"/></em> | ||||
|             </li> | ||||
|             <li | ||||
|               v-if="session.voteHistory.length" | ||||
|               v-if="session.voteHistory.length || !session.isSpectator" | ||||
|               @click="toggleModal('voteHistory')" | ||||
|             > | ||||
|               Nomination history<em>[V]</em> | ||||
|               Vote history<em>[V]</em> | ||||
|             </li> | ||||
|             <li @click="leaveSession"> | ||||
|               Leave Session | ||||
|  | @ -338,6 +346,7 @@ export default { | |||
|       "toggleMuted", | ||||
|       "toggleNight", | ||||
|       "toggleNightOrder", | ||||
|       "toggleStatic", | ||||
|       "setZoom", | ||||
|       "toggleModal" | ||||
|     ]) | ||||
|  |  | |||
|  | @ -115,6 +115,7 @@ export default { | |||
| .maximized { | ||||
|   background: rgba(0, 0, 0, 0.95); | ||||
|   padding: 0; | ||||
|   border-radius: 0; | ||||
|   height: 100%; | ||||
|   width: 100%; | ||||
|   max-width: 100%; | ||||
|  |  | |||
|  | @ -1,17 +1,36 @@ | |||
| <template> | ||||
|   <Modal | ||||
|     class="vote-history" | ||||
|     v-if="modals.voteHistory && session.voteHistory" | ||||
|     v-if="modals.voteHistory && (session.voteHistory || !session.isSpectator)" | ||||
|     @close="toggleModal('voteHistory')" | ||||
|   > | ||||
|     <font-awesome-icon | ||||
|       @click="clearVoteHistory" | ||||
|       icon="trash-alt" | ||||
|       class="clear" | ||||
|       title="Clear history" | ||||
|       title="Clear vote history" | ||||
|       v-if="session.isSpectator" | ||||
|     /> | ||||
| 
 | ||||
|     <h3>Nomination history</h3> | ||||
|     <h3>Vote history</h3> | ||||
| 
 | ||||
|     <template v-if="!session.isSpectator"> | ||||
|       <div class="options"> | ||||
|         <div class="option" @click="setRecordVoteHistory"> | ||||
|           <font-awesome-icon | ||||
|             :icon="[ | ||||
|               'fas', | ||||
|               session.isVoteHistoryAllowed ? 'check-square' : 'square' | ||||
|             ]" | ||||
|           /> | ||||
|           Accessible to players | ||||
|         </div> | ||||
|         <div class="option" @click="clearVoteHistory"> | ||||
|           <font-awesome-icon icon="trash-alt" /> | ||||
|           Clear for everyone | ||||
|         </div> | ||||
|       </div> | ||||
|     </template> | ||||
|     <table> | ||||
|       <thead> | ||||
|         <tr> | ||||
|  | @ -79,8 +98,16 @@ export default { | |||
|     ...mapState(["session", "modals"]) | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapMutations(["toggleModal"]), | ||||
|     ...mapMutations("session", ["clearVoteHistory"]) | ||||
|     clearVoteHistory() { | ||||
|       this.$store.commit("session/clearVoteHistory"); | ||||
|     }, | ||||
|     setRecordVoteHistory() { | ||||
|       this.$store.commit( | ||||
|         "session/setVoteHistoryAllowed", | ||||
|         !this.session.isVoteHistoryAllowed | ||||
|       ); | ||||
|     }, | ||||
|     ...mapMutations(["toggleModal"]) | ||||
|   } | ||||
| }; | ||||
| </script> | ||||
|  | @ -98,6 +125,24 @@ export default { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .options { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   align-content: center; | ||||
| } | ||||
| 
 | ||||
| .option { | ||||
|   color: white; | ||||
|   text-decoration: none; | ||||
|   margin: 0 15px; | ||||
|   &:hover { | ||||
|     color: red; | ||||
|     cursor: pointer; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| h3 { | ||||
|   margin: 0 40px 0 10px; | ||||
|   svg { | ||||
|  |  | |||
|  | @ -81,6 +81,7 @@ export default new Vuex.Store({ | |||
|       isNightOrder: true, | ||||
|       isPublic: true, | ||||
|       isMenuOpen: false, | ||||
|       isStatic: false, | ||||
|       isMuted: false, | ||||
|       isImageOptIn: false, | ||||
|       zoom: 0, | ||||
|  | @ -144,6 +145,7 @@ export default new Vuex.Store({ | |||
|     toggleMuted: toggle("isMuted"), | ||||
|     toggleMenu: toggle("isMenuOpen"), | ||||
|     toggleNightOrder: toggle("isNightOrder"), | ||||
|     toggleStatic: toggle("isStatic"), | ||||
|     toggleNight: toggle("isNight"), | ||||
|     toggleGrimoire: toggle("isPublic"), | ||||
|     toggleImageOptIn: toggle("isImageOptIn"), | ||||
|  | @ -162,54 +164,62 @@ export default new Vuex.Store({ | |||
|      * @param roles Array of role IDs or full role definitions | ||||
|      */ | ||||
|     setCustomRoles(state, roles) { | ||||
|       state.roles = new Map( | ||||
|         roles | ||||
|           // replace numerical role object keys with matching key names
 | ||||
|           .map(role => { | ||||
|             if (role[0]) { | ||||
|               const customKeys = Object.keys(customRole); | ||||
|               const mappedRole = {}; | ||||
|               for (let prop in role) { | ||||
|                 if (customKeys[prop]) { | ||||
|                   mappedRole[customKeys[prop]] = role[prop]; | ||||
|                 } | ||||
|       const processedRoles = roles | ||||
|         // replace numerical role object keys with matching key names
 | ||||
|         .map(role => { | ||||
|           if (role[0]) { | ||||
|             const customKeys = Object.keys(customRole); | ||||
|             const mappedRole = {}; | ||||
|             for (let prop in role) { | ||||
|               if (customKeys[prop]) { | ||||
|                 mappedRole[customKeys[prop]] = role[prop]; | ||||
|               } | ||||
|               return mappedRole; | ||||
|             } else { | ||||
|               return role; | ||||
|             } | ||||
|           }) | ||||
|           // clean up role.id
 | ||||
|           .map(role => { | ||||
|             role.id = role.id.toLocaleLowerCase().replace(/[^a-z0-9]/g, ""); | ||||
|             return mappedRole; | ||||
|           } else { | ||||
|             return role; | ||||
|           }) | ||||
|           // map existing roles to base definition or pre-populate custom roles to ensure all properties
 | ||||
|           .map( | ||||
|             role => | ||||
|               rolesJSONbyId.get(role.id) || | ||||
|               state.roles.get(role.id) || | ||||
|               Object.assign({}, customRole, role) | ||||
|           ) | ||||
|           // default empty icons and placeholders
 | ||||
|           .map(role => { | ||||
|             if (rolesJSONbyId.get(role.id)) return role; | ||||
|             role.imageAlt = // map team to generic icon
 | ||||
|               { | ||||
|                 townsfolk: "good", | ||||
|                 outsider: "outsider", | ||||
|                 minion: "minion", | ||||
|                 demon: "evil" | ||||
|               }[role.team] || "custom"; | ||||
|             return role; | ||||
|           }) | ||||
|           // filter out roles that don't match an existing role and also don't have name/ability/team
 | ||||
|           .filter(role => role.name && role.ability && role.team) | ||||
|           // sort by team
 | ||||
|           .sort((a, b) => b.team.localeCompare(a.team)) | ||||
|           // convert to Map
 | ||||
|           } | ||||
|         }) | ||||
|         // clean up role.id
 | ||||
|         .map(role => { | ||||
|           role.id = role.id.toLocaleLowerCase().replace(/[^a-z0-9]/g, ""); | ||||
|           return role; | ||||
|         }) | ||||
|         // map existing roles to base definition or pre-populate custom roles to ensure all properties
 | ||||
|         .map( | ||||
|           role => | ||||
|             rolesJSONbyId.get(role.id) || | ||||
|             state.roles.get(role.id) || | ||||
|             Object.assign({}, customRole, role) | ||||
|         ) | ||||
|         // default empty icons and placeholders
 | ||||
|         .map(role => { | ||||
|           if (rolesJSONbyId.get(role.id)) return role; | ||||
|           role.imageAlt = // map team to generic icon
 | ||||
|             { | ||||
|               townsfolk: "good", | ||||
|               outsider: "outsider", | ||||
|               minion: "minion", | ||||
|               demon: "evil", | ||||
|               fabled: "fabled" | ||||
|             }[role.team] || "custom"; | ||||
|           return role; | ||||
|         }) | ||||
|         // filter out roles that don't match an existing role and also don't have name/ability/team
 | ||||
|         .filter(role => role.name && role.ability && role.team) | ||||
|         // sort by team
 | ||||
|         .sort((a, b) => b.team.localeCompare(a.team)); | ||||
|       // convert to Map without Fabled
 | ||||
|       state.roles = new Map( | ||||
|         processedRoles | ||||
|           .filter(role => role.team !== "fabled") | ||||
|           .map(role => [role.id, role]) | ||||
|       ); | ||||
|       // update Fabled to include custom Fabled from this script
 | ||||
|       state.fabled = new Map([ | ||||
|         ...processedRoles.filter(r => r.team === "fabled").map(r => [r.id, r]), | ||||
|         ...fabledJSON.map(role => [role.id, role]) | ||||
|       ]); | ||||
|       // update extraTravelers map to only show travelers not in this script
 | ||||
|       state.otherTravelers = new Map( | ||||
|         rolesJSON | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ const state = () => ({ | |||
|   votingSpeed: 3000, | ||||
|   isVoteInProgress: false, | ||||
|   voteHistory: [], | ||||
|   isVoteHistoryAllowed: true, | ||||
|   isRolesDistributed: false | ||||
| }); | ||||
| 
 | ||||
|  | @ -46,6 +47,7 @@ const mutations = { | |||
|   setVotingSpeed: set("votingSpeed"), | ||||
|   setVoteInProgress: set("isVoteInProgress"), | ||||
|   setNomination: set("nomination"), | ||||
|   setVoteHistoryAllowed: set("isVoteHistoryAllowed"), | ||||
|   claimSeat: set("claimedSeat"), | ||||
|   distributeRoles: set("isRolesDistributed"), | ||||
|   setSessionId(state, sessionId) { | ||||
|  | @ -71,15 +73,16 @@ const mutations = { | |||
|    * @param players | ||||
|    */ | ||||
|   addHistory(state, players) { | ||||
|     if (!state.isVoteHistoryAllowed && state.isSpectator) return; | ||||
|     if (!state.nomination || state.lockedVote <= players.length) return; | ||||
|     const isBanishment = players[state.nomination[1]].role.team === "traveler"; | ||||
|     const isExile = players[state.nomination[1]].role.team === "traveler"; | ||||
|     state.voteHistory.push({ | ||||
|       timestamp: new Date(), | ||||
|       nominator: players[state.nomination[0]].name, | ||||
|       nominee: players[state.nomination[1]].name, | ||||
|       type: isBanishment ? "Banishment" : "Execution", | ||||
|       type: isExile ? "Exile" : "Execution", | ||||
|       majority: Math.ceil( | ||||
|         players.filter(player => !player.isDead || isBanishment).length / 2 | ||||
|         players.filter(player => !player.isDead || isExile).length / 2 | ||||
|       ), | ||||
|       votes: players | ||||
|         .filter((player, index) => state.votes[index]) | ||||
|  |  | |||
|  | @ -11,6 +11,9 @@ module.exports = store => { | |||
|   if (localStorage.getItem("muted")) { | ||||
|     store.commit("toggleMuted", true); | ||||
|   } | ||||
|   if (localStorage.getItem("static")) { | ||||
|     store.commit("toggleStatic", true); | ||||
|   } | ||||
|   if (localStorage.getItem("imageOptIn")) { | ||||
|     store.commit("toggleImageOptIn", true); | ||||
|   } | ||||
|  | @ -39,8 +42,8 @@ module.exports = store => { | |||
|   } | ||||
|   if (localStorage.fabled !== undefined) { | ||||
|     store.commit("players/setFabled", { | ||||
|       fabled: JSON.parse(localStorage.fabled).map(id => | ||||
|         store.state.fabled.get(id) | ||||
|       fabled: JSON.parse(localStorage.fabled).map( | ||||
|         fabled => store.state.fabled.get(fabled.id) || fabled | ||||
|       ) | ||||
|     }); | ||||
|   } | ||||
|  | @ -91,6 +94,13 @@ module.exports = store => { | |||
|           localStorage.removeItem("muted"); | ||||
|         } | ||||
|         break; | ||||
|       case "toggleStatic": | ||||
|         if (state.grimoire.isStatic) { | ||||
|           localStorage.setItem("static", 1); | ||||
|         } else { | ||||
|           localStorage.removeItem("static"); | ||||
|         } | ||||
|         break; | ||||
|       case "toggleImageOptIn": | ||||
|         if (state.grimoire.isImageOptIn) { | ||||
|           localStorage.setItem("imageOptIn", 1); | ||||
|  | @ -127,7 +137,11 @@ module.exports = store => { | |||
|       case "players/setFabled": | ||||
|         localStorage.setItem( | ||||
|           "fabled", | ||||
|           JSON.stringify(state.players.fabled.map(({ id }) => id)) | ||||
|           JSON.stringify( | ||||
|             state.players.fabled.map(fabled => | ||||
|               fabled.isCustom ? fabled : { id: fabled.id } | ||||
|             ) | ||||
|           ) | ||||
|         ); | ||||
|         break; | ||||
|       case "players/add": | ||||
|  |  | |||
|  | @ -172,6 +172,11 @@ class LiveSession { | |||
|         if (!this._isSpectator) return; | ||||
|         this._store.commit("toggleNight", params); | ||||
|         break; | ||||
|       case "isVoteHistoryAllowed": | ||||
|         if (!this._isSpectator) return; | ||||
|         this._store.commit("session/setVoteHistoryAllowed", params); | ||||
|         this._store.commit("session/clearVoteHistory"); | ||||
|         break; | ||||
|       case "votingSpeed": | ||||
|         if (!this._isSpectator) return; | ||||
|         this._store.commit("session/setVotingSpeed", params); | ||||
|  | @ -268,11 +273,12 @@ class LiveSession { | |||
|       this._sendDirect(playerId, "gs", { | ||||
|         gamestate: this._gamestate, | ||||
|         isNight: grimoire.isNight, | ||||
|         isVoteHistoryAllowed: session.isVoteHistoryAllowed, | ||||
|         nomination: session.nomination, | ||||
|         votingSpeed: session.votingSpeed, | ||||
|         lockedVote: session.lockedVote, | ||||
|         isVoteInProgress: session.isVoteInProgress, | ||||
|         fabled: fabled.map(({ id }) => id), | ||||
|         fabled: fabled.map(f => (f.isCustom ? f : { id: f.id })), | ||||
|         ...(session.nomination ? { votes: session.votes } : {}) | ||||
|       }); | ||||
|     } | ||||
|  | @ -289,6 +295,7 @@ class LiveSession { | |||
|       gamestate, | ||||
|       isLightweight, | ||||
|       isNight, | ||||
|       isVoteHistoryAllowed, | ||||
|       nomination, | ||||
|       votingSpeed, | ||||
|       votes, | ||||
|  | @ -340,6 +347,7 @@ class LiveSession { | |||
|     }); | ||||
|     if (!isLightweight) { | ||||
|       this._store.commit("toggleNight", !!isNight); | ||||
|       this._store.commit("session/setVoteHistoryAllowed", isVoteHistoryAllowed); | ||||
|       this._store.commit("session/nomination", { | ||||
|         nomination, | ||||
|         votes, | ||||
|  | @ -348,7 +356,7 @@ class LiveSession { | |||
|         isVoteInProgress | ||||
|       }); | ||||
|       this._store.commit("players/setFabled", { | ||||
|         fabled: fabled.map(id => this._store.state.fabled.get(id)) | ||||
|         fabled: fabled.map(f => this._store.state.fabled.get(f.id) || f) | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
|  | @ -407,7 +415,7 @@ class LiveSession { | |||
|     const { fabled } = this._store.state.players; | ||||
|     this._send( | ||||
|       "fabled", | ||||
|       fabled.map(({ id }) => id) | ||||
|       fabled.map(f => (f.isCustom ? f : { id: f.id })) | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|  | @ -419,7 +427,7 @@ class LiveSession { | |||
|   _updateFabled(fabled) { | ||||
|     if (!this._isSpectator) return; | ||||
|     this._store.commit("players/setFabled", { | ||||
|       fabled: fabled.map(id => this._store.state.fabled.get(id)) | ||||
|       fabled: fabled.map(f => this._store.state.fabled.get(f.id) || f) | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|  | @ -688,6 +696,17 @@ class LiveSession { | |||
|     this._send("isNight", this._store.state.grimoire.isNight); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Send the isVoteHistoryAllowed state. ST only | ||||
|    */ | ||||
|   setVoteHistoryAllowed() { | ||||
|     if (this._isSpectator) return; | ||||
|     this._send( | ||||
|       "isVoteHistoryAllowed", | ||||
|       this._store.state.session.isVoteHistoryAllowed | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Send the voting speed. ST only | ||||
|    * @param votingSpeed voting speed in seconds, minimum 1 | ||||
|  | @ -843,6 +862,9 @@ export default store => { | |||
|       case "session/clearVoteHistory": | ||||
|         session.clearVoteHistory(); | ||||
|         break; | ||||
|       case "session/setVoteHistoryAllowed": | ||||
|         session.setVoteHistoryAllowed(); | ||||
|         break; | ||||
|       case "toggleNight": | ||||
|         session.setIsNight(); | ||||
|         break; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue