Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

yarn run lint-staged
yarn run eslint . --fix
yarn run prettier --write .
yarn run prettier --write .
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
"mixpanel-browser": "^2.45.0",
"pako": "^2.1.0",
"react": "^18.2.0",
"react-activity-calendar": "^2.0.2",
"react-app-polyfill": "^3.0.0",
"react-calendar-heatmap": "^1.9.0",
"react-dom": "^18.2.0",
"react-hotkeys-hook": "^4.3.7",
"react-router-dom": "^6.8.2",
Expand Down Expand Up @@ -99,6 +99,7 @@
"@types/node": "18.14.6",
"@types/pako": "^2.0.0",
"@types/react": "^18.0.28",
"@types/react-calendar-heatmap": "^1.9.0",
"@types/react-dom": "^18.0.11",
"@types/react-router-dom": "^5.1.7",
"@vitejs/plugin-react": "^3.1.0",
Expand Down
Binary file removed src/assets/flags/code.png
Binary file not shown.
Binary file removed src/assets/flags/de.png
Binary file not shown.
Binary file removed src/assets/flags/en.png
Binary file not shown.
Binary file removed src/assets/flags/id.png
Binary file not shown.
Binary file removed src/assets/flags/ja.png
Binary file not shown.
Binary file removed src/assets/flags/kk.png
Binary file not shown.
12 changes: 6 additions & 6 deletions src/components/DonateCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ export const DonateCard = () => {
>
<Dialog.Panel className="relative my-8 w-[37rem] transform select-text overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all">
<div className="flex w-full flex-col justify-center gap-4 bg-white px-2 pb-4 pt-5 dark:bg-gray-800 dark:text-gray-300">
<h1 className="gradient-text w-full pt-3 text-center text-[2.4rem] font-bold">{`${chapterNumber} Chapters Achievement !`}</h1>
<h1 className="gradient-text w-full pt-3 text-center text-2xl font-bold sm:text-[2.4rem]">{`${chapterNumber} Chapters Achievement !`}</h1>
<div className="flex w-full flex-col gap-4 px-4">
<p className="mx-auto px-4 indent-4">
<p className="mx-auto px-2 indent-4 sm:px-4">
您刚刚完成了<HighlightedText> {chapterNumber} </HighlightedText>章节的练习,Qwerty Learner 已经陪你走过
<HighlightedText> {dayFromFirstWord} </HighlightedText> 天,一起完成了
<HighlightedText> {wordNumber} </HighlightedText>
Expand All @@ -121,13 +121,13 @@ export const DonateCard = () => {
<IconParty className="inline-block" fontSize={16} />
<br />
</p>
<p className="mx-auto px-4 indent-4">
<p className="mx-auto px-2 indent-4 sm:px-4">
Qwerty Learner 已经坚持 <span className="font-medium ">开放源码、无广告、无商业化</span> 运营
<HighlightedText className="text-indigo-500"> {dayFromQwerty} </HighlightedText> 天,
我们的目标是为所有学习者提供一个高效、便捷、无干扰的学习环境。我们诚挚地邀请您考虑进行捐赠,捐赠将直接用于维持 Qwerty
的日常运营以及未来发展,让 Qwerty 与您一起成长。
</p>
<p className="mx-auto px-4 indent-4 ">
<p className="mx-auto px-2 indent-4 sm:px-4 ">
为了感谢您的慷慨,单次 50 rmb 及以上的捐赠, 我们将回赠 Qwerty 的定制贴纸 5 枚
<span className="text-xs">(仅限大陆地区)</span>,希望您可以跟朋友分享您的快乐
</p>
Expand All @@ -137,10 +137,10 @@ export const DonateCard = () => {
</div>

<DonatingCard className="mt-2" onAmountChange={onAmountChange} />
<div className="flex w-full justify-between px-14 pb-3 pt-0">
<div className="flex w-full justify-center px-14 pb-3 pt-0">
<button
type="button"
className={`my-btn-primary ${!amount && 'invisible'} w-36 bg-amber-500 font-medium transition-all`}
className={`my-btn-primary ${!amount && 'hidden'} w-36 bg-amber-500 font-medium transition-all`}
onClick={onClickHasDonated}
>
我已捐赠
Expand Down
10 changes: 5 additions & 5 deletions src/components/DonatingCard/components/StickerButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export const StickerButton = ({ className }: { className?: string }) => {
dark:!bg-gray-800 dark:text-gray-300 dark:shadow-lg dark:shadow-gray-700"
>
<div className="flex gap-2">
<img src={sticker1} alt="alipay" className=" h-44 rounded shadow-lg shadow-gray-300 dark:shadow-gray-700" />
<img src={sticker2} alt="alipay" className=" h-44 rounded shadow-lg shadow-gray-300 dark:shadow-gray-700" />
<img src={sticker1} alt="sticker1" className="h-36 rounded shadow-lg shadow-gray-300 dark:shadow-gray-700" />
<img src={sticker2} alt="sticker2" className="h-36 rounded shadow-lg shadow-gray-300 dark:shadow-gray-700" />
</div>
<span className="mt-3 text-xs font-bold text-gray-500">
<IconInfo className="mb-[3px] mr-1 inline-block" />
此贴纸非商品,仅用于感谢您的捐赠,不可用于任何商业用途
<span className="mt-2 flex flex-col items-center justify-center text-xs font-bold text-gray-500 sm:flex-row">
<IconInfo className="mb-[3px] mr-1" />
<span>此贴纸非商品,仅用于感谢您的捐赠,不可用于任何商业用途</span>
</span>
</Tooltip>
</>
Expand Down
6 changes: 3 additions & 3 deletions src/components/DonatingCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ export const DonatingCard = ({ className, onAmountChange }: { className?: string

<div className={`mt-3 flex w-full flex-col overflow-hidden px-11 transition-[height] duration-500 ${amount ? 'h-44' : 'h-0'}`}>
{amount && (
<div className="flex w-full justify-between">
<img src={AmountImageMap[amount][0]} alt="alipay" className=" h-44" />
<img src={AmountImageMap[amount][1]} alt="weChat" className=" h-44" />
<div className="flex w-full justify-center gap-x-2">
<img src={AmountImageMap[amount][0]} alt="alipay" className="h-40" />
<img src={AmountImageMap[amount][1]} alt="weChat" className="h-40" />
</div>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default function Drawer(props: DrawerProps) {
className={classNames(
`${placement}-0`,
props.classNames || '',
'absolute flex h-full w-[35rem] flex-col drop-shadow-2xl transition-all duration-300 ease-out',
'absolute flex h-full w-85 flex-col drop-shadow-2xl transition-all duration-300 ease-out sm:w-150',
)}
>
{children}
Expand Down
207 changes: 110 additions & 97 deletions src/components/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ const Footer: React.FC = () => {
<br />
<p className="text-sm text-gray-500 dark:text-gray-400">再次感谢您的支持和关注!</p>
<br />
<img className="ml-1 w-2/6 " src="https://qwerty.kaiyi.cool/weChat-group.png" alt="weChat-group" />
<div className="flex justify-center">
<img className="ml-1 w-40 " src="https://qwerty.kaiyi.cool/weChat-group.png" alt="weChat-group" />
</div>
<br />
</InfoPanel>

Expand All @@ -142,108 +144,119 @@ const Footer: React.FC = () => {
「Qwerty Learner」!
</p>
<br />
<img className="ml-1 w-5/12 " src={redBookCode} alt="redBook" />
<p className="text-sm text-gray-500 dark:text-gray-400">Tips: 从小红书“我”的左上角点击 三 找到 扫一扫</p>
<div className="flex flex-col items-center justify-center">
<img className="ml-1 w-40 " src={redBookCode} alt="redBook" />
<p className="mt-2 text-sm text-gray-500 dark:text-gray-400">Tips: 从小红书“我”的左上角点击 三 找到 扫一扫</p>
</div>
<br />
</InfoPanel>

<footer className="mb-1 mt-4 flex w-full items-center justify-center gap-2.5 text-sm ease-in" onClick={(e) => e.currentTarget.blur()}>
<a href="https://github.com/Kaiyiwing/qwerty-learner" target="_blank" rel="noreferrer" aria-label="前往 GitHub 项目主页">
<IconGithub fontSize={15} className="text-gray-500 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-100" />
</a>
<footer
className="fixed bottom-4 flex w-full flex-col items-center justify-center gap-4 text-sm ease-in sm:flex-row"
onClick={(e) => e.currentTarget.blur()}
>
<div className="flex gap-3">
<a href="https://github.com/Kaiyiwing/qwerty-learner" target="_blank" rel="noreferrer" aria-label="前往 GitHub 项目主页">
<IconGithub fontSize={15} className="text-gray-500 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-100" />
</a>

<button
className="cursor-pointer"
type="button"
onClick={(e) => {
handleOpenInfoPanel('redBook')
e.currentTarget.blur()
}}
aria-label="加入我们的小红书社群"
>
<IconXiaoHongShu fontSize={14} className="text-gray-500 hover:text-red-500 dark:text-gray-400 dark:hover:text-red-500" />
</button>

<button
className="cursor-pointer focus:outline-none"
type="button"
onClick={(e) => {
handleOpenInfoPanel('community')
e.currentTarget.blur()
}}
aria-label="加入我们的微信用户群"
>
<IconWechat2 fontSize={16} className="text-gray-500 hover:text-green-500 dark:text-gray-400 dark:hover:text-green-500" />
</button>

<a href="https://twitter.com/real_kai42" target="_blank" title="x" rel="noreferrer">
<IconTwitter fontSize={16} className="text-gray-500 hover:text-[#1DA1F2] dark:text-gray-400 dark:hover:text-[#1DA1F2]" />
</a>
<button
className="cursor-pointer focus:outline-none "
type="button"
onClick={(e) => {
handleOpenInfoPanel('donate')
e.currentTarget.blur()
}}
aria-label="考虑捐赠我们"
>
<IconCoffee2 fontSize={16} className="text-gray-500 hover:text-amber-500 dark:text-gray-400 dark:hover:text-amber-500" />
</button>

<button
className="cursor-pointer focus:outline-none"
type="button"
onClick={(e) => {
handleOpenInfoPanel('vsc')
e.currentTarget.blur()
}}
aria-label="使用 Visual Studio Code 插件版 Qwerty Learner"
>
<IconVisualstudiocode fontSize={14} className="text-gray-500 hover:text-sky-500 dark:text-gray-400 dark:hover:text-sky-500" />
</button>

<a
href="mailto:[email protected]"
target="_blank"
rel="noreferrer"
onClick={(e) => e.currentTarget.blur()}
aria-label="发送邮件到 [email protected]"
>
<IconMail fontSize={16} className="text-gray-500 hover:text-indigo-400 dark:text-gray-400 dark:hover:text-indigo-400" />
</a>
<a rel="noreferrer" className="cursor-pointer focus:outline-none" onClick={() => navigate('/friend-links')} aria-label="查看友链">
<RiLinksLine fontSize={14} className="text-gray-500 hover:text-indigo-400 dark:text-gray-400 dark:hover:text-indigo-400" />
</a>
<button
className="cursor-pointer"
type="button"
onClick={(e) => {
handleOpenInfoPanel('redBook')
e.currentTarget.blur()
}}
aria-label="加入我们的小红书社群"
>
<IconXiaoHongShu fontSize={14} className="text-gray-500 hover:text-red-500 dark:text-gray-400 dark:hover:text-red-500" />
</button>

<Tooltip content="中国大陆镜像">
<a href="https://kaiyiwing.gitee.io/qwerty-learner" target="_self" title="前往中国大陆镜像">
<IconFlagChina fontSize={16} />
<button
className="cursor-pointer focus:outline-none"
type="button"
onClick={(e) => {
handleOpenInfoPanel('community')
e.currentTarget.blur()
}}
aria-label="加入我们的微信用户群"
>
<IconWechat2 fontSize={16} className="text-gray-500 hover:text-green-500 dark:text-gray-400 dark:hover:text-green-500" />
</button>

<a href="https://twitter.com/real_kai42" target="_blank" title="x" rel="noreferrer">
<IconTwitter fontSize={16} className="text-gray-500 hover:text-[#1DA1F2] dark:text-gray-400 dark:hover:text-[#1DA1F2]" />
</a>
</Tooltip>

<button
className="cursor-pointer text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
type="button"
onClick={(e) => {
handleOpenInfoPanel('donate')
e.currentTarget.blur()
}}
>
@ Qwerty Learner
</button>

<a
className="cursor-pointer text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
href="https://beian.miit.gov.cn"
target="_blank"
rel="noreferrer"
>
鲁ICP备2022030649号
</a>
<span className="select-none rounded bg-slate-200 px-1 text-xs text-slate-600 dark:bg-slate-800 dark:text-slate-400">
Build <span className="select-all">{LATEST_COMMIT_HASH}</span>
</span>
<button
className="cursor-pointer focus:outline-none "
type="button"
onClick={(e) => {
handleOpenInfoPanel('donate')
e.currentTarget.blur()
}}
aria-label="考虑捐赠我们"
>
<IconCoffee2 fontSize={16} className="text-gray-500 hover:text-amber-500 dark:text-gray-400 dark:hover:text-amber-500" />
</button>

<button
className="cursor-pointer focus:outline-none"
type="button"
onClick={(e) => {
handleOpenInfoPanel('vsc')
e.currentTarget.blur()
}}
aria-label="使用 Visual Studio Code 插件版 Qwerty Learner"
>
<IconVisualstudiocode fontSize={14} className="text-gray-500 hover:text-sky-500 dark:text-gray-400 dark:hover:text-sky-500" />
</button>

<a
href="mailto:[email protected]"
target="_blank"
rel="noreferrer"
onClick={(e) => e.currentTarget.blur()}
aria-label="发送邮件到 [email protected]"
>
<IconMail fontSize={16} className="text-gray-500 hover:text-indigo-400 dark:text-gray-400 dark:hover:text-indigo-400" />
</a>
<a rel="noreferrer" className="cursor-pointer focus:outline-none" onClick={() => navigate('/friend-links')} aria-label="查看友链">
<RiLinksLine fontSize={14} className="text-gray-500 hover:text-indigo-400 dark:text-gray-400 dark:hover:text-indigo-400" />
</a>

<Tooltip content="中国大陆镜像">
<a href="https://kaiyiwing.gitee.io/qwerty-learner" target="_self" title="前往中国大陆镜像">
<IconFlagChina fontSize={16} />
</a>
</Tooltip>
</div>

<div className="flex flex-col items-center justify-center gap-x-2 gap-y-1 sm:flex-row">
<div className="flex items-center gap-x-2">
<button
className="cursor-pointer text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
type="button"
onClick={(e) => {
handleOpenInfoPanel('donate')
e.currentTarget.blur()
}}
>
@ Qwerty Learner
</button>
<span className="select-none rounded bg-slate-200 px-1 text-xs text-slate-600 dark:bg-slate-800 dark:text-slate-400">
Build <span className="select-all">{LATEST_COMMIT_HASH}</span>
</span>
</div>

<a
className="cursor-pointer text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
href="https://beian.miit.gov.cn"
target="_blank"
rel="noreferrer"
>
鲁ICP备2022030649号
</a>
</div>
</footer>
</>
)
Expand Down
28 changes: 19 additions & 9 deletions src/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import logo from '@/assets/logo.svg'
import { TypingContext } from '@/pages/Typing/store'
import { isMobileAtom } from '@/store'
import { useAtomValue } from 'jotai'
import type { PropsWithChildren } from 'react'
import { useContext } from 'react'
import type React from 'react'
import { NavLink } from 'react-router-dom'

const Header: React.FC<PropsWithChildren> = ({ children }) => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { state } = useContext(TypingContext)!
const isMobile = useAtomValue(isMobileAtom)

return (
<header className="container z-20 mx-auto w-full px-10 py-6">
<header className="container z-20 mx-auto w-full px-2 py-6 sm:px-10">
<div className="flex w-full flex-col items-center justify-between space-y-3 lg:flex-row lg:space-y-0">
<NavLink
className="flex items-center text-2xl font-bold text-indigo-500 no-underline hover:no-underline lg:text-4xl"
to="https://qwerty.kaiyi.cool/"
>
<img src={logo} className="mr-3 h-16 w-16" alt="Qwerty Learner Logo" />
<h1>Qwerty Learner</h1>
</NavLink>
<nav className="my-card on element flex w-auto content-center items-center justify-end space-x-3 rounded-xl bg-white p-4 transition-colors duration-300 dark:bg-gray-800">
{!(state.isTyping && isMobile) && (
<NavLink
className="flex items-center text-2xl font-bold text-indigo-500 no-underline hover:no-underline lg:text-4xl"
to="/introduction"
>
<img src={logo} className="mr-3 h-16 w-16" alt="Qwerty Learner Logo" />
<h1>Qwerty Learner</h1>
</NavLink>
)}
<nav className="my-card on element flex w-auto flex-wrap content-center items-center justify-center gap-y-4 space-x-3 rounded-xl bg-white p-4 transition-colors duration-300 dark:bg-gray-800 sm:flex-nowrap">
{children}
</nav>
</div>
Expand Down
8 changes: 1 addition & 7 deletions src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import Footer from './Footer'
import type React from 'react'

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<main className="flex h-screen w-full flex-col items-center pb-4">
{children}
<Footer />
</main>
)
return <main className="flex h-screen w-screen flex-col items-center overflow-hidden pb-4">{children}</main>
}
Loading