mirror of
https://github.com/BewlyBewly/BewlyBewly.git
synced 2025-04-14 13:15:29 +00:00
Merge pull request #434 from cloudflypeng/refactor/background-api
Refactor messageListeners and add utils module to simply use api
This commit is contained in:
@@ -1,57 +1,66 @@
|
||||
import browser from 'webextension-polyfill'
|
||||
import type { APIMAP, _FETCH } from '../utils'
|
||||
import { AHS } from '../utils'
|
||||
|
||||
const API_ANIME: APIMAP = {
|
||||
getPopularAnimeList: {
|
||||
url: 'https://api.bilibili.com/pgc/web/rank/list',
|
||||
_fetch: {
|
||||
method: 'get',
|
||||
},
|
||||
params: {
|
||||
season_type: 1,
|
||||
day: 3,
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
getAnimeWatchList: {
|
||||
url: 'https://api.bilibili.com/x/space/bangumi/follow/list',
|
||||
_fetch: {
|
||||
method: 'get',
|
||||
},
|
||||
params: {
|
||||
pn: 1,
|
||||
ps: 15,
|
||||
type: 1,
|
||||
follow_status: 0,
|
||||
vmid: '',
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
getRecommendAnimeList: {
|
||||
url: 'https://api.bilibili.com/pgc/page/web/v3/feed',
|
||||
_fetch: {
|
||||
method: 'get',
|
||||
},
|
||||
params: {
|
||||
coursor: '',
|
||||
name: 'anime',
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
getAnimeTimeTable: {
|
||||
url: 'https://api.bilibili.com/pgc/web/timeline',
|
||||
_fetch: {
|
||||
method: 'get',
|
||||
},
|
||||
params: {
|
||||
types: 1,
|
||||
before: 6,
|
||||
after: 6,
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
getAnimeDetail: {
|
||||
url: 'https://api.bilibili.com/pgc/view/web/season',
|
||||
_fetch: {
|
||||
method: 'get',
|
||||
},
|
||||
params: {
|
||||
ep_id: '234406',
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
|
||||
function handleMessage(message: any) {
|
||||
// get popular anime list
|
||||
if (message.contentScriptQuery === 'getPopularAnimeList') {
|
||||
const url
|
||||
= 'https://api.bilibili.com/pgc/web/rank/list?season_type=1&day=3'
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/36e250090800793b41b223b55eefdcbb9391b53e/user/space.md#%E6%9F%A5%E8%AF%A2%E7%94%A8%E6%88%B7%E8%BF%BD%E7%95%AA%E8%BF%BD%E5%89%A7%E6%98%8E%E7%BB%86
|
||||
else if (message.contentScriptQuery === 'getAnimeWatchList') {
|
||||
const url = `https://api.bilibili.com/x/space/bangumi/follow/list?type=1&follow_status=0&pn=${message.pn}&ps=${message.ps}&vmid=${message.vmid}`
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
else if (message.contentScriptQuery === 'getRecommendAnimeList') {
|
||||
const url = `https://api.bilibili.com/pgc/page/web/v3/feed?name=anime&coursor=${
|
||||
message.coursor ?? ''
|
||||
}`
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/bangumi/timeline.md#%E7%95%AA%E5%89%A7%E6%88%96%E5%BD%B1%E8%A7%86%E6%97%B6%E9%97%B4%E7%BA%BF
|
||||
else if (message.contentScriptQuery === 'getAnimeTimeTable') {
|
||||
const url
|
||||
= 'https://api.bilibili.com/pgc/web/timeline?types=1&before=6&after=6'
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
else if (message.contentScriptQuery === 'getAnimeDetail') {
|
||||
const url = 'https://api.bilibili.com/pgc/view/web/season?ep_id=234406'
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
// TODO: https://api.bilibili.com/pgc/season/index/condition?season_type=1&type=1
|
||||
}
|
||||
|
||||
function handleConnect() {
|
||||
browser.runtime.onMessage.removeListener(handleMessage)
|
||||
browser.runtime.onMessage.addListener(handleMessage)
|
||||
}
|
||||
|
||||
export function setupAnimeMsgLstnr() {
|
||||
browser.runtime.onConnect.removeListener(handleConnect)
|
||||
browser.runtime.onConnect.addListener(handleConnect)
|
||||
}
|
||||
export default API_ANIME
|
||||
|
||||
@@ -1,81 +1,74 @@
|
||||
import browser from 'webextension-polyfill'
|
||||
import type { APIMAP, _FETCH } from '../utils'
|
||||
import { AHS } from '../utils'
|
||||
|
||||
function handleMessage(message: any) {
|
||||
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/history.md#%E8%8E%B7%E5%8F%96%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95%E5%88%97%E8%A1%A8_web%E7%AB%AF
|
||||
if (message.contentScriptQuery === 'getHistoryList') {
|
||||
const url = `https://api.bilibili.com/x/web-interface/history/cursor?ps=20&type=${message.type}&view_at=${message.viewAt}`
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
else if (message.contentScriptQuery === 'searchHistoryList') {
|
||||
const url = `https://api.bilibili.com/x/web-goblin/history/search?pn=${message.pn}&keyword=${message.keyword}&business=all`
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/history.md#%E5%88%A0%E9%99%A4%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95
|
||||
else if (message.contentScriptQuery === 'deleteHistoryItem') {
|
||||
const url = 'https://api.bilibili.com/x/v2/history/delete'
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
const API_HISTORY: APIMAP = {
|
||||
getHistoryList: {
|
||||
url: 'https://api.bilibili.com/x/web-interface/history/cursor',
|
||||
_fetch: {
|
||||
method: 'get',
|
||||
},
|
||||
params: {
|
||||
ps: 20,
|
||||
type: '',
|
||||
view_at: '',
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
searchHistoryList: {
|
||||
url: 'https://api.bilibili.com/x/web-goblin/history/search',
|
||||
_fetch: {
|
||||
method: 'get',
|
||||
},
|
||||
params: {
|
||||
pn: 1,
|
||||
keyword: '',
|
||||
business: 'all',
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
deleteHistoryItem: {
|
||||
url: 'https://api.bilibili.com/x/v2/history/delete',
|
||||
_fetch: {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
kid: message.kid,
|
||||
csrf: message.csrf,
|
||||
}),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/history.md#%E6%B8%85%E7%A9%BA%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95
|
||||
else if (message.contentScriptQuery === 'clearAllHistory') {
|
||||
const url = 'https://api.bilibili.com/x/v2/history/clear'
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
csrf: message.csrf,
|
||||
}),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/history.md#%E6%9F%A5%E8%AF%A2%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95%E5%81%9C%E7%94%A8%E7%8A%B6%E6%80%81
|
||||
else if (message.contentScriptQuery === 'getHistoryPauseStatus') {
|
||||
const url = 'https://api.bilibili.com/x/v2/history/shadow'
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/history.md#%E5%81%9C%E7%94%A8%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95
|
||||
else if (message.contentScriptQuery === 'setHistoryPauseStatus') {
|
||||
const url = 'https://api.bilibili.com/x/v2/history/shadow/set'
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
switch: message.switch,
|
||||
csrf: message.csrf,
|
||||
}),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => data)
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
},
|
||||
params: {
|
||||
kid: '',
|
||||
csrf: '',
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
clearAllHistory: {
|
||||
url: 'https://api.bilibili.com/x/v2/history/clear',
|
||||
_fetch: {
|
||||
method: 'post',
|
||||
},
|
||||
params: {
|
||||
csrf: '',
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
getHistoryPauseStatus: {
|
||||
url: 'https://api.bilibili.com/x/v2/history/shadow',
|
||||
_fetch: {
|
||||
method: 'get',
|
||||
},
|
||||
params: {},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
setHistoryPauseStatus: {
|
||||
url: 'https://api.bilibili.com/x/v2/history/shadow/set',
|
||||
_fetch: {
|
||||
method: 'post',
|
||||
},
|
||||
params: {
|
||||
switch: '',
|
||||
csrf: '',
|
||||
},
|
||||
afterHandle: AHS.J_D,
|
||||
},
|
||||
}
|
||||
|
||||
function handleConnect() {
|
||||
browser.runtime.onMessage.removeListener(handleMessage)
|
||||
browser.runtime.onMessage.addListener(handleMessage)
|
||||
}
|
||||
|
||||
export function setupHistoryMsgLstnr() {
|
||||
browser.runtime.onConnect.removeListener(handleConnect)
|
||||
browser.runtime.onConnect.addListener(handleConnect)
|
||||
}
|
||||
export default API_HISTORY
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { setupAnimeMsgLstnr } from './anime'
|
||||
import browser from 'webextension-polyfill'
|
||||
import { apiListenerFactory } from '../utils'
|
||||
import API_ANIME from './anime'
|
||||
import { setupAuthMsgLstnr } from './auth'
|
||||
import { setupVideoMsgLstnr } from './video'
|
||||
import { setupUserMsgLstnr } from './user'
|
||||
import { setupSearchMsgLstnr } from './search'
|
||||
import { setupNotificationMsgLstnr } from './notification'
|
||||
import { setupMomentMsgLstnr } from './moment'
|
||||
import { setupHistoryMsgLstnr } from './history'
|
||||
import API_HISTORY from './history'
|
||||
import { setupFavoriteMsgLstnr } from './favorite'
|
||||
import { setupWatchLaterMsgLstnr } from './watchLater'
|
||||
import { setupRankingMsgLstnr } from './ranking'
|
||||
@@ -17,9 +19,16 @@ export function setupAllMsgLstnrs() {
|
||||
setupSearchMsgLstnr()
|
||||
setupNotificationMsgLstnr()
|
||||
setupMomentMsgLstnr()
|
||||
setupHistoryMsgLstnr()
|
||||
setupFavoriteMsgLstnr()
|
||||
setupAnimeMsgLstnr()
|
||||
setupWatchLaterMsgLstnr()
|
||||
setupRankingMsgLstnr()
|
||||
|
||||
// 上面的会全部删除, 每个文件只保留定义API 的对象, 在这里进行mixin
|
||||
// 然后整个开始监听
|
||||
|
||||
const FullAPI = Object.assign({}, API_ANIME, API_HISTORY)
|
||||
|
||||
const handleMessage = apiListenerFactory(FullAPI)
|
||||
browser.runtime.onMessage.removeListener(handleMessage)
|
||||
browser.runtime.onMessage.addListener(handleMessage)
|
||||
}
|
||||
|
||||
100
src/background/utils.ts
Normal file
100
src/background/utils.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
// 对于fetch的常见后处理
|
||||
// 1. 直接返回data
|
||||
// 2. json化后返回data
|
||||
|
||||
type FetchAfterHandler = ((data: Response) => Promise<any>) | ((data: any) => any)
|
||||
|
||||
function toJsonHandler(data: Response): Promise<any> {
|
||||
return data.json()
|
||||
}
|
||||
function toData(data: Promise<any>): Promise<any> {
|
||||
return data
|
||||
}
|
||||
|
||||
// if need sendResponse, use this
|
||||
function sendResponseHandler(sendResponse: any) {
|
||||
return (data: any) => sendResponse(data)
|
||||
}
|
||||
|
||||
// 定义后处理流
|
||||
const AHS: {
|
||||
J_D: FetchAfterHandler[]
|
||||
J_S: FetchAfterHandler[]
|
||||
} = {
|
||||
J_D: [toJsonHandler, toData],
|
||||
J_S: [toJsonHandler, sendResponseHandler],
|
||||
}
|
||||
|
||||
interface Message {
|
||||
contentScriptQuery: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
interface _FETCH {
|
||||
method: string
|
||||
headers?: {
|
||||
[key: string]: any
|
||||
}
|
||||
body?: any
|
||||
}
|
||||
|
||||
interface API {
|
||||
url: string
|
||||
_fetch: _FETCH
|
||||
params: {
|
||||
[key: string]: any
|
||||
}
|
||||
afterHandle: ((response: Response) => Response | Promise<Response>)[]
|
||||
}
|
||||
interface APIMAP {
|
||||
[key: string]: API
|
||||
}
|
||||
// 工厂函数API_LISTENER_FACTORY
|
||||
function apiListenerFactory(API_MAP: APIMAP) {
|
||||
return (message: Message) => {
|
||||
if (API_MAP[message?.contentScriptQuery]) {
|
||||
try {
|
||||
let { contentScriptQuery, ...rest } = message
|
||||
rest = rest || {}
|
||||
const { _fetch, url, params, afterHandle } = API_MAP[contentScriptQuery] as API
|
||||
const { method, headers, body } = _fetch as _FETCH
|
||||
const targetParams = Object.assign({}, params, rest)
|
||||
let targetUrl = url
|
||||
let targetBody = Object.assign({}, body)
|
||||
|
||||
if (method === 'get') {
|
||||
const urlParams = new URLSearchParams()
|
||||
for (const key in targetParams)
|
||||
urlParams.append(key, targetParams[key])
|
||||
targetUrl += `?${urlParams.toString()}`
|
||||
}
|
||||
else {
|
||||
targetBody = JSON.stringify(targetParams)
|
||||
}
|
||||
// get cant take body
|
||||
const fetchOpt = method === 'get' ? { method, headers } : { method, headers, body: targetBody }
|
||||
let baseFunc = fetch(targetUrl, fetchOpt)
|
||||
afterHandle.forEach(func => baseFunc = baseFunc.then(func))
|
||||
baseFunc.catch(console.error)
|
||||
|
||||
return baseFunc
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
FetchAfterHandler,
|
||||
toJsonHandler,
|
||||
toData,
|
||||
sendResponseHandler,
|
||||
AHS,
|
||||
Message,
|
||||
_FETCH,
|
||||
API,
|
||||
APIMAP,
|
||||
apiListenerFactory,
|
||||
}
|
||||
Reference in New Issue
Block a user