support searching players when applying textures
This commit is contained in:
parent
9e792b9c3a
commit
cf6f1aa547
@ -5,21 +5,25 @@
|
||||
:title="$t('user.closet.use-as.title')"
|
||||
:ok-button-text="$t('general.submit')"
|
||||
flex-footer
|
||||
center
|
||||
>
|
||||
<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 class="form-group">
|
||||
<input
|
||||
v-model="search"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:placeholder="$t('user.typeToSearch')"
|
||||
>
|
||||
</div>
|
||||
<button
|
||||
v-for="player in filteredPlayers"
|
||||
:key="player.pid"
|
||||
class="btn btn-block btn-outline-info text-left"
|
||||
@click="submit(player.pid)"
|
||||
>
|
||||
<img :src="avatarUrl(player)" width="45" height="45">
|
||||
<span>{{ player.name }}</span>
|
||||
</button>
|
||||
</template>
|
||||
<p v-else v-t="'user.closet.use-as.empty'" />
|
||||
<template #footer>
|
||||
@ -31,8 +35,8 @@
|
||||
class="btn btn-default"
|
||||
href="#"
|
||||
/>
|
||||
<button class="btn btn-primary" data-test="submit" @click="submit">
|
||||
{{ $t('general.submit') }}
|
||||
<button class="btn btn-default" data-dismiss="modal">
|
||||
{{ $t('general.cancel') }}
|
||||
</button>
|
||||
</template>
|
||||
</modal>
|
||||
@ -59,26 +63,29 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
players: [],
|
||||
selected: 0,
|
||||
search: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredPlayers() {
|
||||
return this.players.filter(player => player.name.includes(this.search))
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetchList()
|
||||
},
|
||||
methods: {
|
||||
async fetchList() {
|
||||
this.players = (await this.$http.get('/user/player/list')).data
|
||||
},
|
||||
async submit() {
|
||||
if (!this.selected) {
|
||||
toast.info(this.$t('user.emptySelectedPlayer'))
|
||||
return
|
||||
}
|
||||
|
||||
async submit(selected) {
|
||||
if (!this.skin && !this.cape) {
|
||||
toast.info(this.$t('user.emptySelectedTexture'))
|
||||
return
|
||||
}
|
||||
|
||||
const { code, message } = await this.$http.post(
|
||||
`/user/player/set/${this.selected}`,
|
||||
`/user/player/set/${selected}`,
|
||||
{
|
||||
skin: this.skin || undefined,
|
||||
cape: this.cape || undefined,
|
||||
@ -92,13 +99,8 @@ export default {
|
||||
}
|
||||
},
|
||||
avatarUrl(player) {
|
||||
return `${blessing.base_url}/avatar/${player.tid_skin}?3d&size=35`
|
||||
return `${blessing.base_url}/avatar/${player.tid_skin}?3d&size=45`
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus">
|
||||
.player-item:not(:nth-child(1))
|
||||
margin-top 10px
|
||||
</style>
|
||||
|
@ -8,16 +8,13 @@ import ApplyToPlayerDialog from '@/components/ApplyToPlayerDialog.vue'
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
test('submit applying texture', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [{ pid: 1 }] })
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [{ pid: 1, name: 'a' }] })
|
||||
Vue.prototype.$http.post.mockResolvedValueOnce({ code: 1 })
|
||||
.mockResolvedValue({ code: 0, message: 'ok' })
|
||||
const wrapper = mount(ApplyToPlayerDialog)
|
||||
const button = wrapper.find('[data-test=submit]')
|
||||
await flushPromises()
|
||||
const button = wrapper.find('.btn-outline-info')
|
||||
|
||||
button.trigger('click')
|
||||
expect(toast.info).toBeCalledWith('user.emptySelectedPlayer')
|
||||
|
||||
wrapper.setData({ selected: 1 })
|
||||
button.trigger('click')
|
||||
expect(toast.info).toBeCalledWith('user.emptySelectedTexture')
|
||||
|
||||
@ -48,5 +45,17 @@ test('compute avatar URL', () => {
|
||||
// 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/1?3d&size=35')
|
||||
expect(avatarUrl({ tid_skin: 1 })).toBe('/avatar/1?3d&size=45')
|
||||
})
|
||||
|
||||
test('search players', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [{ pid: 1, name: 'abc' }] })
|
||||
const wrapper = mount(ApplyToPlayerDialog)
|
||||
await flushPromises()
|
||||
|
||||
wrapper.find('input').setValue('e')
|
||||
expect(wrapper.find('.btn-outline-info').exists()).toBeFalse()
|
||||
|
||||
wrapper.find('input').setValue('b')
|
||||
expect(wrapper.find('.btn-outline-info').exists()).toBeTrue()
|
||||
})
|
||||
|
@ -18,6 +18,7 @@
|
||||
- Added login with 3rd-party services. (GitHub and Microsoft Live are supported currently.)
|
||||
- Added support of character "§" for player name. (Under CJK mode.)
|
||||
- New password hash algorithm: Argon2i.
|
||||
- Support searching players when applying textures.
|
||||
|
||||
## Tweaked
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
- 第三方登录(目前仅支持 GitHub 和 Microsoft Live)
|
||||
- 角色名支持字符「§」(需开启「CJK」模式)
|
||||
- 新的密码哈希算法:Argon2i
|
||||
- 将材质应用到角色时可进行搜索
|
||||
|
||||
## 调整
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user