Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1049719e3f | ||
|
|
6b5c69ee53 | ||
|
|
8a62e7383d |
54
app/page.jsx
54
app/page.jsx
@@ -472,7 +472,7 @@ function Stat({ label, value, delta }) {
|
||||
);
|
||||
}
|
||||
|
||||
function FeedbackModal({ onClose }) {
|
||||
function FeedbackModal({ onClose, user }) {
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [succeeded, setSucceeded] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
@@ -563,7 +563,7 @@ function FeedbackModal({ onClose }) {
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="email" value={user?.email || ''} />
|
||||
<div className="form-group" style={{ marginBottom: 20 }}>
|
||||
<label htmlFor="message" className="muted" style={{ display: 'block', marginBottom: 8, fontSize: '14px' }}>
|
||||
反馈内容
|
||||
@@ -1856,12 +1856,17 @@ export default function HomePage() {
|
||||
// 检查更新
|
||||
const [hasUpdate, setHasUpdate] = useState(false);
|
||||
const [latestVersion, setLatestVersion] = useState('');
|
||||
const [updateContent, setUpdateContent] = useState('');
|
||||
|
||||
// FIXME 强制登出
|
||||
useLayoutEffect(() => {
|
||||
handleLogout();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const checkUpdate = async () => {
|
||||
try {
|
||||
const res = await fetch('https://api.github.com/repos/hzm0321/real-time-fund/releases/latest');
|
||||
console.log(packageJson.version)
|
||||
if (!res.ok) return;
|
||||
const data = await res.json();
|
||||
if (data.tag_name) {
|
||||
@@ -1869,6 +1874,7 @@ export default function HomePage() {
|
||||
if (remoteVersion !== packageJson.version) {
|
||||
setHasUpdate(true);
|
||||
setLatestVersion(remoteVersion);
|
||||
setUpdateContent(data.body || '');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -3224,7 +3230,6 @@ export default function HomePage() {
|
||||
}))
|
||||
: [];
|
||||
return {
|
||||
version: 1,
|
||||
funds,
|
||||
favorites: cleanedFavorites,
|
||||
groups: cleanedGroups,
|
||||
@@ -3235,7 +3240,6 @@ export default function HomePage() {
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
version: 1,
|
||||
funds: [],
|
||||
favorites: [],
|
||||
groups: [],
|
||||
@@ -3366,13 +3370,11 @@ export default function HomePage() {
|
||||
const exportLocalData = async () => {
|
||||
try {
|
||||
const payload = {
|
||||
version: 1,
|
||||
funds: JSON.parse(localStorage.getItem('funds') || '[]'),
|
||||
favorites: JSON.parse(localStorage.getItem('favorites') || '[]'),
|
||||
groups: JSON.parse(localStorage.getItem('groups') || '[]'),
|
||||
collapsedCodes: JSON.parse(localStorage.getItem('collapsedCodes') || '[]'),
|
||||
refreshMs: parseInt(localStorage.getItem('refreshMs') || '30000', 10),
|
||||
viewMode,
|
||||
holdings: JSON.parse(localStorage.getItem('holdings') || '{}'),
|
||||
exportedAt: new Date().toISOString()
|
||||
};
|
||||
@@ -3579,7 +3581,6 @@ export default function HomePage() {
|
||||
<span>基估宝</span>
|
||||
</div>
|
||||
<div className="actions">
|
||||
<img alt="项目Github地址" src={githubImg.src} style={{ width: '30px', height: '30px', cursor: 'pointer' }} onClick={() => window.open("https://github.com/hzm0321/real-time-fund")} />
|
||||
{hasUpdate && (
|
||||
<div
|
||||
className="badge"
|
||||
@@ -3590,6 +3591,7 @@ export default function HomePage() {
|
||||
<UpdateIcon width="14" height="14" />
|
||||
</div>
|
||||
)}
|
||||
<img alt="项目Github地址" src={githubImg.src} style={{ width: '30px', height: '30px', cursor: 'pointer' }} onClick={() => window.open("https://github.com/hzm0321/real-time-fund")} />
|
||||
<div className="badge" title="当前刷新频率">
|
||||
<span>刷新</span>
|
||||
<strong>{Math.round(refreshMs / 1000)}秒</strong>
|
||||
@@ -3604,8 +3606,16 @@ export default function HomePage() {
|
||||
>
|
||||
<RefreshIcon className={refreshing ? 'spin' : ''} width="18" height="18" />
|
||||
</button>
|
||||
<button
|
||||
className="icon-button"
|
||||
aria-label="打开设置"
|
||||
onClick={() => setSettingsOpen(true)}
|
||||
title="设置"
|
||||
>
|
||||
<SettingsIcon width="18" height="18" />
|
||||
</button>
|
||||
{/* 用户菜单 */}
|
||||
<div className="user-menu-container" ref={userMenuRef}>
|
||||
<div className="user-menu-container" ref={userMenuRef} hidden>
|
||||
<button
|
||||
className={`icon-button user-menu-trigger ${user ? 'logged-in' : ''}`}
|
||||
aria-label={user ? '用户菜单' : '登录'}
|
||||
@@ -4599,6 +4609,7 @@ export default function HomePage() {
|
||||
<FeedbackModal
|
||||
key={feedbackNonce}
|
||||
onClose={() => setFeedbackOpen(false)}
|
||||
user={user}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
@@ -4837,9 +4848,28 @@ export default function HomePage() {
|
||||
<UpdateIcon width="20" height="20" style={{color: 'var(--success)'}} />
|
||||
<span>更新提示</span>
|
||||
</div>
|
||||
<p className="muted" style={{ marginBottom: 24, fontSize: '14px', lineHeight: '1.6' }}>
|
||||
检测到新版本,是否刷新浏览器以更新
|
||||
</p>
|
||||
<div style={{ marginBottom: 24 }}>
|
||||
<p className="muted" style={{ fontSize: '14px', lineHeight: '1.6', marginBottom: 12 }}>
|
||||
检测到新版本,是否刷新浏览器以更新?
|
||||
<br/>
|
||||
更新内容如下:
|
||||
</p>
|
||||
{updateContent && (
|
||||
<div style={{
|
||||
background: 'rgba(0,0,0,0.2)',
|
||||
padding: '12px',
|
||||
borderRadius: '8px',
|
||||
fontSize: '13px',
|
||||
lineHeight: '1.5',
|
||||
maxHeight: '200px',
|
||||
overflowY: 'auto',
|
||||
whiteSpace: 'pre-wrap',
|
||||
border: '1px solid rgba(255,255,255,0.1)'
|
||||
}}>
|
||||
{updateContent}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="row" style={{ gap: 12 }}>
|
||||
<button
|
||||
className="button secondary"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "real-time-fund",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
Reference in New Issue
Block a user