Created
March 4, 2021 13:39
-
-
Save valex/f675bc3f11e93fad7bc7e7d1751e6ada to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<v-row> | |
<v-col :cols="5"> | |
<chessboard-with-controls | |
:initial-orientation=initialOrientation | |
></chessboard-with-controls> | |
<v-card v-if="mounted && $store.getters['users/isAdmin']"> | |
<v-card-text> | |
<v-text-field | |
v-model="position_title" | |
label="Название" | |
></v-text-field> | |
<v-textarea | |
v-model="move_description" | |
label="Описание последнего хода" | |
></v-textarea> | |
<v-textarea | |
v-model="position_description" | |
label="Описание позиции" | |
></v-textarea> | |
<v-textarea | |
v-model="position_notes" | |
label="Заметки" | |
></v-textarea> | |
</v-card-text> | |
<v-card-actions> | |
<v-spacer /> | |
<v-btn | |
@click="clickSaveAll" | |
:loading = "loadings.save_all" | |
color="error" | |
> | |
Save All | |
</v-btn> | |
</v-card-actions> | |
</v-card> | |
</v-col> | |
<v-col :cols="7"> | |
<v-card | |
min-height="66" | |
outlined | |
tile | |
> | |
<v-card-text> | |
<v-btn v-for="move in possible_moves" :key="move.san" @click="clickMove(move)" tile depressed small style="text-transform: none;" class="mb-1 mr-1"> | |
{{move.san}} | |
</v-btn> | |
</v-card-text> | |
</v-card> | |
<v-card tile outlined> | |
<v-card-title v-if="position_title"><h1 class="headline">{{position_title}}</h1></v-card-title> | |
<v-card-text v-if="move_description" v-html="move_description"></v-card-text> | |
<v-divider v-if="move_description"></v-divider> | |
<v-card-text v-html="position_description"></v-card-text> | |
</v-card> | |
</v-col> | |
</v-row> | |
</template> | |
<script lang="js"> | |
import * as firebase from 'firebase/app'; | |
import 'firebase/firestore'; | |
import * as _ from "lodash"; | |
import { mapState } from 'vuex'; | |
import ChessboardWithControls from '~/components/ChessboardWithControls.vue'; | |
import FenHelper from '~/app/helpers/FenHelper'; | |
export default { | |
name: 'ChessboardPage', | |
lastMoveRef: null, | |
props: { | |
initialOrientation:{ // 'white', 'black' | |
type: String, | |
default: 'white' | |
}, | |
}, | |
components: { | |
ChessboardWithControls | |
}, | |
data(context) { | |
return { | |
mounted: false, | |
loadings: { | |
save_all: false | |
} | |
}; | |
}, | |
// Только на стороне сервера | |
// Будет автоматически вызвано рендером сервера | |
serverPrefetch () { | |
// возвращает Promise из действия, поэтому | |
// компонент ждёт данные перед рендерингом | |
return this.syncPosition(this.initial_fen); | |
}, | |
mounted() { | |
this.mounted = true; | |
this.$eventBus.$on('move', this.onMove); | |
this.$eventBus.$on('move-back', this.onHistoryMove); | |
this.$eventBus.$on('move-forward', this.onHistoryMove); | |
if(_.isEmpty(this.possible_moves)){ | |
this.syncPosition(this.initial_fen); | |
} | |
if(this.addCurrentToFSFromClient){ | |
this.addNewPositionToFS(this.initial_fen).then(()=>{ | |
this.$store.commit('chessboard/SET_ADD_CURRENT_TO_FS', false); | |
}); | |
} | |
}, | |
methods: { | |
async syncPosition( currentFen, fromFen, moveObject){ | |
this.clearPageMeta(); | |
const currentParsedFen = FenHelper.parse(currentFen); | |
const currentFirestoreFen = _.get(currentParsedFen, 'firestore_fen'); | |
const positionsRef = firebase.firestore().collection("positions"); | |
const currentPositionRef = positionsRef.doc(currentFirestoreFen); | |
// Add position if not exists | |
await currentPositionRef.get().then(async (positionSnapshot)=> { | |
if (positionSnapshot.exists) { | |
//console.log("Document data:", positionSnapshot.data()); | |
} else { | |
// positionSnapshot.data() will be undefined in this case | |
// No such document! | |
if(process.server){ | |
this.$store.commit('chessboard/SET_ADD_CURRENT_TO_FS', true); | |
}else{ | |
await this.addNewPositionToFS(currentFen); | |
} | |
} | |
}).catch(function(error) { | |
console.log("Error getting POSITION document:", error); | |
}); | |
if( ! _.isNil(fromFen) && ! _.isNil(moveObject)) { | |
const fromParsedFen = FenHelper.parse(fromFen); | |
const fromFirestoreFen = _.get(fromParsedFen, 'firestore_fen'); | |
const fromPositionRef = positionsRef.doc(fromFirestoreFen); | |
const possibleMovesRef = fromPositionRef.collection("possible_moves"); | |
this.$options.lastMoveRef = possibleMovesRef.doc(moveObject.san); | |
// Add move if not exists | |
await this.$options.lastMoveRef.get().then((snapshot) => { | |
if (snapshot.exists) { | |
const increment = firebase.firestore.FieldValue.increment(1); | |
this.$options.lastMoveRef.update({ views: increment }); | |
this.$store.commit('chessboard/SET_MOVE_DESCRIPTION', _.get(snapshot.data(), 'description')); | |
} else { | |
// snapshot.data() will be undefined in this case | |
// No such document! | |
this.$options.lastMoveRef.set({ | |
views: 0, | |
...moveObject | |
} ) | |
} | |
}).catch(function(error) { | |
console.log("Error getting MOVE document:", error); | |
}); | |
} | |
// GET DATA FOR CURRENT POSITION | |
const positionSnap = await currentPositionRef.get(); | |
if( ! positionSnap.exists ) | |
return; | |
const movesSnap = await currentPositionRef | |
.collection("possible_moves") | |
.orderBy("views", "desc").get(); | |
let movesFromSnap = []; | |
movesSnap.forEach((move) =>{ | |
// doc.data() is never undefined for query doc snapshots | |
movesFromSnap.push(move.data()) | |
}); | |
this.possible_moves = movesFromSnap; | |
const positionData = positionSnap.data(); | |
// setup shapes | |
if( ! _.isEmpty(positionData.shapes)){ | |
this.shapes = positionData.shapes; | |
} | |
this.position_title = positionData.name; | |
this.position_description = positionData.description; | |
this.position_notes = positionData.notes; | |
this.saveHistoryMeta(fromFen, moveObject); | |
}, | |
addNewPositionToFS(fen){ | |
const parsedFen = FenHelper.parse(fen); | |
return firebase.firestore() | |
.collection("positions") | |
.doc(_.get(parsedFen, 'firestore_fen')) | |
.set({ | |
fen: ''+_.get(parsedFen, 'valuable_fen'), | |
move_number: +_.get(parsedFen, 'move_number'), | |
shapes: [] | |
}); | |
}, | |
async clickSaveAll() { | |
this.$eventBus.$emit('sync-chessground-state'); | |
let vuexShapes = this.$store.state.chessboard.chessgroundState.shapes; | |
let shapes = _.map(vuexShapes, shape=>{ | |
return _.pickBy(shape, (value, key) => { | |
if( _.isUndefined(value)) | |
return false; | |
return _.includes(['orig', 'dest', 'brush', 'modifiers'], key); | |
}); | |
}); | |
this.loadings.save_all=true; | |
await this.saveShapes(shapes); | |
await this.savePositionMeta(); | |
await this.saveLastMoveMeta(); | |
this.loadings.save_all=false; | |
}, | |
saveLastMoveMeta(){ | |
if( _.isNil(this.$options.lastMoveRef) ){ | |
console.error('this.$options.lastMoveRef not set. Move Description not save'); | |
return; | |
}else{ | |
this.$options.lastMoveRef.update({ | |
description: this.move_description || null, | |
}); | |
} | |
}, | |
savePositionMeta(){ | |
const currentFen = this.$store.state.chessboard.chessgroundState.fen; | |
const currentParsedFen = FenHelper.parse(currentFen); | |
const currentFirestoreFen = _.get(currentParsedFen, 'firestore_fen'); | |
const currentPositionRef = firebase.firestore().collection("positions").doc(currentFirestoreFen); | |
return currentPositionRef.update({ | |
name: this.position_title || null, | |
description: this.position_description || null, | |
notes: this.position_notes || null, | |
}); | |
}, | |
saveShapes(shapes) { | |
const currentFen = this.$store.state.chessboard.chessgroundState.fen; | |
const currentParsedFen = FenHelper.parse(currentFen); | |
const currentFirestoreFen = _.get(currentParsedFen, 'firestore_fen'); | |
const currentPositionRef = firebase.firestore().collection("positions").doc(currentFirestoreFen); | |
return currentPositionRef.update({ | |
shapes: shapes, | |
}); | |
}, | |
clickMove(moveObject) { | |
this.$eventBus.$emit('make-move', moveObject); | |
}, | |
onMove(currentFen, fromFen, moveObject){ | |
this.syncPosition(currentFen, fromFen, moveObject); | |
}, | |
onHistoryMove() { | |
this.clearPageMeta(); | |
this.applyHistoryMeta(); | |
}, | |
saveHistoryMeta(fromFen, moveObject){ | |
let from_firestore_fen = null; | |
let last_move_san = null; | |
if( ! _.isNil(fromFen) && ! _.isNil(moveObject)) { | |
from_firestore_fen = _.get(FenHelper.parse(fromFen), 'firestore_fen'); | |
last_move_san = moveObject.san; | |
} | |
this.meta_history = { | |
from_firestore_fen, | |
last_move_san, | |
possible_moves: this.possible_moves, | |
position_title: this.position_title, | |
position_description: this.position_description, | |
position_notes: this.position_notes, | |
move_description: this.move_description, | |
shapes: this.shapes, | |
}; | |
}, | |
applyHistoryMeta(){ | |
if( _.isNil(this.meta_history[this.historyMetaPointer])) | |
return; | |
if( ! _.isNil(this.meta_history[this.historyMetaPointer]['from_firestore_fen']) && | |
! _.isNil(this.meta_history[this.historyMetaPointer]['last_move_san'])) | |
{ | |
this.$options.lastMoveRef = firebase.firestore() | |
.collection("positions") | |
.doc(this.meta_history[this.historyMetaPointer]['from_firestore_fen']) | |
.collection("possible_moves") | |
.doc(this.meta_history[this.historyMetaPointer]['last_move_san']); | |
} | |
this.possible_moves = this.meta_history[this.historyMetaPointer]['possible_moves']; | |
this.position_title = this.meta_history[this.historyMetaPointer]['position_title']; | |
this.position_description = this.meta_history[this.historyMetaPointer]['position_description']; | |
this.position_notes = this.meta_history[this.historyMetaPointer]['position_notes']; | |
this.move_description = this.meta_history[this.historyMetaPointer]['move_description']; | |
this.shapes = this.meta_history[this.historyMetaPointer]['shapes']; | |
}, | |
clearPageMeta() { | |
this.$options.lastMoveRef = null; | |
this.possible_moves = []; | |
this.position_title = ''; | |
this.position_description = ''; | |
this.position_notes = ''; | |
this.move_description = ''; | |
} | |
}, | |
computed: { | |
position_title: { | |
get () { | |
return this.$store.state.chessboard.position_title | |
}, | |
set (value) { | |
this.$store.commit('chessboard/SET_POSITION_TITLE', value); | |
} | |
}, | |
position_description: { | |
get () { | |
return this.$store.state.chessboard.position_description | |
}, | |
set (value) { | |
this.$store.commit('chessboard/SET_POSITION_DESCRIPTION', value); | |
} | |
}, | |
position_notes:{ | |
get () { | |
return this.$store.state.chessboard.position_notes | |
}, | |
set (value) { | |
this.$store.commit('chessboard/SET_POSITION_NOTES', value); | |
} | |
}, | |
move_description: { | |
get () { | |
return this.$store.state.chessboard.move_description | |
}, | |
set (value) { | |
this.$store.commit('chessboard/SET_MOVE_DESCRIPTION', value); | |
} | |
}, | |
possible_moves: { | |
get () { | |
return this.$store.state.chessboard.possible_moves | |
}, | |
set (value) { | |
this.$store.commit('chessboard/SET_POSSIBLE_MOVES', value); | |
} | |
}, | |
shapes:{ | |
get () { | |
return this.$store.state.chessboard.shapes | |
}, | |
set (value) { | |
this.$store.commit('chessboard/SET_SHAPES', value); | |
} | |
}, | |
meta_history:{ | |
get () { | |
return this.$store.state.chessboard.pageMetaHistory | |
}, | |
set (value) { | |
this.$store.commit('chessboard/SET_PAGE_META_HISTORY', { | |
index:this.historyMetaPointer, | |
value | |
} | |
); | |
} | |
}, | |
historyMetaPointer(){ | |
return 1 + this.historyMovesPointer; | |
}, | |
...mapState({ | |
initial_fen: state => state.chessboard.initial_fen, | |
historyMovesPointer: state => state.chessboard.historyMovesPointer, | |
addCurrentToFSFromClient: state => state.chessboard.addCurrentToFSFromClient, | |
}) | |
}, | |
} | |
</script> | |
<style scoped> | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment