wip
This commit is contained in:
		
							parent
							
								
									c016d212ed
								
							
						
					
					
						commit
						000635252c
					
				
					 3 changed files with 272 additions and 202 deletions
				
			
		| 
						 | 
				
			
			@ -132,6 +132,11 @@ common:
 | 
			
		|||
    pop-right: "右に出す"
 | 
			
		||||
 | 
			
		||||
common/views/components/games/reversi/reversi.vue:
 | 
			
		||||
  matching:
 | 
			
		||||
    waiting-for: "{}を待っています"
 | 
			
		||||
    cancel: "キャンセル"
 | 
			
		||||
 | 
			
		||||
common/views/components/games/reversi/reversi.index.vue:
 | 
			
		||||
  title: "Misskey Reversi"
 | 
			
		||||
  sub-title: "他のMisskeyユーザーとリバーシで対戦しよう"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
| 
						 | 
				
			
			@ -146,9 +151,6 @@ common/views/components/games/reversi/reversi.vue:
 | 
			
		|||
  game-state:
 | 
			
		||||
    ended: "終了"
 | 
			
		||||
    playing: "進行中"
 | 
			
		||||
  matching:
 | 
			
		||||
    waiting-for: "{}を待っています"
 | 
			
		||||
    cancel: "キャンセル"
 | 
			
		||||
 | 
			
		||||
