diff --git a/auto-imports.d.ts b/auto-imports.d.ts
index 08908ed..a51b7a6 100644
--- a/auto-imports.d.ts
+++ b/auto-imports.d.ts
@@ -1,5 +1,5 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
-
+ const ElNotification: typeof import('element-plus/es')['ElNotification']
}
diff --git a/components.d.ts b/components.d.ts
index 906442f..f7cd2b0 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -7,14 +7,29 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
+ ASider: typeof import('./src/components/ASider.vue')['default']
Config: typeof import('./src/components/Config.vue')['default']
DisplaySVG: typeof import('./src/components/DisplaySVG.vue')['default']
+ ElAlert: typeof import('element-plus/es')['ElAlert']
+ ElAside: typeof import('element-plus/es')['ElAside']
+ ElButton: typeof import('element-plus/es')['ElButton']
+ ElContainer: typeof import('element-plus/es')['ElContainer']
+ ElDivider: typeof import('element-plus/es')['ElDivider']
+ ElFooter: typeof import('element-plus/es')['ElFooter']
+ ElHeader: typeof import('element-plus/es')['ElHeader']
+ ElIcon: typeof import('element-plus/es')['ElIcon']
+ ElInput: typeof import('element-plus/es')['ElInput']
+ ElLink: typeof import('element-plus/es')['ElLink']
+ ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
- ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
+ ElSapce: typeof import('element-plus/es')['ElSapce']
+ ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
+ ElSpace: typeof import('element-plus/es')['ElSpace']
Footer: typeof import('./src/components/Footer.vue')['default']
}
export interface ComponentCustomProperties {
+ vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll']
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}
diff --git a/config.ts b/config.ts
index 862a54d..dc63097 100644
--- a/config.ts
+++ b/config.ts
@@ -1,8 +1,8 @@
-import { ConfigItem } from "./src/types"
+import { ConfigItem } from "@/types"
/**
* Github user custom contributors svg here
- * ignore: {array} if you need ignore some users
+ * ignore: {array} if you need ignore some users.
* height: svg height
* width: svg width
* fontSize: svg login name width
@@ -33,7 +33,7 @@ const config: ConfigItem =
'LinusBorg', 'KiritaniAyaka', 'Alex-Sokolov', 'sdras', 'marina-mosti', 'CyberAP',
'LinusBorg', 'KiritaniAyaka', 'Alex-Sokolov', 'sdras', 'marina-mosti', 'CyberAP',
'danielkellyio', 'tylermercer',
- ], // if you need ignore some users
+ ], // if you need ignore some users.
// users: [],?? maybe we need this field.
ignoreTotal: 1, // 过滤低于这个 total 的用户
size: 100,
@@ -48,7 +48,7 @@ const config: ConfigItem =
'yyx990803', 'NataliaTepluhina', 'skirtles-code', 'bencodezen', 'dependabot[bot]',
'LinusBorg', 'KiritaniAyaka', 'Alex-Sokolov', 'sdras', 'marina-mosti', 'CyberAP',
'danielkellyio', 'tylermercer',
- ], // if you need ignore some users
+ ], // if you need ignore some users..
// users: [],?? maybe we need this field.
ignoreTotal: 1, // 过滤低于这个 total 的用户
size: 100,
@@ -64,7 +64,7 @@ const config: ConfigItem =
'yyx990803', 'NataliaTepluhina', 'skirtles-code', 'bencodezen', 'dependabot[bot]',
'LinusBorg', 'KiritaniAyaka', 'Alex-Sokolov', 'sdras', 'marina-mosti', 'CyberAP',
'danielkellyio', 'tylermercer',
- ], // if you need ignore some users
+ ], // if you need ignore some users.
// users: [],?? maybe we need this field.
ignoreTotal: 1, // 过滤低于这个 total 的用户
size: 100,
@@ -73,14 +73,14 @@ const config: ConfigItem =
fontSize: 30,
// isRadius: false,
},
-
+
// https://github.com/vuejs-translations/docs-zh-cn
'vuejs-translations/veaba2': {
ignore: [
'yyx990803', 'NataliaTepluhina', 'skirtles-code', 'bencodezen', 'dependabot[bot]',
'LinusBorg', 'KiritaniAyaka', 'Alex-Sokolov', 'sdras', 'marina-mosti', 'CyberAP',
'danielkellyio', 'tylermercer',
- ], // if you need ignore some users
+ ], // if you need ignore some users.
// users: [],?? maybe we need this field.
ignoreTotal: 1, // 过滤低于这个 total 的用户
size: 100,
@@ -89,14 +89,14 @@ const config: ConfigItem =
fontSize: 30,
// isRadius: false,
},
-
+
// https://github.com/vuejs-translations/docs-zh-cn
'vuejs-translations/veaba3': {
ignore: [
'yyx990803', 'NataliaTepluhina', 'skirtles-code', 'bencodezen', 'dependabot[bot]',
'LinusBorg', 'KiritaniAyaka', 'Alex-Sokolov', 'sdras', 'marina-mosti', 'CyberAP',
'danielkellyio', 'tylermercer',
- ], // if you need ignore some users
+ ], // if you need ignore some users.
// users: [],?? maybe we need this field.
ignoreTotal: 1, // 过滤低于这个 total 的用户
size: 100,
@@ -105,14 +105,14 @@ const config: ConfigItem =
fontSize: 30,
// isRadius: false,
},
-
+
// https://github.com/vuejs-translations/docs-zh-cn
'vuejs-translations/veaba4': {
ignore: [
'yyx990803', 'NataliaTepluhina', 'skirtles-code', 'bencodezen', 'dependabot[bot]',
'LinusBorg', 'KiritaniAyaka', 'Alex-Sokolov', 'sdras', 'marina-mosti', 'CyberAP',
'danielkellyio', 'tylermercer',
- ], // if you need ignore some users
+ ], // if you need ignore some users.
// users: [],?? maybe we need this field.
ignoreTotal: 1, // 过滤低于这个 total 的用户
size: 100,
@@ -121,14 +121,14 @@ const config: ConfigItem =
fontSize: 30,
// isRadius: false,
},
-
+
// https://github.com/vuejs-translations/docs-zh-cn
'vuejs-translations/veaba5': {
ignore: [
'yyx990803', 'NataliaTepluhina', 'skirtles-code', 'bencodezen', 'dependabot[bot]',
'LinusBorg', 'KiritaniAyaka', 'Alex-Sokolov', 'sdras', 'marina-mosti', 'CyberAP',
'danielkellyio', 'tylermercer',
- ], // if you need ignore some users
+ ], // if you need ignore some users.
// users: [],?? maybe we need this field.
ignoreTotal: 1, // 过滤低于这个 total 的用户
size: 100,
diff --git a/index.html b/index.html
index eabb007..d5d5bfe 100644
--- a/index.html
+++ b/index.html
@@ -1,17 +1,22 @@
-
+
-
-
-
- A automatic generate Github Repository contributor group photo tool
+
+
+
+ A automatic generate Github Repository contributor group photo tool
+
-
-
+
+
-
\ No newline at end of file
+
diff --git a/src/App.vue b/src/App.vue
index d391b0c..083f1bd 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -6,11 +6,18 @@ import Home from './pages/Home.vue'
-
diff --git a/src/actions/README.md b/src/actions/README.md
new file mode 100644
index 0000000..331b6a6
--- /dev/null
+++ b/src/actions/README.md
@@ -0,0 +1,2 @@
+# A github-actions for generate github repo's contributors pictures
+
diff --git a/src/components/ASider.vue b/src/components/ASider.vue
index 45a45b5..42cb774 100644
--- a/src/components/ASider.vue
+++ b/src/components/ASider.vue
@@ -1,30 +1,26 @@
-
+
- SVG veaba/contributor demo
-
-
-
-
+
+ Download the SVG
+
-
-
+
+
diff --git a/src/components/Footer.vue b/src/components/Footer.vue
index 623a6ec..d204497 100644
--- a/src/components/Footer.vue
+++ b/src/components/Footer.vue
@@ -1,7 +1,7 @@
-
-
diff --git a/src/core/app.ts b/src/core/app.ts
index 6e3fbdb..02606d7 100644
--- a/src/core/app.ts
+++ b/src/core/app.ts
@@ -1,34 +1,19 @@
-
-// 1. get the repo's contributors list
-// 2. generate svg
-// 3. save to local
-// 4. 根据仓库地址,会保存头像在本地,如果通过actions 触发后,通过对比,本地存在头像则不会再更新
-// 4.1 第4点中,bug:如果用户更新,则还是旧头像。出现用户头像,除非用头像生成 md5 存储作为指纹
-// import { http } from 'node:http'
-
-import { writeFile } from 'node:fs/promises';
-import { chunk } from 'lodash';
-import { svgStart, svgEnd, asyncHandleUsersSVG, asyncHandlerUserDefsSVG } from './svg';
-import { listTen } from '../../tests/mock'
-import { UserConfig, UserItem } from '../types';
-import { getOwnerRepo } from '../utils';
-
-import config from '../../config'
-import console from 'node:console';
+import {chunk} from 'lodash';
+import {svgStart, svgEnd, asyncHandleUsersSVG, asyncHandlerUserDefsSVG} from './svg';
+import {UserConfig, UserItem} from '@/types';
// global constants
const SVG_WIDTH = 800;
-const SVG_HEIGHT = 370;
-const FONT_SIZE = 0
+const FONT_SIZE = 20
const BASE_SIZE = 100
-const generateUserListSVG = async (userList: UserItem[], config: UserConfig) => {
+export const generateUserListSVG = async (userList: UserItem[], config: UserConfig) => {
- // split => two dimensional array
+ // split => two-dimensional array
let splitList: UserItem[] | UserItem[][] = userList
const svgWidth = config.width || SVG_WIDTH
- const svgHeight = config.height || SVG_HEIGHT
+ // const svgHeight = config.height
const baseSize = config.size || BASE_SIZE
const fontSize = config.fontSize || FONT_SIZE
@@ -41,6 +26,10 @@ const generateUserListSVG = async (userList: UserItem[], config: UserConfig) =>
splitList = chunk(userList, oneRowMax)
}
+ // TODO => 計算不對
+ console.info('splitList=>', splitList, splitList.length + 1, outSize + 5);
+ const svgHeight = (splitList.length + 1) * (outSize + 5)
+
const svgConfig = {
baseSize,
fontSize,
@@ -52,7 +41,7 @@ const generateUserListSVG = async (userList: UserItem[], config: UserConfig) =>
}
// radius
- if (config.isRadius === undefined || config.isRadius === true) {
+ if (config.isRadius === undefined || config.isRadius) {
return `${svgStart(svgWidth, svgHeight)}
${await asyncHandlerUserDefsSVG(splitList, svgConfig)}
@@ -61,7 +50,7 @@ const generateUserListSVG = async (userList: UserItem[], config: UserConfig) =>
${await asyncHandleUsersSVG(splitList, svgConfig)}
${svgEnd()}
`
- } else if (config.isRadius === false) {
+ } else if (!config.isRadius) {
const userBlockData = await asyncHandleUsersSVG(splitList, svgConfig)
return `${svgStart(svgWidth, svgHeight)}
${userBlockData}
@@ -70,26 +59,3 @@ ${svgEnd()}
}
return ''
}
-
-export const saveSVG = async (ownerRepo: string, repoUserList: UserItem[]) => {
- console.log('saveSVG=>', ownerRepo, repoUserList.length)
- const { owner, repo } = getOwnerRepo && getOwnerRepo(ownerRepo) || {}
- if (!owner || !repo) {
- console.error('Invalid repo address:', ownerRepo)
- return
- }
-
- const userConfig: UserConfig = config[ownerRepo]
- try {
- // const controller = new AbortController();
- const svgStr = await generateUserListSVG(repoUserList, userConfig)
-
- const filename = `./repos/${owner}/${repo}.svg`
- await writeFile(filename, svgStr, { encoding: 'utf-8' })
- } catch (error) {
- console.error('err=>', error)
- }
-}
-
-// saveSVG('veaba/contributors',listTen)
-// saveSVG('vuejs-translations/docs-zh-cn',listTen)
diff --git a/src/core/circle.ts b/src/core/circle.ts
deleted file mode 100644
index 2824975..0000000
--- a/src/core/circle.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * @TODO
-*
-*/
-export const getCircleX = () => {
-
-}
-
-export const getCircleY = () => {
-
-}
\ No newline at end of file
diff --git a/src/core/github.ts b/src/core/github.ts
index 0432b5b..a182a0d 100644
--- a/src/core/github.ts
+++ b/src/core/github.ts
@@ -2,7 +2,7 @@ import axios from "axios"
import { createWriteStream } from 'node:fs'
import { resolve } from 'path'
-import { MD5Item, UserConfig, UserItem } from "../types"
+import { UserConfig, UserItem } from "../types"
import { sortBy } from 'lodash'
import { data } from '../../tests/mock'
import { getTotalList, getOwnerRepo } from "../utils"
diff --git a/src/core/image.ts b/src/core/image.ts
deleted file mode 100644
index 7a33662..0000000
--- a/src/core/image.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { readFile } from 'node:fs/promises'
-/**
- * save image locally
- *
-*/
-
-/**
- * locally image to base64
- *
-*/
-export const imagePathToBase64 = async (imagePath: string) => {
- const imageBuffer = await readFile(imagePath)
- return imageBuffer.toString('base64')
-}
\ No newline at end of file
diff --git a/src/core/index.ts b/src/core/index.ts
deleted file mode 100644
index 60bec58..0000000
--- a/src/core/index.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import config from '../../config'
-import { resolve } from 'path'
-import { saveSVG } from './app';
-import { writeFile, access } from "node:fs/promises" // access
-import { downloadAvatar, getRepoData } from './github';
-import { MD5Item, UserItem } from '../types';
-// import { isHasFile, readMD5 } from "../utils"
-
-import md5JSON from '../../public/avatars/avatarsMD5.json'
-
-const md5s: any = md5JSON
-
-interface TypesContributors {
- repo: string;
-}
-
-const updateAvatars = async (sortList: UserItem[]) => {
- await Promise.all(sortList.map(async userItem => {
-
- const isHas = await isHasFile(resolve(__dirname, `../public/avatars/${userItem.id}.jpg`))
- if (!isHas) {
- return await downloadAvatar(userItem)
- }
- // const md5Item: MD5Item = md5s[userItem.id] || {}
- // const filename = md5Item.filename || userItem.id + '.jpg'
- // let { md5 } = md5Item
- // TODO 开销较大,暂时移除
- // if (md5) {
- // // const readAvatarMD5 = await readMD5(filename)
- // // // 两个 md5 不相等,需要 download 文件,并更改 md5 的值
- // // if (readAvatarMD5 !== md5) {
- // // md5 = readAvatarMD5
- // // await downloadAvatar(userItem)
- // // md5Item.md5 = readAvatarMD5
- // // const buffer = Buffer.from(JSON.stringify(md5s));
- // // await writeFile(resolve(__dirname, `../public/avatars/avatarsMD5.json`), buffer, 'utf-8')
- // // }
- // return Promise.resolve()
- // } else {
- // md5s[userItem.id] = {
- // filename: `${userItem.id}.jpg`,
- // md5: await readMD5(filename)
- // }
- // await downloadAvatar(userItem)
- // const buffer = Buffer.from(JSON.stringify(md5s));
- // await writeFile(resolve(__dirname, `../public/avatars/avatarsMD5.json`), buffer, 'utf-8')
- // return Promise.resolve()
- // }
- }))
-}
-
-export const serverStart = async () => {
- const now = Date.now()
- console.log('开始=>', new Date())
-
- console.time('task=>')
- const repos = Object.keys(config)
- // const reposConfigs = Object.values(config)
-
- await Promise.all(repos.map(async repo => {
- const repoConfig = config[repo]
- const repoList = await getRepoData(repo, repoConfig)
- await updateAvatars(repoList)
- await saveSVG(repo, repoList)
- }))
-
- console.timeEnd('task=>')
- console.log('结束=>', new Date(), Date.now() - now)
-
-
-}
-
-// serverStart()
diff --git a/src/core/svg.ts b/src/core/svg.ts
index ccb66b9..1cfe1fa 100644
--- a/src/core/svg.ts
+++ b/src/core/svg.ts
@@ -1,6 +1,5 @@
-import { imagePathToBase64 } from "./image"
-import { ImageXYItem, SvgConfig, UserItem, XYItem } from "../types"
-import { autoCenter, getImageX, getImageY, getTextX, getTextY } from "../utils"
+import {ImageXYItem, SvgConfig, UserItem, XYItem} from "../types"
+import {autoCenter, getImageX, getImageY, getTextX, getTextY} from "../utils"
export const svgStart = (width: number, height: number) => {
return `