Skip to content

Commit

Permalink
Update getTitleList API (#4403)
Browse files Browse the repository at this point in the history
Refactor BadgeHelper codes
  • Loading branch information
the1812 committed Sep 2, 2023
1 parent e116962 commit 5451586
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 159 deletions.
135 changes: 63 additions & 72 deletions registry/lib/components/live/badge-helper/BadgeHelper.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="multiple-widgets">
<div ref="element" class="multiple-widgets">
<VPopup
ref="medalPopup"
v-model="medalOpen"
Expand Down Expand Up @@ -50,85 +50,76 @@
</div>
</template>

<script lang="ts">
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { addComponentListener, getComponentSettings } from '@/core/settings'
import { descendingSort } from '@/core/utils/sort'
import { DefaultWidget, VPopup } from '@/ui'
import { Medal, Title, Badge, getMedalList, getTitleList } from './badge'
import { BadgeHelperOptions } from './options'
const { options } = getComponentSettings('badgeHelper')
export default Vue.extend({
components: {
DefaultWidget,
VPopup,
},
data() {
return {
medalList: [],
titleList: [],
medalOpen: false,
titleOpen: false,
grayEffect: true,
const { options } = getComponentSettings<BadgeHelperOptions>('badgeHelper')
const element = ref<HTMLElement>()
const medalList = ref<Medal[]>([])
const titleList = ref<Title[]>([])
const medalOpen = ref(false)
const titleOpen = ref(false)
const grayEffect = ref(true)
const updateColumnsCount = () => {
const maxColumnCount = 15
const columnLength = 18
const medalColumns = Math.min(Math.ceil(medalList.value.length / columnLength), maxColumnCount)
element.value.style.setProperty('--medal-columns', medalColumns.toString())
const titleColumns = Math.min(Math.ceil(titleList.value.length / columnLength), maxColumnCount)
element.value.style.setProperty('--title-columns', titleColumns.toString())
}
const loadMedalList = async () => {
medalList.value = (await getMedalList())
.sort(descendingSort(it => it.level))
.slice(0, options.maxBadgeCount)
}
const loadTitleList = async () => {
titleList.value = (await getTitleList()).slice(0, options.maxBadgeCount)
}
const toggleBadge = async (badge: Badge, list: Badge[]) => {
console.log(badge)
if (badge.isActive) {
badge.isActive = false
await badge.deactivate()
} else {
const activeBadge = list.find(b => b.isActive)
if (activeBadge) {
activeBadge.isActive = false
}
},
async mounted() {
addComponentListener(
'badgeHelper.grayEffect',
(enable: boolean) => {
this.grayEffect = enable
},
true,
)
const init = async () => {
const medal = this.loadMedalList()
await Title.getImageMap()
const title = this.loadTitleList()
return Promise.all([medal, title])
badge.isActive = true
await badge.activate()
if (badge instanceof Medal) {
options.defaultMedalID = badge.id
}
await init()
this.updateColumnsCount()
},
methods: {
updateColumnsCount() {
const maxColumnCount = 15
const columnLength = 18
const element = this.$el as HTMLElement
const medalColumns = Math.min(Math.ceil(this.medalList.length / columnLength), maxColumnCount)
element.style.setProperty('--medal-columns', medalColumns.toString())
const titleColumns = Math.min(Math.ceil(this.titleList.length / columnLength), maxColumnCount)
element.style.setProperty('--title-columns', titleColumns.toString())
},
async loadMedalList() {
this.medalList = (await getMedalList())
.sort(descendingSort(it => it.level))
.slice(0, options.maxBadgeCount)
},
async loadTitleList() {
this.titleList = (await getTitleList()).slice(0, options.maxBadgeCount)
},
async toggleBadge(badge: Badge, list: Badge[]) {
console.log(badge)
if (badge.isActive) {
badge.isActive = false
await badge.deactivate()
} else {
const activeBadge = list.find(b => b.isActive)
if (activeBadge) {
activeBadge.isActive = false
}
badge.isActive = true
await badge.activate()
if (badge instanceof Medal) {
options.defaultMedalID = badge.id
}
}
if (badge instanceof Medal) {
await this.loadMedalList()
} else if (badge instanceof Title) {
await this.loadTitleList()
}
}
if (badge instanceof Medal) {
await loadMedalList()
} else if (badge instanceof Title) {
await loadTitleList()
}
}
onMounted(async () => {
addComponentListener(
'badgeHelper.grayEffect',
(enable: boolean) => {
grayEffect.value = enable
},
},
true,
)
const init = async () => {
const medal = loadMedalList()
await Title.getImageMap()
const title = loadTitleList()
return Promise.all([medal, title])
}
await init()
updateColumnsCount()
})
</script>

Expand Down
98 changes: 36 additions & 62 deletions registry/lib/components/live/badge-helper/badge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
getTextWithCredentials,
postTextWithCredentials,
} from '@/core/ajax'
import { formData, getCsrf } from '@/core/utils'
import { getCsrf } from '@/core/utils'
import { logError } from '@/core/utils/log'

const validateJson = (json: any, errorMessage: string) => {
Expand All @@ -18,22 +18,6 @@ const validateJson = (json: any, errorMessage: string) => {

export abstract class Badge {
constructor(public isActive: boolean = false, public id: number = 0) {}
/** @deprecated */
static parseJson<T>(
text: string,
actions: {
successAction: (json: any) => T
errorMessage: string
errorAction: (json: any) => T
},
) {
const json = JSON.parse(text)
if (json.code !== 0) {
logError(`${actions.errorMessage} 错误码:${json.code} ${json.message || ''}`)
return actions.errorAction(json)
}
return actions.successAction(json)
}
abstract activate(): Promise<boolean>
abstract deactivate(): Promise<boolean>
}
Expand All @@ -59,8 +43,8 @@ export class Medal extends Badge {
async activate() {
const text = await postTextWithCredentials(
'https://api.live.bilibili.com/xlive/web-room/v1/fansMedal/wear',
formData({
medal_id: this.id,
new URLSearchParams({
medal_id: this.id.toString(),
csrf_token: getCsrf(),
csrf: getCsrf(),
}),
Expand All @@ -72,7 +56,7 @@ export class Medal extends Badge {
async deactivate() {
const text = await postTextWithCredentials(
'https://api.live.bilibili.com/xlive/web-room/v1/fansMedal/take_off',
formData({
new URLSearchParams({
csrf_token: getCsrf(),
csrf: getCsrf(),
}),
Expand Down Expand Up @@ -104,9 +88,9 @@ export class Title extends Badge {
source: string
imageUrl: string
constructor(json: any) {
const { id, cid, wear, css, name, source } = json
super(wear, css)
this.tid = id
const { identification, wear, tid, cid, name, source } = json
super(wear, identification)
this.tid = tid
this.cid = cid
this.name = name
this.source = source
Expand All @@ -116,66 +100,56 @@ export class Title extends Badge {
}
static async getImageMap() {
if (Title.imageMap === undefined) {
return Badge.parseJson(
const json = JSON.parse(
await getTextWithCredentials('https://api.live.bilibili.com/rc/v1/Title/webTitles'),
{
successAction(json) {
Title.imageMap = {}
json.data.forEach((it: any) => {
Title.imageMap[it.identification] = it.web_pic_url
})
return Title.imageMap
},
errorAction: () => ({}),
errorMessage: '获取头衔图片失败.',
},
)
if (validateJson(json, '获取头衔图片失败.')) {
Title.imageMap = {}
json.data.forEach((it: any) => {
Title.imageMap[it.identification] = it.web_pic_url
})
return Title.imageMap
}
return {}
}

return Title.imageMap
}
async activate() {
return Badge.parseJson(
const json = JSON.parse(
await postTextWithCredentials(
'https://api.live.bilibili.com/i/ajaxWearTitle',
`id=${this.tid}&cid=${this.cid}&csrf=${getCsrf()}&csrf_token=${getCsrf()}`,
),
{
successAction: () => {
this.isActive = true
return true
},
errorAction: () => false,
errorMessage: '佩戴头衔失败.',
},
)
if (validateJson(json, '佩戴头衔失败.')) {
this.isActive = true
return true
}
return false
}
async deactivate() {
return Badge.parseJson(
const json = JSON.parse(
await postTextWithCredentials(
'https://api.live.bilibili.com/i/ajaxCancelWearTitle',
`csrf=${getCsrf()}&csrf_token=${getCsrf()}`,
),
{
successAction: () => {
this.isActive = false
return true
},
errorAction: () => false,
errorMessage: '卸下头衔失败.',
},
)
if (validateJson(json, '卸下头衔失败.')) {
this.isActive = false
return true
}
return false
}
}
export const getTitleList = async () =>
Badge.parseJson(
export const getTitleList = async (): Promise<Title[]> => {
const json = JSON.parse(
await getTextWithCredentials(
'https://api.live.bilibili.com/i/api/ajaxTitleInfo?page=1&pageSize=256&had=1',
'https://api.live.bilibili.com/xlive/web-ucenter/v1/user_title/TitleList?normal=0&special=0&had=1&page=1&page_size=256',
),
{
successAction: json =>
lodash.get(json, 'data.list', []).map((it: any) => new Title(it)) as Title[],
errorAction: () => [] as Title[],
errorMessage: '无法获取头衔列表.',
},
)
if (validateJson(json, '无法获取头衔列表.')) {
return lodash.get(json, 'data.list', []).map((it: any) => new Title(it))
}
return []
}
1 change: 1 addition & 0 deletions registry/lib/components/live/badge-helper/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
在直播区中, 可从功能面板中直接切换勋章和头衔. 默认显示 256 个 (同时也是上限), 可在选项中修改.
28 changes: 3 additions & 25 deletions registry/lib/components/live/badge-helper/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { defineComponentMetadata } from '@/components/define'
import { getNumberValidator, getUID, none } from '@/core/utils'
import { getUID, none } from '@/core/utils'
import { autoMatchMedal } from './auto-match'
import { badgeHelperOptions } from './options'

export const component = defineComponentMetadata({
name: 'badgeHelper',
displayName: '直播勋章快速更换',
description: {
'zh-CN':
'在直播区中, 可从功能面板中直接切换勋章和头衔. 默认显示 256 个 (同时也是上限), 可在选项中修改.',
},
entry: () => autoMatchMedal(),
reload: none,
unload: none,
Expand All @@ -17,25 +14,6 @@ export const component = defineComponentMetadata({
component: () => import('./BadgeHelper.vue').then(m => m.default),
condition: () => Boolean(getUID()),
},
options: {
autoMatchMedal: {
defaultValue: true,
displayName: '自动佩戴当前直播间勋章',
},
maxBadgeCount: {
defaultValue: 256,
displayName: '最大显示数量',
validator: getNumberValidator(1, 256),
},
defaultMedalID: {
displayName: '默认勋章ID',
hidden: true,
defaultValue: 0,
},
grayEffect: {
displayName: '显示勋章的未点亮状态',
defaultValue: true,
},
},
options: badgeHelperOptions,
urlInclude: ['//live.bilibili.com'],
})
24 changes: 24 additions & 0 deletions registry/lib/components/live/badge-helper/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { OptionsOfMetadata, defineOptionsMetadata } from '@/components/define'
import { getNumberValidator } from '@/core/utils'

export const badgeHelperOptions = defineOptionsMetadata({
autoMatchMedal: {
defaultValue: true,
displayName: '自动佩戴当前直播间勋章',
},
maxBadgeCount: {
defaultValue: 256,
displayName: '最大显示数量',
validator: getNumberValidator(1, 256),
},
defaultMedalID: {
displayName: '默认勋章ID',
hidden: true,
defaultValue: 0,
},
grayEffect: {
displayName: '显示勋章的未点亮状态',
defaultValue: true,
},
})
export type BadgeHelperOptions = OptionsOfMetadata<typeof badgeHelperOptions>

0 comments on commit 5451586

Please sign in to comment.