common/views/components/games/reversi/reversi.room.vue:
 | 
			
		||||
  settings-of-the-game: "ゲームの設定"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,258 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="phgnkghfpyvkrvwiajkiuoxyrdaqpzcx">
 | 
			
		||||
	<h1>%i18n:@title%</h1>
 | 
			
		||||
	<p>%i18n:@sub-title%</p>
 | 
			
		||||
	<div class="play">
 | 
			
		||||
		<!--<el-button round>フリーマッチ(準備中)</el-button>-->
 | 
			
		||||
		<form-button primary round @click="match">%i18n:@invite%</form-button>
 | 
			
		||||
		<details>
 | 
			
		||||
			<summary>%i18n:@rule%</summary>
 | 
			
		||||
			<div>
 | 
			
		||||
				<p>%i18n:@rule-desc%</p>
 | 
			
		||||
				<dl>
 | 
			
		||||
					<dt><b>%i18n:@mode-invite%</b></dt>
 | 
			
		||||
					<dd>%i18n:@mode-invite-desc%</dd>
 | 
			
		||||
				</dl>
 | 
			
		||||
			</div>
 | 
			
		||||
		</details>
 | 
			
		||||
	</div>
 | 
			
		||||
	<section v-if="invitations.length > 0">
 | 
			
		||||
		<h2>%i18n:@invitations%</h2>
 | 
			
		||||
		<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>%i18n:@my-games%</h2>
 | 
			
		||||
		<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>
 | 
			
		||||
			<span class="state">{{ g.isEnded ? '%i18n:@game-state.ended%' : '%i18n:@game-state.playing%' }}</span>
 | 
			
		||||
		</a>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section v-if="games.length > 0">
 | 
			
		||||
		<h2>%i18n:@all-games%</h2>
 | 
			
		||||
		<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>
 | 
			
		||||
			<span class="state">{{ g.isEnded ? '%i18n:@game-state.ended%' : '%i18n:@game-state.playing%' }}</span>
 | 
			
		||||
		</a>
 | 
			
		||||
	</section>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			games: [],
 | 
			
		||||
			gamesFetching: true,
 | 
			
		||||
			gamesMoreFetching: false,
 | 
			
		||||
			myGames: [],
 | 
			
		||||
			matching: null,
 | 
			
		||||
			invitations: [],
 | 
			
		||||
			connection: null,
 | 
			
		||||
			connectionId: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		if (this.$store.getters.isSignedIn) {
 | 
			
		||||
			this.connection = (this as any).os.streams.reversiStream.getConnection();
 | 
			
		||||
			this.connectionId = (this as any).os.streams.reversiStream.use();
 | 
			
		||||
 | 
			
		||||
			this.connection.on('invited', this.onInvited);
 | 
			
		||||
 | 
			
		||||
			(this as any).api('games/reversi/games', {
 | 
			
		||||
				my: true
 | 
			
		||||
			}).then(games => {
 | 
			
		||||
				this.myGames = games;
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			(this as any).api('games/reversi/invitations').then(invitations => {
 | 
			
		||||
				this.invitations = this.invitations.concat(invitations);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		(this as any).api('games/reversi/games').then(games => {
 | 
			
		||||
			this.games = games;
 | 
			
		||||
			this.gamesFetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
		if (this.connection) {
 | 
			
		||||
			this.connection.off('invited', this.onInvited);
 | 
			
		||||
			(this as any).os.streams.reversiStream.dispose(this.connectionId);
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		go(game) {
 | 
			
		||||
			(this as any).api('games/reversi/games/show', {
 | 
			
		||||
				gameId: game.id
 | 
			
		||||
			}).then(game => {
 | 
			
		||||
				this.$emit('go', game);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		match() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@enter-username%'
 | 
			
		||||
			}).then(username => {
 | 
			
		||||
				(this as any).api('users/show', {
 | 
			
		||||
					username
 | 
			
		||||
				}).then(user => {
 | 
			
		||||
					(this as any).api('games/reversi/match', {
 | 
			
		||||
						userId: user.id
 | 
			
		||||
					}).then(res => {
 | 
			
		||||
						if (res == null) {
 | 
			
		||||
							this.$emit('matching', user);
 | 
			
		||||
						} else {
 | 
			
		||||
							this.$emit('go', res);
 | 
			
		||||
						}
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		accept(invitation) {
 | 
			
		||||
			(this as any).api('games/reversi/match', {
 | 
			
		||||
				userId: invitation.parent.id
 | 
			
		||||
			}).then(game => {
 | 
			
		||||
				if (game) {
 | 
			
		||||
					this.$emit('go', game);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onInvited(invite) {
 | 
			
		||||
			this.invitations.unshift(invite);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
@import '~const.styl'
 | 
			
		||||
 | 
			
		||||
root(isDark)
 | 
			
		||||
	> h1
 | 
			
		||||
		margin 0
 | 
			
		||||
		padding 24px
 | 
			
		||||
		font-size 24px
 | 
			
		||||
		text-align center
 | 
			
		||||
		font-weight normal
 | 
			
		||||
		color #fff
 | 
			
		||||
		background linear-gradient(to bottom, isDark ? #45730e : #8bca3e, isDark ? #464300 : #d6cf31)
 | 
			
		||||
 | 
			
		||||
		& + p
 | 
			
		||||
			margin 0
 | 
			
		||||
			padding 12px
 | 
			
		||||
			margin-bottom 12px
 | 
			
		||||
			text-align center
 | 
			
		||||
			font-size 14px
 | 
			
		||||
			border-bottom solid 1px isDark ? #535f65 : #d3d9dc
 | 
			
		||||
 | 
			
		||||
	> .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
 | 
			
		||||
				background isDark ? #282c37 : #f5f5f5
 | 
			
		||||
				border-radius 8px
 | 
			
		||||
 | 
			
		||||
	> section
 | 
			
		||||
		margin 0 auto
 | 
			
		||||
		padding 0 16px 16px 16px
 | 
			
		||||
		max-width 500px
 | 
			
		||||
		border-top solid 1px isDark ? #535f65 : #d3d9dc
 | 
			
		||||
 | 
			
		||||
		> h2
 | 
			
		||||
			margin 0
 | 
			
		||||
			padding 16px 0 8px 0
 | 
			
		||||
			font-size 16px
 | 
			
		||||
			font-weight bold
 | 
			
		||||
 | 
			
		||||
	.invitation
 | 
			
		||||
		margin 8px 0
 | 
			
		||||
		padding 8px
 | 
			
		||||
		color isDark ? #fff : #677f84
 | 
			
		||||
		background isDark ? #282c37 : #fff
 | 
			
		||||
		box-shadow 0 2px 16px rgba(#000, isDark ? 0.7 : 0.15)
 | 
			
		||||
		border-radius 6px
 | 
			
		||||
		cursor pointer
 | 
			
		||||
 | 
			
		||||
		*
 | 
			
		||||
			pointer-events none
 | 
			
		||||
			user-select none
 | 
			
		||||
 | 
			
		||||
		&:focus
 | 
			
		||||
			border-color $theme-color
 | 
			
		||||
 | 
			
		||||
		&:hover
 | 
			
		||||
			background isDark ? #313543 : #f5f5f5
 | 
			
		||||
 | 
			
		||||
		&:active
 | 
			
		||||
			background isDark ? #1e222b : #eee
 | 
			
		||||
 | 
			
		||||
		> .avatar
 | 
			
		||||
			width 32px
 | 
			
		||||
			height 32px
 | 
			
		||||
			border-radius 100%
 | 
			
		||||
 | 
			
		||||
		> span
 | 
			
		||||
			margin 0 8px
 | 
			
		||||
			line-height 32px
 | 
			
		||||
 | 
			
		||||
	.game
 | 
			
		||||
		display block
 | 
			
		||||
		margin 8px 0
 | 
			
		||||
		padding 8px
 | 
			
		||||
		color isDark ? #fff : #677f84
 | 
			
		||||
		background isDark ? #282c37 : #fff
 | 
			
		||||
		box-shadow 0 2px 16px rgba(#000, isDark ? 0.7 : 0.15)
 | 
			
		||||
		border-radius 6px
 | 
			
		||||
		cursor pointer
 | 
			
		||||
 | 
			
		||||
		*
 | 
			
		||||
			pointer-events none
 | 
			
		||||
			user-select none
 | 
			
		||||
 | 
			
		||||
		&:hover
 | 
			
		||||
			background isDark ? #313543 : #f5f5f5
 | 
			
		||||
 | 
			
		||||
		&:active
 | 
			
		||||
			background isDark ? #1e222b : #eee
 | 
			
		||||
 | 
			
		||||
		> .avatar
 | 
			
		||||
			width 32px
 | 
			
		||||
			height 32px
 | 
			
		||||
			border-radius 100%
 | 
			
		||||
 | 
			
		||||
		> span
 | 
			
		||||
			margin 0 8px
 | 
			
		||||
			line-height 32px
 | 
			
		||||
 | 
			
		||||
.phgnkghfpyvkrvwiajkiuoxyrdaqpzcx[data-darkmode]
 | 
			
		||||
	root(true)
 | 
			
		||||
 | 
			
		||||
.phgnkghfpyvkrvwiajkiuoxyrdaqpzcx:not([data-darkmode])
 | 
			
		||||
	root(false)
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -10,49 +10,7 @@
 | 
			
		|||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="index" v-else>
 | 
			
		||||
		<h1>%i18n:@title%</h1>
 | 
			
		||||
		<p>%i18n:@sub-title%</p>
 | 
			
		||||
		<div class="play">
 | 
			
		||||
			<!--<el-button round>フリーマッチ(準備中)</el-button>-->
 | 
			
		||||
			<form-button primary round @click="match">%i18n:@invite%</form-button>
 | 
			
		||||
			<details>
 | 
			
		||||
				<summary>%i18n:@rule%</summary>
 | 
			
		||||
				<div>
 | 
			
		||||
					<p>%i18n:@rule-desc%</p>
 | 
			
		||||
					<dl>
 | 
			
		||||
						<dt><b>%i18n:@mode-invite%</b></dt>
 | 
			
		||||
						<dd>%i18n:@mode-invite-desc%</dd>
 | 
			
		||||
					</dl>
 | 
			
		||||
				</div>
 | 
			
		||||
			</details>
 | 
			
		||||
		</div>
 | 
			
		||||
		<section v-if="invitations.length > 0">
 | 
			
		||||
			<h2>%i18n:@invitations%</h2>
 | 
			
		||||
			<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>%i18n:@my-games%</h2>
 | 
			
		||||
			<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>
 | 
			
		||||
				<span class="state">{{ g.isEnded ? '%i18n:@game-state.ended%' : '%i18n:@game-state.playing%' }}</span>
 | 
			
		||||
			</a>
 | 
			
		||||
		</section>
 | 
			
		||||
		<section v-if="games.length > 0">
 | 
			
		||||
			<h2>%i18n:@all-games%</h2>
 | 
			
		||||
			<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>
 | 
			
		||||
				<span class="state">{{ g.isEnded ? '%i18n:@game-state.ended%' : '%i18n:@game-state.playing%' }}</span>
 | 
			
		||||
			</a>
 | 
			
		||||
		</section>
 | 
			
		||||
		<x-index @go="onGo" @matching="onMatching"/>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -60,10 +18,12 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import XGameroom from './reversi.gameroom.vue';
 | 
			
		||||
import XIndex from './reversi.index.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		XGameroom
 | 
			
		||||
		XGameroom,
 | 
			
		||||
		XIndex
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	props: ['initGame'],
 | 
			
		||||
| 
						 | 
				
			
			@ -71,12 +31,7 @@ export default Vue.extend({
 | 
			
		|||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			game: null,
 | 
			
		||||
			games: [],
 | 
			
		||||
			gamesFetching: true,
 | 
			
		||||
			gamesMoreFetching: false,
 | 
			
		||||
			myGames: [],
 | 
			
		||||
			matching: null,
 | 
			
		||||
			invitations: [],
 | 
			
		||||
			connection: null,
 | 
			
		||||
			connectionId: null,
 | 
			
		||||
			pingClock: null
 | 
			
		||||
| 
						 | 
				
			
			@ -101,17 +56,6 @@ export default Vue.extend({
 | 
			
		|||
			this.connectionId = (this as any).os.streams.reversiStream.use();
 | 
			
		||||
 | 
			
		||||
			this.connection.on('matched', this.onMatched);
 | 
			
		||||
			this.connection.on('invited', this.onInvited);
 | 
			
		||||
 | 
			
		||||
			(this as any).api('games/reversi/games', {
 | 
			
		||||
				my: true
 | 
			
		||||
			}).then(games => {
 | 
			
		||||
				this.myGames = games;
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			(this as any).api('games/reversi/invitations').then(invitations => {
 | 
			
		||||
				this.invitations = this.invitations.concat(invitations);
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.pingClock = setInterval(() => {
 | 
			
		||||
				if (this.matching) {
 | 
			
		||||
| 
						 | 
				
			
			@ -122,17 +66,11 @@ export default Vue.extend({
 | 
			
		|||
				}
 | 
			
		||||
			}, 3000);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		(this as any).api('games/reversi/games').then(games => {
 | 
			
		||||
			this.games = games;
 | 
			
		||||
			this.gamesFetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
		if (this.connection) {
 | 
			
		||||
			this.connection.off('matched', this.onMatched);
 | 
			
		||||
			this.connection.off('invited', this.onInvited);
 | 
			
		||||
			(this as any).os.streams.reversiStream.dispose(this.connectionId);
 | 
			
		||||
 | 
			
		||||
			clearInterval(this.pingClock);
 | 
			
		||||
| 
						 | 
				
			
			@ -140,33 +78,13 @@ export default Vue.extend({
 | 
			
		|||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		go(game) {
 | 
			
		||||
			(this as any).api('games/reversi/games/show', {
 | 
			
		||||
				gameId: game.id
 | 
			
		||||
			}).then(game => {
 | 
			
		||||
		onGo(game) {
 | 
			
		||||
			this.matching = null;
 | 
			
		||||
			this.game = game;
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		match() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@enter-username%'
 | 
			
		||||
			}).then(username => {
 | 
			
		||||
				(this as any).api('users/show', {
 | 
			
		||||
					username
 | 
			
		||||
				}).then(user => {
 | 
			
		||||
					(this as any).api('games/reversi/match', {
 | 
			
		||||
						userId: user.id
 | 
			
		||||
					}).then(res => {
 | 
			
		||||
						if (res == null) {
 | 
			
		||||
		onMatching(user) {
 | 
			
		||||
			this.matching = user;
 | 
			
		||||
						} else {
 | 
			
		||||
							this.game = res;
 | 
			
		||||
						}
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		cancel() {
 | 
			
		||||
| 
						 | 
				
			
			@ -188,10 +106,6 @@ export default Vue.extend({
 | 
			
		|||
		onMatched(game) {
 | 
			
		||||
			this.matching = null;
 | 
			
		||||
			this.game = game;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onInvited(invite) {
 | 
			
		||||
			this.invitations.unshift(invite);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -219,110 +133,6 @@ root(isDark)
 | 
			
		|||
			text-align center
 | 
			
		||||
			border-top dashed 1px #c4cdd4
 | 
			
		||||
 | 
			
		||||
	> .index
 | 
			
		||||
		> h1
 | 
			
		||||
			margin 0
 | 
			
		||||
			padding 24px
 | 
			
		||||
			font-size 24px
 | 
			
		||||
			text-align center
 | 
			
		||||
			font-weight normal
 | 
			
		||||
			color #fff
 | 
			
		||||
			background linear-gradient(to bottom, isDark ? #45730e : #8bca3e, isDark ? #464300 : #d6cf31)
 | 
			
		||||
 | 
			
		||||
			& + p
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 12px
 | 
			
		||||
				margin-bottom 12px
 | 
			
		||||
				text-align center
 | 
			
		||||
				font-size 14px
 | 
			
		||||
				border-bottom solid 1px isDark ? #535f65 : #d3d9dc
 | 
			
		||||
 | 
			
		||||
		> .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
 | 
			
		||||
					background isDark ? #282c37 : #f5f5f5
 | 
			
		||||
					border-radius 8px
 | 
			
		||||
 | 
			
		||||
		> section
 | 
			
		||||
			margin 0 auto
 | 
			
		||||
			padding 0 16px 16px 16px
 | 
			
		||||
			max-width 500px
 | 
			
		||||
			border-top solid 1px isDark ? #535f65 : #d3d9dc
 | 
			
		||||
 | 
			
		||||
			> h2
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 16px 0 8px 0
 | 
			
		||||
				font-size 16px
 | 
			
		||||
				font-weight bold
 | 
			
		||||
 | 
			
		||||
	.invitation
 | 
			
		||||
		margin 8px 0
 | 
			
		||||
		padding 8px
 | 
			
		||||
		border solid 1px #e1e5e8
 | 
			
		||||
		border-radius 6px
 | 
			
		||||
		cursor pointer
 | 
			
		||||
 | 
			
		||||
		*
 | 
			
		||||
			pointer-events none
 | 
			
		||||
			user-select none
 | 
			
		||||
 | 
			
		||||
		&:focus
 | 
			
		||||
			border-color $theme-color
 | 
			
		||||
 | 
			
		||||
		&:hover
 | 
			
		||||
			background #f5f5f5
 | 
			
		||||
 | 
			
		||||
		&:active
 | 
			
		||||
			background #eee
 | 
			
		||||
 | 
			
		||||
		> .avatar
 | 
			
		||||
			width 32px
 | 
			
		||||
			height 32px
 | 
			
		||||
			border-radius 100%
 | 
			
		||||
 | 
			
		||||
		> span
 | 
			
		||||
			margin 0 8px
 | 
			
		||||
			line-height 32px
 | 
			
		||||
 | 
			
		||||
	.game
 | 
			
		||||
		display block
 | 
			
		||||
		margin 8px 0
 | 
			
		||||
		padding 8px
 | 
			
		||||
		color isDark ? #fff : #677f84
 | 
			
		||||
		background isDark ? #282c37 : #fff
 | 
			
		||||
		box-shadow 0 2px 16px rgba(#000, isDark ? 0.7 : 0.15)
 | 
			
		||||
		border-radius 6px
 | 
			
		||||
		cursor pointer
 | 
			
		||||
 | 
			
		||||
		*
 | 
			
		||||
			pointer-events none
 | 
			
		||||
			user-select none
 | 
			
		||||
 | 
			
		||||
		&:hover
 | 
			
		||||
			background isDark ? #313543 : #f5f5f5
 | 
			
		||||
 | 
			
		||||
		&:active
 | 
			
		||||
			background isDark ? #1e222b : #eee
 | 
			
		||||
 | 
			
		||||
		> .avatar
 | 
			
		||||
			width 32px
 | 
			
		||||
			height 32px
 | 
			
		||||
			border-radius 100%
 | 
			
		||||
 | 
			
		||||
		> span
 | 
			
		||||
			margin 0 8px
 | 
			
		||||
			line-height 32px
 | 
			
		||||
 | 
			
		||||
.vchtoekanapleubgzioubdtmlkribzfd[data-darkmode]
 | 
			
		||||
	root(true)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue