Skip to content

Commit

Permalink
feat: design
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Jul 5, 2023
1 parent 9964c14 commit 655340e
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 34 deletions.
12 changes: 9 additions & 3 deletions src/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const appConfig = {
template: [
{
type: 'h1',
text: '你好呀,我是',
text: "Hi, I'm ",
class: 'font-light text-4xl',
},
{
Expand All @@ -31,12 +31,18 @@ export const appConfig = {
},
{
type: 'h1',
text: '一个独立开发者',
text: 'A NodeJS Full Stack ',
class: 'font-light text-4xl',
},
{
type: 'code',
text: '<Developer />',
class:
'font-medium mx-2 text-3xl rounded p-1 bg-opacity-0 hover:bg-opacity-100 bg-gray-200 dark:bg-gray-800 transition-background duration-200',
},
],
},
description: `一位深入研究编程领域的独立开发者,热衷于纯音乐、二次元文化和电子产品。持有强烈的创新精神,始终以用户体验为首要考虑,在技术开发中追求卓越。`,
description: `An independent developer coding with love.`,
},
module: {
donate: {
Expand Down
138 changes: 125 additions & 13 deletions src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@ import { useQuery } from '@tanstack/react-query'
import React, { createElement, forwardRef } from 'react'
import clsx from 'clsx'
import { m } from 'framer-motion'
import Link from 'next/link'
import type { PropsWithChildren } from 'react'

import { MotionButtonBase } from '~/components/ui/button'
import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
import { SocialIcon } from '~/components/widgets/home/SocialIcon'
import { softBouncePrest } from '~/constants/spring'
import { TextUpTransitionView } from '~/components/ui/transition/TextUpTransitionView'
import { isSupportIcon, SocialIcon } from '~/components/widgets/home/SocialIcon'
import { PostMetaBar } from '~/components/widgets/post'
import { softBouncePrest, softSpringPreset } from '~/constants/spring'
import { useConfig } from '~/hooks/data/use-config'
import { isDev } from '~/lib/env'
import { clsxm } from '~/lib/helper'
import { noopObj } from '~/lib/noop'
import { apiClient } from '~/lib/request'
import { routeBuilder, Routes } from '~/lib/route-builder'
import { useAggregationSelector } from '~/providers/root/aggregation-data-provider'

import { useHomeQueryData } from './query'
Expand Down Expand Up @@ -41,6 +46,7 @@ const Screen = forwardRef<
)
})
Screen.displayName = 'Screen'

