This repository has no description
0

Configure Feed

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

change filters setup

+84 -42
+38 -12
src/components/CollectionsFeed/CollectionsFeed.css
··· 105 105 } 106 106 107 107 .collections-filter { 108 - display: flex; 109 - flex-wrap: wrap; 110 - gap: 10px; 111 - max-height: 200px; 108 + max-height: 300px; 112 109 overflow-y: auto; 113 110 padding: 10px 0; 111 + background-color: var(--background); 112 + border-radius: 8px; 113 + border: 1px solid var(--card-border); 114 + margin-top: 10px; 114 115 } 115 116 116 - .collection-checkbox { 117 + .collection-item { 118 + padding: 8px 12px; 119 + border-bottom: 1px solid var(--card-border); 120 + cursor: pointer; 117 121 display: flex; 118 122 align-items: center; 119 - margin-right: 15px; 120 - margin-bottom: 5px; 123 + transition: background-color 0.2s; 121 124 } 122 125 123 - .collection-checkbox input[type="checkbox"] { 124 - margin-right: 5px; 126 + .collection-item:last-child { 127 + border-bottom: none; 125 128 } 126 129 127 - .collection-checkbox label { 128 - font-size: 0.9rem; 130 + .collection-item:hover { 131 + background-color: rgba(0, 0, 0, 0.05); 132 + } 133 + 134 + .collection-item.selected { 135 + background-color: rgba(var(--button-bg-rgb), 0.1); 136 + } 137 + 138 + .collection-item-name { 139 + font-size: 0.95rem; 129 140 color: var(--text); 130 - cursor: pointer; 141 + flex-grow: 1; 142 + } 143 + 144 + .collection-item-checkbox { 145 + margin-right: 10px; 146 + width: 16px; 147 + height: 16px; 148 + accent-color: var(--button-bg); 149 + } 150 + 151 + .dark-mode .collection-item:hover { 152 + background-color: rgba(255, 255, 255, 0.05); 153 + } 154 + 155 + .dark-mode .collection-item.selected { 156 + background-color: rgba(var(--button-bg-rgb), 0.2); 131 157 } 132 158 133 159 .refresh-button {
+21 -15
src/components/CollectionsFeed/CollectionsFeed.js
··· 106 106 107 107 // Fetch records for each collection in parallel 108 108 const fetchPromises = collectionsList.map(async (collection) => { 109 - let url = `${endpoint}/xrpc/com.atproto.repo.listRecords?repo=${encodeURIComponent(userDid)}&collection=${encodeURIComponent(collection)}&limit=10`; 109 + // Limit to 5 records per collection initially (for 20 records total across ~4 collections) 110 + let url = `${endpoint}/xrpc/com.atproto.repo.listRecords?repo=${encodeURIComponent(userDid)}&collection=${encodeURIComponent(collection)}&limit=5`; 110 111 111 112 // Add cursor if loading more and we have a cursor for this collection 112 113 if (isLoadMore && newCursors[collection]) { ··· 155 156 return new Date(b.timestamp) - new Date(a.timestamp); 156 157 }); 157 158 159 + // If not loading more, limit to 20 most recent records 160 + if (!isLoadMore) { 161 + allRecords = allRecords.slice(0, 20); 162 + } 163 + 158 164 setRecords(allRecords); 159 165 setCollectionCursors(newCursors); 160 166 setFetchingMore(false); ··· 165 171 } 166 172 }; 167 173 168 - // Handle filter change 169 - const handleFilterChange = (e) => { 170 - const { value, checked } = e.target; 171 - 172 - if (checked) { 173 - setSelectedCollections(prev => [...prev, value]); 174 + // Toggle collection selection 175 + const toggleCollection = (collection) => { 176 + if (selectedCollections.includes(collection)) { 177 + setSelectedCollections(prev => prev.filter(item => item !== collection)); 174 178 } else { 175 - setSelectedCollections(prev => prev.filter(item => item !== value)); 179 + setSelectedCollections(prev => [...prev, collection]); 176 180 } 177 181 }; 178 182 ··· 294 298 295 299 <div className="collections-filter"> 296 300 {collections.map(collection => ( 297 - <div key={collection} className="collection-checkbox"> 301 + <div 302 + key={collection} 303 + className={`collection-item ${selectedCollections.includes(collection) ? 'selected' : ''}`} 304 + onClick={() => toggleCollection(collection)} 305 + > 298 306 <input 299 307 type="checkbox" 300 - id={`collection-${collection}`} 301 - value={collection} 308 + className="collection-item-checkbox" 302 309 checked={selectedCollections.includes(collection)} 303 - onChange={handleFilterChange} 310 + onChange={() => {}} // Handled by the div onClick 311 + onClick={(e) => e.stopPropagation()} 304 312 /> 305 - <label htmlFor={`collection-${collection}`}> 306 - {collection.split('.').pop()} 307 - </label> 313 + <span className="collection-item-name">{collection}</span> 308 314 </div> 309 315 ))} 310 316 </div>
+21 -7
src/components/CollectionsFeed/FeedTimeline.css
··· 7 7 } 8 8 9 9 .feed-item { 10 - background-color: var(--navbar-bg); 11 - border: 1px solid var(--card-border); 12 - border-radius: 8px; 10 + background: var(--navbar-bg); 13 11 padding: 15px; 12 + box-shadow: 0 2px 4px rgba(0,0,0,0.1); 13 + border: 5px solid var(--card-border); 14 + border-radius: 12px; 14 15 transition: transform 0.2s, box-shadow 0.2s; 15 16 } 16 17 17 18 .feed-item:hover { 18 19 transform: translateY(-2px); 19 - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); 20 + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); 20 21 } 21 22 22 23 .feed-item-header { ··· 24 25 justify-content: space-between; 25 26 align-items: center; 26 27 margin-bottom: 10px; 28 + border-bottom: 1px solid var(--card-border); 29 + padding-bottom: 10px; 27 30 } 28 31 29 32 .collection-type { ··· 41 44 margin-left: 8px; 42 45 font-size: 0.8rem; 43 46 color: var(--text); 44 - opacity: 0.6; 47 + opacity: 0.7; 45 48 } 46 49 47 50 .record-rkey { ··· 55 58 } 56 59 57 60 .feed-item-content { 58 - padding: 5px 0; 61 + padding: 10px 0; 59 62 margin-bottom: 10px; 60 - border-top: 1px solid var(--card-border); 61 63 border-bottom: 1px solid var(--card-border); 62 64 } 63 65 ··· 88 90 color: var(--text); 89 91 opacity: 0.7; 90 92 font-style: italic; 93 + } 94 + 95 + /* Dark mode overrides */ 96 + .dark-mode .feed-item { 97 + background: #2c2c2c; 98 + border: 5px solid #444; 99 + box-shadow: 0 2px 4px rgba(0,0,0,0.6); 100 + } 101 + 102 + .dark-mode .feed-item-header, 103 + .dark-mode .feed-item-content { 104 + border-color: #555; 91 105 } 92 106 93 107 /* Responsive styles */
+1 -8
src/components/CollectionsFeed/FeedTimeline.js
··· 17 17 } 18 18 }; 19 19 20 - // Helper to get a readable collection name 21 - const getCollectionDisplayName = (collection) => { 22 - // Extract the last part of the collection name (e.g., 'like' from 'app.bsky.feed.like') 23 - const parts = collection.split('.'); 24 - return parts[parts.length - 1]; 25 - }; 26 - 27 20 return ( 28 21 <div className="feed-timeline"> 29 22 {records.map((record, index) => ( 30 23 <div key={`${record.collection}-${record.rkey}-${index}`} className="feed-item"> 31 24 <div className="feed-item-header"> 32 25 <div className="collection-type"> 33 - <span className="collection-name">{getCollectionDisplayName(record.collection)}</span> 26 + <span className="collection-name">{record.collection.split('.').pop()}</span> 34 27 <span className="collection-full">{record.collection}</span> 35 28 </div> 36 29 <div className="record-rkey">{record.rkey}</div>
+3
src/styles/variables.css
··· 2 2 --navbar-bg: #ffffff; 3 3 --navbar-text: #000000; 4 4 --button-bg: #3B9AF8; 5 + --button-bg-rgb: 59, 154, 248; /* RGB version for transparency */ 5 6 --button-text: #ffffff; 6 7 --background: #f0f0f0; 7 8 --text: #000000; ··· 14 15 --navbar-bg: #1f1f1f; 15 16 --navbar-text: #f5f5f5; 16 17 --button-bg: #3b9af8; 18 + --button-bg-rgb: 59, 154, 248; /* RGB version for transparency */ 17 19 --button-text: #f5f5f5; 18 20 --background: #181818; 19 21 --text: #ffffff; ··· 25 27 --navbar-bg: #ffffff; 26 28 --navbar-text: #000000; 27 29 --button-bg: #3B9AF8; 30 + --button-bg-rgb: 59, 154, 248; /* RGB version for transparency */ 28 31 --button-text: #ffffff; 29 32 --background: #f0f0f0; 30 33 --text: #000000;