Skip to content

Commit

Permalink
v5.0.0-alpha.172: Move history, initial position customization, and i…
Browse files Browse the repository at this point in the history
…mprovements (GamesCrafters#61)

* Initial position customization with validation

* Move history import/export with validation

* Search bar improvement: the user can now use the esc key to clear input

* Restart game now clears the move history

Co-authored-by: Victoria Phelps <[email protected]>
Co-authored-by: Cameron Cheung <[email protected]>
  • Loading branch information
3 people authored Nov 17, 2022
1 parent 00f64f1 commit 7d51a42
Show file tree
Hide file tree
Showing 17 changed files with 687 additions and 69 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@
"preview:https": "serve dist",
"reinstall": "rm -rf node_modules; yarn; vue-tsc --noEmit"
},
"version": "5.0.0-alpha.171"
"version": "5.0.0-alpha.172"
}
8 changes: 5 additions & 3 deletions src/components/units/AppGame.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div id="app-game">
<AppGameBody />
<AppGameVvh />
<AppGameMenu v-show="showVvh"/>
</div>
</template>

Expand All @@ -10,21 +10,23 @@
import { onBeforeRouteLeave, useRoute } from "vue-router";
import { actionTypes, useStore } from "../../scripts/plugins/store";
import AppGameBody from "./AppGameBody.vue";
import AppGameVvh from "./AppGameVvh.vue";
import AppGameMenu from "./AppGameMenu.vue";
const route = useRoute();
const store = useStore();
const gameType = computed(() => route.params.type as string);
const gameId = computed(() => route.params.gameId as string);
const variantId = computed(() => route.params.variantId as string);
store.dispatch(actionTypes.initiateMatch, { gameType: gameType.value, gameId: gameId.value, variantId: variantId.value });
const options = computed(() => (store.getters.currentPlayer ? store.getters.currentPlayer.options : undefined));
const showVvh = computed(() => (options.value ? options.value.showMenu : true));
onBeforeRouteLeave(() => store.dispatch(actionTypes.exitMatch));
</script>

<style lang="scss" scoped>
#app-game {
align-content: normal;
align-items: flex-end;
align-items: flex-start;
display: flex;
flex-direction: row;
flex-wrap: wrap;
Expand Down
10 changes: 5 additions & 5 deletions src/components/units/AppGameBodyHeaderOptions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,15 @@
</div>
<div id="computer-move-duration" v-if="updatedMatchType.includes('c')">
<h3 class="title">Computer Move Duration (milliseconds)</h3>
<VueSlider id="slider" v-model="options.computerMoveDuration" :min="0" :max="10000" interval="10" :tooltip="'active'" />
<VueSlider id="slider" v-model="options.computerMoveDuration" :min="0" :max="10000" :interval="10" :tooltip="'active'" />
<i>(Note: The actual duration will be either the ideal duration above or server data load time if there is any server data load action, whichever is greater.)</i>
</div>
<div id="visibility-options">
<h3 id="title">Visibility Options</h3>
<div id="options">
<div class="option">
<input class="uni-toggle-button" aria-label="toggle" type="checkbox" v-model="options.showVvh" />
<label for="checkbox">Visual Value History</label>
<input class="uni-toggle-button" aria-label="toggle" type="checkbox" v-model="options.showMenu" />
<label for="checkbox">Game Menu</label>
</div>
<div class="option">
<input class="uni-toggle-button" aria-label="toggle" type="checkbox" v-model="options.showNextMoves" />
Expand Down Expand Up @@ -196,9 +196,9 @@
const currentPlayerName = computed(() => (store.getters.users ? store.getters.users[currentPlayerId.value].name : ""));
const updatedPlayerName = ref("");
const currentLeftPlayerName = computed(() => (store.getters.users ? store.getters.users[currentLeftPlayerId.value].name : ""));
const currentLeftPlayerName = computed(() => (store.getters.users && store.getters.users[currentLeftPlayerId.value] ? store.getters.users[currentLeftPlayerId.value].name : ""));
const updatedLeftPlayerName = ref("");
const currentRightPlayerName = computed(() => (store.getters.users ? store.getters.users[currentRightPlayerId.value].name : ""));
const currentRightPlayerName = computed(() => (store.getters.users && store.getters.users[currentRightPlayerId.value] ? store.getters.users[currentRightPlayerId.value].name : ""));
const updatedRightPlayerName = ref("");
const gameType = route.params.type as string;
const gameId = route.params.gameId as string;
Expand Down
61 changes: 61 additions & 0 deletions src/components/units/AppGameMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<div id="app-game-menu">
<AppGameMenuHeader />
<div id="app-game-menu-content">
<div id="app-game-menu-content-buttons">
<button class="buttons" @click="activeTab = 'vvh'">
Visual Value History
</button>
<!-- <button class="buttons" @click="activeTab = 'analysis'">
Analysis
</button> -->
<button class="buttons" @click="activeTab = 'startPos'">
Customize Starting Position
</button>
<button class="buttons" @click="activeTab = 'moveHist'">
Move History
</button>
</div>
<div id="app-game-menu-content-active">
<AppGameVvh v-show="activeTab === 'vvh'"/>
<!-- <AppGameMenuAnalysis/> -->
<AppGameMenuPosition v-show="activeTab === 'startPos'"/>
<AppGameMenuMoveHistory v-show="activeTab === 'moveHist'"/>
</div>
</div>
</div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import AppGameVvh from "./AppGameVvh.vue";
import AppGameMenuHeader from "./AppGameMenuHeader.vue";
import AppGameMenuPosition from "./AppGameMenuPosition.vue";
import AppGameMenuMoveHistory from "./AppGameMenuHistory.vue";
const activeTab = ref('vvh');
</script>

