diff --git a/src/components/Menu.vue b/src/components/Menu.vue
index 79715a5..aa8ea5a 100644
--- a/src/components/Menu.vue
+++ b/src/components/Menu.vue
@@ -73,7 +73,7 @@
Background image
-
+
Mute Sounds
Live Session
-
- Host (Storyteller)[H]
-
-
- Join (Player)[J]
-
-
- Delay to {{ session.isSpectator ? "host" : "players" }}
- {{ session.ping }}ms
-
-
- Copy player link
-
-
-
- Send Characters
-
-
-
- Nomination history[V]
-
-
- Leave Session
- {{ session.sessionId }}
-
+
+ Host (Storyteller)[H]
+ Join (Player)[J]
+
+
+
+ Delay to {{ session.isSpectator ? "host" : "players" }}
+ {{ session.ping }}ms
+
+
+ Copy player link
+
+
+
+ Send Characters
+
+
+
+ Show Custom Images
+
+
+
+ Nomination history[V]
+
+
+ Leave Session
+ {{ session.sessionId }}
+
+
@@ -218,9 +228,6 @@ export default {
this.$store.commit("setBackground", background);
}
},
- toggleMute() {
- this.$store.commit("setIsMuted", !this.grimoire.isMuted);
- },
hostSession() {
if (this.session.sessionId) return;
const sessionId = prompt(
@@ -253,6 +260,13 @@ export default {
);
}
},
+ imageOptIn() {
+ const popup =
+ "Are you sure you want to allow custom images? A malicious storyteller might get access to your IP address this way.";
+ if (this.grimoire.isImageOptIn || confirm(popup)) {
+ this.toggleImageOptIn();
+ }
+ },
joinSession() {
if (this.session.sessionId) return this.leaveSession();
const sessionId = prompt(
@@ -299,6 +313,8 @@ export default {
...mapMutations([
"toggleGrimoire",
"toggleMenu",
+ "toggleImageOptIn",
+ "toggleMuted",
"toggleNight",
"toggleNightOrder",
"setZoom",
diff --git a/src/store/index.js b/src/store/index.js
index bbd0c60..31813f4 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -10,12 +10,14 @@ import fabledJSON from "../fabled.json";
Vue.use(Vuex);
+// global data maps
const editionJSONbyId = new Map(
editionJSON.map(edition => [edition.id, edition])
);
const rolesJSONbyId = new Map(rolesJSON.map(role => [role.id, role]));
const fabled = new Map(fabledJSON.map(role => [role.id, role]));
+// helper functions
const getRolesByEdition = (edition = editionJSON[0]) => {
return new Map(
rolesJSON
@@ -38,6 +40,18 @@ const getTravelersNotInEdition = (edition = editionJSON[0]) => {
);
};
+const set = key => ({ grimoire }, val) => {
+ grimoire[key] = val;
+};
+
+const toggle = key => ({ grimoire }, val) => {
+ if (val === true || val === false) {
+ grimoire[key] = val;
+ } else {
+ grimoire[key] = !grimoire[key];
+ }
+};
+
// base definition for custom roles
const imageBase =
"https://raw.githubusercontent.com/bra1n/townsquare/main/src/assets/icons/";
@@ -67,6 +81,7 @@ export default new Vuex.Store({
isPublic: true,
isMenuOpen: false,
isMuted: false,
+ isImageOptIn: false,
zoom: 0,
background: ""
},
@@ -119,38 +134,14 @@ export default new Vuex.Store({
rolesJSONbyId: () => rolesJSONbyId
},
mutations: {
- toggleMenu({ grimoire }) {
- grimoire.isMenuOpen = !grimoire.isMenuOpen;
- },
- toggleGrimoire({ grimoire }, isPublic) {
- if (isPublic === true || isPublic === false) {
- grimoire.isPublic = isPublic;
- } else {
- grimoire.isPublic = !grimoire.isPublic;
- }
- document.title = `Blood on the Clocktower ${
- grimoire.isPublic ? "Town Square" : "Grimoire"
- }`;
- },
- toggleNight({ grimoire }, isNight) {
- if (isNight === true || isNight === false) {
- grimoire.isNight = isNight;
- } else {
- grimoire.isNight = !grimoire.isNight;
- }
- },
- toggleNightOrder({ grimoire }) {
- grimoire.isNightOrder = !grimoire.isNightOrder;
- },
- setZoom({ grimoire }, zoom) {
- grimoire.zoom = zoom;
- },
- setBackground({ grimoire }, background) {
- grimoire.background = background;
- },
- setIsMuted({ grimoire }, isMuted) {
- grimoire.isMuted = isMuted;
- },
+ setZoom: set("zoom"),
+ setBackground: set("background"),
+ toggleMuted: toggle("isMuted"),
+ toggleMenu: toggle("isMenuOpen"),
+ toggleNightOrder: toggle("isNightOrder"),
+ toggleNight: toggle("isNight"),
+ toggleGrimoire: toggle("isPublic"),
+ toggleImageOptIn: toggle("isImageOptIn"),
toggleModal({ modals }, name) {
if (name) {
modals[name] = !modals[name];
diff --git a/src/store/modules/session.js b/src/store/modules/session.js
index 62dda3c..80d4aaf 100644
--- a/src/store/modules/session.js
+++ b/src/store/modules/session.js
@@ -1,8 +1,3 @@
-// helper functions
-const set = key => (state, val) => {
- state[key] = val;
-};
-
/**
* Handle a vote request.
* If the vote is from a seat that is already locked, ignore it.
@@ -37,6 +32,11 @@ const getters = {};
const actions = {};
+// mutations helper functions
+const set = key => (state, val) => {
+ state[key] = val;
+};
+
const mutations = {
setPlayerId: set("playerId"),
setSpectator: set("isSpectator"),
diff --git a/src/store/persistence.js b/src/store/persistence.js
index fbd22ab..8623a08 100644
--- a/src/store/persistence.js
+++ b/src/store/persistence.js
@@ -1,16 +1,25 @@
module.exports = store => {
+ const updatePagetitle = isPublic =>
+ (document.title = `Blood on the Clocktower ${
+ isPublic ? "Town Square" : "Grimoire"
+ }`);
+
// initialize data
if (localStorage.getItem("background")) {
store.commit("setBackground", localStorage.background);
}
if (localStorage.getItem("muted")) {
- store.commit("setIsMuted", true);
+ store.commit("toggleMuted", true);
+ }
+ if (localStorage.getItem("imageOptIn")) {
+ store.commit("toggleImageOptIn", true);
}
if (localStorage.getItem("zoom")) {
store.commit("setZoom", parseFloat(localStorage.getItem("zoom")));
}
- if (localStorage.isPublic !== undefined) {
- store.commit("toggleGrimoire", JSON.parse(localStorage.isPublic));
+ if (localStorage.getItem("isGrimoire")) {
+ store.commit("toggleGrimoire", false);
+ updatePagetitle(false);
}
if (localStorage.roles !== undefined) {
store.commit("setCustomRoles", JSON.parse(localStorage.roles));
@@ -61,10 +70,12 @@ module.exports = store => {
store.subscribe(({ type, payload }, state) => {
switch (type) {
case "toggleGrimoire":
- localStorage.setItem(
- "isPublic",
- JSON.stringify(state.grimoire.isPublic)
- );
+ if (!state.grimoire.isPublic) {
+ localStorage.setItem("isGrimoire", 1);
+ } else {
+ localStorage.removeItem("isGrimoire");
+ }
+ updatePagetitle(state.grimoire.isPublic);
break;
case "setBackground":
if (payload) {
@@ -73,13 +84,20 @@ module.exports = store => {
localStorage.removeItem("background");
}
break;
- case "setIsMuted":
- if (payload) {
+ case "toggleMuted":
+ if (state.grimoire.isMuted) {
localStorage.setItem("muted", 1);
} else {
localStorage.removeItem("muted");
}
break;
+ case "toggleImageOptIn":
+ if (state.grimoire.isImageOptIn) {
+ localStorage.setItem("imageOptIn", 1);
+ } else {
+ localStorage.removeItem("imageOptIn");
+ }
+ break;
case "setZoom":
if (payload !== 0) {
localStorage.setItem("zoom", payload);