wip
This commit is contained in:
		
							
								
								
									
										82
									
								
								src/client/app/common/views/components/user-lists-index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/client/app/common/views/components/user-lists-index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="xkxvokkjlptzyewouewmceqcxhpgzprp">
 | 
			
		||||
	<button class="ui" @click="add">{{ $t('create-list') }}</button>
 | 
			
		||||
	<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import XEditor from '../../../common/views/components/user-lists.vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('common/views/components/user-lists.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			lists: []
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$root.api('users/lists/list').then(lists => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.lists = lists;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		add() {
 | 
			
		||||
			this.$root.dialog({
 | 
			
		||||
				title: this.$t('list-name'),
 | 
			
		||||
				input: true
 | 
			
		||||
			}).then(async ({ canceled, result: title }) => {
 | 
			
		||||
				if (canceled) return;
 | 
			
		||||
				const list = await this.$root.api('users/lists/create', {
 | 
			
		||||
					title
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				this.$emit('choosen', list);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		choice(list) {
 | 
			
		||||
			this.$emit('choosen', list);
 | 
			
		||||
		},
 | 
			
		||||
		close() {
 | 
			
		||||
			(this as any).$refs.window.close();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.xkxvokkjlptzyewouewmceqcxhpgzprp
 | 
			
		||||
	padding 16px
 | 
			
		||||
 | 
			
		||||
	> button
 | 
			
		||||
		display block
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
		color var(--primaryForeground)
 | 
			
		||||
		background var(--primary)
 | 
			
		||||
		width 100%
 | 
			
		||||
		border-radius 38px
 | 
			
		||||
		user-select none
 | 
			
		||||
		cursor pointer
 | 
			
		||||
		padding 0 16px
 | 
			
		||||
		min-width 100px
 | 
			
		||||
		line-height 38px
 | 
			
		||||
		font-size 14px
 | 
			
		||||
		font-weight 700
 | 
			
		||||
 | 
			
		||||
		&:hover
 | 
			
		||||
			background var(--primaryLighten10)
 | 
			
		||||
 | 
			
		||||
		&:active
 | 
			
		||||
			background var(--primaryDarken10)
 | 
			
		||||
 | 
			
		||||
	> a
 | 
			
		||||
		display block
 | 
			
		||||
		padding 16px
 | 
			
		||||
		border solid 1px var(--faceDivider)
 | 
			
		||||
		border-radius 4px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										175
									
								
								src/client/app/common/views/components/user-lists.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								src/client/app/common/views/components/user-lists.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="vchtoekanapleubgzioubdtmlkribzfd">
 | 
			
		||||
	<div v-if="game">
 | 
			
		||||
		<x-gameroom :game="game" :self-nav="selfNav" @go-index="goIndex"/>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="matching" v-else-if="matching">
 | 
			
		||||
		<h1>{{ this.$t('matching.waiting-for').split('{}')[0] }}<b><mk-user-name :user="matching"/></b>{{ this.$t('matching.waiting-for').split('{}')[1] }}<mk-ellipsis/></h1>
 | 
			
		||||
		<div class="cancel">
 | 
			
		||||
			<form-button round @click="cancel">{{ $t('matching.cancel') }}</form-button>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div v-else-if="gameId">
 | 
			
		||||
		...
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="index" v-else>
 | 
			
		||||
		<x-index @go="nav" @matching="onMatching"/>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../../i18n';
 | 
			
		||||
import XGameroom from './reversi.gameroom.vue';
 | 
			
		||||
import XIndex from './reversi.index.vue';
 | 
			
		||||
import Progress from '../../../../scripts/loading';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('common/views/components/games/reversi/reversi.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XGameroom,
 | 
			
		||||
		XIndex
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	props: {
 | 
			
		||||
		gameId: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: false
 | 
			
		||||
		},
 | 
			
		||||
		selfNav: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			require: false,
 | 
			
		||||
			default: true
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			game: null,
 | 
			
		||||
			matching: null,
 | 
			
		||||
			connection: null,
 | 
			
		||||
			pingClock: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	watch: {
 | 
			
		||||
		game() {
 | 
			
		||||
			this.$emit('gamed', this.game);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		gameId() {
 | 
			
		||||
			this.fetch();
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.fetch();
 | 
			
		||||
 | 
			
		||||
		if (this.$store.getters.isSignedIn) {
 | 
			
		||||
			this.connection = this.$root.stream.useSharedConnection('gamesReversi');
 | 
			
		||||
 | 
			
		||||
			this.connection.on('matched', this.onMatched);
 | 
			
		||||
 | 
			
		||||
			this.pingClock = setInterval(() => {
 | 
			
		||||
				if (this.matching) {
 | 
			
		||||
					this.connection.send('ping', {
 | 
			
		||||
						id: this.matching.id
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			}, 3000);
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
		if (this.connection) {
 | 
			
		||||
			this.connection.dispose();
 | 
			
		||||
			clearInterval(this.pingClock);
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		fetch() {
 | 
			
		||||
			if (this.gameId == null) {
 | 
			
		||||
				this.game = null;
 | 
			
		||||
			} else {
 | 
			
		||||
				Progress.start();
 | 
			
		||||
				this.$root.api('games/reversi/games/show', {
 | 
			
		||||
					gameId: this.gameId
 | 
			
		||||
				}).then(game => {
 | 
			
		||||
					this.game = game;
 | 
			
		||||
					Progress.done();
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async nav(game, actualNav = true) {
 | 
			
		||||
			if (this.selfNav) {
 | 
			
		||||
				// 受け取ったゲーム情報が省略されたものなら完全な情報を取得する
 | 
			
		||||
				if (game != null && (game.settings == null || game.settings.map == null)) {
 | 
			
		||||
					game = await this.$root.api('games/reversi/games/show', {
 | 
			
		||||
						gameId: game.id
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				this.game = game;
 | 
			
		||||
			} else {
 | 
			
		||||
				this.$emit('nav', game, actualNav);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onMatching(user) {
 | 
			
		||||
			this.matching = user;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		cancel() {
 | 
			
		||||
			this.matching = null;
 | 
			
		||||
			this.$root.api('games/reversi/match/cancel');
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		accept(invitation) {
 | 
			
		||||
			this.$root.api('games/reversi/match', {
 | 
			
		||||
				userId: invitation.parent.id
 | 
			
		||||
			}).then(game => {
 | 
			
		||||
				if (game) {
 | 
			
		||||
					this.matching = null;
 | 
			
		||||
 | 
			
		||||
					this.nav(game);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onMatched(game) {
 | 
			
		||||
			this.matching = null;
 | 
			
		||||
			this.game = game;
 | 
			
		||||
			this.nav(game, false);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		goIndex() {
 | 
			
		||||
			this.nav(null);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.vchtoekanapleubgzioubdtmlkribzfd
 | 
			
		||||
	color var(--text)
 | 
			
		||||
	background var(--bg)
 | 
			
		||||
 | 
			
		||||
	> .matching
 | 
			
		||||
		> h1
 | 
			
		||||
			margin 0
 | 
			
		||||
			padding 24px
 | 
			
		||||
			font-size 20px
 | 
			
		||||
			text-align center
 | 
			
		||||
			font-weight normal
 | 
			
		||||
 | 
			
		||||
		> .cancel
 | 
			
		||||
			margin 0 auto
 | 
			
		||||
			padding 24px 0 0 0
 | 
			
		||||
			max-width 200px
 | 
			
		||||
			text-align center
 | 
			
		||||
			border-top dashed 1px #c4cdd4
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,85 +1,31 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" width="450px" height="500px" @closed="destroyDom">
 | 
			
		||||
	<template #header><fa icon="list"/> {{ $t('title') }}</template>
 | 
			
		||||
 | 
			
		||||
	<div class="xkxvokkjlptzyewouewmceqcxhpgzprp">
 | 
			
		||||
		<button class="ui" @click="add">{{ $t('create-list') }}</button>
 | 
			
		||||
		<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a>
 | 
			
		||||
	</div>
 | 
			
		||||
	<x-lists :class="$style.content" @listd="l => list = l">
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import { url } from '../../../config';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/user-lists-window.vue'),
 | 
			
		||||
	i18n: i18n('desktop/views/components/game-window.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XLists: () => import('../../../common/views/components/user-lists.vue').then(m => m.default)
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			lists: []
 | 
			
		||||
			list: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$root.api('users/lists/list').then(lists => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.lists = lists;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		add() {
 | 
			
		||||
			this.$root.dialog({
 | 
			
		||||
				title: this.$t('list-name'),
 | 
			
		||||
				input: true
 | 
			
		||||
			}).then(async ({ canceled, result: title }) => {
 | 
			
		||||
				if (canceled) return;
 | 
			
		||||
				const list = await this.$root.api('users/lists/create', {
 | 
			
		||||
					title
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				this.$emit('choosen', list);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		choice(list) {
 | 
			
		||||
			this.$emit('choosen', list);
 | 
			
		||||
		},
 | 
			
		||||
		close() {
 | 
			
		||||
			(this as any).$refs.window.close();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.xkxvokkjlptzyewouewmceqcxhpgzprp
 | 
			
		||||
	padding 16px
 | 
			
		||||
 | 
			
		||||
	> button
 | 
			
		||||
		display block
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
		color var(--primaryForeground)
 | 
			
		||||
		background var(--primary)
 | 
			
		||||
		width 100%
 | 
			
		||||
		border-radius 38px
 | 
			
		||||
		user-select none
 | 
			
		||||
		cursor pointer
 | 
			
		||||
		padding 0 16px
 | 
			
		||||
		min-width 100px
 | 
			
		||||
		line-height 38px
 | 
			
		||||
		font-size 14px
 | 
			
		||||
		font-weight 700
 | 
			
		||||
 | 
			
		||||
		&:hover
 | 
			
		||||
			background var(--primaryLighten10)
 | 
			
		||||
 | 
			
		||||
		&:active
 | 
			
		||||
			background var(--primaryDarken10)
 | 
			
		||||
 | 
			
		||||
	> a
 | 
			
		||||
		display block
 | 
			
		||||
		padding 16px
 | 
			
		||||
		border solid 1px var(--faceDivider)
 | 
			
		||||
		border-radius 4px
 | 
			
		||||
<style lang="stylus" module>
 | 
			
		||||
.content
 | 
			
		||||
	height 100%
 | 
			
		||||
	overflow auto
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user