<style lang="scss" scoped>
#app-game-menu {
flex: 1 1 auto;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
#app-game-menu-content {
border-radius: 1rem;
border: 0.1rem solid var(--neutralColor);
padding: 4rem;
.buttons {
margin-top: 2rem;
margin-right: 1rem;
margin-left: 1rem;
margin-bottom: 2rem;
padding: 0 0.5rem;
border-radius: 10rem;
border: 0.1rem solid var(--neutralColor);
}
}
}
</style>
19 changes: 19 additions & 0 deletions src/components/units/AppGameMenuHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<div id="app-game-menu-header">
<h1> Menu </h1>
</div>
</template>

<style lang="scss" scoped>
#app-game-menu-header {
align-content: center;
align-items: center;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
> * {
margin: 2.5rem;
}
}
</style>
22 changes: 22 additions & 0 deletions src/components/units/AppGameMenuHistory.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<template>
<div id="app-game-menu-history">
<AppGameMenuHistoryImport />
<AppGameMenuHistoryExport />
</div>
</template>

<script lang="ts" setup>
import AppGameMenuHistoryImport from "./AppGameMenuHistoryImport.vue";
import AppGameMenuHistoryExport from "./AppGameMenuHistoryExport.vue";
</script>

<style lang="scss" scoped>
#app-game-menu-history {
flex: 1 1 auto;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
margin: 2rem;
}
</style>
66 changes: 66 additions & 0 deletions src/components/units/AppGameMenuHistoryExport.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<template>
<div id="app-game-menu-history-export">
<h3>Current Move History</h3>
<textarea id="app-game-menu-history-export-currHist" readonly>{{ moveHistoryText }}</textarea>
<button class="button unclicked" v-show="!copied" @click="copyToClipboard" title="copy to clipboard">copy to clipboard</button>
<button class="button clicked" v-show="copied" @click="copyToClipboard" title="copied!">copy to clipboard</button>
<!-- TODO: Export to file goes here -->
</div>
</template>

<script lang="ts" setup>
import { computed, ref } from "vue";
import { useStore } from "../../scripts/plugins/store";
const copied = ref(false);
const store = useStore();
const moveHistoryText = computed(() => {
copied.value = false;
return store.getters.moveHistory;
});
const copyToClipboard = () => {
navigator.clipboard.writeText(moveHistoryText.value);
copied.value = true;
}
</script>

