Skip to content

Commit d9d1f8b

Browse files
authored
Merge pull request #217 from faweizhao26/contributor
Add contributors wall page
2 parents 8a9b382 + a8d5d6b commit d9d1f8b

8 files changed

Lines changed: 879 additions & 1 deletion

File tree

docusaurus.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ const config = {
198198
href: 'https://atomgit.com/IvorySQL/IvorySQL',
199199
label: 'GitCode',
200200
},
201+
{
202+
label: 'Contributors',
203+
to: '/contributors',
204+
},
201205
]
202206
},
203207
{

i18n/zh-CN/docusaurus-plugin-content-pages/community-page.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ IvorySQL社区包括来自世界各地的开发和使用开源数据库的人员
1919
- [提交bug](https://github.com/IvorySQL/IvorySQL/issues/new/choose)
2020
- [提交拉取请求](https://github.com/IvorySQL/IvorySQL/pulls)
2121

22+
## 贡献者墙
23+
[贡献者墙](/zh-cn/contributors) 认识正在推动 IvorySQL 前进的社区贡献者。
24+
2225
## 对话
2326
Hey everybody!
2427
中国IvorySQL开源数据库社区已经成立啦!如果想要加入IvorySQL中国技术交流群,可添加IvorySQL小助理微信:IvorySQL_official

i18n/zh-CN/docusaurus-theme-classic/navbar.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
"message": "开发者",
1616
"description": "Navbar item with label Developers"
1717
},
18+
"item.label.Contributors": {
19+
"message": "贡献者",
20+
"description": "Navbar item with label Contributors"
21+
},
1822
"item.label.Download": {
1923
"message": "下载",
2024
"description": "Navbar item with label Download"
@@ -96,4 +100,3 @@
96100
"description": "Navbar item with label Ecological Cooperation"
97101
}
98102
}
99-

src/data/contributors.js

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
const CONTRIBUTORS_BY_YEAR = {
2+
2026: [
3+
'cedric-villemain',
4+
'gaoxueyu',
5+
'grant-zhou',
6+
'jiaoshuntian',
7+
'leiyanliang',
8+
'liangxiangyu',
9+
'liuxiaohui',
10+
'liyuan',
11+
'oreo-yang',
12+
'panzhenhao',
13+
'pierre-forstmann',
14+
'rophy',
15+
'shizhuoyan',
16+
'steven-niu',
17+
'suige',
18+
'taozheng',
19+
'xiaoyu509',
20+
'xinjie-lyu',
21+
'yasir-hussain-shah',
22+
'zhangzhe',
23+
'zhaofawei',
24+
],
25+
2025: [
26+
'Alex-Guo',
27+
'Amberwww1',
28+
'Bei-Fu',
29+
'Carlos-Chong',
30+
'Cary-Huang',
31+
'Cedric-Villemain',
32+
'Dapeng-Wang',
33+
'Denis-Lussier',
34+
'Fawei-Zhao',
35+
'Gavin-LYU',
36+
'Ge-Sui',
37+
'Grant-Zhou',
38+
'Hulin-Ji',
39+
'Imran-Zaheer',
40+
'JiaoShuntian',
41+
'Kang-Wang',
42+
'Lily-Wang',
43+
'Martin-Gerhardy',
44+
'Mingran-Feng',
45+
'Oreo-Yang',
46+
'Pedro-Lopez',
47+
'RRRRhl',
48+
'Renli-Zou',
49+
'Rophy-Tsai',
50+
'Ruike-Sun',
51+
'Ruohang-Feng',
52+
'Shaolin-Chu',
53+
'Shawn-Yan',
54+
'Shoubo-Wang',
55+
'Shuisen-Tong',
56+
'Steven-Niu',
57+
'Xiangyu-Liang',
58+
'Xiaohui-Liu',
59+
'Xueyu-Gao',
60+
'Yanliang-Lei',
61+
'Yasir-Hussain-Shah',
62+
'Yuan-Li',
63+
'Zhe-Zhang',
64+
'Zheng-Tao',
65+
'Zhenhao-Pan',
66+
'Zhibin-Wang',
67+
'Zhuoyan-Shi',
68+
'caffiendo',
69+
'ccwxl',
70+
'flyingbeecd',
71+
'huchangqiqi',
72+
'jerome-peng',
73+
'luss',
74+
'omstack',
75+
'otegami',
76+
'shangwei007',
77+
'shlei6067',
78+
'sjw1933',
79+
'tiankongbuqi',
80+
'xuexiaoganghs',
81+
'yangchunwanwusheng',
82+
],
83+
};
84+
85+
const CONTRIBUTOR_ALIASES = {
86+
gaoxueyu: 'xueyugao',
87+
leiyanliang: 'yanlianglei',
88+
liangxiangyu: 'xiangyuliang',
89+
liuxiaohui: 'xiaohuiliu',
90+
liyuan: 'yuanli',
91+
panzhenhao: 'zhenhaopan',
92+
rophy: 'rophytsai',
93+
shizhuoyan: 'zhuoyanshi',
94+
suige: 'gesui',
95+
taozheng: 'zhengtao',
96+
zhaofawei: 'faweizhao',
97+
zhangzhe: 'zhezhang',
98+
};
99+
100+
const CONTRIBUTOR_OVERRIDES = {
101+
carloschong: { github: 'Carlos-Chong200' },
102+
caryhuang: { github: 'caryhuang' },
103+
cedricvillemain: { name: 'Cedric Villemain', github: 'c2main' },
104+
faweizhao: {
105+
name: 'Fawei Zhao',
106+
github: 'faweizhao26',
107+
avatarSrc: '/img/contributors/fawei-zhao.jpeg',
108+
},
109+
gavinlyu: { name: 'Gavin LYU' },
110+
gesui: { name: 'Ge Sui', github: 'suige' },
111+
grantzhou: { github: 'grantzhou' },
112+
imranzaheer: { github: 'imranzaheer612' },
113+
jiaoshuntian: { name: 'Jiao Shuntian', github: 'jiaoshuntian' },
114+
martingerhardy: { github: 'mgerhardy' },
115+
oreoyang: { name: 'Oreo Yang', github: 'OreoYang' },
116+
pierreforstmann: { name: 'Pierre Forstmann', github: 'pierreforstmann' },
117+
renlizou: { github: 'zourenli' },
118+
rophytsai: { name: 'Rophy Tsai', github: 'rophy' },
119+
rrrrhl: { github: 'RRRRhl' },
120+
ruohangfeng: { github: 'Vonng' },
121+
shaolinchu: { github: 'shaolinchu' },
122+
shawnyan: { github: 'shawn0915' },
123+
stevenniu: { name: 'Steven Niu', github: 'bigplaice' },
124+
xiaohuiliu: { name: 'Xiaohui Liu', github: 'hs-liuxh' },
125+
xiangyuliang: { name: 'Xiangyu Liang', github: 'balinorLiang' },
126+
xinjielyu: { name: 'Xinjie Lyu' },
127+
xueyugao: { name: 'Xueyu Gao', github: 'gaoxueyu' },
128+
yanlianglei: { name: 'Yanliang Lei', github: 'msdnchina' },
129+
yasirhussainshah: { name: 'Yasir Hussain Shah', github: 'yasir-hussain-shah' },
130+
yuanli: { name: 'Yuan Li', github: 'yuanyl630' },
131+
zhezhang: { name: 'Zhe Zhang', github: 'zhangzhe' },
132+
zhengtao: { name: 'Zheng Tao', github: 'NotHimmel' },
133+
zhenhaopan: { name: 'Zhenhao Pan', github: 'panzhenhao' },
134+
zhibinwang: { github: 'killerwzb' },
135+
zhuoyanshi: { name: 'Zhuoyan Shi', github: 'shizhuoyan' },
136+
};
137+
138+
function normalizeContributorId(value) {
139+
return value
140+
.normalize('NFKD')
141+
.replace(/[\u0300-\u036f]/g, '')
142+
.replace(/[^a-zA-Z0-9]/g, '')
143+
.toLowerCase();
144+
}
145+
146+
function looksLikeGithubHandle(value) {
147+
return /^[a-z0-9-]+$/.test(value);
148+
}
149+
150+
function slugBeautyScore(value) {
151+
let score = 0;
152+
if (/[-_]/.test(value)) {
153+
score += 2;
154+
}
155+
if (/[A-Z]/.test(value.slice(1))) {
156+
score += 2;
157+
}
158+
if (!looksLikeGithubHandle(value)) {
159+
score += 1;
160+
}
161+
return score;
162+
}
163+
164+
function humanizeContributorName(value) {
165+
if (/^[a-z0-9]+$/.test(value)) {
166+
return `@${value}`;
167+
}
168+
169+
const words = value
170+
.replace(/([a-z])([A-Z])/g, '$1 $2')
171+
.replace(/[-_]+/g, ' ')
172+
.trim()
173+
.split(/\s+/);
174+
175+
return words
176+
.map((word) => {
177+
if (!word) {
178+
return word;
179+
}
180+
if (word === word.toUpperCase()) {
181+
return word;
182+
}
183+
if (/^[a-z0-9]+$/.test(word)) {
184+
return `${word.charAt(0).toUpperCase()}${word.slice(1)}`;
185+
}
186+
return word;
187+
})
188+
.join(' ');
189+
}
190+
191+
const contributorMap = new Map();
192+
193+
Object.entries(CONTRIBUTORS_BY_YEAR).forEach(([year, slugs]) => {
194+
slugs.forEach((slug) => {
195+
const normalizedId = normalizeContributorId(slug);
196+
const canonicalId = CONTRIBUTOR_ALIASES[normalizedId] || normalizedId;
197+
const existing = contributorMap.get(canonicalId) || {
198+
id: canonicalId,
199+
displaySlug: slug,
200+
github: null,
201+
years: new Set(),
202+
slugScore: slugBeautyScore(slug),
203+
};
204+
205+
const nextScore = slugBeautyScore(slug);
206+
if (nextScore > existing.slugScore) {
207+
existing.displaySlug = slug;
208+
existing.slugScore = nextScore;
209+
}
210+
211+
if (looksLikeGithubHandle(slug) && !existing.github) {
212+
existing.github = slug;
213+
}
214+
215+
existing.years.add(Number(year));
216+
contributorMap.set(canonicalId, existing);
217+
});
218+
});
219+
220+
export const contributors = Array.from(contributorMap.values())
221+
.map((item) => {
222+
const override = CONTRIBUTOR_OVERRIDES[item.id] || {};
223+
const years = Array.from(item.years).sort((a, b) => b - a);
224+
225+
return {
226+
id: item.id,
227+
name: override.name || humanizeContributorName(item.displaySlug),
228+
github: override.github || item.github || null,
229+
avatarSrc: override.avatarSrc || null,
230+
avatarMode: override.avatarMode || null,
231+
years,
232+
latestYear: years[0],
233+
};
234+
})
235+
.sort((left, right) => {
236+
if (right.latestYear !== left.latestYear) {
237+
return right.latestYear - left.latestYear;
238+
}
239+
240+
const leftName = left.name.replace(/^@/, '').toLowerCase();
241+
const rightName = right.name.replace(/^@/, '').toLowerCase();
242+
return leftName.localeCompare(rightName);
243+
});
244+
245+
export const contributorYears = Object.keys(CONTRIBUTORS_BY_YEAR)
246+
.map(Number)
247+
.sort((a, b) => b - a);

src/pages/community-page.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ Read our [**contribution guidelines**](https://github.com/IvorySQL/IvorySQL/blob
1919
- [Report a Bug](https://github.com/IvorySQL/IvorySQL/issues/new/choose)
2020
- [Submit a pull request](https://github.com/IvorySQL/IvorySQL/pulls)
2121

22+
## Contributors Wall
23+
Meet the people helping IvorySQL grow on our [Contributors Wall](/contributors).
24+
2225
## Conversations
2326
Participate in IvorySQL community discussions through the following channels:
2427

0 commit comments

Comments
 (0)