diff --git a/.eslintrc.json b/.eslintrc.json index 63db096..3ac5a1c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "@luooooob" -} \ No newline at end of file + "extends": "@luooooob" +} diff --git a/package.json b/package.json index ab555d9..da1015c 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,10 @@ { "name": "asoul-notifications", "displayName": "A-SOUL 提醒小助手", - "description": "A-SOUL 成员新动态提醒, 直播状态提醒", "version": "0.6.4", + "description": "A-SOUL 成员新动态提醒, 直播状态提醒", "publisher": "JiangYan", "icon": "logo.png", - "repository": { - "type": "git", - "url": "https://github.com/luooooob/vscode-asoul-notifications.git" - }, "keywords": [ "asoul", "bilibili", @@ -18,6 +14,10 @@ "乃琳", "珈乐" ], + "repository": { + "type": "git", + "url": "https://github.com/luooooob/vscode-asoul-notifications.git" + }, "engines": { "vscode": "^1.60.0" }, @@ -92,9 +92,13 @@ "compile": "tsc -p ./", "watch": "tsc -watch -p ./", "pretest": "npm run compile && npm run lint", - "lint": "eslint src --ext ts", + "lint": "eslint .", "test": "node ./out/test/runTest.js" }, + "dependencies": { + "axios": "^0.24.0", + "node-cron": "^3.0.0" + }, "devDependencies": { "@luooooob/eslint-config": "^0.5.0", "@types/glob": "^7.2.0", @@ -108,9 +112,5 @@ "typescript": "^4.5.2", "vsce": "^2.3.0", "vscode-test": "^1.5.2" - }, - "dependencies": { - "axios": "^0.24.0", - "node-cron": "^3.0.0" } -} \ No newline at end of file +} diff --git a/src/bilibiliDynamics.ts b/src/bilibiliDynamics.ts index f3be78b..3e3ad85 100644 --- a/src/bilibiliDynamics.ts +++ b/src/bilibiliDynamics.ts @@ -1,35 +1,34 @@ -import axios from "axios"; -import * as vscode from "vscode"; -import type { BilibiliDynamic, BilibiliDynamicsResponse, RequstOptions } from "./types"; +import axios from "axios" +import * as vscode from "vscode" +import type { BilibiliDynamic, BilibiliDynamicsResponse, RequstOptions } from "./types" export const requestDynamics = async (bid: number): Promise => { - const url = `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?host_uid=${bid}`; + const url = `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?host_uid=${bid}` return axios .get(url) - .then(res => res.data); -}; + .then(res => res.data) +} export const getDynamicsFromResponse = (res: BilibiliDynamicsResponse, nickname?: string): BilibiliDynamic[] => { return res.data.cards.map(card => { - const { type, dynamic_id_str, user_profile } = card.desc; - const dynamicId = dynamic_id_str; + const { type, dynamic_id_str, user_profile } = card.desc + const dynamicId = dynamic_id_str - const { uname } = user_profile.info; - const name = nickname || uname; - const isVideo = type === 8 || type === 16; - const isArticle = type === 64; + const { uname } = user_profile.info + const name = nickname ?? uname + const isVideo = type === 8 || type === 16 + const isArticle = type === 64 const message = isVideo ? `${name}投稿了新视频` : isArticle ? `${name}投稿了新专栏` - : `${name}有了新动态`; + : `${name}有了新动态` const commands: vscode.Command[] = [{ title: "前往动态", command: "vscode.open", arguments: [vscode.Uri.parse(`https://t.bilibili.com/${dynamic_id_str}`)] - }]; - return { dynamicId, message, commands }; - }); -}; - + }] + return { dynamicId, message, commands } + }) +} diff --git a/src/bilibiliLiveStatus.ts b/src/bilibiliLiveStatus.ts index 2074abc..03d2326 100644 --- a/src/bilibiliLiveStatus.ts +++ b/src/bilibiliLiveStatus.ts @@ -1,47 +1,45 @@ -import * as vscode from "vscode"; -import axios from "axios"; -import { +import * as vscode from "vscode" +import axios from "axios" +import type { BilibiliLiveStatusResponse, - BilibiliLiveStatus, -} from "./types"; + BilibiliLiveStatus +} from "./types" // export const makeLiveStatusRequstOptions = (bid: number) => ({ // url: `https://api.bilibili.com/x/space/acc/info?mid=${bid}` // }); export const requestLiveStatus = async (bid: number): Promise => { - const url = `https://api.bilibili.com/x/space/acc/info?mid=${bid}`; + const url = `https://api.bilibili.com/x/space/acc/info?mid=${bid}` return axios .get(url) - .then(res => res.data); -}; + .then(res => res.data) +} export const getLiveStatusFromResponse = (res: BilibiliLiveStatusResponse, nickname: string | undefined): BilibiliLiveStatus => { - const name = nickname || res.data.name; - const isLive = res.data.live_room.liveStatus === 1; + const name = nickname ?? res.data.name + const isLive = res.data.live_room.liveStatus === 1 if (isLive) { - const url = res.data.live_room.url; - return { name, isLive, url }; + const { url } = res.data.live_room + return { name, isLive, url } } - return { name, isLive }; -}; + return { name, isLive } +} export const displayStatusBar = (statusBarItem: vscode.StatusBarItem, liveStatus: BilibiliLiveStatus) => { if (liveStatus.isLive) { - statusBarItem.text = `--${liveStatus.name}正在直播--`; - statusBarItem.tooltip = "前往直播间"; + statusBarItem.text = `--${liveStatus.name}正在直播--` + statusBarItem.tooltip = "前往直播间" statusBarItem.command = { title: "To Liveroom", - command: 'vscode.open', + command: "vscode.open", arguments: [vscode.Uri.parse(liveStatus.url)] - }; - statusBarItem.show(); + } + statusBarItem.show() } else { - statusBarItem.hide(); + statusBarItem.hide() } -}; - - +} // export const getLiveroomUrl = (id: number) => { // return `https://live.bilibili.com/${id}`; diff --git a/src/douyinVideos.ts b/src/douyinVideos.ts index 74457a3..b64ec84 100644 --- a/src/douyinVideos.ts +++ b/src/douyinVideos.ts @@ -1,26 +1,26 @@ -import axios from "axios"; -import * as vscode from "vscode"; -import type { DouyinVideo, DouyinVideosResponse } from "./types"; +import axios from "axios" +import * as vscode from "vscode" +import type { DouyinVideo, DouyinVideosResponse } from "./types" export const requestVideos = async (did: string): Promise => { - const url = `https://www.iesdouyin.com/web/api/v2/aweme/post/?sec_uid=${did}`; + const url = `https://www.iesdouyin.com/web/api/v2/aweme/post/?sec_uid=${did}` return axios .get(url) - .then(res => res.data); -}; + .then(res => res.data) +} export const getVideosFromResponse = (res: DouyinVideosResponse, nickname?: string): DouyinVideo[] => { return res.aweme_list.map(aweme => { - const { aweme_id, author } = aweme; - const videoId = aweme_id; - const name = nickname || author.nickname; + const { aweme_id, author } = aweme + const videoId = aweme_id + const name = nickname ?? author.nickname - const message = `${name} 投稿了新抖音短视频`; + const message = `${name} 投稿了新抖音短视频` const commands: vscode.Command[] = [{ title: "前往视频", command: "vscode.open", arguments: [vscode.Uri.parse(`https://www.douyin.com/video/${aweme_id}`)] - }]; - return { videoId, message, commands }; - }); -}; \ No newline at end of file + }] + return { videoId, message, commands } + }) +} diff --git a/src/extension.ts b/src/extension.ts index 04087e9..9fa90dc 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,110 +1,109 @@ -import * as cron from "node-cron"; -import * as vscode from 'vscode'; -import * as bilibiliLiveStatus from './bilibiliLiveStatus'; -import * as bilibiliDynamics from './bilibiliDynamics'; -import * as douyinVideos from "./douyinVideos"; -import { AsoulMember, BilibiliUser, DouyinUser } from "./types"; -import { createNotification } from "./notification"; +import * as cron from "node-cron" +import * as vscode from "vscode" +import * as bilibiliLiveStatus from "./bilibiliLiveStatus" +import * as bilibiliDynamics from "./bilibiliDynamics" +import * as douyinVideos from "./douyinVideos" +import type { AsoulMember, BilibiliUser, DouyinUser } from "./types" +import { createNotification } from "./notification" // this method is called when your extension is activated export const activate = (context: vscode.ExtensionContext) => { - const configuration = vscode.workspace.getConfiguration("asoulNotifications"); - const asoulMembers = configuration.get("asoulMembers", []); - - const bilibiliDynamicsNotificationsEnabled = configuration.get("bilibiliDynamics.enabled", false); - const bilibiliLiveStatusNotificationsEnabled = configuration.get("bilibiliLiveStatus.enabled", false); - const douyinVideosNotificationsEnabled = configuration.get("douyinVideos.enabled", false); - - const bilibiliDynamicsCronExpression = "*/2 * * * *"; - const bilibiliLiveStatusCronExpression = "*/2 * * * *"; - const douyinVideosCronExpression = "*/2 * * * *"; - - const bilibiliUsers: BilibiliUser[] = asoulMembers - .reduce((users, { bilibiliId, nickname }) => { - return bilibiliId - ? [...users, { nickname, bilibiliId }] - : users; - }, [] as BilibiliUser[]); - - const douyinUsers: DouyinUser[] = asoulMembers - .reduce((users, { douyinId, nickname }) => { - return douyinId - ? [...users, { nickname, douyinId }] - : users; - - }, [] as DouyinUser[]); - - - const bilibiliDynamicsNotificationsTask = cron.schedule(bilibiliDynamicsCronExpression, () => { - bilibiliUsers.map(async ({ bilibiliId, nickname }) => { - try { - const oldDynamicIdsKey = `old-dynamic-ids-${bilibiliId}`; - const res = await bilibiliDynamics.requestDynamics(bilibiliId); - const oldDynamicIds = context.globalState.get(oldDynamicIdsKey) || []; - const newDynamics = bilibiliDynamics - .getDynamicsFromResponse(res, nickname) - .filter(({ dynamicId }) => (oldDynamicIds.length > 0) && !oldDynamicIds.includes(dynamicId)); - newDynamics.forEach(({ message, commands }) => createNotification(message, ...commands)); - const newDynamicIds = newDynamics.map(({ dynamicId }) => dynamicId); - context.globalState.update(oldDynamicIdsKey, [...oldDynamicIds, ...newDynamicIds]); - } catch (err) { - console.log(err); - } - }); - }, { scheduled: false }); - - if (bilibiliDynamicsNotificationsEnabled) { - bilibiliDynamicsNotificationsTask.start(); - } - - const statusBarItems = bilibiliUsers.map(user => vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left)); - - const bilibiliLiveStatusNotificationsTask = cron.schedule(bilibiliLiveStatusCronExpression, () => { - bilibiliUsers.map(async ({ bilibiliId, nickname }, index) => { - const res = await bilibiliLiveStatus.requestLiveStatus(bilibiliId); - const liveStatus = bilibiliLiveStatus.getLiveStatusFromResponse(res, nickname); - bilibiliLiveStatus.displayStatusBar(statusBarItems[index], liveStatus); - }); - }, { scheduled: false }); - - if (bilibiliLiveStatusNotificationsEnabled) { - bilibiliLiveStatusNotificationsTask.start(); - } - - const douyinVideosNotificationsTask = cron.schedule(douyinVideosCronExpression, () => { - douyinUsers.map(async ({ douyinId, nickname }) => { - try { - const oldVideoIdsKey = `old-video-ids-${douyinId}`; - const res = await douyinVideos.requestVideos(douyinId); - const oldVideoIds = context.globalState.get(oldVideoIdsKey) || []; - const newVideos = douyinVideos - .getVideosFromResponse(res, nickname) - .filter(({ videoId }) => (oldVideoIds.length > 0) && !oldVideoIds.includes(videoId)); - newVideos.forEach(({ message, commands }) => createNotification(message, ...commands)); - const newVideoIds = newVideos.map(({ videoId }) => videoId); - context.globalState.update(oldVideoIdsKey, [...oldVideoIds, ...newVideoIds]); - } catch (err) { - console.log(err); - } - }); - }, { scheduled: false }); - - if (douyinVideosNotificationsEnabled) { - douyinVideosNotificationsTask.start(); - } - - vscode.workspace.onDidChangeConfiguration((ds) => { - if (ds.affectsConfiguration("asoulNotifications")) { - vscode.window - .showInformationMessage("A-SOUL 提醒小助手的配置需要在 VS Code 重启之后生效", "立即重启") - .then(selection => { - if (selection === "立即重启") { - vscode.commands.executeCommand("workbench.action.reloadWindow"); - } - }); - } - }); -}; + const configuration = vscode.workspace.getConfiguration("asoulNotifications") + const asoulMembers = configuration.get("asoulMembers", []) + + const bilibiliDynamicsNotificationsEnabled = configuration.get("bilibiliDynamics.enabled", false) + const bilibiliLiveStatusNotificationsEnabled = configuration.get("bilibiliLiveStatus.enabled", false) + const douyinVideosNotificationsEnabled = configuration.get("douyinVideos.enabled", false) + + const bilibiliDynamicsCronExpression = "*/2 * * * *" + const bilibiliLiveStatusCronExpression = "*/2 * * * *" + const douyinVideosCronExpression = "*/2 * * * *" + + const bilibiliUsers: BilibiliUser[] = asoulMembers + .reduce((users, { bilibiliId, nickname }) => { + return bilibiliId + ? [...users, { nickname, bilibiliId }] + : users + }, [] as BilibiliUser[]) + + const douyinUsers: DouyinUser[] = asoulMembers + .reduce((users, { douyinId, nickname }) => { + return douyinId + ? [...users, { nickname, douyinId }] + : users + + }, [] as DouyinUser[]) + + const bilibiliDynamicsNotificationsTask = cron.schedule(bilibiliDynamicsCronExpression, () => { + bilibiliUsers.map(async ({ bilibiliId, nickname }) => { + try { + const oldDynamicIdsKey = `old-dynamic-ids-${bilibiliId}` + const res = await bilibiliDynamics.requestDynamics(bilibiliId) + const oldDynamicIds = context.globalState.get(oldDynamicIdsKey) ?? [] + const newDynamics = bilibiliDynamics + .getDynamicsFromResponse(res, nickname) + .filter(({ dynamicId }) => oldDynamicIds.length > 0 && !oldDynamicIds.includes(dynamicId)) + newDynamics.forEach(({ message, commands }) => createNotification(message, ...commands)) + const newDynamicIds = newDynamics.map(({ dynamicId }) => dynamicId) + context.globalState.update(oldDynamicIdsKey, [...oldDynamicIds, ...newDynamicIds]) + } catch (err) { + console.log(err) + } + }) + }, { scheduled: false }) + + if (bilibiliDynamicsNotificationsEnabled) { + bilibiliDynamicsNotificationsTask.start() + } + + const statusBarItems = bilibiliUsers.map(user => vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left)) + + const bilibiliLiveStatusNotificationsTask = cron.schedule(bilibiliLiveStatusCronExpression, () => { + bilibiliUsers.map(async ({ bilibiliId, nickname }, index) => { + const res = await bilibiliLiveStatus.requestLiveStatus(bilibiliId) + const liveStatus = bilibiliLiveStatus.getLiveStatusFromResponse(res, nickname) + bilibiliLiveStatus.displayStatusBar(statusBarItems[index], liveStatus) + }) + }, { scheduled: false }) + + if (bilibiliLiveStatusNotificationsEnabled) { + bilibiliLiveStatusNotificationsTask.start() + } + + const douyinVideosNotificationsTask = cron.schedule(douyinVideosCronExpression, () => { + douyinUsers.map(async ({ douyinId, nickname }) => { + try { + const oldVideoIdsKey = `old-video-ids-${douyinId}` + const res = await douyinVideos.requestVideos(douyinId) + const oldVideoIds = context.globalState.get(oldVideoIdsKey) ?? [] + const newVideos = douyinVideos + .getVideosFromResponse(res, nickname) + .filter(({ videoId }) => oldVideoIds.length > 0 && !oldVideoIds.includes(videoId)) + newVideos.forEach(({ message, commands }) => createNotification(message, ...commands)) + const newVideoIds = newVideos.map(({ videoId }) => videoId) + context.globalState.update(oldVideoIdsKey, [...oldVideoIds, ...newVideoIds]) + } catch (err) { + console.log(err) + } + }) + }, { scheduled: false }) + + if (douyinVideosNotificationsEnabled) { + douyinVideosNotificationsTask.start() + } + + vscode.workspace.onDidChangeConfiguration(ds => { + if (ds.affectsConfiguration("asoulNotifications")) { + vscode.window + .showInformationMessage("A-SOUL 提醒小助手的配置需要在 VS Code 重启之后生效", "立即重启") + .then(selection => { + if (selection === "立即重启") { + vscode.commands.executeCommand("workbench.action.reloadWindow") + } + }) + } + }) +} // this method is called when your extension is deactivated -export const deactivate = () => { }; +export const deactivate = () => { } diff --git a/src/notification.ts b/src/notification.ts index 63a65d6..9008c7f 100644 --- a/src/notification.ts +++ b/src/notification.ts @@ -1,12 +1,12 @@ -import * as vscode from "vscode"; +import * as vscode from "vscode" export const createNotification = (message: string, ...commands: vscode.Command[]) => { vscode.window .showInformationMessage(message, ...commands.map(item => item.title)) .then(selection => { - const command = commands.find(item => item.title === selection); + const command = commands.find(item => item.title === selection) if (command) { - vscode.commands.executeCommand(command.command, ...(command.arguments || [])); + vscode.commands.executeCommand(command.command, ...command.arguments ?? []) } - }); -}; + }) +} diff --git a/src/types.ts b/src/types.ts index c9c6752..9457c91 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,21 +1,21 @@ -import type { Command } from "vscode"; +import type { Command } from "vscode" export type RequstOptions = { url: string -}; +} export type AsoulMember = { nickname?: string, bilibiliId?: number, douyinId?: string -}; +} export type BilibiliUser = { nickname?: string bilibiliId: number -}; +} -export interface BilibiliDynamicsResponse { +export type BilibiliDynamicsResponse = { data: { cards: { desc: { @@ -37,9 +37,9 @@ export type BilibiliDynamic = { dynamicId: string message: string commands: Command[] -}; +} -export interface BilibiliLiveStatusResponse { +export type BilibiliLiveStatusResponse = { data: { name: string live_room: { @@ -56,14 +56,14 @@ export type BilibiliLiveStatus = { } | { isLive: true, url: string -}); +}) export type DouyinUser = { nickname?: string douyinId: string -}; +} -export interface DouyinVideosResponse { +export type DouyinVideosResponse = { aweme_list: { aweme_id: string desc: string @@ -71,10 +71,10 @@ export interface DouyinVideosResponse { nickname: string } }[] -}; +} export type DouyinVideo = { videoId: string message: string commands: Command[] -}; +} diff --git a/tsconfig.json b/tsconfig.json index 73ca143..7e85cbf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,21 @@ { - "compilerOptions": { - "module": "commonjs", - "target": "esnext", - "outDir": "out", - "lib": [ - "es6" - ], - "sourceMap": true, - "rootDir": "src", - "strict": true /* enable all strict type-checking options */ - /* Additional Checks */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - }, - "exclude": [ - "node_modules", - ".vscode-test" - ] -} \ No newline at end of file + "compilerOptions": { + "module": "commonjs", + "target": "esnext", + "outDir": "out", + "lib": [ + "es6" + ], + "sourceMap": true, + "rootDir": "src", + "strict": true /* enable all strict type-checking options */ + /* Additional Checks */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +}