this repo has no description
0
fork

Configure Feed

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

Grouped favourite+boost notifications!

+122 -23
+3 -3
src/app.css
··· 1258 1258 } 1259 1259 /* I'm just feeling bored, so having fun here */ 1260 1260 @media (hover: hover) { 1261 - .avatars-stack > * { 1261 + .avatars-stack > * img { 1262 1262 transition: transform 0.3s ease-in-out; 1263 1263 } 1264 - .avatars-stack:hover > *:nth-of-type(odd) { 1264 + .avatars-stack:hover > *:nth-of-type(odd) img { 1265 1265 transform: rotate(15deg); 1266 1266 } 1267 - .avatars-stack:hover > *:nth-of-type(even) { 1267 + .avatars-stack:hover > *:nth-of-type(even) img { 1268 1268 transform: rotate(-15deg); 1269 1269 } 1270 1270 }
+49
src/pages/notifications.css
··· 20 20 flex-shrink: 0; 21 21 opacity: 0.75; 22 22 color: var(--text-insignificant-color); 23 + line-height: 0; 23 24 } 24 25 .notification-type.notification-mention { 25 26 color: var(--reply-to-color); ··· 32 33 } 33 34 .notification-type.notification-poll { 34 35 color: var(--link-color); 36 + } 37 + 38 + .notification .reblog-icon { 39 + color: var(--reblog-color); 40 + } 41 + .notification .favourite-icon { 42 + color: var(--favourite-color); 43 + } 44 + 45 + .notification .account-avatar-stack { 46 + position: relative; 47 + text-align: center; 48 + } 49 + .notification .account-avatar-stack .account-sub-icons { 50 + display: block; 51 + width: fit-content; 52 + margin: -0.25em auto 0; 53 + line-height: 1; 54 + background-color: var(--bg-blur-color); 55 + /* background-image: linear-gradient( 56 + to bottom, 57 + var(--bg-color), 58 + var(--bg-blur-color) 59 + ); */ 60 + backdrop-filter: blur(16px) saturate(3); 61 + padding: 2px 4px; 62 + border-radius: 999px; 63 + overflow: hidden; 64 + border: var(--hairline-width) solid var(--bg-color); 65 + box-shadow: 0 1px var(--drop-shadow-color); 66 + } 67 + .notification .avatars-stack .account-avatar-stack .account-sub-icons .icon { 68 + transition: transform 0.2s ease-out; 69 + } 70 + .notification 71 + .avatars-stack:hover 72 + .account-avatar-stack 73 + .account-sub-icons 74 + .icon { 75 + transform: rotate(-15deg); 76 + } 77 + .notification 78 + .avatars-stack:hover 79 + .account-avatar-stack 80 + .account-sub-icons 81 + .icon 82 + + .icon { 83 + transform: rotate(15deg); 35 84 } 36 85 37 86 .notification .status-link {
+70 -20
src/pages/notifications.jsx
··· 45 45 'poll-self': 'A poll you have created has ended.', 46 46 'poll-voted': 'A poll you have voted in has ended.', 47 47 update: 'A status you interacted with has been edited.', 48 + 'favourite+reblog': 'boosted & favourited your status.', 49 + }; 50 + 51 + const NOTIFICATION_ICONS = { 52 + mention: 'comment', 53 + status: 'notification', 54 + reblog: 'rocket', 55 + follow: 'follow', 56 + follow_request: 'follow-add', 57 + favourite: 'heart', 58 + poll: 'poll', 59 + update: 'pencil', 48 60 }; 49 61 50 62 const LIMIT = 30; // 30 is the maximum limit :( ··· 275 287 ); 276 288 } 277 289 function Notification({ notification, instance }) { 278 - const { id, type, status, account, _accounts } = notification; 290 + const { id, status, account, _accounts } = notification; 291 + let { type } = notification; 279 292 280 293 // status = Attached when type of the notification is favourite, reblog, status, mention, poll, or update 281 294 const actualStatusID = status?.reblog?.id || status?.id; ··· 283 296 const currentAccount = store.session.get('currentAccount'); 284 297 const isSelf = currentAccount === account?.id; 285 298 const isVoted = status?.poll?.voted; 299 + 300 + let favsCount = 0; 301 + let reblogsCount = 0; 302 + if (type === 'favourite+reblog') { 303 + for (const account of _accounts) { 304 + if (account._types?.includes('favourite')) { 305 + favsCount++; 306 + } else if (account._types?.includes('reblog')) { 307 + reblogsCount++; 308 + } 309 + } 310 + if (!reblogsCount && favsCount) type = 'favourite'; 311 + if (!favsCount && reblogsCount) type = 'reblog'; 312 + } 286 313 287 314 const text = 288 315 type === 'poll' ··· 295 322 class={`notification-type notification-${type}`} 296 323 title={new Date(notification.createdAt).toLocaleString()} 297 324 > 298 - <Icon 299 - icon={ 300 - { 301 - mention: 'comment', 302 - status: 'notification', 303 - reblog: 'rocket', 304 - follow: 'follow', 305 - follow_request: 'follow-add', 306 - favourite: 'heart', 307 - poll: 'poll', 308 - update: 'pencil', 309 - }[type] || 'notification' 310 - } 311 - size="xl" 312 - alt={type} 313 - /> 325 + {type === 'favourite+reblog' ? ( 326 + <> 327 + <Icon icon="rocket" size="xl" alt={type} class="reblog-icon" /> 328 + <Icon icon="heart" size="xl" alt={type} class="favourite-icon" /> 329 + </> 330 + ) : ( 331 + <Icon 332 + icon={NOTIFICATION_ICONS[type] || 'notification'} 333 + size="xl" 334 + alt={type} 335 + /> 336 + )} 314 337 </div> 315 338 <div class="notification-content"> 316 339 {type !== 'mention' && ( ··· 358 381 <a 359 382 href={account.url} 360 383 rel="noopener noreferrer" 384 + class="account-avatar-stack" 361 385 onClick={(e) => { 362 386 e.preventDefault(); 363 387 states.showAccount = account; ··· 379 403 key={account.id} 380 404 alt={`${account.displayName} @${account.acct}`} 381 405 /> 406 + {type === 'favourite+reblog' && ( 407 + <div class="account-sub-icons"> 408 + {account._types.map((type) => ( 409 + <Icon 410 + icon={NOTIFICATION_ICONS[type]} 411 + size="s" 412 + class={`${type}-icon`} 413 + /> 414 + ))} 415 + </div> 416 + )} 382 417 </a>{' '} 383 418 </> 384 419 ))} ··· 458 493 const notification = notifications[i]; 459 494 const { status, account, type, createdAt } = notification; 460 495 const date = new Date(createdAt).toLocaleDateString(); 461 - const key = `${status?.id}-${type}-${date}`; 496 + let virtualType = type; 497 + if (type === 'favourite' || type === 'reblog') { 498 + virtualType = 'favourite+reblog'; 499 + } 500 + const key = `${status?.id}-${virtualType}-${date}`; 462 501 const mappedNotification = notificationsMap[key]; 463 - if (type === 'follow_request') { 502 + if (virtualType === 'follow_request') { 464 503 cleanNotifications[j++] = notification; 465 504 } else if (mappedNotification?.account) { 466 - mappedNotification._accounts.push(account); 505 + const mappedAccount = mappedNotification._accounts.find( 506 + (a) => a.id === account.id, 507 + ); 508 + if (mappedAccount) { 509 + mappedAccount._types.push(type); 510 + mappedAccount._types.sort().reverse(); 511 + } else { 512 + account._types = [type]; 513 + mappedNotification._accounts.push(account); 514 + } 467 515 } else { 516 + account._types = [type]; 468 517 let n = (notificationsMap[key] = { 469 518 ...notification, 519 + type: virtualType, 470 520 _accounts: [account], 471 521 }); 472 522 cleanNotifications[j++] = n;