UNPKG

bilibili-bangumi-component

Version:

展示 bilibili 与 Bangumi 追番列表的 WebComponent 组件

332 lines (331 loc) 12.4 kB
import { h } from "@stencil/core"; import { getBangumi, getBilibili, getCustom } from "../shared/api"; import { thorttle } from "../shared/utils"; import { collectionLabelMap } from "../shared/dataMap"; import { Tabs } from "./Tabs"; import { List } from "./List"; import { Pagination } from "./Pagination"; import { Skeleton } from "./Skeleton"; import { Empty } from "./Empty"; import { Error } from "./Error"; export class BilibiliBangumi { constructor() { this.platformLabels = ['Bilibili', 'Bangumi']; this.subjectLabels = ['动画', '游戏', '书籍']; this.fetchData = async () => { try { this.loading = true; this.error = null; let response; const bilibiliParams = { uid: this.bilibiliUid, collectionType: this.activeCollection, pageSize: this.pageSize, pageNumber: this.pageNumber, }; if (this.activePlatform === 'Bilibili') { response = await getBilibili(this.api, bilibiliParams); } else if (this.activePlatform === 'Bangumi') { response = await getBangumi(this.api, Object.assign(Object.assign({}, bilibiliParams), { uid: this.bgmUid, subjectType: this.activeSubject })); } else { response = await getCustom(this.api, Object.assign(Object.assign({}, bilibiliParams), { subjectType: this.activeSubject })); } if (response.code === 200) { this.responseData = response.data; } else { this.error = response; this.responseData = null; } } catch (error) { this.error = error; this.responseData = null; } this.loading = false; }; this.handlePlatformChange = (label) => { this.collectionLabels = collectionLabelMap['动画']; this.activePlatform = label; this.pageNumber = 1; this.activeSubject = '动画'; this.activeCollection = '全部'; this.fetchData(); }; this.handleSubjectChange = (label) => { this.collectionLabels = collectionLabelMap[label]; this.activeSubject = label; this.pageNumber = 1; this.activeCollection = '全部'; this.fetchData(); }; this.handleCollectionChange = (label) => { this.activeCollection = label; this.pageNumber = 1; this.fetchData(); }; this.scrollToTop = () => { document.documentElement.scrollTo({ top: 0, behavior: 'smooth', }); }; this.handlePageChange = (changeType) => { const { totalPages } = this.responseData; switch (changeType) { case 'head': this.pageNumber = 1; break; case 'prev': if (this.pageNumber === 1) return; this.pageNumber--; break; case 'next': if (this.pageNumber === totalPages) return; this.pageNumber++; break; case 'tail': this.pageNumber = totalPages; break; } this.scrollToTop(); this.fetchData(); }; this.handleInputChange = (event) => { const inputValue = Number.parseInt(event.target.value); if (Object.is(inputValue, Number.NaN)) return; const { totalPages } = this.responseData; if (inputValue < 1) this.pageNumber = 1; else if (inputValue > totalPages) this.pageNumber = totalPages; else this.pageNumber = inputValue; this.scrollToTop(); this.fetchData(); }; this.api = undefined; this.bilibiliUid = undefined; this.bgmUid = undefined; this.bilibiliEnabled = true; this.bgmEnabled = true; this.pageSize = 15; this.customEnabled = false; this.customLabel = '自定义'; this.loading = false; this.error = undefined; this.pageNumber = 1; this.responseData = undefined; this.activePlatform = 'Bilibili'; this.activeSubject = '动画'; this.collectionLabels = ['全部', '想看', '在看', '看过']; this.activeCollection = '全部'; this.containerRef = null; this.containerState = 'large'; } componentWillLoad() { const platformLabels = [...this.platformLabels]; if (this.customEnabled) platformLabels.push(this.customLabel); const filterArr = [this.bilibiliEnabled, this.bgmEnabled, this.customEnabled]; this.platformLabels = platformLabels.filter((_, index) => filterArr[index]); this.activePlatform = this.platformLabels[0]; this.fetchData(); } componentDidLoad() { // 监听容器尺寸变化 const update = thorttle((width) => { let containerState = 'large'; if (width <= 640) containerState = 'middle'; if (width <= 465) containerState = 'small'; this.containerState = containerState; }, 100).bind(this); const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) update(entry.contentRect.width); }); resizeObserver.observe(this.containerRef); } render() { return (h("div", { ref: ele => this.containerRef = ele }, h("div", { class: "bbc-header-platform" }, h(Tabs, { containerState: this.containerState, activeLabel: this.activePlatform, labels: this.platformLabels, onChange: this.handlePlatformChange }), this.activePlatform !== 'Bilibili' && h("div", { class: "divider" }), this.activePlatform !== 'Bilibili' && h(Tabs, { containerState: this.containerState, activeLabel: this.activeSubject, labels: this.subjectLabels, onChange: this.handleSubjectChange })), h("div", null, h(Tabs, { containerState: this.containerState, activeLabel: this.activeCollection, labels: this.collectionLabels, onChange: this.handleCollectionChange })), this.loading && !this.responseData && h(Skeleton, null), this.error && h(Error, { error: this.error }), this.responseData && h(List, { containerState: this.containerState, loading: this.loading, list: this.responseData.list }), this.responseData && this.responseData.total === 0 && h(Empty, null), this.responseData && (h(Pagination, { pageNumber: this.pageNumber, totalPages: this.responseData.totalPages, onChange: this.handlePageChange, onInputChange: this.handleInputChange })))); } static get is() { return "bilibili-bangumi"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["index.css"] }; } static get styleUrls() { return { "$": ["index.css"] }; } static get properties() { return { "api": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "api", "reflect": false }, "bilibiliUid": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "attribute": "bilibili-uid", "reflect": false }, "bgmUid": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "attribute": "bgm-uid", "reflect": false }, "bilibiliEnabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "bilibili-enabled", "reflect": false, "defaultValue": "true" }, "bgmEnabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "bgm-enabled", "reflect": false, "defaultValue": "true" }, "pageSize": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "page-size", "reflect": false, "defaultValue": "15" }, "customEnabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "custom-enabled", "reflect": false, "defaultValue": "false" }, "customLabel": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "custom-label", "reflect": false, "defaultValue": "'\u81EA\u5B9A\u4E49'" } }; } static get states() { return { "loading": {}, "error": {}, "pageNumber": {}, "responseData": {}, "activePlatform": {}, "activeSubject": {}, "collectionLabels": {}, "activeCollection": {}, "containerRef": {}, "containerState": {} }; } }