♻️ Compete migrate to interactive

This commit is contained in:
LittleSheep 2024-02-10 02:34:09 +08:00
parent bb65c2a507
commit afaf9fdea4
11 changed files with 105 additions and 282 deletions

View File

@ -26,6 +26,7 @@
"html-react-parser": "^5.1.2",
"marked": "^12.0.0",
"medium-zoom": "^1.1.0",
"nprogress": "^0.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass": "^1.70.0",
@ -37,6 +38,7 @@
"@tailwindcss/typography": "^0.5.10",
"@types/dompurify": "^3.0.5",
"@types/node": "^20.11.5",
"@types/nprogress": "^0.2.3",
"daisyui": "^4.6.0",
"prettier": "^3.2.4"
}

View File

@ -9,7 +9,6 @@ const items: MenuItem[] = [
{
label: "情报", children: [
{ href: "/posts", label: "记录" },
{ href: "/events", label: "活动" },
{ href: "/moments", label: "回忆" }
]
}

View File

@ -1,6 +1,8 @@
---
import "../assets/fonts/fonts.css";
import "@fortawesome/fontawesome-free/css/all.min.css";
import "nprogress/nprogress.css";
import Navbar from "../components/Navbar.astro";
import { ViewTransitions } from "astro:transitions";
@ -25,6 +27,17 @@ const { title } = Astro.props;
}
</script>
<script>
import NProgress from "nprogress";
NProgress.configure({ showSpinner: false, trickleRate: 0.02, trickleSpeed: 800 });
document.addEventListener("astro:before-preparation", function () {
NProgress.start();
});
document.addEventListener("astro:after-preparation", function () {
NProgress.done();
});
</script>
<ViewTransitions />
</head>
<body>
@ -60,6 +73,10 @@ const { title } = Astro.props;
.top-header {
top: 64px;
}
#nprogress .bar {
background: #49509e !important;
}
</style>
<script>

View File

@ -8,41 +8,15 @@ export const prerender = false;
const { slug } = Astro.params;
const { posts } = (
await graphQuery(
`query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) {
posts(where: $where, orderBy: $orderBy) {
slug
type
title
description
cover {
image {
url
}
}
content {
document
}
categories {
name
}
tags {
name
}
createdAt
}
}`,
{
orderBy: [
{
createdAt: "desc",
},
],
where: { categories: { some: { slug: { equals: slug } } } },
}
)
).data;
const response = await fetch(
`https://feed.smartsheep.studio/api/posts?${new URLSearchParams({
offset: (0).toString(),
take: (10).toString(),
category: slug ?? "none",
realmId: process.env.PUBLIC_REALM_ID ?? (0).toString(),
})}`,
);
const posts = (await response.json())["data"];
---
<PageLayout title="分类检索">

View File

@ -1,85 +0,0 @@
---
import PageLayout from "../../layouts/PageLayout.astro";
import { graphQuery } from "../../scripts/requests";
import { DocumentRenderer } from "@keystone-6/document-renderer";
export const prerender = false;
const { events } = (
await graphQuery(
`query Query($where: EventWhereInput!) {
events(where: $where) {
slug
title
description
content {
document
}
createdAt
}
}`,
{
where: {
isHistory: {
equals: true,
},
},
}
)
).data;
---
<PageLayout title="活动">
<div class="max-w-[720px] mx-auto">
<div class="card w-full shadow-xl">
<div class="card-body">
<h2 class="card-title">活动</h2>
<p>读岁月史书,涨人生阅历</p>
<div class="divider"></div>
<ul
class="timeline timeline-snap-icon max-md:timeline-compact timeline-vertical"
>
{
events?.map((item: any, idx: number) => {
let align = idx % 2 === 0 ? "timeline-start" : "timeline-end";
let textAlign = idx % 2 === 0 ? "md:text-right" : "md:text-left";
return (
<li>
{idx > 0 && <hr />}
<div class="timeline-middle">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="h-5 w-5"
>
<path
fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class={`${align} ${textAlign} mb-10`}>
<time class="font-mono italic">
{new Date(item.createdAt).toLocaleDateString()}
</time>
<div class="text-lg font-black">{item.title}</div>
<DocumentRenderer document={item.content.document} />
</div>
<hr />
</li>
);
})
}
</ul>
<div class="text-center max-md:text-left italic">
我们的故事还在继续……
</div>
</div>
</div>
</div>
</PageLayout>

View File

