✨ Sharable rewind
This commit is contained in:
@@ -921,10 +921,10 @@
|
|||||||
|
|
||||||
<div class="flex justify-between gap-4 w-full md:col-span-2">
|
<div class="flex justify-between gap-4 w-full md:col-span-2">
|
||||||
<div class="flex gap-4 items-center">
|
<div class="flex gap-4 items-center">
|
||||||
<n-avatar :src="getAccountAvatar(userInfo.user!)" />
|
<n-avatar :src="getAccountAvatar(rewindData.account)" />
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<p class="text-md font-bold">{{ userInfo.user!.nick }} 的 {{ rewindData.year }} 年</p>
|
<p class="text-md font-bold">{{ rewindData.account.nick }} 的 {{ rewindData.year }} 年</p>
|
||||||
<p>@{{ userInfo.user!.name }}</p>
|
<p>@{{ rewindData.account.name }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-4 items-center text-right">
|
<div class="flex gap-4 items-center text-right">
|
||||||
@@ -961,6 +961,52 @@
|
|||||||
与朋友分享你在 Solar Network 的精彩旅程!
|
与朋友分享你在 Solar Network 的精彩旅程!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<n-alert
|
||||||
|
v-if="rewindData?.sharableCode"
|
||||||
|
type="success"
|
||||||
|
:bordered="false"
|
||||||
|
:show-icon="false"
|
||||||
|
class="mb-4 px-2"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<n-icon :component="ShareIcon" size="16" />
|
||||||
|
<span>公开链接</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
:value="sharableUrl"
|
||||||
|
readonly
|
||||||
|
class="flex-1 bg-transparent border-none outline-none text-sm"
|
||||||
|
/>
|
||||||
|
<n-button
|
||||||
|
size="small"
|
||||||
|
quaternary
|
||||||
|
@click="copySharableUrl"
|
||||||
|
>
|
||||||
|
复制
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</n-alert>
|
||||||
|
|
||||||
|
<n-alert
|
||||||
|
v-else
|
||||||
|
type="info"
|
||||||
|
:bordered="false"
|
||||||
|
:show-icon="false"
|
||||||
|
class="mb-4 px-2"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<n-icon :component="LockIcon" size="16" />
|
||||||
|
<span>私密模式</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<span class="text-sm">您的年度回顾目前仅自己可见</span>
|
||||||
|
</n-alert>
|
||||||
|
|
||||||
<div class="flex gap-3 justify-center">
|
<div class="flex gap-3 justify-center">
|
||||||
<n-button
|
<n-button
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -972,12 +1018,21 @@
|
|||||||
</template>
|
</template>
|
||||||
下载总结
|
下载总结
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button size="large" @click="shareOnSocial">
|
<n-button v-if="rewindData?.sharableCode" size="large" @click="shareOnSocial">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon :component="ShareIcon" />
|
<n-icon :component="ShareIcon" />
|
||||||
</template>
|
</template>
|
||||||
分享到社交媒体
|
分享到社交媒体
|
||||||
</n-button>
|
</n-button>
|
||||||
|
<n-button
|
||||||
|
size="large"
|
||||||
|
@click="toggleVisibility(!rewindData?.sharableCode)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<n-icon :component="rewindData?.sharableCode ? LockIcon : ShareIcon" />
|
||||||
|
</template>
|
||||||
|
{{ rewindData?.sharableCode ? "设为私密" : "设为公开" }}
|
||||||
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
</n-card>
|
</n-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -999,7 +1054,8 @@ import {
|
|||||||
PartyPopperIcon,
|
PartyPopperIcon,
|
||||||
PhoneCallIcon,
|
PhoneCallIcon,
|
||||||
WebhookIcon,
|
WebhookIcon,
|
||||||
ArrowDown
|
ArrowDown,
|
||||||
|
LockIcon
|
||||||
} from "lucide-vue-next"
|
} from "lucide-vue-next"
|
||||||
import { ref } from "vue"
|
import { ref } from "vue"
|
||||||
import type {
|
import type {
|
||||||
@@ -1015,20 +1071,19 @@ import CloudyRewind from "~/assets/images/cloudy-lamb-rewind.png"
|
|||||||
import CloudyLamb from "~/assets/images/cloudy-lamb.png"
|
import CloudyLamb from "~/assets/images/cloudy-lamb.png"
|
||||||
|
|
||||||
const api = useSolarNetwork()
|
const api = useSolarNetwork()
|
||||||
const userInfo = useUserStore()
|
|
||||||
|
|
||||||
const pending = ref(true)
|
const pending = ref(true)
|
||||||
const error = ref<unknown>(null)
|
const error = ref<unknown>(null)
|
||||||
const rewindData = ref<SnRewind | null>(null)
|
const rewindData = ref<SnRewind | null>(null)
|
||||||
|
|
||||||
gsap.registerPlugin(ScrollTrigger)
|
const route = useRoute()
|
||||||
|
|
||||||
// Fetch rewind data
|
// Fetch rewind data
|
||||||
const fetchRewindData = async () => {
|
const fetchRewindData = async () => {
|
||||||
pending.value = true
|
pending.value = true
|
||||||
error.value = null
|
error.value = null
|
||||||
try {
|
try {
|
||||||
const data = await api<SnRewind>("/pass/rewind/me")
|
const data = await api<SnRewind>(`/pass/rewind/${route.params.code || 'me'}`)
|
||||||
rewindData.value = data
|
rewindData.value = data
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error.value = e
|
error.value = e
|
||||||
@@ -1038,6 +1093,8 @@ const fetchRewindData = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
gsap.registerPlugin(ScrollTrigger)
|
||||||
|
|
||||||
await fetchRewindData()
|
await fetchRewindData()
|
||||||
|
|
||||||
// Ensure DOM is updated before running GSAP
|
// Ensure DOM is updated before running GSAP
|
||||||
@@ -1136,6 +1193,13 @@ const getAccountAvatar = (account: SnAccount) => {
|
|||||||
: "/api/placeholder/32/32"
|
: "/api/placeholder/32/32"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sharableUrl = computed(() => `${window.location.origin}/rewind/${rewindData.value!.sharableCode}`)
|
||||||
|
|
||||||
|
function copySharableUrl() {
|
||||||
|
navigator.clipboard.writeText(sharableUrl.value)
|
||||||
|
message.success("链接已复制")
|
||||||
|
}
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
// Download functionality
|
// Download functionality
|
||||||
@@ -1184,6 +1248,26 @@ const downloadSummary = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toggle public/private visibility
|
||||||
|
const toggleVisibility = async (makePublic: boolean) => {
|
||||||
|
if (!rewindData.value) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
const endpoint = makePublic
|
||||||
|
? `/pass/rewind/me/${rewindData.value.year}/public`
|
||||||
|
: `/pass/rewind/me/${rewindData.value.year}/private`
|
||||||
|
|
||||||
|
const result = await api<SnRewind>(endpoint, {
|
||||||
|
method: "POST"
|
||||||
|
})
|
||||||
|
|
||||||
|
rewindData.value = result
|
||||||
|
message.success(makePublic ? "已设置为公开" : "已设置为私密")
|
||||||
|
} catch (error: unknown) {
|
||||||
|
message.error(`操作失败: ${error}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const shareOnSocial = () => {
|
const shareOnSocial = () => {
|
||||||
const text = `Just checked out my Solar Network Rewind ${rewindData.value?.year}! 🚀\n\nI made ${rewindData.value?.data.sphere.totalPostCount} posts and got ${rewindData.value?.data.sphere.totalUpvoteCount} upvotes. What was your highlight of the year?`
|
const text = `Just checked out my Solar Network Rewind ${rewindData.value?.year}! 🚀\n\nI made ${rewindData.value?.data.sphere.totalPostCount} posts and got ${rewindData.value?.data.sphere.totalUpvoteCount} upvotes. What was your highlight of the year?`
|
||||||
|
|
||||||
@@ -1523,7 +1607,7 @@ useHead({
|
|||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: "minimal",
|
layout: "minimal",
|
||||||
middleware: ["auth"]
|
middleware: ["auth"],
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -129,6 +129,7 @@ export interface SnRewind {
|
|||||||
sphere: SnRewindSocialData
|
sphere: SnRewindSocialData
|
||||||
}
|
}
|
||||||
accountId: string
|
accountId: string
|
||||||
|
account: SnAccount
|
||||||
createdAt: string
|
createdAt: string
|
||||||
updatedAt: string
|
updatedAt: string
|
||||||
deletedAt: string | null
|
deletedAt: string | null
|
||||||
|
|||||||
Reference in New Issue
Block a user