monkeeShark/src/client/app/common/views/components/games/reversi/reversi.index.vue

246 lines
5.3 KiB
Vue
Raw Normal View History

2018-08-03 12:30:44 +00:00
<template>
<div class="phgnkghfpyvkrvwiajkiuoxyrdaqpzcx">
<h1>{{ $t('title') }}</h1>
<p>{{ $t('sub-title') }}</p>
2018-08-03 12:30:44 +00:00
<div class="play">
<form-button primary round @click="match">{{ $t('invite') }}</form-button>
2018-08-03 12:30:44 +00:00
<details>
<summary>{{ $t('rule') }}</summary>
2018-08-03 12:30:44 +00:00
<div>
<p>{{ $t('rule-desc') }}</p>
2018-08-03 12:30:44 +00:00
<dl>
<dt><b>{{ $t('mode-invite') }}</b></dt>
<dd>{{ $t('mode-invite-desc') }}</dd>
2018-08-03 12:30:44 +00:00
</dl>
</div>
</details>
</div>
<section v-if="invitations.length > 0">
<h2>{{ $t('invitations') }}</h2>
2018-08-03 12:30:44 +00:00
<div class="invitation" v-for="i in invitations" tabindex="-1" @click="accept(i)">
<mk-avatar class="avatar" :user="i.parent"/>
<span class="name"><b>{{ i.parent | userName }}</b></span>
<span class="username">@{{ i.parent.username }}</span>
<mk-time :time="i.createdAt"/>
</div>
</section>
<section v-if="myGames.length > 0">
<h2>{{ $t('my-games') }}</h2>
2018-08-03 12:30:44 +00:00
<a class="game" v-for="g in myGames" tabindex="-1" @click.prevent="go(g)" :href="`/reversi/${g.id}`">
<mk-avatar class="avatar" :user="g.user1"/>
<mk-avatar class="avatar" :user="g.user2"/>
<span><b>{{ g.user1 | userName }}</b> vs <b>{{ g.user2 | userName }}</b></span>
2018-11-09 05:19:30 +00:00
<span class="state">{{ g.isEnded ? $t('game-state.ended') : $t('game-state.playing') }}</span>
2018-08-17 22:53:06 +00:00
<mk-time :time="g.createdAt" />
2018-08-03 12:30:44 +00:00
</a>
</section>
<section v-if="games.length > 0">
<h2>{{ $t('all-games') }}</h2>
2018-08-03 12:30:44 +00:00
<a class="game" v-for="g in games" tabindex="-1" @click.prevent="go(g)" :href="`/reversi/${g.id}`">
<mk-avatar class="avatar" :user="g.user1"/>
<mk-avatar class="avatar" :user="g.user2"/>
<span><b>{{ g.user1 | userName }}</b> vs <b>{{ g.user2 | userName }}</b></span>
2018-11-09 05:19:30 +00:00
<span class="state">{{ g.isEnded ? $t('game-state.ended') : $t('game-state.playing') }}</span>
2018-08-17 22:53:06 +00:00
<mk-time :time="g.createdAt" />
2018-08-03 12:30:44 +00:00
</a>
</section>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../../../i18n';
2018-08-03 12:30:44 +00:00
export default Vue.extend({
i18n: i18n('common/views/components/games/reversi/reversi.index.vue'),
2018-08-03 12:30:44 +00:00
data() {
return {
games: [],
gamesFetching: true,
gamesMoreFetching: false,
myGames: [],
matching: null,
invitations: [],
connection: null
2018-08-03 12:30:44 +00:00
};
},
mounted() {
if (this.$store.getters.isSignedIn) {
2018-11-08 23:13:34 +00:00
this.connection = this.$root.stream.useSharedConnection('gamesReversi');
2018-08-03 12:30:44 +00:00
this.connection.on('invited', this.onInvited);
2018-11-08 23:13:34 +00:00
this.$root.api('games/reversi/games', {
2018-08-03 12:30:44 +00:00
my: true
}).then(games => {
this.myGames = games;
});
2018-11-08 23:13:34 +00:00
this.$root.api('games/reversi/invitations').then(invitations => {
2018-08-03 12:30:44 +00:00
this.invitations = this.invitations.concat(invitations);
});
}
2018-11-08 23:13:34 +00:00
this.$root.api('games/reversi/games').then(games => {
2018-08-03 12:30:44 +00:00
this.games = games;
this.gamesFetching = false;
});
},
beforeDestroy() {
if (this.connection) {
this.connection.dispose();
2018-08-03 12:30:44 +00:00
}
},
methods: {
go(game) {
2018-08-05 04:40:26 +00:00
this.$emit('go', game);
2018-08-03 12:30:44 +00:00
},
2018-12-02 11:10:53 +00:00
async match() {
const { result: user } = await this.$root.dialog({
title: this.$t('enter-username'),
user: {
local: true
}
});
if (user == null) return;
this.$root.api('games/reversi/match', {
userId: user.id
}).then(res => {
if (res == null) {
this.$emit('matching', user);
} else {
this.$emit('go', res);
}
2018-08-03 12:30:44 +00:00
});
},
accept(invitation) {
2018-11-08 23:13:34 +00:00
this.$root.api('games/reversi/match', {
2018-08-03 12:30:44 +00:00
userId: invitation.parent.id
}).then(game => {
if (game) {
this.$emit('go', game);
}
});
},
onInvited(invite) {
this.invitations.unshift(invite);
}
}
});
</script>
<style lang="stylus" scoped>
2018-09-28 10:59:19 +00:00
.phgnkghfpyvkrvwiajkiuoxyrdaqpzcx
2018-08-03 12:30:44 +00:00
> h1
margin 0
padding 24px
font-size 24px
text-align center
font-weight normal
color #fff
2018-09-28 10:59:19 +00:00
background linear-gradient(to bottom, var(--reversiBannerGradientStart), var(--reversiBannerGradientEnd))
2018-08-03 12:30:44 +00:00
& + p
margin 0
padding 12px
margin-bottom 12px
text-align center
font-size 14px
2018-09-28 10:59:19 +00:00
border-bottom solid 1px var(--faceDivider)
2018-08-03 12:30:44 +00:00
> .play
margin 0 auto
padding 0 16px
max-width 500px
text-align center
> details
margin 8px 0
> div
padding 16px
font-size 14px
text-align left
2018-09-28 10:59:19 +00:00
background var(--reversiDescBg)
2018-08-03 12:30:44 +00:00
border-radius 8px
> section
margin 0 auto
padding 0 16px 16px 16px
max-width 500px
2018-09-28 10:59:19 +00:00
border-top solid 1px var(--faceDivider)
2018-08-03 12:30:44 +00:00
> h2
margin 0
padding 16px 0 8px 0
font-size 16px
font-weight bold
.invitation
margin 8px 0
padding 8px
2018-09-28 10:59:19 +00:00
color var(--text)
2018-09-26 11:28:13 +00:00
background var(--face)
2018-09-28 10:59:19 +00:00
box-shadow 0 2px 16px var(--reversiListItemShadow)
2018-08-03 12:30:44 +00:00
border-radius 6px
cursor pointer
*
pointer-events none
user-select none
&:focus
2018-09-26 11:19:35 +00:00
border-color var(--primary)
2018-08-03 12:30:44 +00:00
&:hover
2018-09-28 10:59:19 +00:00
box-shadow 0 0 0 100px inset rgba(0, 0, 0, 0.05)
2018-08-03 12:30:44 +00:00
&:active
2018-09-28 10:59:19 +00:00
box-shadow 0 0 0 100px inset rgba(0, 0, 0, 0.1)
2018-08-03 12:30:44 +00:00
> .avatar
width 32px
height 32px
border-radius 100%
> span
margin 0 8px
line-height 32px
.game
display block
margin 8px 0
padding 8px
2018-09-28 10:59:19 +00:00
color var(--text)
2018-09-26 11:28:13 +00:00
background var(--face)
2018-09-28 10:59:19 +00:00
box-shadow 0 2px 16px var(--reversiListItemShadow)
2018-08-03 12:30:44 +00:00
border-radius 6px
cursor pointer
*
pointer-events none
user-select none
&:hover
2018-09-28 10:59:19 +00:00
box-shadow 0 0 0 100px inset rgba(0, 0, 0, 0.05)
2018-08-03 12:30:44 +00:00
&:active
2018-09-28 10:59:19 +00:00
box-shadow 0 0 0 100px inset rgba(0, 0, 0, 0.1)
2018-08-03 12:30:44 +00:00
> .avatar
width 32px
height 32px
border-radius 100%
> span
margin 0 8px
line-height 32px
</style>