(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
99
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix some mobile stuff

scanash00 455f9fd2 0f4e727e

+68 -27
+3 -3
web/src/components/feed/MasonryFeed.tsx
··· 107 107 } 108 108 109 109 return ( 110 - <div className="columns-1 sm:columns-2 xl:columns-3 2xl:columns-4 gap-4 animate-fade-in"> 110 + <div className="columns-1 sm:columns-2 md:columns-3 xl:columns-4 gap-4 animate-fade-in"> 111 111 {items.map((item) => ( 112 112 <div key={item.uri || item.cid} className="break-inside-avoid mb-4"> 113 113 <Card item={item} onDelete={handleDelete} /> ··· 158 158 onChange={handleTabChange} 159 159 /> 160 160 </div> 161 - <LayoutToggle /> 161 + <LayoutToggle className="hidden sm:inline-flex" /> 162 162 </div> 163 163 </div> 164 164 )} 165 165 166 166 {!showTabs && ( 167 167 <div className="flex justify-end mb-4"> 168 - <LayoutToggle /> 168 + <LayoutToggle className="hidden sm:inline-flex" /> 169 169 </div> 170 170 )} 171 171
+14
web/src/components/navigation/MobileNav.tsx
··· 17 17 Highlighter, 18 18 X, 19 19 } from "lucide-react"; 20 + import { AppleIcon } from "../common/Icons"; 20 21 21 22 export default function MobileNav() { 22 23 const user = useStore($user); ··· 118 119 <Settings size={20} /> 119 120 <span>Settings</span> 120 121 </Link> 122 + 123 + <div className="h-px bg-surface-200 dark:bg-surface-700 my-2" /> 124 + 125 + <a 126 + href="https://www.icloud.com/shortcuts/21c87edf29b046db892c9e57dac6d1fd" 127 + target="_blank" 128 + rel="noopener noreferrer" 129 + className="flex items-center gap-3 p-3 rounded-xl hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors text-surface-700 dark:text-surface-200" 130 + onClick={closeMenu} 131 + > 132 + <AppleIcon size={20} /> 133 + <span>iOS Shortcut</span> 134 + </a> 121 135 122 136 <div className="h-px bg-surface-200 dark:bg-surface-700 my-2" /> 123 137
+7 -2
web/src/components/ui/LayoutToggle.tsx
··· 8 8 } from "../../store/feedLayout"; 9 9 import { clsx } from "clsx"; 10 10 11 - export default function LayoutToggle() { 11 + export default function LayoutToggle({ className }: { className?: string }) { 12 12 const layout = useStore($feedLayout); 13 13 14 14 const options: { id: FeedLayout; icon: typeof List; label: string }[] = [ ··· 17 17 ]; 18 18 19 19 return ( 20 - <div className="inline-flex items-center rounded-lg border border-surface-200 dark:border-surface-700 p-0.5 bg-surface-100 dark:bg-surface-800/60"> 20 + <div 21 + className={clsx( 22 + "inline-flex items-center rounded-lg border border-surface-200 dark:border-surface-700 p-0.5 bg-surface-100 dark:bg-surface-800/60", 23 + className, 24 + )} 25 + > 21 26 {options.map((opt) => ( 22 27 <button 23 28 key={opt.id}
+25 -3
web/src/views/content/Url.tsx
··· 17 17 Globe, 18 18 } from "lucide-react"; 19 19 20 - import { EmptyState, Tabs } from "../../components/ui"; 20 + import { EmptyState, Tabs, Input, Button } from "../../components/ui"; 21 21 22 22 export default function UrlPage() { 23 23 const user = useStore($user); ··· 187 187 Explore 188 188 </h1> 189 189 <p className="text-surface-500 dark:text-surface-400 max-w-md mx-auto mb-8"> 190 - Search for any URL in the sidebar to specific see annotations and 190 + Search for any URL in the sidebar to see specific annotations and 191 191 highlights. 192 192 </p> 193 + 194 + <form 195 + onSubmit={(e) => { 196 + e.preventDefault(); 197 + const formData = new FormData(e.currentTarget); 198 + const q = formData.get("q") as string; 199 + if (q?.trim()) { 200 + navigate(`/url?q=${encodeURIComponent(q.trim())}`); 201 + } 202 + }} 203 + className="max-w-md mx-auto mb-8 flex gap-2" 204 + > 205 + <div className="flex-1"> 206 + <Input 207 + name="q" 208 + placeholder="https://example.com" 209 + className="w-full bg-surface-50 dark:bg-surface-800" 210 + autoFocus 211 + /> 212 + </div> 213 + <Button type="submit">Search</Button> 214 + </form> 193 215 194 216 {recentSearches.length > 0 && ( 195 217 <div className="text-left max-w-lg mx-auto bg-surface-50 dark:bg-surface-800/50 rounded-2xl p-6 border border-surface-100 dark:border-surface-800"> ··· 259 281 className="flex items-center gap-1.5 px-3 py-1.5 bg-surface-100 dark:bg-surface-800 hover:bg-surface-200 dark:hover:bg-surface-700 text-surface-900 dark:text-white text-sm font-medium rounded-lg transition-colors" 260 282 > 261 283 {copied ? <Check size={14} /> : <Copy size={14} />} 262 - {copied ? "Copied" : "Share"} 284 + {copied ? "Copied" : "Share your thoughts on this URL"} 263 285 </button> 264 286 )} 265 287 </div>
+19 -19
web/src/views/content/UserUrl.tsx
··· 135 135 136 136 return ( 137 137 <div className="max-w-3xl mx-auto pb-20"> 138 - <header className="flex items-center gap-6 mb-8 p-6 bg-white rounded-2xl border border-surface-200 shadow-sm"> 138 + <header className="flex items-center gap-6 mb-8 p-6 bg-white dark:bg-surface-800 rounded-2xl border border-surface-200 dark:border-surface-700 shadow-sm"> 139 139 <a 140 140 href={bskyProfileUrl} 141 141 target="_blank" ··· 146 146 <img 147 147 src={avatarUrl} 148 148 alt={displayName} 149 - className="w-20 h-20 rounded-full object-cover border-4 border-surface-50" 149 + className="w-20 h-20 rounded-full object-cover border-4 border-surface-50 dark:border-surface-700" 150 150 /> 151 151 ) : ( 152 - <div className="w-20 h-20 rounded-full bg-surface-100 flex items-center justify-center text-2xl font-bold text-surface-500 border-4 border-surface-50"> 152 + <div className="w-20 h-20 rounded-full bg-surface-100 dark:bg-surface-700 flex items-center justify-center text-2xl font-bold text-surface-500 dark:text-surface-400 border-4 border-surface-50 dark:border-surface-700"> 153 153 {getInitial()} 154 154 </div> 155 155 )} 156 156 </a> 157 157 <div className="flex-1"> 158 - <h1 className="text-2xl font-bold text-surface-900 mb-1"> 158 + <h1 className="text-2xl font-bold text-surface-900 dark:text-white mb-1"> 159 159 {displayName} 160 160 </h1> 161 161 {displayHandle && ( ··· 163 163 href={bskyProfileUrl} 164 164 target="_blank" 165 165 rel="noopener noreferrer" 166 - className="text-surface-500 hover:text-primary-600 transition-colors bg-surface-50 hover:bg-primary-50 px-2 py-1 rounded-md text-sm inline-flex items-center gap-1" 166 + className="text-surface-500 dark:text-surface-400 hover:text-primary-600 transition-colors bg-surface-50 dark:bg-surface-700 hover:bg-primary-50 dark:hover:bg-primary-900/30 px-2 py-1 rounded-md text-sm inline-flex items-center gap-1" 167 167 > 168 168 @{displayHandle} <ExternalLink size={12} /> 169 169 </a> ··· 171 171 </div> 172 172 </header> 173 173 174 - <div className="mb-8 p-4 bg-surface-50 border border-surface-200 rounded-xl flex flex-col sm:flex-row sm:items-center gap-4"> 175 - <span className="text-sm font-semibold text-surface-500 uppercase tracking-wide"> 174 + <div className="mb-8 p-4 bg-surface-50 dark:bg-surface-800 border border-surface-200 dark:border-surface-700 rounded-xl flex flex-col sm:flex-row sm:items-center gap-4"> 175 + <span className="text-sm font-semibold text-surface-500 dark:text-surface-400 uppercase tracking-wide"> 176 176 Annotations on: 177 177 </span> 178 178 <a ··· 199 199 )} 200 200 201 201 {!loading && !error && totalItems === 0 && ( 202 - <div className="text-center py-16 bg-surface-50 rounded-2xl border border-dashed border-surface-200"> 203 - <div className="w-12 h-12 bg-surface-100 rounded-full flex items-center justify-center mx-auto mb-4 text-surface-400"> 202 + <div className="text-center py-16 bg-surface-50 dark:bg-surface-800 rounded-2xl border border-dashed border-surface-200 dark:border-surface-700"> 203 + <div className="w-12 h-12 bg-surface-100 dark:bg-surface-700 rounded-full flex items-center justify-center mx-auto mb-4 text-surface-400"> 204 204 <PenTool size={24} /> 205 205 </div> 206 - <h3 className="text-lg font-bold text-surface-900 mb-1"> 206 + <h3 className="text-lg font-bold text-surface-900 dark:text-white mb-1"> 207 207 No items found 208 208 </h3> 209 - <p className="text-surface-500"> 209 + <p className="text-surface-500 dark:text-surface-400"> 210 210 {displayName} hasn&apos;t annotated this page yet. 211 211 </p> 212 212 </div> ··· 215 215 {!loading && !error && totalItems > 0 && ( 216 216 <div className="animate-fade-in"> 217 217 <div className="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-6"> 218 - <h2 className="text-xl font-bold text-surface-900"> 218 + <h2 className="text-xl font-bold text-surface-900 dark:text-white"> 219 219 {totalItems} item{totalItems !== 1 ? "s" : ""} 220 220 </h2> 221 - <div className="flex bg-surface-100 p-1 rounded-xl self-start md:self-auto"> 221 + <div className="flex bg-surface-100 dark:bg-surface-800 p-1 rounded-xl self-start md:self-auto"> 222 222 <button 223 223 className={clsx( 224 224 "px-4 py-1.5 rounded-lg text-sm font-medium transition-all", 225 225 activeTab === "all" 226 - ? "bg-white text-surface-900 shadow-sm" 227 - : "text-surface-500 hover:text-surface-700", 226 + ? "bg-white dark:bg-surface-700 text-surface-900 dark:text-white shadow-sm" 227 + : "text-surface-500 dark:text-surface-400 hover:text-surface-700 dark:hover:text-surface-200", 228 228 )} 229 229 onClick={() => setActiveTab("all")} 230 230 > ··· 234 234 className={clsx( 235 235 "px-4 py-1.5 rounded-lg text-sm font-medium transition-all", 236 236 activeTab === "annotations" 237 - ? "bg-white text-surface-900 shadow-sm" 238 - : "text-surface-500 hover:text-surface-700", 237 + ? "bg-white dark:bg-surface-700 text-surface-900 dark:text-white shadow-sm" 238 + : "text-surface-500 dark:text-surface-400 hover:text-surface-700 dark:hover:text-surface-200", 239 239 )} 240 240 onClick={() => setActiveTab("annotations")} 241 241 > ··· 245 245 className={clsx( 246 246 "px-4 py-1.5 rounded-lg text-sm font-medium transition-all", 247 247 activeTab === "highlights" 248 - ? "bg-white text-surface-900 shadow-sm" 249 - : "text-surface-500 hover:text-surface-700", 248 + ? "bg-white dark:bg-surface-700 text-surface-900 dark:text-white shadow-sm" 249 + : "text-surface-500 dark:text-surface-400 hover:text-surface-700 dark:hover:text-surface-200", 250 250 )} 251 251 onClick={() => setActiveTab("highlights")} 252 252 >