@ -1,51 +1,24 @@
---
import RootLayout from "../layouts/RootLayout.astro";
import { graphQuery } from "../scripts/requests";
export const prerender = false;
const { events } = (
await graphQuery(
`query Query($where: EventWhereInput!) {
events(where: $where) {
slug
title
description
createdAt
}
}`,
{
where: {
isHistory: {
equals: true,
},
},
}
)
).data;
---
<RootLayout>
<div class="max-h-fullpage mt-header wrapper px-5 snap-y snap-mandatory">
<div id="hello" class="hero h-fullpage snap-start">
<div
class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]"
>
<div class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]">
<div class="max-md:text-center">
<h1 class="text-5xl font-bold">你好呀 👋</h1>
<p class="py-6">
欢迎来到 SmartSheep Studio
的官方网站!在这里了解,订阅,跟踪我们的最新消息。
欢迎来到 SmartSheep Studio 的官方网站!在这里了解,订阅,跟踪我们的最新消息。
接触我们最大的官方社区,并且尝试最新产品,参与各种活动,提供反馈,让我们更好的服务您。
</p>
<a href="#about" class="btn btn-primary btn-md">了解更多</a>
</div>
<div class="flex justify-center md:justify-end max-md:order-first">
<div
class="spinning p-3 md:p-5 shadow-2xl aspect-square rounded-[30%] w-[192px] md:w-[256px] lg:w-[384px]"
>
<div class="spinning p-3 md:p-5 shadow-2xl aspect-square rounded-[30%] w-[192px] md:w-[256px] lg:w-[384px]">
<img src="/favicon.svg" alt="logo" loading="lazy" />
</div>
</div>
@ -53,9 +26,7 @@ const { events } = (
</div>
<div id="about" class="hero h-fullpage snap-start">
<div
class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]"
>
<div class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]">
<div class="flex justify-center md:justify-start">
<div class="stats shadow overflow-x-auto">
<div class="stat">
@ -69,8 +40,7 @@ const { events } = (
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
></path></svg
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg
>
</div>
<div class="stat-title">People</div>
@ -109,8 +79,7 @@ const { events } = (
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"
></path></svg
d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"></path></svg
>
</div>
<div class="stat-title">Products</div>
@ -127,55 +96,7 @@ const { events } = (
年。自那年起我们一直在开发让人喜欢的开源软件。在我们这里,“取之于开源,用之于开源”
不仅是原则,更是我们信仰的座右铭。
</p>
<a href="#history" class="btn btn-primary btn-md pl-[24px]">
查看「岁月史书」
</a>
</div>
</div>
</div>
<div
id="history"
class="flex flex-col justify-center items-center h-fullpage snap-start"
>
<div class="text-center">
<div>
<h1 class="text-4xl font-bold">岁月史书</h1>
<p class="pt-2 pb-4 tracking-[8px]">但当涉猎,见往事耳</p>
<ul
class="pb-6 mx-[-20px] max-w-[100vw] px-5 flex justify-center history timeline timeline-horizontal"
>
{
events?.map((item: any, idx: number) => (
<li>
{idx > 0 && <hr />}
<div class="timeline-start">
{new Date(item.createdAt).toLocaleDateString()}
</div>
<div class="timeline-middle">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-5 h-5"
>
<path
fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class="timeline-end timeline-box">
<h2 class="font-bold text-lg">{item.title}</h2>
<div class="line-clamp-2">{item.description}</div>
</div>
{idx < events?.length - 1 && <hr />}
</li>
))
}
</ul>
<a class="btn btn-primary" href="/events">查看更多</a>
<a href="#history" class="btn btn-primary btn-md pl-[24px]"> 查看「岁月史书」</a>
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@ import RootLayout from "../layouts/RootLayout.astro";
---
<RootLayout>
<iframe class="moments-frame" src="https://feed.smartsheep.studio/realms/1?noTitle=yes" />
<iframe class="moments-frame" src="https://feed.smartsheep.studio/realms/1?embedded=yes" />
</RootLayout>
<style>

View File

@ -14,7 +14,7 @@ const post = (await response.json())["data"];
if (!post) {
return Astro.redirect("/404");
} else if (post.realm_id != parseInt(process.env.PUBLIC_REALM_ID ?? "0")) {
return Astro.redirect("https://feed.smartsheep.studio/posts/" + post.id);
return Astro.redirect(`https://feed.smartsheep.studio/posts/${post.id}`);
}
function getThumbnail(item: any): string | null {
@ -39,6 +39,13 @@ function getAttachments(item: any): any[] {
function getAuthorLink(user: any): string {
return `https://feed.smartsheep.studio/accounts/${user.name}`;
}
const embedOptions = new URLSearchParams({
embedded: "yes",
title: "讨论",
noContent: "yes",
noAuthor: "yes",
}).toString();
---
<PageLayout title={post?.title}>
@ -76,53 +83,51 @@ function getAuthorLink(user: any): string {
</div>
<Content content={post?.content} client:only />
<div class="mt-5 flex gap-1">
{
post?.categories?.map((category: any) => (
<a href={`/categories/${category?.alias}`} class="badge badge-primary">
<i class="fa-solid fa-layer-group me-1.5" />
{category?.name}
</a>
))
}
{
post?.tags?.map((tag: any) => (
<a href={`/tags/${tag?.alias}`} class="badge badge-accent">
<i class="fa-regular fa-tag me-1.5" />
{tag?.name}
</a>
))
}
</div>
</div>
</div>
<div class="h-fit sticky top-header">
<div class="card shadow-xl">
<div class="card-body">
<div class="gap-2 text-sm metadata description">
<div>
<div>作者</div>
<div>{post?.author?.name ?? "佚名"}</div>
</div>
<div>
<div>分类</div>
<div class="flex gap-1">
{
post?.categories?.map((category: any) => (
<a href={`/categories/${category?.slug}`} class="link link-primary">
{category?.name}
</a>
))
}
</div>
</div>
<div>
<div>标签</div>
<div class="flex gap-1">
{
post?.tags?.map((tag: any) => (
<a href={`/tags/${tag?.slug}`} class="link link-secondary">
{tag?.name}
</a>
))
}
</div>
</div>
<div>
<div>发布于</div>
<div>{new Date(post?.createdAt).toLocaleString()}</div>
</div>
</div>
</div>
<iframe id="interactive-iframe" src={`https://feed.smartsheep.studio/posts/${slug}?${embedOptions}`}> </iframe>
</div>
</div>
</div>
</PageLayout>
<script></script>
<script>
function resizeInteractiveWidget(element: HTMLIFrameElement) {
const width = element.contentWindow?.document.body.scrollWidth;
const height = element.contentWindow?.document.body.scrollHeight;
element.width = width ? `${width}px` : "100%";
element.height = height ? `${height}px` : "360px";
}
window.addEventListener("DOMContentLoaded", () => {
const element = document.querySelector<HTMLIFrameElement>("#interactive-iframe");
if (element) {
resizeInteractiveWidget(element);
}
});
</script>
<style>
.wrapper {

View File

@ -4,7 +4,13 @@ import PostList from "../../components/PostList.astro";
export const prerender = false;
const response = await fetch(`https://feed.smartsheep.studio/api/posts?offset=0&take=10&realmId=${process.env.PUBLIC_REALM_ID}`);
const response = await fetch(
`https://feed.smartsheep.studio/api/posts?${new URLSearchParams({
offset: (0).toString(),
take: (10).toString(),
realmId: process.env.PUBLIC_REALM_ID ?? (0).toString(),
})}`,
);
const posts = (await response.json())["data"];
---

View File

@ -8,41 +8,15 @@ export const prerender = false;
const { slug } = Astro.params;
const { posts } = (
await graphQuery(
`query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) {
posts(where: $where, orderBy: $orderBy) {
slug
type
title
description
cover {
image {
url
}
}
content {
document
}
categories {
name
}
tags {
name
}
createdAt
}
}`,
{
orderBy: [
{
createdAt: "desc",
},
],
where: { tags: { some: { slug: { equals: slug } } } },
}
)
).data;
const response = await fetch(
`https://feed.smartsheep.studio/api/posts?${new URLSearchParams({
offset: (0).toString(),
take: (10).toString(),
tag: slug ?? "none",
realmId: process.env.PUBLIC_REALM_ID ?? (0).toString(),
})}`,
);
const posts = (await response.json())["data"];
---
<PageLayout title="标签检索">

View File

@ -735,6 +735,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==
"@types/nprogress@^0.2.3":
version "0.2.3"
resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.3.tgz#b2150b054a13622fabcba12cf6f0b54c48b14287"
integrity sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==
"@types/prop-types@*":
version "15.7.11"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563"
@ -2926,6 +2931,11 @@ npm-run-path@^5.1.0:
dependencies:
path-key "^4.0.0"
nprogress@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1"
integrity sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"