export default function Home() {
return (
<div>
Expand Down Expand Up @@ -77,7 +83,7 @@ const TwoColumnLayout = ({
key={i}
className="flex h-1/2 w-full flex-col center lg:h-auto lg:w-1/2"
>
<div className="relative max-w-xl">{child}</div>
<div className="relative max-w-full lg:max-w-xl ">{child}</div>
</div>
)
})}
Expand All @@ -92,6 +98,10 @@ const Welcome = () => {
const siteOwner = useAggregationSelector((agg) => agg.user)
const { avatar, socialIds } = siteOwner || {}

const titleAnimateD =
title.template.reduce((acc, cur) => {
return acc + (cur.text?.length || 0)
}, 0) * 50
return (
<Screen className="mt-[-4.5rem]">
<TwoColumnLayout>
Expand All @@ -104,12 +114,28 @@ const Welcome = () => {
>
{title.template.map((t, i) => {
const { type } = t
return createElement(type, { key: i, className: t.class }, t.text)
const prevAllTextLength = title.template
.slice(0, i)
.reduce((acc, cur) => {
return acc + (cur.text?.length || 0)
}, 0)
return createElement(
type,
{ key: i, className: t.class },
t.text && (
<TextUpTransitionView
initialDelay={prevAllTextLength * 0.05}
eachDelay={0.05}
>
{t.text}
</TextUpTransitionView>
),
)
})}
</m.div>

<BottomToUpTransitionView
delay={300}
delay={titleAnimateD + 500}
transition={softBouncePrest}
className="my-3"
>
Expand All @@ -119,10 +145,11 @@ const Welcome = () => {
<ul className="mt-8 flex space-x-4 center lg:mt-[7rem] lg:block">
{Object.entries(socialIds || noopObj).map(
([type, id]: any, index) => {
if (!isSupportIcon(type)) return null
return (
<BottomToUpTransitionView
key={type}
delay={index * 100 + 500}
delay={index * 100 + titleAnimateD + 500}
className="inline-block"
as="li"
>
Expand Down Expand Up @@ -172,17 +199,102 @@ const PostScreen = () => {
return (
<Screen>
<TwoColumnLayout>
<h2 className="text-2xl font-medium leading-loose">
在这个矩阵中,你可以找到各种各样的代码块。
<m.h2
initial={{
opacity: 0.0001,
y: 50,
}}
whileInView={{
opacity: 1,
y: 0,
}}
viewport={{ once: true }}
transition={softSpringPreset}
className="text-2xl font-medium leading-loose"
>
看看最近我又在折腾啥捏
<br />
它们是我在计算机科学的探索和实践的证明
</h2>
随便水水文章,重在折腾
</m.h2>
<div>
<ul>
{posts.map((post) => {
return <li key={post.id}>{post.title}</li>
<ul className="space-y-4">
{posts.map((post, i) => {
const imageSrc = post.images?.[0]?.src

return (
<m.li
viewport={{ once: true }}
whileInView={{
opacity: 1,
x: 0,
}}
initial={{ opacity: 0.001, x: 50 }}
transition={{
...softSpringPreset,
delay: 0.3 + 0.2 * i,
}}
key={post.id}
className={clsx(
'relative h-[100px] w-full overflow-hidden rounded-md',
'border border-slate-200 dark:border-neutral-700/80',
'group p-4 pb-0',
)}
>
<Link
className="flex h-full w-full flex-col"
href={routeBuilder(Routes.Post, {
category: post.category.slug,
slug: post.slug,
})}
>
<h4 className="truncate text-xl font-medium">
{post.title}
</h4>
<PostMetaBar meta={post} className="-mb-2" />

<MotionButtonBase className="absolute bottom-4 right-4 flex items-center p-2 text-accent/95 opacity-0 duration-200 group-hover:opacity-100">
阅读全文
<i className="icon-[mingcute--arrow-right-line]" />
</MotionButtonBase>

{!!imageSrc && (
<div
aria-hidden
className="mask-cover absolute inset-0 top-0 z-[-1]"
>
<div
className="absolute inset-0 h-full w-full bg-cover bg-center"
style={{
backgroundImage: `url(${imageSrc})`,
}}
/>
</div>
)}
</Link>
</m.li>
)
})}
</ul>

<m.div
initial={{ opacity: 0.0001, y: 10 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{
...softBouncePrest,
delay: 0.3 + 0.2 * posts.length,
}}
className="relative mt-12 w-full text-center"
>
<MotionButtonBase>
<Link
className="shiro-link--underline"
href={routeBuilder(Routes.Posts, {})}
>
还有更多,要不要看看?
</Link>
</MotionButtonBase>
</m.div>
</div>
</TwoColumnLayout>
</Screen>
Expand Down
7 changes: 4 additions & 3 deletions src/components/ui/transition/TextUpTransitionView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const TextUpTransitionView: FC<
> = (props) => {
const {
appear = true,
eachDelay = 0.001,
eachDelay = 0.1,
initialDelay = 0,
children,
text,
Expand All @@ -30,20 +30,21 @@ export const TextUpTransitionView: FC<
// @ts-ignore
return <div {...rest}>{text ?? children}</div>
}

return (
<div {...rest}>
{Array.from(text ?? (children as string)).map((char, i) => (
<m.span
key={i}
className="inline-block whitespace-pre"
initial={{ transform: 'translateY(10px)', opacity: 0 }}
initial={{ transform: 'translateY(10px)', opacity: 0.001 }}
animate={{
transform: 'translateY(0px)',

opacity: 1,
transition: {
...microReboundPreset,
duration: 0.001,
duration: 0.1,
delay: i * eachDelay + initialDelay,
},
}}
Expand Down
2 changes: 2 additions & 0 deletions src/components/widgets/home/SocialIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const type2Copy = {
email: 'Email',
feed: 'RSS',
} as any
const icons = new Set(Object.keys(type2Copy))
export const isSupportIcon = (icon: string) => icons.has(icon)
export const SocialIcon = memo((props: SocialIconProps) => {
const { id, type } = props
const Icon = useMemo(() => {
Expand Down
34 changes: 21 additions & 13 deletions src/components/widgets/post/PostMetaBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import { RelativeTime } from '~/components/ui/relative-time'
import { clsxm } from '~/lib/helper'

export const PostMetaBar: Component<{
meta: Pick<PostModel, 'created' | 'modified' | 'category' | 'tags' | 'count'>
meta: Partial<
Pick<PostModel, 'created' | 'modified' | 'category' | 'tags' | 'count'>
>
}> = ({ className, meta }) => {
return (
<div
Expand All @@ -21,11 +23,15 @@ export const PostMetaBar: Component<{
)}
>
<div className="flex min-w-0 items-center space-x-1">
<MdiClockOutline />
<span>
<RelativeTime date={meta.created} />
</span>
{meta.modified && (
{!!meta.created && (
<>
<MdiClockOutline />
<span>
<RelativeTime date={meta.created} />
</span>
</>
)}
{!!meta.modified && (
<FloatPopover
wrapperClassName="text-xs self-end translate-y-[-1px]"
as="span"
Expand All @@ -36,13 +42,15 @@ export const PostMetaBar: Component<{
)}
</div>

<div className="flex min-w-0 items-center space-x-1">
<FeHash className="translate-y-[0.5px]" />
<span className="min-w-0 truncate">
{meta.category.name}
{meta.tags.length ? ` / ${meta.tags.join(', ')}` : ''}
</span>
</div>
{!!meta.category && (
<div className="flex min-w-0 items-center space-x-1">
<FeHash className="translate-y-[0.5px]" />
<span className="min-w-0 truncate">
{meta.category?.name}
{meta.tags?.length ? ` / ${meta.tags.join(', ')}` : ''}
</span>
</div>
)}

{!!meta.count?.read && (
<div className="flex min-w-0 items-center space-x-1">
Expand Down
5 changes: 3 additions & 2 deletions src/styles/tailwindcss.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/styles/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,15 @@
}
}
}

@layer components {
.mask-cover {
mask-image: linear-gradient(to right, transparent, rgb(0 0 0 / 100%) 90%);
opacity: 0.3;
transition: opacity 0.3s ease-in-out;
}

.group:hover .mask-cover {
opacity: 0.5;
}
}

1 comment on commit 655340e

@vercel
Copy link

@vercel vercel bot commented on 655340e Jul 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

shiro – ./

shiro-git-main-innei.vercel.app
innei.in
shiro-innei.vercel.app
springtide.vercel.app

Please sign in to comment.