<style lang="scss" scoped>
#app-game-menu-history-export {
flex: 1 1 auto;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
#app-game-menu-history-export-currHist {
width: 15vw;
height: 15vh;
text-align: left;
resize: none;
border-radius: 1rem;
border: 0.1rem solid var(--neutralColor);
padding: 1rem;
margin-top: 1rem;
}
.button {
margin: 1rem;
padding: 0 0.5rem;
border-radius: 10rem;
border: 0.1rem solid var(--neutralColor);
}
.clicked {
background-color: rgba(76, 220, 37, 0.645);
}
// #app-game-menu-history-export-copy {
// width: 10rem;
// height: 10rem;
// margin-top: 2rem;
// margin-right: 1rem;
// margin-left: 1rem;
// margin-bottom: 2rem;
// padding: 0 0.5rem;
// border-radius: 10rem;
// border: 0.1rem solid var(--neutralColor);
// }
}
</style>
84 changes: 84 additions & 0 deletions src/components/units/AppGameMenuHistoryImport.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<template>
<div id="app-game-menu-history-import">
<h3>Import Move History</h3>
<div id="app-game-menu-history-import-text">
<button id="app-game-menu-history-import-text-info" @click="showInfo = !showInfo">𝓲</button>
<textarea
v-model="inputHist"
id="app-game-menu-history-import-text-input"
placeholder="Enter move history of game here"
@keyup.enter="onTextSubmit"
/>
<button id="app-game-menu-history-import-text-submit" @click="onTextSubmit">Submit</button>
</div>
<div class="error" v-show="errorMsg">Error: {{ errorMsg }}</div>
<AppGameMenuHistoryImportFile />
<p v-show="showInfo" id="app-game-menu-history-import-infoMsg">
Instructions on how to format the move history...
</p>
</div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import { actionTypes, useStore } from "../../scripts/plugins/store";
import AppGameMenuHistoryImportFile from "./AppGameMenuHistoryImportFile.vue";
const store = useStore();
const showInfo = ref(false);
const inputHist = ref("");
const errorMsg = ref("");
const onTextSubmit = async () => {
const error = await store.dispatch(actionTypes.loadMoveHistory, { history: inputHist.value });
if (error) {
errorMsg.value = error.message;
} else {
errorMsg.value = "";
inputHist.value = "";
}
};
</script>

<style lang="scss" scoped>
#app-game-menu-history-import {
#app-game-menu-history-import-text {
flex: 1 1 auto;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
margin: 1rem;
align-items: center;
#app-game-menu-history-import-text-info {
margin-right: 2rem;
border-radius: 100%;
font-size: 2rem;
height: max(2.5rem, min(5vh, 5vw));
width: max(2.5rem, min(5vh, 5vw));
}
#app-game-menu-history-import-text-input {
border-radius: 1rem;
border: 0.1rem solid var(--neutralColor);
padding: 1rem;
border-spacing: 5rem;
width: 15vw;
height: 15vh;
text-align: left;
resize: none;
}
#app-game-menu-history-import-text-submit {
padding: 0.3rem;
margin-left: 2rem;
border: 0.1rem solid var(--neutralColor);
}
}
#app-game-menu-history-import-infoMsg {
padding: 1rem;
text-align: center;
}
.error {
color: red;
margin: 1rem;
}
}
</style>
48 changes: 48 additions & 0 deletions src/components/units/AppGameMenuHistoryImportFile.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<div id="app-game-menu-history-import-file">
<input type="file" accept=".txt" v-on:change="onFileChange" />
</div>
</template>

<script lang="ts" setup>
import { actionTypes, useStore } from "../../scripts/plugins/store";
interface HTMLInputEvent extends Event {
target: HTMLInputElement & EventTarget
};
const store = useStore();
const readHistoryFromFile = (file: File) => {
if (!file) return;
const reader = new FileReader();
reader.readAsText(file);
reader.onload = () => {
if (typeof reader.result === "string") {
store.dispatch(actionTypes.loadMoveHistory, { history: reader.result });
}
};
reader.onerror = () => {
console.log(reader.error);
alert(reader.error);
};
};
const onFileChange = (e: HTMLInputEvent) => {
if (!e.target || !e.target.files) return;
readHistoryFromFile(e.target.files[0]);
};
</script>

<style lang="scss" scoped>
// #app-game-menu-history-import-file {
// #input-file {
// margin-left: 2rem;
// padding: 1rem;
// padding-top: 1rem;
// float: center;
// justify-content: space-around;
// width: 15rem;
// }
// #upload {
// padding: 0.5rem;
// border: 0.1rem solid var(--neutralColor);
// }
// }
</style>
Loading

0 comments on commit 7d51a42

Please sign in to comment.