From 798f73ece5c1d60bbcdb98c71e77f83a34f113d8 Mon Sep 17 00:00:00 2001 From: patak Date: Sat, 17 Dec 2022 22:11:39 +0100 Subject: [PATCH] feat: GitHub cards (#450) --- components/nav/SelectFeatureFlags.vue | 6 + components/status/StatusPreviewCard.vue | 4 +- components/status/StatusPreviewGitHub.vue | 127 ++++++++++++++++++++++ composables/featureFlags.ts | 2 + locales/es-ES.json | 1 + locales/fr-FR.json | 1 + locales/zh-CN.json | 1 + 7 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 components/status/StatusPreviewGitHub.vue diff --git a/components/nav/SelectFeatureFlags.vue b/components/nav/SelectFeatureFlags.vue index 89f232e7..57a5356b 100644 --- a/components/nav/SelectFeatureFlags.vue +++ b/components/nav/SelectFeatureFlags.vue @@ -18,6 +18,12 @@ const featureFlags = useFeatureFlags() > {{ $t('feature_flag.avatar_on_avatar') }} + + {{ $t('feature_flag.github_cards') }} + diff --git a/components/status/StatusPreviewCard.vue b/components/status/StatusPreviewCard.vue index 36c30b29..2603fc25 100644 --- a/components/status/StatusPreviewCard.vue +++ b/components/status/StatusPreviewCard.vue @@ -21,6 +21,7 @@ const isSquare = $computed(() => ( )) const providerName = $computed(() => props.card.providerName ? props.card.providerName : new URL(props.card.url).hostname) +const gitHubCards = $(computedEager(() => useFeatureFlags().experimentalGitHubCards)) // TODO: handle card.type: 'photo' | 'video' | 'rich'; @@ -37,8 +38,9 @@ const providerName = $computed(() => props.card.providerName ? props.card.provid }" target="_blank" > +
+import type { Card } from 'masto' + +const props = defineProps<{ + card: Card +}>() + +const isSquare = false +const root = true + +type UrlType = 'user' | 'repo' | 'issue' | 'pull' +interface Meta { + type: UrlType + user: string + avatar: string + details: string + repo?: string + number?: string + extra?: { + state: string + author?: { + avatar: string + user: string + } + } +} + +const meta = $computed(() => { + const { url } = props.card + const path = url.split('https://github.com/')[1] + const user = path.match(/([\w-]+)\//)![1] + const repo = path.match(/[\w-]+\/([\w-]+)/)?.[1] + const repoPath = `${user}/${repo}` + const inRepoPath = path.split(`${repoPath}/`)?.[1] + let number: string | undefined + let type: UrlType = repo ? 'repo' : 'user' + if (inRepoPath) { + number = inRepoPath.match(/issues\/(\d+)/)?.[1] + if (number) { + type = 'issue' + } + else { + number = inRepoPath.match(/pull\/(\d+)/)?.[1] + if (number) + type = 'pull' + } + } + const avatar = `https://github.com/${user}.png` + const details = (props.card.title ?? '').replace('GitHub - ', '').replace(`${repoPath}: `, '').split(' · ')[0] + const info = $ref({ + type, + user, + details, + repo, + number, + avatar, + }) + /* It is rate limited for anonymous usage, leaving this to play, but for now it is probably better to avoid the call + We can't show the author of the PR or issue without this info, because the handle isn't in the meta. I think we + could ask GitHub to add it. + + if (number) { + fetch(`https://api.github.com/repos/${user}/${repo}/issues/${number}`).then(res => res.json()).then((data) => { + info.extra = { + state: data.state as string, + author: { + avatar: data.user.avatar_url as string, + user: data.user.login as string, + }, + } + }) + } + */ + return info +}) + + + diff --git a/composables/featureFlags.ts b/composables/featureFlags.ts index cbad089c..b4e7135d 100644 --- a/composables/featureFlags.ts +++ b/composables/featureFlags.ts @@ -3,6 +3,7 @@ import { STORAGE_KEY_FEATURE_FLAGS } from '~/constants' export interface FeatureFlags { experimentalVirtualScroll: boolean experimentalAvatarOnAvatar: boolean + experimentalGitHubCards: boolean } export type FeatureFlagsMap = Record @@ -10,6 +11,7 @@ export function getDefaultFeatureFlags(): FeatureFlags { return { experimentalVirtualScroll: false, experimentalAvatarOnAvatar: true, + experimentalGitHubCards: true, } } diff --git a/locales/es-ES.json b/locales/es-ES.json index 3c63860e..cc336549 100644 --- a/locales/es-ES.json +++ b/locales/es-ES.json @@ -78,6 +78,7 @@ }, "feature_flag": { "avatar_on_avatar": "Avatar en Avatar", + "github_cards": "GitHub Cards", "virtual_scroll": "Virtual Scrolling" }, "help": { diff --git a/locales/fr-FR.json b/locales/fr-FR.json index 73b78aac..200d2cb8 100644 --- a/locales/fr-FR.json +++ b/locales/fr-FR.json @@ -81,6 +81,7 @@ }, "feature_flag": { "avatar_on_avatar": "Avatar sur avatar", + "github_cards": "GitHub Cards", "virtual_scroll": "Défilement virtuel" }, "help": { diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 65456a07..ef81ab27 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -80,6 +80,7 @@ }, "feature_flag": { "avatar_on_avatar": "头像堆叠", + "github_cards": "GitHub Cards", "virtual_scroll": "虚拟滚动" }, "help": {