diff --git a/src/components/sidebar/MainPageSidebar.tsx b/src/components/sidebar/MainPageSidebar.tsx index 258fd85..0b72932 100644 --- a/src/components/sidebar/MainPageSidebar.tsx +++ b/src/components/sidebar/MainPageSidebar.tsx @@ -1,9 +1,155 @@ +import { useCallback, useEffect, useState } from "react"; import Enclave from "@/app/app"; +import { getCyberNews, NewsItem } from "@/lib/cyberNews"; +import { openUrl } from "@tauri-apps/plugin-opener"; +import { Button } from "@/components/ui/button"; +import { RefreshCw, Rss } from "lucide-react"; +import { cn } from "@/lib/utils"; -export default function MainPageSidebar({ - appRef, -}: { +function formatTime(publishedAt: number): string { + if (!publishedAt) return ""; + + const diff = Date.now() - publishedAt; + const minutes = Math.floor(diff / 60_000); + + if (minutes < 1) return "just now"; + if (minutes < 60) return `${minutes}m ago`; + + const hours = Math.floor(minutes / 60); + if (hours < 24) return `${hours}h ago`; + + const days = Math.floor(hours / 24); + return `${days}d ago`; +} + +function StaticFallback() { + const staticLinks = [ + { + title: "Surveillance Self-Defense", + source: "EFF", + href: "https://ssd.eff.org", + }, + { + title: "Privacy Guides", + source: "Community", + href: "https://www.privacyguides.org", + }, + { + title: "The Hacker News", + source: "News", + href: "https://thehackernews.com", + }, + { + title: "Krebs on Security", + source: "News", + href: "https://krebsonsecurity.com", + }, + { + title: "CISA Alerts", + source: "Gov", + href: "https://www.cisa.gov/news-events/cybersecurity-advisories", + }, + ]; + + return ( +
+

+ Live news couldn't be loaded right now. Here are security resources you + can open manually: +

+ {staticLinks.map((link) => ( + + ))} +
+ ); +} + +export default function MainPageSidebar(_props: { appRef: React.RefObject; }) { - return null; + const [items, setItems] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + + const load = useCallback(() => { + setLoading(true); + setError(false); + + getCyberNews() + .then((news) => setItems(news)) + .catch(() => { + setItems(null); + setError(true); + }) + .finally(() => setLoading(false)); + }, []); + + useEffect(() => { + load(); + }, [load]); + + return ( +
+
+

+ + Security News +

+ +
+ +
+ {loading && items === null && ( +

+ Loading news… +

+ )} + + {error && !loading && } + + {items && ( +
+ {items.map((item) => ( + + ))} +
+ )} +
+
+ ); }