Skip to content

Commit

Permalink
add repo list
Browse files Browse the repository at this point in the history
  • Loading branch information
gusibi committed Oct 2, 2024
1 parent c1c2acf commit 19324e3
Show file tree
Hide file tree
Showing 14 changed files with 613 additions and 7 deletions.
14 changes: 12 additions & 2 deletions components/CommentButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div>
<NuxtLink :to="`/blog/${postNumber}`" class="inline-flex items-center text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300">
<NuxtLink :to="getBlogUrl(postNumber)" class="inline-flex items-center text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M18 10c0 3.866-3.582 7-8 7a8.841 8.841 0 01-4.083-.98L2 17l1.338-3.123C2.493 12.767 2 11.434 2 10c0-3.866 3.582-7 8-7s8 3.134 8 7zM7 9H5v2h2V9zm8 0h-2v2h2V9zM9 9h2v2H9V9z" clip-rule="evenodd" />
</svg>
Expand All @@ -10,14 +10,24 @@
</div>
</template>
<script setup lang="ts">
defineProps({
const props = defineProps({
postNumber: {
type: Number,
required: true
},
commentCount: {
type: Number,
default: 0
},
repoUrl: {
type: String,
default: ''
}
})
const getBlogUrl = (postNumber: number) => {
if (props.repoUrl) {
return `${props.repoUrl}/blog/${postNumber}`
}
return `/blog/${postNumber}`
}
</script>
31 changes: 26 additions & 5 deletions components/PostLabels.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
<template>
<div class="flex flex-wrap text-sm font-medium ">
<NuxtLink v-for="label in labels" :key="label.name" :to="`/tag/${encodeURIComponent(label.name)}`" class="card-label inline-block mx-1 dark:text-slate-800 transition-all duration-300 hover:scale-110" :style="{ color: `#${label.color}` }"> #{{ label.name }} </NuxtLink>
<div>
<NuxtLink v-for="label in labels" :key="label.name" :to="getLabelUrl(label.name)" class="card-label inline-block mx-1 dark:text-slate-800 transition-all duration-300 hover:scale-110" :style="{ color: `#${label.color}` }"> #{{ label.name }} </NuxtLink>
</div>
</template>
<script setup lang="ts">
defineProps<{
labels: Array<{ color: string; name: string }>
}>()
import { PropType } from 'vue'
interface Label {
name: string
color: string
}
const props = defineProps({
labels: {
type: Array as PropType<Label[]>,
required: true
},
repoUrl: {
type: String,
default: ''
}
})
const getLabelUrl = (labelName: string) => {
if (props.repoUrl) {
return `${props.repoUrl}/tag/${encodeURIComponent(labelName)}`
}
return `/tag/${encodeURIComponent(labelName)}`
}
</script>
53 changes: 53 additions & 0 deletions components/RepoCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden mb-4">
<div class="p-6">
<h2 class="text-xl font-semibold mb-2">
<NuxtLink :to="`/repo/${repo.owner_name}/${repo.name}`" class="text-blue-600 hover:underline">
{{ repo.owner_name }}/{{ repo.name }}
</NuxtLink>
</h2>
<p class="text-gray-600 dark:text-gray-300 text-sm mb-4">{{ repo.description }}</p>
<div class="flex justify-between items-center text-sm">
<div class="flex space-x-4">
<span class="flex items-center">
<svg class="w-4 h-4 mr-1 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"></path>
</svg>
{{ repo.stars }}
</span>
<span class="flex items-center">
<svg class="w-4 h-4 mr-1 text-gray-500" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M5 3a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2V5a2 2 0 00-2-2H5zm0 2h10v7h-2l-1 2H8l-1-2H5V5z" clip-rule="evenodd"></path>
</svg>
{{ repo.forks }}
</span>
</div>
<span class="text-gray-500">Updated {{ formatDate(repo.updated_at) }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
interface Repo {
name: string
description: string
stars: number
forks: number
owner_name: string
updated_at: string
}
const props = defineProps({
repo: {
type: Object as PropType<Repo>,
required: true
}
})
const formatDate = (dateString: string) => {
const date = new Date(dateString)
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })
}
</script>
43 changes: 43 additions & 0 deletions components/RepoInfo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<div class="container max-w-content mx-auto px-4">
<div class="space-y-8">
<div v-if="repo" class="bg-white dark:bg-gray-800 shadow-md rounded-lg p-6 mb-8 w-full">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">{{ repo.name }}</h2>
<p class="text-gray-600 dark:text-gray-300 mb-4">{{ repo.description }}</p>
<div class="flex justify-between items-center">
<div class="flex items-center space-x-4">
<div class="flex items-center">
<svg class="w-5 h-5 text-yellow-400 mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"></path>
</svg>
<span class="text-gray-700 dark:text-gray-300">{{ repo.stars }}</span>
</div>
<div class="flex items-center">
<svg class="w-5 h-5 text-gray-400 mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
<span class="text-gray-700 dark:text-gray-300">{{ repo.forks }}</span>
</div>
</div>
<a :href="`https://github.com/${repoOwner}/${repoName}`" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> View on GitHub </a>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
defineProps({
repo: {
type: Object,
required: true
},
repoOwner: {
type: String,
required: true
},
repoName: {
type: String,
required: true
}
})
</script>
126 changes: 126 additions & 0 deletions components/RepoTimeline.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<template>
<div class="container max-w-content mx-auto px-4">
<div class="space-y-8">
<div v-for="post in blogPosts" :key="post.id" class="flex items-start">
<!-- <div class="flex-shrink-0 mr-4">
<span class="inline-flex items-center justify-center w-8 h-8 rounded-full text-white" :style="{ backgroundColor: getLabelColor(post.labels) }">
{{ getFirstLabelChar(post.labels) }}
</span>
</div> -->
<div class="flex-grow bg-card-light dark:bg-card-dark rounded-lg px-6 shadow-xl" :data-post-id="post.number">
<div class="pt-4 flex justify-between items-center text-sm">
<!-- 左上角标签 -->
<div class="flex items-center space-x-4">
<PostLabels :labels="post.labels" :repo-url="post.repo_url" />
</div>
<!-- 右上角反应 -->
<div class="flex items-center space-x-4">
<PostReactions :reactions="post.reactions" class="" />
</div>
</div>
<div class="py-3">
<h1 v-if="!isMemePost(post.labels)" class="text-xl font-medium">
<NuxtLink :to="`${post.html_url}`" class="hover:underline">{{ post.title }}</NuxtLink>
</h1>
<div class="mt-2 text-sm prose dark:prose-invert" v-html="$md(truncatedBody(post.body))"></div>
</div>
<!-- 底部信息栏 -->
<div class="pb-6 pt-3 flex justify-between items-center text-sm">
<!-- 左下角 GitHub 链接 -->
<div class="flex items-center space-x-4">
<a class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300" :href="post.github_url" target="_blank">🔗</a>
<span class="text-gray-500 dark:text-gray-400">{{ formatDate(post.created_at, false) }}</span>
</div>
<div class="flex items-center space-x-4">
<CommentButton :post-number="post.number" :repo-url="post.repo_url" :comment-count="post.comments || 0" />
<ShareButton :post="post" :repo-url="post.repo_url" :card-selector="`[data-post-id='${post.number}']`" />
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <ShareModal :post="selectedPost" :is-open="isShareModalOpen" @close="closeShareModal" /> -->
</template>
<script setup lang="ts">
import { ref } from 'vue'
import ShareModal from '~/components/ShareButton.vue'
interface BlogPost {
id: number
number: number
title: string
body: string
created_at: string
reactions: Record<string, number>
comments: number
html_url: string
labels: Array<{ color: string; name: string }>
}
const props = defineProps({
blogPosts: {
type: Array as PropType<BlogPost[]>,
required: true,
default: () => [] // 添加默认值
}
})
const selectedPost = ref<BlogPost | null>(null)
const isShareModalOpen = ref(false)
const openShareModal = (post: BlogPost) => {
selectedPost.value = post
isShareModalOpen.value = true
}
const closeShareModal = () => {
isShareModalOpen.value = false
selectedPost.value = null
}
const formatDate = (dateString: string, showYear = false) => {
const date = new Date(dateString)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
if (showYear) {
return `${year}-${month}-${day} ${hours}:${minutes}`
} else {
return `${month}-${day} ${hours}:${minutes}`
}
}
const truncatedBody = (post: string) => {
const maxLength = 400;
if (post.length <= maxLength) {
return post;
}
return post.slice(0, maxLength).trim() + '...';
}
const renderLabels = (labels: Array<{ color: string; name: string }>) => {
return labels.map(label => ({
color: `#${label.color}`,
name: label.name,
displayName: label.name.length > 10 ? label.name.substring(0, 10) + '...' : label.name
}))
}
const getLabelColor = (labels: Array<{ color: string }>) => {
return labels.length > 0 ? `#${labels[0].color}` : '#ccc'
}
const getFirstLabelChar = (labels: Array<{ name: string }>) => {
return labels.length > 0 ? labels[0].name.charAt(0) : ''
}
const isMemePost = (labels: Array<{ name: string }>): boolean => {
return labels.some(label => label.name.toLowerCase() === 'meme')
}
</script>
1 change: 1 addition & 0 deletions layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<a href="https://momo.gusibi.mobi" class="mr-4 hover:underline">本站地址</a>
<a href="/api/rss.xml" class="mr-4 hover:underline">RSS</a>
<a href="/sitemap.xml" class="mr-4 hover:underline">SiteMap</a>
<a href="/repo" class="mr-4 hover:underline">RepoList</a>
</div>
<div class="text-sm text-gray-500">Design by <a href="https://github.com/gusibi/path-meme-web">gusibi@path-meme</a></div>
</div>
Expand Down
3 changes: 3 additions & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ export default defineNuxtConfig({
apiBaseUrl: process.env.API_BASE_URL || 'https://path-memo-api.gusibi.mobi',
siteUrl: process.env.SITE_URL || 'https://momo.gusibi.mobi',
repoName: process.env.REPO_NAME || 'path-meme-db',
},
private: {
githubToken: process.env.GITHUB_TOKEN
}
},
gtag: {
Expand Down
Loading

0 comments on commit 19324e3

Please sign in to comment.