Write on the margins of the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
at main 6.2 kB view raw
1import { useState, useEffect } from "react"; 2import { Link } from "react-router-dom"; 3import { ExternalLink } from "lucide-react"; 4import { 5 SiFirefox, 6 SiGooglechrome, 7 SiGithub, 8 SiBluesky, 9 SiApple, 10 SiKofi, 11 SiDiscord, 12} from "react-icons/si"; 13import { FaEdge } from "react-icons/fa"; 14import { useAuth } from "../context/AuthContext"; 15import { getTrendingTags } from "../api/client"; 16 17const isFirefox = 18 typeof navigator !== "undefined" && /Firefox/i.test(navigator.userAgent); 19const isEdge = 20 typeof navigator !== "undefined" && /Edg/i.test(navigator.userAgent); 21const isMobileSafari = 22 typeof navigator !== "undefined" && 23 /iPhone|iPad|iPod/.test(navigator.userAgent) && 24 /Safari/.test(navigator.userAgent) && 25 !/CriOS|FxiOS|OPiOS|EdgiOS/.test(navigator.userAgent); 26 27function getExtensionInfo() { 28 if (isMobileSafari) { 29 return { 30 url: "https://margin.at/soon", 31 icon: SiApple, 32 name: "iOS", 33 label: "Coming Soon", 34 }; 35 } 36 if (isFirefox) { 37 return { 38 url: "https://addons.mozilla.org/en-US/firefox/addon/margin/", 39 icon: SiFirefox, 40 name: "Firefox", 41 label: "Install for Firefox", 42 }; 43 } 44 if (isEdge) { 45 return { 46 url: "https://microsoftedge.microsoft.com/addons/detail/margin/nfjnmllpdgcdnhmmggjihjbidmeadddn", 47 icon: FaEdge, 48 name: "Edge", 49 label: "Install for Edge", 50 }; 51 } 52 return { 53 url: "https://chromewebstore.google.com/detail/margin/cgpmbiiagnehkikhcbnhiagfomajncpa/", 54 icon: SiGooglechrome, 55 name: "Chrome", 56 label: "Install for Chrome", 57 }; 58} 59 60export default function RightSidebar() { 61 const { isAuthenticated } = useAuth(); 62 const ext = getExtensionInfo(); 63 const ExtIcon = ext.icon; 64 const [trendingTags, setTrendingTags] = useState([]); 65 const [loading, setLoading] = useState(true); 66 67 useEffect(() => { 68 getTrendingTags() 69 .then((tags) => setTrendingTags(tags)) 70 .catch((err) => console.error("Failed to fetch trending tags:", err)) 71 .finally(() => setLoading(false)); 72 }, []); 73 74 return ( 75 <aside className="right-sidebar"> 76 <div className="right-section"> 77 <h3 className="right-section-title"> 78 {isMobileSafari ? "Save from Safari" : "Get the Extension"} 79 </h3> 80 <p className="right-section-desc"> 81 {isMobileSafari 82 ? "Bookmark pages using Safari's share sheet" 83 : "Annotate, highlight, and bookmark any webpage"} 84 </p> 85 <a 86 href={ext.url} 87 target="_blank" 88 rel="noopener noreferrer" 89 className="right-extension-btn" 90 > 91 <ExtIcon size={18} /> 92 {ext.label} 93 <ExternalLink size={14} /> 94 </a> 95 </div> 96 97 {isAuthenticated ? ( 98 <div className="right-section"> 99 <h3 className="right-section-title">Trending Tags</h3> 100 <div className="right-links"> 101 {loading ? ( 102 <span className="right-section-desc">Loading...</span> 103 ) : trendingTags.length > 0 ? ( 104 trendingTags.map(({ tag, count }) => ( 105 <Link 106 key={tag} 107 to={`/?tag=${encodeURIComponent(tag)}`} 108 className="right-link" 109 > 110 <span>#{tag}</span> 111 <span style={{ fontSize: "0.75rem", opacity: 0.6 }}> 112 {count} 113 </span> 114 </Link> 115 )) 116 ) : ( 117 <span className="right-section-desc">No trending tags yet</span> 118 )} 119 </div> 120 </div> 121 ) : ( 122 <div className="right-section"> 123 <h3 className="right-section-title">Explore</h3> 124 <nav className="right-links"> 125 <Link to="/url" className="right-link"> 126 Browse by URL 127 </Link> 128 </nav> 129 </div> 130 )} 131 132 <div className="right-section"> 133 <h3 className="right-section-title">Resources</h3> 134 <nav className="right-links"> 135 <a 136 href="https://github.com/margin-at/margin" 137 target="_blank" 138 rel="noopener noreferrer" 139 className="right-link" 140 > 141 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> 142 <SiGithub size={16} /> 143 GitHub 144 </div> 145 <ExternalLink size={12} /> 146 </a> 147 <a 148 href="https://tangled.org/margin.at/margin" 149 target="_blank" 150 rel="noopener noreferrer" 151 className="right-link" 152 > 153 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> 154 <div className="tangled-icon" /> 155 Tangled 156 </div> 157 <ExternalLink size={12} /> 158 </a> 159 <a 160 href="https://bsky.app/profile/margin.at" 161 target="_blank" 162 rel="noopener noreferrer" 163 className="right-link" 164 > 165 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> 166 <SiBluesky size={16} /> 167 Bluesky 168 </div> 169 <ExternalLink size={12} /> 170 </a> 171 <a 172 href="https://discord.gg/ZQbkGqwzBH" 173 target="_blank" 174 rel="noopener noreferrer" 175 className="right-link" 176 > 177 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> 178 <SiDiscord size={16} /> 179 Discord 180 </div> 181 <ExternalLink size={12} /> 182 </a> 183 <a 184 href="https://ko-fi.com/scan" 185 target="_blank" 186 rel="noopener noreferrer" 187 className="right-link" 188 > 189 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}> 190 <SiKofi size={16} /> 191 Donate 192 </div> 193 <ExternalLink size={12} /> 194 </a> 195 </nav> 196 </div> 197 198 <div className="right-footer"> 199 <Link to="/privacy">Privacy</Link> 200 <span>·</span> 201 <Link to="/terms">Terms</Link> 202 </div> 203 </aside> 204 ); 205}