feat: make game name and lang editable on gamemaster page
This commit is contained in:
parent
9a5c647523
commit
604b4f9f08
200
client/src/assets/icons/edit-white.svg
Normal file
200
client/src/assets/icons/edit-white.svg
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:ns1="http://sozi.baierouge.fr"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
id="svg6254"
|
||||||
|
sodipodi:docname="新規ドキュメント 9"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
>
|
||||||
|
<title
|
||||||
|
id="title7073"
|
||||||
|
>Pencil Pictogram</title
|
||||||
|
>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
bordercolor="#666666"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-y="-4"
|
||||||
|
fit-margin-left="0"
|
||||||
|
pagecolor="#000000"
|
||||||
|
fit-margin-top="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:zoom="4.0745363"
|
||||||
|
inkscape:window-x="-4"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
showgrid="false"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:cx="45.584279"
|
||||||
|
inkscape:cy="49.522511"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
/>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="レイヤー 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(-222.76 -630.44)"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
id="g7066"
|
||||||
|
transform="matrix(1.7183 0 0 1.7068 -160 -536.05)"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
id="path5336-6"
|
||||||
|
sodipodi:nodetypes="ccccc"
|
||||||
|
style="stroke-linejoin:round;stroke:#ffffff;stroke-linecap:round;stroke-width:2.6122;fill:none"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
d="m295.94 710.91l-36.816 36.816-35.073 9.3978 9.3949-35.062 37.195-37.195"
|
||||||
|
/>
|
||||||
|
<rect
|
||||||
|
id="rect5338-48"
|
||||||
|
style="fill:#fff0ff"
|
||||||
|
transform="matrix(-.26499 -.96425 .70711 -.70711 0 0)"
|
||||||
|
rx="1.8358"
|
||||||
|
ry="1.8187"
|
||||||
|
height="53.027"
|
||||||
|
width="9.58"
|
||||||
|
y="60.3"
|
||||||
|
x="-820.59"
|
||||||
|
/>
|
||||||
|
<rect
|
||||||
|
id="rect5338-4-2"
|
||||||
|
ry="1.8187"
|
||||||
|
style="fill:#fff0ff"
|
||||||
|
rx="1.377"
|
||||||
|
transform="rotate(225)"
|
||||||
|
height="53.819"
|
||||||
|
width="16.654"
|
||||||
|
y="-340.44"
|
||||||
|
x="-702.13"
|
||||||
|
/>
|
||||||
|
<rect
|
||||||
|
id="rect5338-1-1"
|
||||||
|
style="fill:#fff0ff"
|
||||||
|
transform="matrix(.96593 .25882 .70711 -.70711 0 0)"
|
||||||
|
rx="1.836"
|
||||||
|
ry="1.8187"
|
||||||
|
height="53.819"
|
||||||
|
width="9.6152"
|
||||||
|
y="-734.79"
|
||||||
|
x="778.66"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="path5336-1-6"
|
||||||
|
style="stroke-linejoin:round;stroke:#ffffff;stroke-linecap:round;stroke-width:2.6122;fill:#a0a0a0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
d="m224.06 757.12 18.038-4.8199-13.219-13.219-4.8199 18.038z"
|
||||||
|
/>
|
||||||
|
</g
|
||||||
|
>
|
||||||
|
</g
|
||||||
|
>
|
||||||
|
<metadata
|
||||||
|
>
|
||||||
|
<rdf:RDF
|
||||||
|
>
|
||||||
|
<cc:Work
|
||||||
|
>
|
||||||
|
<dc:format
|
||||||
|
>image/svg+xml</dc:format
|
||||||
|
>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage"
|
||||||
|
/>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/publicdomain/"
|
||||||
|
/>
|
||||||
|
<dc:publisher
|
||||||
|
>
|
||||||
|
<cc:Agent
|
||||||
|
rdf:about="http://openclipart.org/"
|
||||||
|
>
|
||||||
|
<dc:title
|
||||||
|
>Openclipart</dc:title
|
||||||
|
>
|
||||||
|
</cc:Agent
|
||||||
|
>
|
||||||
|
</dc:publisher
|
||||||
|
>
|
||||||
|
<dc:title
|
||||||
|
>Pencil Pictogram</dc:title
|
||||||
|
>
|
||||||
|
<dc:date
|
||||||
|
>2013-11-16T20:22:22</dc:date
|
||||||
|
>
|
||||||
|
<dc:description
|
||||||
|
>black pencil pictogram.</dc:description
|
||||||
|
>
|
||||||
|
<dc:source
|
||||||
|
>https://openclipart.org/detail/188837/pencil-pictogram-by-libberry-188837</dc:source
|
||||||
|
>
|
||||||
|
<dc:creator
|
||||||
|
>
|
||||||
|
<cc:Agent
|
||||||
|
>
|
||||||
|
<dc:title
|
||||||
|
>libberry</dc:title
|
||||||
|
>
|
||||||
|
</cc:Agent
|
||||||
|
>
|
||||||
|
</dc:creator
|
||||||
|
>
|
||||||
|
<dc:subject
|
||||||
|
>
|
||||||
|
<rdf:Bag
|
||||||
|
>
|
||||||
|
<rdf:li
|
||||||
|
>learning</rdf:li
|
||||||
|
>
|
||||||
|
<rdf:li
|
||||||
|
>pencil</rdf:li
|
||||||
|
>
|
||||||
|
<rdf:li
|
||||||
|
>stationery</rdf:li
|
||||||
|
>
|
||||||
|
<rdf:li
|
||||||
|
>study</rdf:li
|
||||||
|
>
|
||||||
|
<rdf:li
|
||||||
|
>writing</rdf:li
|
||||||
|
>
|
||||||
|
</rdf:Bag
|
||||||
|
>
|
||||||
|
</dc:subject
|
||||||
|
>
|
||||||
|
</cc:Work
|
||||||
|
>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/publicdomain/"
|
||||||
|
>
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Reproduction"
|
||||||
|
/>
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Distribution"
|
||||||
|
/>
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
|
||||||
|
/>
|
||||||
|
</cc:License
|
||||||
|
>
|
||||||
|
</rdf:RDF
|
||||||
|
>
|
||||||
|
</metadata
|
||||||
|
>
|
||||||
|
</svg
|
||||||
|
>
|
After Width: | Height: | Size: 5.1 KiB |
@ -62,7 +62,7 @@
|
|||||||
/>
|
/>
|
||||||
<rect
|
<rect
|
||||||
id="rect5338-48"
|
id="rect5338-48"
|
||||||
style="fill:#000200"
|
style="fill:#ff0200"
|
||||||
transform="matrix(-.26499 -.96425 .70711 -.70711 0 0)"
|
transform="matrix(-.26499 -.96425 .70711 -.70711 0 0)"
|
||||||
rx="1.8358"
|
rx="1.8358"
|
||||||
ry="1.8187"
|
ry="1.8187"
|
||||||
@ -74,7 +74,7 @@
|
|||||||
<rect
|
<rect
|
||||||
id="rect5338-4-2"
|
id="rect5338-4-2"
|
||||||
ry="1.8187"
|
ry="1.8187"
|
||||||
style="fill:#000200"
|
style="fill:#ff0200"
|
||||||
rx="1.377"
|
rx="1.377"
|
||||||
transform="rotate(225)"
|
transform="rotate(225)"
|
||||||
height="53.819"
|
height="53.819"
|
||||||
@ -84,7 +84,7 @@
|
|||||||
/>
|
/>
|
||||||
<rect
|
<rect
|
||||||
id="rect5338-1-1"
|
id="rect5338-1-1"
|
||||||
style="fill:#000200"
|
style="fill:#ff0200"
|
||||||
transform="matrix(.96593 .25882 .70711 -.70711 0 0)"
|
transform="matrix(.96593 .25882 .70711 -.70711 0 0)"
|
||||||
rx="1.836"
|
rx="1.836"
|
||||||
ry="1.8187"
|
ry="1.8187"
|
||||||
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
@ -1,36 +1,46 @@
|
|||||||
<template>
|
<template>
|
||||||
<AdminTile title="Game">
|
<AdminTile title="Game">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr class="gameinfo-tile__row">
|
||||||
<td>{{ $t('name') }}:</td>
|
<td>{{ $t('name') }}:</td>
|
||||||
<td>{{ gameinfo.name }}</td>
|
<td>{{ gameinfo.name }}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="gameinfo-tile__edit-game-name" @click="editName"></div>
|
<div class="gameinfo-tile__edit" @click="editName">
|
||||||
|
<Icon name="edit-white" />
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr class="gameinfo-tile__row">
|
||||||
<td>{{ $t('language') }}:</td>
|
<td>{{ $t('language') }}:</td>
|
||||||
<td>{{ gameinfo.lang }}</td>
|
<td v-if="!editLangShowDropdown">{{ gameinfo.lang }}</td>
|
||||||
<td>
|
<td v-if="!editLangShowDropdown">
|
||||||
<div class="gameinfo-tile__edit-lang" @click="editLang"></div>
|
<div class="gameinfo-tile__edit" @click="editLang">
|
||||||
|
<Icon name="edit-white" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td v-if="editLangShowDropdown" colspan="2">
|
||||||
|
<select v-model="lang" @change="editLangChange">
|
||||||
|
<option value="en">en</option>
|
||||||
|
<option value="de">de</option>
|
||||||
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr class="gameinfo-tile__row">
|
||||||
<td>{{ $t('created') }}:</td>
|
<td>{{ $t('created') }}:</td>
|
||||||
<td colspan="2">{{ date(gameinfo.created) }}</td>
|
<td colspan="2">{{ date(gameinfo.created) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr class="gameinfo-tile__row">
|
||||||
<td>{{ $t('num-players') }}:</td>
|
<td>{{ $t('num-players') }}:</td>
|
||||||
<td colspan="2">{{ gameinfo.players.length }}</td>
|
<td colspan="2">{{ gameinfo.players.length }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr class="gameinfo-tile__row">
|
||||||
<td>{{ $t('num-quotes-played') }}:</td>
|
<td>{{ $t('num-quotes-played') }}:</td>
|
||||||
<td colspan="2">{{ gameinfo.numQuotesLeft - gameinfo.numQuotesLeft }} / {{ gameinfo.numQuotesTotal }}</td>
|
<td colspan="2">{{ gameinfo.numQuotesLeft - gameinfo.numQuotesLeft }} / {{ gameinfo.numQuotesTotal }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="!showId" @click="showId = true">
|
<tr class="gameinfo-tile__row" v-if="!showId" @click="showId = true">
|
||||||
<td colspan="3"> </td>
|
<td colspan="3"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="showId">
|
<tr class="gameinfo-tile__row" v-if="showId">
|
||||||
<td colspan="3">{{ gameinfo.id }}</td>
|
<td colspan="3">{{ gameinfo.id }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -41,13 +51,15 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import useI18n from '@/composables/useI18n'
|
import useI18n from '@/composables/useI18n'
|
||||||
import useDateFormatter from '@/composables/useDateFormatter';
|
import useDateFormatter from '@/composables/useDateFormatter';
|
||||||
|
import useEngine from '@/composables/useEngine'
|
||||||
import type { GameInfo } from '@/composables/engine.d'
|
import type { GameInfo } from '@/composables/engine.d'
|
||||||
|
|
||||||
const { date } = useDateFormatter()
|
const { date } = useDateFormatter()
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
gameinfo: GameInfo
|
gameinfo: GameInfo
|
||||||
}>()
|
}>()
|
||||||
|
const emit = defineEmits(['update'])
|
||||||
|
|
||||||
const { $t } = useI18n({
|
const { $t } = useI18n({
|
||||||
id: { en: 'Id', de: 'Id' },
|
id: { en: 'Id', de: 'Id' },
|
||||||
@ -55,13 +67,28 @@ const { $t } = useI18n({
|
|||||||
language: { en: 'Language', de: 'Sprache' },
|
language: { en: 'Language', de: 'Sprache' },
|
||||||
created: { en: 'Created', de: 'Erstellt' },
|
created: { en: 'Created', de: 'Erstellt' },
|
||||||
'num-players': { en: '# Players', de: '# Spieler' },
|
'num-players': { en: '# Players', de: '# Spieler' },
|
||||||
'num-quotes-played': { en: '# Quotes played', de: '# Aussagen gespielt'}
|
'num-quotes-played': { en: '# Quotes played', de: '# Aussagen gespielt' },
|
||||||
|
'new-game-name': { en: 'New game name', de: 'Neuer Spielname' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const editName = () => { alert('not yet implemented') }
|
|
||||||
const editLang = () => { alert('not yet implemented') }
|
|
||||||
|
|
||||||
const showId = ref(false)
|
const showId = ref(false)
|
||||||
|
|
||||||
|
const editName = async (): Promise<void> => {
|
||||||
|
const name = window.prompt(`${$t('new-game-name')}: `)
|
||||||
|
if (name) {
|
||||||
|
await useEngine().setGameName(name)
|
||||||
|
emit('update')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const lang = ref(props.gameinfo.lang)
|
||||||
|
const editLangShowDropdown = ref(false)
|
||||||
|
const editLang = () => { editLangShowDropdown.value = true }
|
||||||
|
const editLangChange = async (): Promise<void> => {
|
||||||
|
editLangShowDropdown.value = false
|
||||||
|
await useEngine().setGameLang(lang.value)
|
||||||
|
emit('update')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -70,5 +97,16 @@ const showId = ref(false)
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__row {
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__edit {
|
||||||
|
margin-left: 24px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -42,4 +42,20 @@ export async function fetchGameInfo(this: EngineContext): Promise<GameInfo> {
|
|||||||
return await this.callApi('/api/gameinfo', {
|
return await this.callApi('/api/gameinfo', {
|
||||||
g: userInfoStore.gameId,
|
g: userInfoStore.gameId,
|
||||||
}) as GameInfo
|
}) as GameInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setGameLang(this: EngineContext, lang: string): Promise<void> {
|
||||||
|
const userInfoStore = useUserinfoStore()
|
||||||
|
await this.callApi('/api/setGameLang', {
|
||||||
|
g: userInfoStore.gameId,
|
||||||
|
lang,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setGameName(this: EngineContext, name: string): Promise<void> {
|
||||||
|
const userInfoStore = useUserinfoStore()
|
||||||
|
await this.callApi('/api/setGameName', {
|
||||||
|
g: userInfoStore.gameId,
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { callApi, QueryParams } from '@/composables/engine/callApi'
|
|||||||
import { start, stop } from '@/composables/engine/startStop'
|
import { start, stop } from '@/composables/engine/startStop'
|
||||||
import { fetchUpdate } from '@/composables/engine/fetchUpdate'
|
import { fetchUpdate } from '@/composables/engine/fetchUpdate'
|
||||||
import { loadQuotes, getQuotesRef, deleteQuote, saveQuote } from '@/composables/engine/quotes'
|
import { loadQuotes, getQuotesRef, deleteQuote, saveQuote } from '@/composables/engine/quotes'
|
||||||
import { collectQuotes, startGame, continueGame, resetGame, finishGame, fetchGameInfo } from '@/composables/engine/gamemaster'
|
import { collectQuotes, startGame, continueGame, resetGame, finishGame, fetchGameInfo, setGameLang, setGameName } from '@/composables/engine/gamemaster'
|
||||||
import { saveSelection } from '@/composables/engine/play'
|
import { saveSelection } from '@/composables/engine/play'
|
||||||
import type { Quotes, GameInfo } from '@/composables/engine.d'
|
import type { Quotes, GameInfo } from '@/composables/engine.d'
|
||||||
|
|
||||||
@ -37,6 +37,8 @@ export interface useEngine {
|
|||||||
finishGame: () => Promise<void>
|
finishGame: () => Promise<void>
|
||||||
saveSelection: (selection: string) => Promise<void>
|
saveSelection: (selection: string) => Promise<void>
|
||||||
fetchGameInfo: () => Promise<GameInfo>
|
fetchGameInfo: () => Promise<GameInfo>
|
||||||
|
setGameLang: (lang: string) => Promise<void>
|
||||||
|
setGameName: (name: string) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (): useEngine => {
|
export default (): useEngine => {
|
||||||
@ -71,5 +73,7 @@ export default (): useEngine => {
|
|||||||
finishGame: () => finishGame.apply(context),
|
finishGame: () => finishGame.apply(context),
|
||||||
saveSelection: (selection: string) => saveSelection.apply(context, [selection]),
|
saveSelection: (selection: string) => saveSelection.apply(context, [selection]),
|
||||||
fetchGameInfo: () => fetchGameInfo.apply(context),
|
fetchGameInfo: () => fetchGameInfo.apply(context),
|
||||||
|
setGameLang: (lang: string) => setGameLang.apply(context, [lang]),
|
||||||
|
setGameName: (name: string) => setGameName.apply(context, [name]),
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,7 @@
|
|||||||
<div class="gamemaster__container">
|
<div class="gamemaster__container">
|
||||||
<TopBar />
|
<TopBar />
|
||||||
<div class="gamemaster__tiles">
|
<div class="gamemaster__tiles">
|
||||||
<AdminGameInfoTile :gameinfo="gameinfo" />
|
<AdminGameInfoTile :gameinfo="gameinfo" @update="updateGameinfo" />
|
||||||
<div class="gamemaster__tiles-spacer" />
|
<div class="gamemaster__tiles-spacer" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { navigateTo } from '#app'
|
import { navigateTo } from '#app'
|
||||||
import { onMounted, onBeforeUnmount } from 'vue'
|
import { ref } from 'vue'
|
||||||
import useAuth from '@/composables/useAuth'
|
import useAuth from '@/composables/useAuth'
|
||||||
import useEngine from '@/composables/useEngine'
|
import useEngine from '@/composables/useEngine'
|
||||||
|
|
||||||
@ -23,7 +23,10 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { fetchGameInfo } = useEngine()
|
const { fetchGameInfo } = useEngine()
|
||||||
const gameinfo = await fetchGameInfo()
|
const gameinfo = ref(await fetchGameInfo())
|
||||||
|
const updateGameinfo = async (): Promise<void> => {
|
||||||
|
gameinfo.value = await fetchGameInfo()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
Loading…
Reference in New Issue
Block a user