const STORAGE_PATH = `data/.cache/${Plugin.id}_repos.json`
/* 触发器 手动触发 */
const onRun = async () => {
const component = {
template: `
`,
setup() {
const { ref, onMounted } = Vue
const input = ref('')
const loading = ref(false)
const repos = ref([])
const comments = ref([])
async function loadRepos() {
const content = await Plugins.ReadFile(STORAGE_PATH).catch(() => '')
if (content) {
try {
repos.value = JSON.parse(content)
} catch (e) {
console.log(`[${Plugin.name}]`, '解析 repos.json 失败: ', e)
}
}
}
async function saveRepos() {
try {
await Plugins.WriteFile(STORAGE_PATH, JSON.stringify(repos.value, null, 2))
} catch (e) {
console.log(`[${Plugin.name}]`, '保存 repos.json 失败: ', e)
}
}
async function fetchCommitsForRepo(repo) {
// repo 可能是 "owner/repo" 或 "owner/repo@branch"
const [fullRepo, branch = ''] = repo.split('@')
const [owner, repoName] = fullRepo.split('/')
const url = `https://api.github.com/repos/${owner}/${repoName}/commits?per_page=20${branch ? `&sha=${encodeURIComponent(branch)}` : ''}`
const { status, body } = await Plugins.HttpGet(url, {
Accept: 'application/vnd.github.v3+json',
Authorization: Plugin.TOKEN_MODE === 'gui' ? Plugins.getGitHubApiAuthorization() : Plugin.TOKEN_MODE === 'plugin' ? `Bearer ${Plugin.TOKEN}` : ''
})
if (status < 200 || status >= 300) {
throw new Error(`获取 ${repo} 提交失败,状态码 ${status}`)
}
return body
}
async function handleAddRepo() {
const repo = input.value.trim()
if (!repo) return
repos.value.push({ name: repo, hash: '' })
await saveRepos()
input.value = ''
}
async function handleRemoveRepo(index) {
repos.value.splice(index, 1)
await saveRepos()
}
async function handleChange(repo) {
comments.value = []
loading.value = true
try {
const res = await fetchCommitsForRepo(repo.name)
const lastHashIndex = res.findIndex((v) => v.sha === repo.hash)
if (lastHashIndex !== -1) {
res.forEach((comment, index) => {
if (index >= lastHashIndex) {
comment.selected = true
}
})
}
comments.value = res
if (res[0]?.sha) {
repo.hash = res[0]?.sha
await saveRepos()
}
} catch (e) {
Plugins.message.error(e.message || e)
} finally {
loading.value = false
}
}
onMounted(() => loadRepos())
return {
loading,
input,
repos,
comments,
handleAddRepo,
handleRemoveRepo,
handleChange,
formatTime(d) {
return Plugins.formatRelativeTime(d)
},
handleView(c, url) {
c.selected = true
Plugins.BrowserOpenURL(url)
},
getMessage(msg) {
return msg.split('\n')[0]
}
}
}
}
const modal = Plugins.modal(
{
title: Plugin.name,
maskClosable: true,
submit: false,
cancelText: 'common.close',
width: '90',
height: '90'
},
{
default: () => Vue.h(component)
}
)
modal.open()
}