Better UX about players
This commit is contained in:
parent
58437a1b97
commit
1f2d7a98ce
|
|
@ -14,7 +14,14 @@ class ClosetController extends Controller
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return view('user.closet')
|
return view('user.closet')
|
||||||
->with('extra', ['unverified' => option('require_verification') && ! $user->verified]);
|
->with('extra', [
|
||||||
|
'unverified' => option('require_verification') && ! $user->verified,
|
||||||
|
'rule' => trans('user.player.player-name-rule.'.option('player_name_rule')),
|
||||||
|
'length' => trans(
|
||||||
|
'user.player.player-name-length',
|
||||||
|
['min' => option('player_name_length_min'), 'max' => option('player_name_length_max')]
|
||||||
|
),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getClosetData(Request $request)
|
public function getClosetData(Request $request)
|
||||||
|
|
|
||||||
77
resources/assets/src/components/AddPlayerDialog.vue
Normal file
77
resources/assets/src/components/AddPlayerDialog.vue
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
id="modal-add-player"
|
||||||
|
class="modal fade"
|
||||||
|
tabindex="-1"
|
||||||
|
role="dialog"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
<h4 v-t="'user.player.add-player'" class="modal-title" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td v-t="'general.player.player-name'" class="key" />
|
||||||
|
<td class="value">
|
||||||
|
<el-input v-model="name" type="text" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="callout callout-info">
|
||||||
|
<ul style="padding: 0 0 0 20px; margin: 0;">
|
||||||
|
<li>{{ rule }}</li>
|
||||||
|
<li>{{ length }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<el-button data-dismiss="modal">{{ $t('general.close') }}</el-button>
|
||||||
|
<el-button type="primary" data-test="addPlayer" @click="addPlayer">
|
||||||
|
{{ $t('general.submit') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AddPlayerDialog',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
name: '',
|
||||||
|
rule: blessing.extra.rule,
|
||||||
|
length: blessing.extra.length,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async addPlayer() {
|
||||||
|
const { errno, msg } = await this.$http.post(
|
||||||
|
'/user/player/add',
|
||||||
|
{ player_name: this.name }
|
||||||
|
)
|
||||||
|
if (errno === 0) {
|
||||||
|
$('#modal-add-player').modal('hide')
|
||||||
|
this.$message.success(msg)
|
||||||
|
this.$emit('add')
|
||||||
|
} else {
|
||||||
|
this.$message.warning(msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
112
resources/assets/src/components/ApplyToPlayerDialog.vue
Normal file
112
resources/assets/src/components/ApplyToPlayerDialog.vue
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
id="modal-use-as"
|
||||||
|
class="modal fade"
|
||||||
|
tabindex="-1"
|
||||||
|
role="dialog"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
<h4 v-t="'user.closet.use-as.title'" class="modal-title" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<template v-if="players.length !== 0">
|
||||||
|
<div v-for="player in players" :key="player.pid" class="player-item">
|
||||||
|
<label class="model-label" :for="player.pid">
|
||||||
|
<input
|
||||||
|
v-model="selected"
|
||||||
|
type="radio"
|
||||||
|
name="player"
|
||||||
|
:value="player.pid"
|
||||||
|
>
|
||||||
|
<img :src="avatarUrl(player)" width="35" height="35">
|
||||||
|
<span>{{ player.name }}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<p v-else v-t="'user.closet.use-as.empty'" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a
|
||||||
|
v-if="allowAdd"
|
||||||
|
v-t="'user.closet.use-as.add'"
|
||||||
|
data-toggle="modal"
|
||||||
|
data-target="#modal-add-player"
|
||||||
|
class="el-button pull-left"
|
||||||
|
/>
|
||||||
|
<el-button type="primary" data-test="submit" @click="submit">
|
||||||
|
{{ $t('general.submit') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ApplyToPlayerDialog',
|
||||||
|
props: {
|
||||||
|
skin: Number,
|
||||||
|
cape: Number,
|
||||||
|
allowAdd: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
players: [],
|
||||||
|
selected: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async fetchList() {
|
||||||
|
this.players = await this.$http.get('/user/player/list')
|
||||||
|
},
|
||||||
|
async submit() {
|
||||||
|
if (!this.selected) {
|
||||||
|
return this.$message.info(this.$t('user.emptySelectedPlayer'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.skin && !this.cape) {
|
||||||
|
return this.$message.info(this.$t('user.emptySelectedTexture'))
|
||||||
|
}
|
||||||
|
|
||||||
|
const { errno, msg } = await this.$http.post(
|
||||||
|
'/user/player/set',
|
||||||
|
{
|
||||||
|
pid: this.selected,
|
||||||
|
tid: {
|
||||||
|
skin: this.skin || undefined,
|
||||||
|
cape: this.cape || undefined,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (errno === 0) {
|
||||||
|
this.$message.success(msg)
|
||||||
|
$('#modal-use-as').modal('hide')
|
||||||
|
} else {
|
||||||
|
this.$message.warning(msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
avatarUrl(player) {
|
||||||
|
return `${blessing.base_url}/avatar/35/${player.tid_skin}`
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus">
|
||||||
|
.player-item:not(:nth-child(1))
|
||||||
|
margin-top 10px
|
||||||
|
</style>
|
||||||
|
|
@ -11,14 +11,16 @@
|
||||||
{{ $t('skinlib.addToCloset') }}
|
{{ $t('skinlib.addToCloset') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<a
|
<el-button
|
||||||
v-if="liked"
|
v-if="liked"
|
||||||
native-type="a"
|
type="success"
|
||||||
:href="`${baseUrl}/user/closet?tid=${tid}`"
|
size="medium"
|
||||||
class="el-button el-button--success el-button--medium"
|
data-toggle="modal"
|
||||||
|
data-target="#modal-use-as"
|
||||||
|
@click="fetchPlayersList"
|
||||||
>
|
>
|
||||||
{{ $t('skinlib.apply') }}
|
{{ $t('skinlib.apply') }}
|
||||||
</a>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="liked"
|
v-if="liked"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -150,6 +152,13 @@
|
||||||
</div><!-- /.box-footer -->
|
</div><!-- /.box-footer -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<apply-to-player-dialog
|
||||||
|
ref="useAs"
|
||||||
|
:allow-add="false"
|
||||||
|
:skin="type !== 'cape' ? tid : 0"
|
||||||
|
:cape="type === 'cape' ? tid : 0"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -157,10 +166,12 @@
|
||||||
import setAsAvatar from '../../components/mixins/setAsAvatar'
|
import setAsAvatar from '../../components/mixins/setAsAvatar'
|
||||||
import addClosetItem from '../../components/mixins/addClosetItem'
|
import addClosetItem from '../../components/mixins/addClosetItem'
|
||||||
import removeClosetItem from '../../components/mixins/removeClosetItem'
|
import removeClosetItem from '../../components/mixins/removeClosetItem'
|
||||||
|
import ApplyToPlayerDialog from '../../components/ApplyToPlayerDialog.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Show',
|
name: 'Show',
|
||||||
components: {
|
components: {
|
||||||
|
ApplyToPlayerDialog,
|
||||||
Previewer: () => import('../../components/Previewer.vue'),
|
Previewer: () => import('../../components/Previewer.vue'),
|
||||||
},
|
},
|
||||||
mixins: [
|
mixins: [
|
||||||
|
|
@ -366,6 +377,9 @@ export default {
|
||||||
this.$message.warning(msg)
|
this.$message.warning(msg)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
fetchPlayersList() {
|
||||||
|
this.$refs.useAs.fetchList()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
data-toggle="modal"
|
data-toggle="modal"
|
||||||
data-target="#modal-use-as"
|
data-target="#modal-use-as"
|
||||||
@click="applyTexture"
|
@click="fetchPlayersList"
|
||||||
>
|
>
|
||||||
{{ $t('user.useAs') }}
|
{{ $t('user.useAs') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -142,52 +142,8 @@
|
||||||
</previewer>
|
</previewer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<apply-to-player-dialog ref="useAs" :skin="selectedSkin" :cape="selectedCape" />
|
||||||
<div
|
<add-player-dialog @add="fetchPlayersList" />
|
||||||
id="modal-use-as"
|
|
||||||
class="modal fade"
|
|
||||||
tabindex="-1"
|
|
||||||
role="dialog"
|
|
||||||
>
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="close"
|
|
||||||
data-dismiss="modal"
|
|
||||||
aria-label="Close"
|
|
||||||
>
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
<h4 v-t="'user.closet.use-as.title'" class="modal-title" />
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<template v-if="players.length !== 0">
|
|
||||||
<div v-for="player in players" :key="player.pid" class="player-item">
|
|
||||||
<label class="model-label" :for="player.pid">
|
|
||||||
<input
|
|
||||||
v-model="selectedPlayer"
|
|
||||||
type="radio"
|
|
||||||
name="player"
|
|
||||||
:value="player.pid"
|
|
||||||
>
|
|
||||||
<img :src="avatarUrl(player)" width="35" height="35">
|
|
||||||
<span>{{ player.name }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<p v-else v-t="'user.closet.use-as.empty'" />
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<a v-t="'user.closet.use-as.add'" href="./player" class="el-button pull-left" />
|
|
||||||
<el-button type="primary" data-test="submitApplyTexture" @click="submitApplyTexture">
|
|
||||||
{{ $t('general.submit') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div><!-- /.modal-content -->
|
|
||||||
</div><!-- /.modal-dialog -->
|
|
||||||
</div><!-- /.modal -->
|
|
||||||
</section><!-- /.content -->
|
</section><!-- /.content -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -196,6 +152,8 @@ import Paginate from 'vuejs-paginate'
|
||||||
import { debounce, queryString } from '../../scripts/utils'
|
import { debounce, queryString } from '../../scripts/utils'
|
||||||
import ClosetItem from '../../components/ClosetItem.vue'
|
import ClosetItem from '../../components/ClosetItem.vue'
|
||||||
import EmailVerification from '../../components/EmailVerification.vue'
|
import EmailVerification from '../../components/EmailVerification.vue'
|
||||||
|
import AddPlayerDialog from '../../components/AddPlayerDialog.vue'
|
||||||
|
import ApplyToPlayerDialog from '../../components/ApplyToPlayerDialog.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Closet',
|
name: 'Closet',
|
||||||
|
|
@ -204,6 +162,8 @@ export default {
|
||||||
ClosetItem,
|
ClosetItem,
|
||||||
Previewer: () => import('../../components/Previewer.vue'),
|
Previewer: () => import('../../components/Previewer.vue'),
|
||||||
EmailVerification,
|
EmailVerification,
|
||||||
|
AddPlayerDialog,
|
||||||
|
ApplyToPlayerDialog,
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
category: 'skin',
|
category: 'skin',
|
||||||
|
|
@ -218,8 +178,6 @@ export default {
|
||||||
skinUrl: '',
|
skinUrl: '',
|
||||||
selectedCape: 0,
|
selectedCape: 0,
|
||||||
capeUrl: '',
|
capeUrl: '',
|
||||||
players: [],
|
|
||||||
selectedPlayer: 0,
|
|
||||||
linkToSkin: `${blessing.base_url}/skinlib?filter=skin`,
|
linkToSkin: `${blessing.base_url}/skinlib?filter=skin`,
|
||||||
linkToCape: `${blessing.base_url}/skinlib?filter=cape`,
|
linkToCape: `${blessing.base_url}/skinlib?filter=cape`,
|
||||||
}),
|
}),
|
||||||
|
|
@ -233,7 +191,7 @@ export default {
|
||||||
const tid = +queryString('tid', 0)
|
const tid = +queryString('tid', 0)
|
||||||
if (tid) {
|
if (tid) {
|
||||||
this.selectTexture(tid)
|
this.selectTexture(tid)
|
||||||
this.applyTexture()
|
this.fetchPlayersList()
|
||||||
$('#modal-use-as').modal()
|
$('#modal-use-as').modal()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -267,9 +225,6 @@ export default {
|
||||||
pageChanged(page) {
|
pageChanged(page) {
|
||||||
this.loadCloset(page)
|
this.loadCloset(page)
|
||||||
},
|
},
|
||||||
avatarUrl(player) {
|
|
||||||
return `${blessing.base_url}/avatar/35/${player.tid_skin}`
|
|
||||||
},
|
|
||||||
async selectTexture(tid) {
|
async selectTexture(tid) {
|
||||||
const { type, hash } = await this.$http.get(`/skinlib/info/${tid}`)
|
const { type, hash } = await this.$http.get(`/skinlib/info/${tid}`)
|
||||||
if (type === 'cape') {
|
if (type === 'cape') {
|
||||||
|
|
@ -280,41 +235,15 @@ export default {
|
||||||
this.selectedSkin = tid
|
this.selectedSkin = tid
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async applyTexture() {
|
|
||||||
this.players = await this.$http.get('/user/player/list')
|
|
||||||
},
|
|
||||||
async submitApplyTexture() {
|
|
||||||
if (!this.selectedPlayer) {
|
|
||||||
return this.$message.info(this.$t('user.emptySelectedPlayer'))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.selectedSkin && !this.selectedCape) {
|
|
||||||
return this.$message.info(this.$t('user.emptySelectedTexture'))
|
|
||||||
}
|
|
||||||
|
|
||||||
const { errno, msg } = await this.$http.post(
|
|
||||||
'/user/player/set',
|
|
||||||
{
|
|
||||||
pid: this.selectedPlayer,
|
|
||||||
tid: {
|
|
||||||
skin: this.selectedSkin || undefined,
|
|
||||||
cape: this.selectedCape || undefined,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if (errno === 0) {
|
|
||||||
this.$message.success(msg)
|
|
||||||
$('#modal-use-as').modal('hide')
|
|
||||||
} else {
|
|
||||||
this.$message.warning(msg)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
resetSelected() {
|
resetSelected() {
|
||||||
this.selectedSkin = 0
|
this.selectedSkin = 0
|
||||||
this.selectedCape = 0
|
this.selectedCape = 0
|
||||||
this.skinUrl = ''
|
this.skinUrl = ''
|
||||||
this.capeUrl = ''
|
this.capeUrl = ''
|
||||||
},
|
},
|
||||||
|
fetchPlayersList() {
|
||||||
|
this.$refs.useAs.fetchList()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -345,9 +274,6 @@ export default {
|
||||||
a.selected
|
a.selected
|
||||||
color #3c8dbc
|
color #3c8dbc
|
||||||
|
|
||||||
.player-item:not(:nth-child(1))
|
|
||||||
margin-top 10px
|
|
||||||
|
|
||||||
.breadcrumb
|
.breadcrumb
|
||||||
a
|
a
|
||||||
margin-right 10px
|
margin-right 10px
|
||||||
|
|
|
||||||
|
|
@ -116,57 +116,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<add-player-dialog @add="fetchPlayers" />
|
||||||
id="modal-add-player"
|
|
||||||
class="modal fade"
|
|
||||||
tabindex="-1"
|
|
||||||
role="dialog"
|
|
||||||
>
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="close"
|
|
||||||
data-dismiss="modal"
|
|
||||||
aria-label="Close"
|
|
||||||
>
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
<h4 v-t="'user.player.add-player'" class="modal-title" />
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td v-t="'general.player.player-name'" class="key" />
|
|
||||||
<td class="value">
|
|
||||||
<input
|
|
||||||
v-model="newPlayer"
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div class="callout callout-info">
|
|
||||||
<ul style="padding: 0 0 0 20px; margin: 0;">
|
|
||||||
<li>{{ playerNameRule }}</li>
|
|
||||||
<li>{{ playerNameLength }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<el-button data-dismiss="modal">{{ $t('general.close') }}</el-button>
|
|
||||||
<el-button type="primary" data-test="addPlayer" @click="addPlayer">
|
|
||||||
{{ $t('general.submit') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div><!-- /.modal-content -->
|
|
||||||
</div><!-- /.modal-dialog -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="modal-clear-texture"
|
id="modal-clear-texture"
|
||||||
|
|
@ -209,9 +159,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import AddPlayerDialog from '../../components/AddPlayerDialog.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Players',
|
name: 'Players',
|
||||||
components: {
|
components: {
|
||||||
|
AddPlayerDialog,
|
||||||
Previewer: () => import('../../components/Previewer.vue'),
|
Previewer: () => import('../../components/Previewer.vue'),
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -231,13 +184,10 @@ export default {
|
||||||
skin: 0,
|
skin: 0,
|
||||||
cape: 0,
|
cape: 0,
|
||||||
},
|
},
|
||||||
newPlayer: '',
|
|
||||||
clear: {
|
clear: {
|
||||||
skin: false,
|
skin: false,
|
||||||
cape: false,
|
cape: false,
|
||||||
},
|
},
|
||||||
playerNameRule: blessing.extra.rule,
|
|
||||||
playerNameLength: blessing.extra.length,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
|
@ -332,19 +282,6 @@ export default {
|
||||||
this.$message.warning(msg)
|
this.$message.warning(msg)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async addPlayer() {
|
|
||||||
$('.modal').modal('hide')
|
|
||||||
const { errno, msg } = await this.$http.post(
|
|
||||||
'/user/player/add',
|
|
||||||
{ player_name: this.newPlayer }
|
|
||||||
)
|
|
||||||
if (errno === 0) {
|
|
||||||
this.$message.success(msg)
|
|
||||||
this.fetchPlayers()
|
|
||||||
} else {
|
|
||||||
this.$message.warning(msg)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -363,9 +300,6 @@ export default {
|
||||||
.player-selected
|
.player-selected
|
||||||
background-color #f5f5f5
|
background-color #f5f5f5
|
||||||
|
|
||||||
.modal-body > label
|
|
||||||
margin-bottom 10px
|
|
||||||
|
|
||||||
.skin2d
|
.skin2d
|
||||||
float right
|
float right
|
||||||
max-height 64px
|
max-height 64px
|
||||||
|
|
|
||||||
35
resources/assets/tests/components/AddPlayerDialog.test.ts
Normal file
35
resources/assets/tests/components/AddPlayerDialog.test.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import { flushPromises } from '../utils'
|
||||||
|
import AddPlayerDialog from '@/components/AddPlayerDialog.vue'
|
||||||
|
|
||||||
|
window.blessing.extra = {
|
||||||
|
rule: 'rule',
|
||||||
|
length: 'length',
|
||||||
|
}
|
||||||
|
|
||||||
|
test('add player', async () => {
|
||||||
|
window.$ = jest.fn(() => ({ modal() {} }))
|
||||||
|
Vue.prototype.$http.get.mockResolvedValueOnce([])
|
||||||
|
Vue.prototype.$http.post
|
||||||
|
.mockResolvedValueOnce({ errno: 1, msg: 'fail' })
|
||||||
|
.mockResolvedValue({ errno: 0, msg: 'ok' })
|
||||||
|
const wrapper = mount(AddPlayerDialog)
|
||||||
|
const button = wrapper.find('[data-test=addPlayer]')
|
||||||
|
wrapper.find('input[type="text"]').setValue('the-new')
|
||||||
|
|
||||||
|
button.trigger('click')
|
||||||
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||||
|
'/user/player/add',
|
||||||
|
{ player_name: 'the-new' }
|
||||||
|
)
|
||||||
|
await flushPromises()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(wrapper.text()).not.toContain('the-new')
|
||||||
|
expect(Vue.prototype.$message.warning).toBeCalledWith('fail')
|
||||||
|
|
||||||
|
button.trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.emitted().add).toBeDefined()
|
||||||
|
expect(Vue.prototype.$message.success).toBeCalledWith('ok')
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import ApplyToPlayerDialog from '@/components/ApplyToPlayerDialog.vue'
|
||||||
|
|
||||||
|
test('submit applying texture', async () => {
|
||||||
|
window.$ = jest.fn(() => ({ modal() {} }))
|
||||||
|
Vue.prototype.$http.get.mockResolvedValue([{ pid: 1 }])
|
||||||
|
Vue.prototype.$http.post.mockResolvedValueOnce({ errno: 1 })
|
||||||
|
.mockResolvedValue({ errno: 0, msg: 'ok' })
|
||||||
|
const wrapper = mount(ApplyToPlayerDialog)
|
||||||
|
const button = wrapper.find('[data-test=submit]')
|
||||||
|
|
||||||
|
button.trigger('click')
|
||||||
|
expect(Vue.prototype.$message.info).toBeCalledWith('user.emptySelectedPlayer')
|
||||||
|
|
||||||
|
wrapper.setData({ selected: 1 })
|
||||||
|
button.trigger('click')
|
||||||
|
expect(Vue.prototype.$message.info).toBeCalledWith('user.emptySelectedTexture')
|
||||||
|
|
||||||
|
wrapper.setProps({ skin: 1 })
|
||||||
|
button.trigger('click')
|
||||||
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||||
|
'/user/player/set',
|
||||||
|
{
|
||||||
|
pid: 1,
|
||||||
|
tid: {
|
||||||
|
skin: 1,
|
||||||
|
cape: undefined,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
wrapper.setProps({ skin: 0, cape: 1 })
|
||||||
|
button.trigger('click')
|
||||||
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||||
|
'/user/player/set',
|
||||||
|
{
|
||||||
|
pid: 1,
|
||||||
|
tid: {
|
||||||
|
skin: undefined,
|
||||||
|
cape: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(Vue.prototype.$message.success).toBeCalledWith('ok')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('compute avatar URL', () => {
|
||||||
|
Vue.prototype.$http.get.mockResolvedValue({})
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
const wrapper = mount<Vue & { avatarUrl(player: { tid_skin: number }): string }>(ApplyToPlayerDialog)
|
||||||
|
const { avatarUrl } = wrapper.vm
|
||||||
|
expect(avatarUrl({ tid_skin: 1 })).toBe('/avatar/35/1')
|
||||||
|
})
|
||||||
|
|
@ -419,3 +419,17 @@ test('report texture', async () => {
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect(Vue.prototype.$message.success).toBeCalledWith('success')
|
expect(Vue.prototype.$message.success).toBeCalledWith('success')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('apply texture to player', () => {
|
||||||
|
Vue.prototype.$http.get
|
||||||
|
.mockResolvedValue({})
|
||||||
|
.mockResolvedValue([])
|
||||||
|
const wrapper = mount(Show, {
|
||||||
|
mocks: {
|
||||||
|
$route: ['/skinlib/show/1', '1'],
|
||||||
|
},
|
||||||
|
stubs: { previewer },
|
||||||
|
})
|
||||||
|
wrapper.find('[data-target="#modal-use-as"]').trigger('click')
|
||||||
|
expect(wrapper.find('[data-target="#modal-add-player"]').exists()).toBeFalse()
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -145,14 +145,6 @@ test('remove cape item', () => {
|
||||||
expect(wrapper.find('#cape-category').text()).toContain('user.emptyClosetMsg')
|
expect(wrapper.find('#cape-category').text()).toContain('user.emptyClosetMsg')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('compute avatar URL', () => {
|
|
||||||
Vue.prototype.$http.get.mockResolvedValue({})
|
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
const wrapper = mount<Vue & { avatarUrl(player: { tid_skin: number }): string }>(Closet)
|
|
||||||
const { avatarUrl } = wrapper.vm
|
|
||||||
expect(avatarUrl({ tid_skin: 1 })).toBe('/avatar/35/1')
|
|
||||||
})
|
|
||||||
|
|
||||||
test('select texture', async () => {
|
test('select texture', async () => {
|
||||||
Vue.prototype.$http.get
|
Vue.prototype.$http.get
|
||||||
.mockResolvedValueOnce({})
|
.mockResolvedValueOnce({})
|
||||||
|
|
@ -200,49 +192,6 @@ test('apply texture', async () => {
|
||||||
jest.runAllTimers()
|
jest.runAllTimers()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('submit applying texture', async () => {
|
|
||||||
window.$ = jest.fn(() => ({ modal() {} }))
|
|
||||||
Vue.prototype.$http.get.mockResolvedValue({})
|
|
||||||
Vue.prototype.$http.post.mockResolvedValueOnce({ errno: 1 })
|
|
||||||
.mockResolvedValue({ errno: 0, msg: 'ok' })
|
|
||||||
const wrapper = mount(Closet)
|
|
||||||
const button = wrapper.find('[data-test=submitApplyTexture]')
|
|
||||||
|
|
||||||
button.trigger('click')
|
|
||||||
expect(Vue.prototype.$message.info).toBeCalledWith('user.emptySelectedPlayer')
|
|
||||||
|
|
||||||
wrapper.setData({ selectedPlayer: 1 })
|
|
||||||
button.trigger('click')
|
|
||||||
expect(Vue.prototype.$message.info).toBeCalledWith('user.emptySelectedTexture')
|
|
||||||
|
|
||||||
wrapper.setData({ selectedSkin: 1 })
|
|
||||||
button.trigger('click')
|
|
||||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
||||||
'/user/player/set',
|
|
||||||
{
|
|
||||||
pid: 1,
|
|
||||||
tid: {
|
|
||||||
skin: 1,
|
|
||||||
cape: undefined,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
wrapper.setData({ selectedSkin: 0, selectedCape: 1 })
|
|
||||||
button.trigger('click')
|
|
||||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
||||||
'/user/player/set',
|
|
||||||
{
|
|
||||||
pid: 1,
|
|
||||||
tid: {
|
|
||||||
skin: undefined,
|
|
||||||
cape: 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await wrapper.vm.$nextTick()
|
|
||||||
expect(Vue.prototype.$message.success).toBeCalledWith('ok')
|
|
||||||
})
|
|
||||||
|
|
||||||
test('reset selected texture', () => {
|
test('reset selected texture', () => {
|
||||||
Vue.prototype.$http.get.mockResolvedValue({})
|
Vue.prototype.$http.get.mockResolvedValue({})
|
||||||
const wrapper = mount(Closet)
|
const wrapper = mount(Closet)
|
||||||
|
|
|
||||||
|
|
@ -127,22 +127,11 @@ test('toggle preview mode', () => {
|
||||||
test('add player', async () => {
|
test('add player', async () => {
|
||||||
window.$ = jest.fn(() => ({ modal() {} }))
|
window.$ = jest.fn(() => ({ modal() {} }))
|
||||||
Vue.prototype.$http.get.mockResolvedValueOnce([])
|
Vue.prototype.$http.get.mockResolvedValueOnce([])
|
||||||
Vue.prototype.$http.post
|
Vue.prototype.$http.post.mockResolvedValue({ errno: 0 })
|
||||||
.mockResolvedValueOnce({ errno: 1 })
|
|
||||||
.mockResolvedValue({ errno: 0 })
|
|
||||||
const wrapper = mount(Players)
|
const wrapper = mount(Players)
|
||||||
const button = wrapper.find('[data-test=addPlayer]')
|
const button = wrapper.find('[data-test=addPlayer]')
|
||||||
|
|
||||||
wrapper.find('input[type="text"]').setValue('the-new')
|
wrapper.find('input[type="text"]').setValue('the-new')
|
||||||
|
|
||||||
button.trigger('click')
|
|
||||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
||||||
'/user/player/add',
|
|
||||||
{ player_name: 'the-new' }
|
|
||||||
)
|
|
||||||
await flushPromises()
|
|
||||||
await wrapper.vm.$nextTick()
|
|
||||||
expect(wrapper.text()).not.toContain('the-new')
|
|
||||||
|
|
||||||
button.trigger('click')
|
button.trigger('click')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect(Vue.prototype.$http.get).toBeCalledTimes(2)
|
expect(Vue.prototype.$http.get).toBeCalledTimes(2)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user