diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3a4df851..8df70db6 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -18,6 +18,7 @@ Include the hardware you use, such as your computer and other related equipment. * Ensure this PR has a title in the following format * ✅ Add Your Name * ✅ Add @twitterusername + * ✅ Add @mastodonusername@instance.url * ❌ Add myself * ❌ Adding myself! * ❌ Add Your Name @twitter @github diff --git a/contribution-guide.md b/contribution-guide.md index 3b27008b..42bd806f 100644 --- a/contribution-guide.md +++ b/contribution-guide.md @@ -30,6 +30,7 @@ Include the hardware you use, such as your computer and other related equipment. * Ensure this PR has a title in the following format * ✅ Add Your Name * ✅ Add @twitterusername + * ✅ Add @mastodonusername@instance.url * ❌ Add myself * ❌ Adding myself! * ❌ Add Your Name @twitter @github diff --git a/scripts/utils.js b/scripts/utils.js index 2aa0fd8a..2ca3c26e 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -61,6 +61,7 @@ module.exports.Schema = Joi.object({ .valid(...flags) .required(), twitter: Joi.string().pattern(new RegExp(/^@?(\w){1,15}$/)), + mastodon: Joi.string().pattern(new RegExp(/^@(\w){1,30}@(\w)+\.(\w)+$/)), emoji: Joi.string().allow(''), computer: Joi.string().valid('apple', 'windows', 'linux', 'bsd'), phone: Joi.string().valid('iphone', 'android', 'windowsphone', 'flipphone'), diff --git a/src/components/Person.js b/src/components/Person.js index b1e8597a..0df7718c 100644 --- a/src/components/Person.js +++ b/src/components/Person.js @@ -14,7 +14,22 @@ export default function Person({ person }) { ? `${twitter}?fallback=${website}&ttl=28d` : website; // const img = `https://images.weserv.nl/?url=${unavatar}&w=100&l=9&af&il&n=-1`; - const img = unavatar; + const mastodonArr = person.mastodon + ? person.mastodon.replace('@', '').split('@') + : null; + const webfinger = + person.mastodon + ? JSON.parse(`https://${mastodonArr[0]}/.well-known/webfinger?resource=https://${mastodonArr[0]}/@${mastodonArr[1]}`) + : null; + const wfIndex = + person.mastodon && webfinger + ? webfinger.links.findIndex((link) => link.rel === 'http://webfinger.net/rel/avatar') + : null; + const wfAvatar = + person.mastodon && wfIndex + ? webfinger.links[wfIndex].href + : website; + const img = person.twitter ? unavatar : (person.mastodon ? wfAvatar : website); const { tag: currentTag } = useParams(); return (
)} - {person.twitter && ( -
+ {person.twitter || person.mastodon && ( +
@ - {person.twitter.replace('@', '')} + { + person.twitter + ? person.twitter.replace('@', '') + : `${mastodonArr[1]}/@${mastodonArr[0]}` + }
)} @@ -113,7 +136,15 @@ Person.propTypes = { if (!/^@?(\w){1,15}$/.test(props[propName])) { return new Error( `Invalid prop \`${propName}\` supplied to` + - ` \`${componentName}\`. This isn't a legit twitter handle.` + ` \`${componentName}\`. This isn't a legit Twitter handle.` + ); + } + }, + mastodon(props, propName, componentName) { + if (!/^@(\w){1,30}@(\w)+\.(\w)+$/.test(props[propName])) { + return new Error( + `Invalid prop \`${propName}\` supplied to` + + ` \`${componentName}\`. This isn't a legit Mastodon handle.` ); } }, diff --git a/src/data.js b/src/data.js index 67ac5aac..f77eb662 100644 --- a/src/data.js +++ b/src/data.js @@ -7,6 +7,7 @@ * @property {string} url - link to contributor's /uses page * @property {string} country - flag emoji for contributor's country * @property {string} [twitter] - optional Twitter username (beginning with `@`) + * @property {string} [mastodon] - optional Mastodon username & server (beginning with `@`, ex: `@hello@mastodon.social`) * @property {string} [emoji] - some emoji corresponding to the contributor * @property {'apple' | 'windows' | 'linux' | 'bsd'} [computer] * @property {'iphone' | 'android' | 'windowsphone' | 'flipphone'} [phone] diff --git a/src/styles.css b/src/styles.css index 5f3ae20a..9bcfd231 100644 --- a/src/styles.css +++ b/src/styles.css @@ -189,7 +189,7 @@ body::-webkit-scrollbar-thumb { } } -.TwitterHandle { +.SocialHandle { font-size: 1.24323423426928098420394802rem; & .at { color: var(--yellow);