Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add custom footer support #211

Merged
merged 7 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ jobs:
RSS_DESCRIPTION: ${{ vars.RSS_DESCRIPTION }}
run: |
cd Rin/
bun install --frozen-lockfile
bun install
bun scripts/migrator.ts
28 changes: 10 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ English | [简体中文](./README_zh_CN.md)

![Cover](https://repository-images.githubusercontent.com/803866357/958bc2c1-1703-4127-920c-853291495bdc)

![GitHub commit activity](https://img.shields.io/github/commit-activity/w/OXeu/Rin?style=for-the-badge)
![GitHub branch check runs](https://img.shields.io/github/check-runs/OXeu/Rin/main?style=for-the-badge)
![GitHub top language](https://img.shields.io/github/languages/top/OXeu/Rin?style=for-the-badge)
![GitHub License](https://img.shields.io/github/license/OXeu/Rin?style=for-the-badge)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/OXeu/Rin/deploy.yaml?style=for-the-badge)
![GitHub commit activity](https://img.shields.io/github/commit-activity/w/openRin/Rin?style=for-the-badge)
![GitHub branch check runs](https://img.shields.io/github/check-runs/openRin/Rin/main?style=for-the-badge)
![GitHub top language](https://img.shields.io/github/languages/top/openRin/Rin?style=for-the-badge)
![GitHub License](https://img.shields.io/github/license/openRin/Rin?style=for-the-badge)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/openRin/Rin/deploy.yaml?style=for-the-badge)

# Introduction

Expand All @@ -34,23 +34,15 @@ Rin is a blog based on Cloudflare Pages + Workers + D1 + R2. It does not require
13. For more features, please refer to https://xeu.life

# Documentation
1. [Deployment Documentation](./docs/DEPLOY.md)

2. [Environment Variables List](./docs/ENV.md)

3. [SEO Optimization Configuration](./docs/SEO.md)

4. [Contribution Guide](./CONTRIBUTING.md)

5. [Code of Conduct](./CODE_OF_CONDUCT.md)
[rin-docs.xeu.life](https://rin-docs.xeu.life)

## Star History

<a href="https://star-history.com/#OXeu/Rin&Date">
<a href="https://star-history.com/#openRin/Rin&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=OXeu/Rin&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=OXeu/Rin&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=OXeu/Rin&type=Date" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=openRin/Rin&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=openRin/Rin&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=openRin/Rin&type=Date" />
</picture>
</a>

Expand Down
27 changes: 10 additions & 17 deletions README_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

![封面](https://repository-images.githubusercontent.com/803866357/958bc2c1-1703-4127-920c-853291495bdc)

![GitHub commit activity](https://img.shields.io/github/commit-activity/w/OXeu/Rin?style=for-the-badge)
![GitHub branch check runs](https://img.shields.io/github/check-runs/OXeu/Rin/main?style=for-the-badge)
![GitHub top language](https://img.shields.io/github/languages/top/OXeu/Rin?style=for-the-badge)
![GitHub License](https://img.shields.io/github/license/OXeu/Rin?style=for-the-badge)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/OXeu/Rin/deploy.yaml?style=for-the-badge)
![GitHub commit activity](https://img.shields.io/github/commit-activity/w/openRin/Rin?style=for-the-badge)
![GitHub branch check runs](https://img.shields.io/github/check-runs/openRin/Rin/main?style=for-the-badge)
![GitHub top language](https://img.shields.io/github/languages/top/openRin/Rin?style=for-the-badge)
![GitHub License](https://img.shields.io/github/license/openRin/Rin?style=for-the-badge)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/openRin/Rin/deploy.yaml?style=for-the-badge)

# 介绍

Expand All @@ -36,23 +36,16 @@ Rin 是一个基于 Cloudflare Pages + Workers + D1 + R2 全家桶的博客,
13. 更多特性请参考 https://xeu.life

# 文档
1. [部署文档(Github)](./docs/DEPLOY.md)

2. [环境变量列表](./docs/ENV.md)

3. [SEO 优化配置](./docs/SEO.md)

4. [贡献指南](./CONTRIBUTING.md)

5. [行为准则](./CODE_OF_CONDUCT.md)
[rin-docs.xeu.life](https://rin-docs.xeu.life)

## Star History

<a href="https://star-history.com/#OXeu/Rin&Date">
<a href="https://star-history.com/#openRin/Rin&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=OXeu/Rin&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=OXeu/Rin&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=OXeu/Rin&type=Date" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=openRin/Rin&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=openRin/Rin&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=openRin/Rin&type=Date" />
</picture>
</a>

Expand Down
4 changes: 4 additions & 0 deletions client/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@
"desc": "Set the icon (Favicon) displayed in the browser's address bar",
"title": "Favicon"
},
"footer": {
"desc": "Set the footer content of the site (HTML)",
"title": "Footer"
},
"friend": {
"apply": {
"desc": "Allow other users to apply for friend links (requires review)",
Expand Down
4 changes: 4 additions & 0 deletions client/public/locales/ja/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@
"desc": "ブラウザのアドレスバーに表示されるアイコン(ファビコン)を設定します。",
"title": "ファビコン"
},
"footer": {
"desc": "サイトのフッターコンテンツを設定する(HTML)",
"title": "フッター"
},
"friend": {
"apply": {
"desc": "他のユーザーが友人リンクを申請できるようにする(審査が必要)",
Expand Down
4 changes: 4 additions & 0 deletions client/public/locales/zh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@
"desc": "设置显示于浏览器的地址栏的图标(Favicon)",
"title": "网站图标"
},
"footer": {
"desc": "设置显示于站点底部的内容(HTML)",
"title": "站点底部内容"
},
"friend": {
"apply": {
"desc": "允许其他用户申请友链(需审核)",
Expand Down
4 changes: 2 additions & 2 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function App() {
client.user.profile.get({
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
setProfile({
id: data.id,
avatar: data.avatar || '',
Expand All @@ -49,7 +49,7 @@ function App() {
setConfig(configWrapper)
} else {
client.config({ type: "client" }).get().then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
sessionStorage.setItem('config', JSON.stringify(data))
const config = new ConfigWrapper(data, defaultClientConfig)
setConfig(config)
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function Footer() {
const { t } = useTranslation()
const [modeState, setModeState] = useState<ThemeMode>('system');
const config = useContext(ClientConfigContext);
const footerHtml = config.get<string>('footer');
useEffect(() => {
const mode = localStorage.getItem('theme') as ThemeMode || 'system';
setModeState(mode);
Expand Down Expand Up @@ -42,9 +43,10 @@ function Footer() {
<link rel="alternate" type="application/json" title={siteName} href="/sub/rss.json" />
</Helmet>
<div className="flex flex-col mb-8 space-y-2 justify-center items-center t-primary ani-show">
{footerHtml && <div dangerouslySetInnerHTML={{ __html: footerHtml }} />}
<p className='text-sm text-neutral-500 font-normal link-line'>
<span>
© 2024 Powered by <a className='hover:underline' href="https://github.com/OXeu/Rin" target="_blank">Rin</a>
© 2024 Powered by <a className='hover:underline' href="https://github.com/openRin/Rin" target="_blank">Rin</a>
</span>
{config.get<boolean>('rss') && <>
<Spliter />
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ function SearchButton({ className, onClose }: { className?: string, onClose?: ()
setIsOpened(false)
onClose?.()
}, 100)
if (value.length != 0)
if (value.length !== 0)
setLocation(`/search/${key}`)
}
return (<div className={className + " flex flex-row items-center"}>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ export function Markdown({ content }: { content: string }) {
},
};
})
.filter((slide) => slide.src != "");
.filter((slide) => slide.src !== "");
slides.current = (slidesLocal);
}
const index = slidesLocal?.findIndex((slide) => slide.src === src) ?? -1;
Expand Down
2 changes: 1 addition & 1 deletion client/src/hooks/useTableOfContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const useTableOfContents = (selector: string) => {
)
intersectingList.length = 0 // reset array
headers.forEach((header, i) => {
if (header.getAttribute('data-id') != null) return
if (header.getAttribute('data-id') !== null) return
header.setAttribute('data-id', i.toString()) // set data-id
intersectingList.push(false) // increase array length
io.current!.observe(header) // register to observe
Expand Down
6 changes: 3 additions & 3 deletions client/src/page/feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function FeedPage({ id, TOC, clean }: { id: string, TOC: () => JSX.Elemen
}
function topFeed() {
const isUnTop = !(top > 0)
const topNew = top === 0 ? 1 : 0;
const topNew = isUnTop ? 1 : 0;
// Confirm
showConfirm(
isUnTop ? t("article.top.title") : t("article.untop.title"),
Expand Down Expand Up @@ -204,12 +204,12 @@ export function FeedPage({ id, TOC, clean }: { id: string, TOC: () => JSX.Elemen
)}
</div>
{counterEnabled && <p className='text-[12px] text-gray-400 font-normal link-line'>
<span className="font-bold"> {t("count.pv")} </span>
<span> {t("count.pv")} </span>
<span>
{feed.pv}
</span>
<span> |</span>
<span className="font-bold"> {t("count.uv")} </span>
<span> {t("count.uv")} </span>
<span>
{feed.uv}
</span>
Expand Down
2 changes: 1 addition & 1 deletion client/src/page/feeds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function FeedsPage() {
},
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
setFeeds({
...feeds,
[type]: data
Expand Down
8 changes: 4 additions & 4 deletions client/src/page/friends.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@ export function FriendsPage() {
<meta property="og:type" content="article" />
<meta property="og:url" content={document.URL} />
</Helmet>
<Waiting for={friendsAvailable.length != 0 || friendsUnavailable.length != 0 || status === "idle"}>
<Waiting for={friendsAvailable.length !== 0 || friendsUnavailable.length !== 0 || status === "idle"}>
<main className="w-full flex flex-col justify-center items-center mb-8 t-primary">
<FriendList title={t('friends.title')} show={friendsAvailable.length > 0} friends={friendsAvailable} />
<FriendList title={t('friends.left')} show={friendsUnavailable.length > 0} friends={friendsUnavailable} />
<FriendList title={t('friends.review.waiting')} show={waitList.length > 0} friends={waitList} />
<FriendList title={t('friends.review.rejected')} show={refusedList.length > 0} friends={refusedList} />
<FriendList title={t('friends.my_apply')} show={profile?.permission != true && apply != undefined} friends={apply ? [apply] : []} />
<FriendList title={t('friends.my_apply')} show={profile?.permission !== true && apply !== undefined} friends={apply ? [apply] : []} />
{profile && (profile.permission || config.get("friend_apply_enable")) &&
<div className="wauto t-primary flex text-start text-2xl font-bold mt-8 ani-show">
<div className="md:basis-1/2 bg-w rounded-xl p-4">
Expand Down Expand Up @@ -210,7 +210,7 @@ function Friend({ friend }: { friend: FriendItem }) {
</div>
<p className="text-base text-center">{friend.name}</p>
{friend.health.length == 0 && <p className="text-sm text-neutral-500 text-center">{friend.desc}</p>}
{friend.accepted != 1 && <p className={`${friend.accepted === 0 ? "t-primary" : "text-theme"}`}>{statusOption[friend.accepted + 1].label}</p>}
{friend.accepted !== 1 && <p className={`${friend.accepted === 0 ? "t-primary" : "text-theme"}`}>{statusOption[friend.accepted + 1].label}</p>}
{friend.health.length > 0 && <p className="text-sm text-gray-500 text-center">{errorHumanize(friend.health)}</p>}
{(profile?.permission || profile?.id === friend.uid) && <>
<button onClick={(e) => { e.preventDefault(); setIsOpen(true) }} className="absolute top-0 right-0 m-2 px-2 py-1 bg-secondary t-primary rounded-full bg-active">
Expand Down Expand Up @@ -262,7 +262,7 @@ function Friend({ friend }: { friend: FriendItem }) {
<Select options={statusOption} required defaultValue={statusOption[friend.accepted + 1]}
onChange={(newValue, _) => {
const value = newValue?.value
if (value != undefined) {
if (value !== undefined) {
setStatus(value)
}
}}
Expand Down
2 changes: 1 addition & 1 deletion client/src/page/hashtag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function HashtagPage({ name }: { name: string }) {
client.tag({ name: nameDecoded }).get({
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
setHashtag(data)
setStatus('idle')
}
Expand Down
6 changes: 3 additions & 3 deletions client/src/page/hashtags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ type Hashtag = {

export function HashtagsPage() {
const { t } = useTranslation();
const [hashtags, setHashtags] = useState<Hashtag[]>([]);
const [hashtags, setHashtags] = useState<Hashtag[]>();
const ref = useRef(false);
useEffect(() => {
if (ref.current) return;
client.tag.index.get().then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
setHashtags(data);
}
});
Expand All @@ -47,7 +47,7 @@ export function HashtagsPage() {
</div>

<div className="wauto flex flex-col flex-wrap items-start justify-start">
{hashtags.filter(({ feeds }) => feeds > 0).map((hashtag, index) => {
{hashtags?.filter(({ feeds }) => feeds > 0).map((hashtag, index) => {
return (
<div key={index} className="w-full flex flex-row">
<div className="w-full rounded-2xl m-2 duration-300 flex flex-row items-center space-x-4 ">
Expand Down
2 changes: 1 addition & 1 deletion client/src/page/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function SearchPage({ keyword }: { keyword: string }) {
},
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
setFeeds(data)
setStatus('idle')
}
Expand Down
7 changes: 4 additions & 3 deletions client/src/page/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function Settings() {
}).get({
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
sessionStorage.setItem('config', JSON.stringify(data));
const config = new ConfigWrapper(data, defaultClientConfig)
setClientConfig(config)
Expand All @@ -46,7 +46,7 @@ export function Settings() {
}).get({
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
const config = new ConfigWrapper(data, defaultServerConfig)
setServerConfig(config)
}
Expand All @@ -66,7 +66,7 @@ export function Settings() {
}, {
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
setMsg(t('settings.import_success$success$skipped', { success: data.success, skipped: data.skipped }))
setMsgList(data.skippedList)
setIsOpen(true);
Expand Down Expand Up @@ -97,6 +97,7 @@ export function Settings() {
<ItemSwitch title={t('settings.counter.enable.title')} description={t('settings.counter.enable.desc')} type="client" configKey="counter.enabled" />
<ItemSwitch title={t('settings.rss.title')} description={t('settings.rss.desc')} type="client" configKey="rss" />
<ItemInput title={t('settings.favicon.title')} description={t('settings.favicon.desc')} type="client" configKey="favicon" configKeyTitle="Favicon" />
<ItemInput title={t('settings.footer.title')} description={t('settings.footer.desc')} type="client" configKey="footer" configKeyTitle="Footer HTML" />
<ItemButton title={t('settings.cache.clear.title')} description={t('settings.cache.clear.desc')} buttonTitle={t('clear')} onConfirm={async () => {
await client.config.cache.delete(undefined, {
headers: headersWithAuth()
Expand Down
2 changes: 1 addition & 1 deletion client/src/page/timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function TimelinePage() {
client.feed.timeline.get({
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
if (data && typeof data !== 'string') {
setLength(data.length)
const groups = Object.groupBy(data, ({ createdAt }) => new Date(createdAt).getFullYear())
setFeeds(groups)
Expand Down
6 changes: 3 additions & 3 deletions client/src/page/writing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async function publish({
if (error) {
showAlert(error.value as string);
}
if (data && typeof data != "string") {
if (data && typeof data !== "string") {
showAlert(t("publish.success"));
Cache.with().clear();
window.location.href = "/feed/" + data.insertedId;
Expand Down Expand Up @@ -176,7 +176,7 @@ export function WritingPage({ id }: { id?: number }) {
.split("#")
.filter((tag) => tag !== "")
.map((tag) => tag.trim()) || [];
if (id != undefined) {
if (id !== undefined) {
setPublishing(true)
update({
id,
Expand Down Expand Up @@ -451,7 +451,7 @@ export function WritingPage({ id }: { id?: number }) {
</div>
</div>
<div
className={"px-4 h-[600px] overflow-y-scroll " + (preview != 'edit' ? "" : "hidden")}
className={"px-4 h-[600px] overflow-y-scroll " + (preview !== 'edit' ? "" : "hidden")}
>
<Markdown content={content ? content : "> No content now. Write on the left side."} />
</div>
Expand Down
Loading