Skip to content
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
6 changes: 1 addition & 5 deletions components/Footer.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import React, { useState, useEffect } from 'react';
import React, { useEffect } from 'react';
import packageInfo from '../package.json';
import { useStats } from '../contexts/StatsContext';
import { HiOutlineCursorClick, HiOutlineTag, HiOutlineCode, HiOutlineGlobeAlt, HiOutlineClock } from 'react-icons/hi';

const Footer = () => {
const { stats, updateStats } = useStats();
const [loading, setLoading] = useState(false);

useEffect(() => {
// 如果已经有缓存的访问量,不再重复请求
if (stats.visitCount !== null) return;

const fetchVisitCount = async () => {
setLoading(true);
try {
const response = await fetch('/api/visit-count');
if (!response.ok) {
Expand All @@ -23,8 +21,6 @@ const Footer = () => {
} catch (error) {
console.error('获取访问量失败:', error);
updateStats({ visitCount: 0 });
} finally {
setLoading(false);
}
};

Expand Down
10 changes: 2 additions & 8 deletions components/HeaderBar.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import React, { useEffect } from 'react';
import ThemeToggleButton from './ThemeToggleButton';
import { useTheme } from '../contexts/ThemeContext';
import { useStats } from '../contexts/StatsContext';
import { HiOutlineClock, HiOutlineGlobeAlt, HiOutlineInformationCircle, HiOutlineHome, HiOutlineSearch } from 'react-icons/hi';
import { HiOutlineInformationCircle, HiOutlineHome, HiOutlineSearch } from 'react-icons/hi';
import Link from 'next/link';
import { useRouter } from 'next/router';

const HeaderBar = ({ lastFetched, count, searchQuery, setSearchQuery }) => {
const { mounted } = useTheme();
const { stats, updateStats } = useStats();
const { updateStats } = useStats();
const router = useRouter();
const isAboutPage = router.pathname === '/about';

Expand All @@ -19,10 +17,6 @@ const HeaderBar = ({ lastFetched, count, searchQuery, setSearchQuery }) => {
}
}, [count, lastFetched]);

// 优先使用全局 stats,如果没有则回退到 props
const displayCount = stats.count ?? count;
const displayTime = stats.lastFetched ?? lastFetched;

return (
<header className="sticky top-0 z-40 w-full backdrop-blur-xl bg-white/25 dark:bg-black/25 border-b border-white/45 dark:border-zinc-200/15 shadow-[0_1px_0_0_rgba(255,255,255,0.25)] dark:shadow-[0_1px_0_0_rgba(255,255,255,0.06)] transition-[background-color,border-color,box-shadow] duration-400">
<div className="max-w-[90rem] mx-auto px-4 h-14 flex items-center relative">
Expand Down
36 changes: 15 additions & 21 deletions components/MainPage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import HeaderBar from './HeaderBar';
import Footer from './Footer';
import FontMenu from './FontMenu';
import Tags from './Tags';
import WebList from './WebList';
Expand All @@ -18,8 +17,6 @@ const MainPage = ({ initialPosts, initialTags, lastFetched: initialLastFetched }

const [searchQuery, setSearchQuery] = useState('');
const [onList, setOnList] = useState([]);
const [filteredPosts, setFilteredPosts] = useState([]);
const [visibleTags, setVisibleTags] = useState(tags);

// 初始化全局缓存
useEffect(() => {
Expand All @@ -28,24 +25,21 @@ const MainPage = ({ initialPosts, initialTags, lastFetched: initialLastFetched }
}
}, [initialPosts]);

// 当源数据 posts, 标签过滤 onList 或 搜索内容 searchQuery 变化时更新结果
useEffect(() => {
// 确保有数据时才进行过滤
if (posts && posts.length > 0) {
const results = updateResults(posts, onList);
const finalResults = filterPostsBySearch(results, searchQuery);
const availableTags = extractTags(finalResults);
setFilteredPosts(finalResults);
setVisibleTags(
searchQuery.trim()
? tags.filter(tag => onList.includes(tag) || availableTags.includes(tag))
: tags
);
} else {
setFilteredPosts([]);
setVisibleTags(searchQuery.trim() ? onList : tags);
const filteredPosts = useMemo(() => {
if (!posts || posts.length === 0) {
return [];
}
const results = updateResults(posts, onList);
return filterPostsBySearch(results, searchQuery);
}, [posts, onList, searchQuery]);

const visibleTags = useMemo(() => {
if (!searchQuery.trim()) {
return tags;
}
}, [posts, onList, searchQuery, tags]);
const availableTags = extractTags(filteredPosts);
return tags.filter(tag => onList.includes(tag) || availableTags.includes(tag));
}, [tags, onList, searchQuery, filteredPosts]);

const handleToggleTagButton = tag => {
const newOnList = _.xor(onList, [tag]);
Expand Down
2 changes: 1 addition & 1 deletion contexts/ThemeContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const ThemeProvider = ({ children }) => {
return () => mediaQuery.removeEventListener('change', handleChange);
}, []);

const toggleTheme = (event) => {
const toggleTheme = () => {
const toggle = (newTheme) => {
document.documentElement.classList.toggle('dark', newTheme);

Expand Down
1 change: 0 additions & 1 deletion pages/about.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import FontMenu from '../components/FontMenu';
import { HiOutlineSparkles, HiOutlineCollection, HiOutlineHeart } from 'react-icons/hi';
import Head from 'next/head';
import { getDatabase } from '../lib/notion';
import { unique } from '../lib/dataLoader';
import Link from 'next/link';
import { useStats } from '../contexts/StatsContext';

Expand Down
Loading