bilibili-bangumi-component
Version:
展示 bilibili 与 Bangumi 追番列表的 WebComponent 组件
332 lines (331 loc) • 12.6 kB
JavaScript
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 = label === 'Bilibili' ? ['全部', '想看', '在看', '看过'] : collectionLabelMap['动画'];
this.activePlatform = label;
this.pageNumber = 1;
this.activeSubject = '动画';
this.activeCollection = '全部';
this.fetchData();
};
this.handleSubjectChange = (label) => {
this.collectionLabels = this.activePlatform === 'Bilibili' ? ['全部', '想看', '在看', '看过'] : 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 && 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": {}
};
}
}