Merge pull request #107 from davotronic5000/#43_gender_pronouns

#43 gender pronouns
This commit is contained in:
Steffen 2021-03-09 15:26:30 +01:00 committed by GitHub
commit 2b2500a6c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 144 additions and 12 deletions

View File

@ -1,5 +1,9 @@
# Release Notes # Release Notes
### Version 2.9.0
- added support for assigning pronouns to players and display of the pronouns in a tooltip on the player name.
---
### Version 2.8.0 ### Version 2.8.0
- added hands-off live session support for homebrew / custom characters again! - added hands-off live session support for homebrew / custom characters again!
- added custom image opt-in that will prevent any (potentially malicious / harmful) images from loading until a player manually allows them to - added custom image opt-in that will prevent any (potentially malicious / harmful) images from loading until a player manually allows them to

View File

@ -97,13 +97,16 @@
@click="updatePlayer('isVoteless', true)" @click="updatePlayer('isVoteless', true)"
title="Ghost vote" title="Ghost vote"
/> />
<div <div
class="name" class="name"
@click="isMenuOpen = !isMenuOpen" @click="isMenuOpen = !isMenuOpen"
:class="{ active: isMenuOpen }" :class="{ active: isMenuOpen }"
> >
{{ player.name }} <span>{{ player.name }}</span>
<font-awesome-icon icon="venus-mars" v-if="player.pronouns" />
<div class="pronouns" v-if="player.pronouns">
<span>{{ player.pronouns }}</span>
</div>
</div> </div>
<transition name="fold"> <transition name="fold">
@ -150,6 +153,15 @@
</template> </template>
<template v-else> Seat occupied</template> <template v-else> Seat occupied</template>
</li> </li>
<li
@click="changePronouns"
v-if="
!session.isSpectator ||
(session.isSpectator && player.id === session.playerId)
"
>
<font-awesome-icon icon="venus-mars" />Change Pronouns
</li>
</ul> </ul>
</transition> </transition>
</div> </div>
@ -232,6 +244,15 @@ export default {
}; };
}, },
methods: { methods: {
changePronouns() {
if (this.session.isSpectator && this.player.id !== this.session.playerId)
return;
const pronouns = prompt("Player pronouns", this.player.pronouns);
//Only update pronouns if not null (prompt was not cancelled)
if (pronouns !== null) {
this.updatePlayer("pronouns", pronouns, true);
}
},
toggleStatus() { toggleStatus() {
if (this.grimoire.isPublic) { if (this.grimoire.isPublic) {
if (!this.player.isDead) { if (!this.player.isDead) {
@ -260,7 +281,12 @@ export default {
this.updatePlayer("reminders", reminders, true); this.updatePlayer("reminders", reminders, true);
}, },
updatePlayer(property, value, closeMenu = false) { updatePlayer(property, value, closeMenu = false) {
if (this.session.isSpectator && property !== "reminders") return; if (
this.session.isSpectator &&
property !== "reminders" &&
property !== "pronouns"
)
return;
this.$store.commit("players/update", { this.$store.commit("players/update", {
player: this.player, player: this.player,
property, property,
@ -629,25 +655,72 @@ li.move:not(.from) .player .overlay svg.move {
/***** Player name *****/ /***** Player name *****/
.player > .name { .player > .name {
text-align: center; right: 10%;
display: flex;
justify-content: center;
font-size: 120%; font-size: 120%;
line-height: 120%; line-height: 120%;
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
width: 100%; width: 120%;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
border: 3px solid black; border: 3px solid black;
border-radius: 10px; border-radius: 10px;
top: 5px; top: 5px;
box-shadow: 0 0 5px black; box-shadow: 0 0 5px black;
text-overflow: ellipsis;
overflow: hidden;
padding: 0 4px; padding: 0 4px;
svg {
top: 3px;
margin-right: 2px;
}
span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
flex-grow: 1;
}
#townsquare:not(.spectator) &:hover, #townsquare:not(.spectator) &:hover,
&.active { &.active {
color: red; color: red;
} }
&:hover .pronouns {
opacity: 1;
color: white;
}
.pronouns {
display: flex;
position: absolute;
right: 110%;
max-width: 250px;
z-index: 25;
background: rgba(0, 0, 0, 0.5);
border-radius: 10px;
border: 3px solid black;
filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.5));
align-items: center;
pointer-events: none;
opacity: 0;
transition: opacity 200ms ease-in-out;
padding: 0 4px;
bottom: -3px;
&:before {
content: " ";
border: 10px solid transparent;
width: 0;
height: 0;
border-left-color: black;
position: absolute;
margin-left: 2px;
left: 100%;
}
}
} }
.player.dead > .name { .player.dead > .name {
@ -657,7 +730,7 @@ li.move:not(.from) .player .overlay svg.move {
/***** Player menu *****/ /***** Player menu *****/
.player > .menu { .player > .menu {
position: absolute; position: absolute;
left: 100%; left: 110%;
bottom: -5px; bottom: -5px;
text-align: left; text-align: left;
white-space: nowrap; white-space: nowrap;

View File

@ -264,7 +264,7 @@ export default {
// open menu on the left // open menu on the left
.player > .menu { .player > .menu {
left: auto; left: auto;
right: 100%; right: 110%;
margin-right: 15px; margin-right: 15px;
&:before { &:before {
border-left-color: black; border-left-color: black;
@ -292,6 +292,16 @@ export default {
left: 100%; left: 100%;
} }
} }
.pronouns {
left: 110%;
right: auto;
&:before {
border-left-color: transparent;
border-right-color: black;
left: auto;
right: 100%;
}
}
} @else { } @else {
// second half of players // second half of players
z-index: $i - 1; z-index: $i - 1;

View File

@ -44,6 +44,7 @@ const faIcons = [
"UserEdit", "UserEdit",
"UserFriends", "UserFriends",
"Users", "Users",
"VenusMars",
"VolumeUp", "VolumeUp",
"VolumeMute", "VolumeMute",
"VoteYea", "VoteYea",

View File

@ -4,7 +4,8 @@ const NEWPLAYER = {
role: {}, role: {},
reminders: [], reminders: [],
isVoteless: false, isVoteless: false,
isDead: false isDead: false,
pronouns: ""
}; };
const state = () => ({ const state = () => ({

View File

@ -189,6 +189,9 @@ class LiveSession {
case "bye": case "bye":
this._handleBye(params); this._handleBye(params);
break; break;
case "pronouns":
this._updatePlayerPronouns(params);
break;
} }
} }
@ -244,6 +247,7 @@ class LiveSession {
id: player.id, id: player.id,
isDead: player.isDead, isDead: player.isDead,
isVoteless: player.isVoteless, isVoteless: player.isVoteless,
pronouns: player.pronouns,
...(player.role && player.role.team === "traveler" ...(player.role && player.role.team === "traveler"
? { roleId: player.role.id } ? { roleId: player.role.id }
: {}) : {})
@ -304,7 +308,7 @@ class LiveSession {
const player = players[x]; const player = players[x];
const { roleId } = state; const { roleId } = state;
// update relevant properties // update relevant properties
["name", "id", "isDead", "isVoteless"].forEach(property => { ["name", "id", "isDead", "isVoteless", "pronouns"].forEach(property => {
const value = state[property]; const value = state[property];
if (player[property] !== value) { if (player[property] !== value) {
this._store.commit("players/update", { player, property, value }); this._store.commit("players/update", { player, property, value });
@ -481,6 +485,41 @@ class LiveSession {
} }
} }
/**
* Publish a player pronouns update
* @param player
* @param value
*/
sendPlayerPronouns({ player, value }) {
//send pronoun only for the seated player or storyteller
if (this._isSpectator && this._store.state.session.playerId !== player.id)
return;
const index = this._store.state.players.players.indexOf(player);
this._send("pronouns", [index, value, !this._isSpectator]);
}
/**
* Update a pronouns based on incoming data. Player only.
* @param index
* @param value
* @param fromSt
* @private
*/
_updatePlayerPronouns([index, value, fromST]) {
const player = this._store.state.players.players[index];
if (
player &&
(fromST || this._store.state.session.playerId !== player.id) &&
player.pronouns !== value
) {
this._store.commit("players/update", {
player,
property: "pronouns",
value
});
}
}
/** /**
* Handle a ping message by another player / storyteller * Handle a ping message by another player / storyteller
* @param playerIdOrCount * @param playerIdOrCount
@ -810,7 +849,11 @@ export default store => {
session.sendGamestate("", true); session.sendGamestate("", true);
break; break;
case "players/update": case "players/update":
if (payload.property === "pronouns") {
session.sendPlayerPronouns(payload);
} else {
session.sendPlayer(payload); session.sendPlayer(payload);
}
break; break;
} }
}); });