Grouped favourite+boost notifications!
This commit is contained in:
parent
e7dc2c8517
commit
7b8c7f3fb6
|
@ -1258,13 +1258,13 @@ meter.donut:is(.danger, .explode):after {
|
||||||
}
|
}
|
||||||
/* I'm just feeling bored, so having fun here */
|
/* I'm just feeling bored, so having fun here */
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
.avatars-stack > * {
|
.avatars-stack > * img {
|
||||||
transition: transform 0.3s ease-in-out;
|
transition: transform 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
.avatars-stack:hover > *:nth-of-type(odd) {
|
.avatars-stack:hover > *:nth-of-type(odd) img {
|
||||||
transform: rotate(15deg);
|
transform: rotate(15deg);
|
||||||
}
|
}
|
||||||
.avatars-stack:hover > *:nth-of-type(even) {
|
.avatars-stack:hover > *:nth-of-type(even) img {
|
||||||
transform: rotate(-15deg);
|
transform: rotate(-15deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
color: var(--text-insignificant-color);
|
color: var(--text-insignificant-color);
|
||||||
|
line-height: 0;
|
||||||
}
|
}
|
||||||
.notification-type.notification-mention {
|
.notification-type.notification-mention {
|
||||||
color: var(--reply-to-color);
|
color: var(--reply-to-color);
|
||||||
|
@ -34,6 +35,54 @@
|
||||||
color: var(--link-color);
|
color: var(--link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification .reblog-icon {
|
||||||
|
color: var(--reblog-color);
|
||||||
|
}
|
||||||
|
.notification .favourite-icon {
|
||||||
|
color: var(--favourite-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification .account-avatar-stack {
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.notification .account-avatar-stack .account-sub-icons {
|
||||||
|
display: block;
|
||||||
|
width: fit-content;
|
||||||
|
margin: -0.25em auto 0;
|
||||||
|
line-height: 1;
|
||||||
|
background-color: var(--bg-blur-color);
|
||||||
|
/* background-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
var(--bg-color),
|
||||||
|
var(--bg-blur-color)
|
||||||
|
); */
|
||||||
|
backdrop-filter: blur(16px) saturate(3);
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 999px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: var(--hairline-width) solid var(--bg-color);
|
||||||
|
box-shadow: 0 1px var(--drop-shadow-color);
|
||||||
|
}
|
||||||
|
.notification .avatars-stack .account-avatar-stack .account-sub-icons .icon {
|
||||||
|
transition: transform 0.2s ease-out;
|
||||||
|
}
|
||||||
|
.notification
|
||||||
|
.avatars-stack:hover
|
||||||
|
.account-avatar-stack
|
||||||
|
.account-sub-icons
|
||||||
|
.icon {
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
}
|
||||||
|
.notification
|
||||||
|
.avatars-stack:hover
|
||||||
|
.account-avatar-stack
|
||||||
|
.account-sub-icons
|
||||||
|
.icon
|
||||||
|
+ .icon {
|
||||||
|
transform: rotate(15deg);
|
||||||
|
}
|
||||||
|
|
||||||
.notification .status-link {
|
.notification .status-link {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid var(--outline-color);
|
border: 1px solid var(--outline-color);
|
||||||
|
|
|
@ -45,6 +45,18 @@ const contentText = {
|
||||||
'poll-self': 'A poll you have created has ended.',
|
'poll-self': 'A poll you have created has ended.',
|
||||||
'poll-voted': 'A poll you have voted in has ended.',
|
'poll-voted': 'A poll you have voted in has ended.',
|
||||||
update: 'A status you interacted with has been edited.',
|
update: 'A status you interacted with has been edited.',
|
||||||
|
'favourite+reblog': 'boosted & favourited your status.',
|
||||||
|
};
|
||||||
|
|
||||||
|
const NOTIFICATION_ICONS = {
|
||||||
|
mention: 'comment',
|
||||||
|
status: 'notification',
|
||||||
|
reblog: 'rocket',
|
||||||
|
follow: 'follow',
|
||||||
|
follow_request: 'follow-add',
|
||||||
|
favourite: 'heart',
|
||||||
|
poll: 'poll',
|
||||||
|
update: 'pencil',
|
||||||
};
|
};
|
||||||
|
|
||||||
const LIMIT = 30; // 30 is the maximum limit :(
|
const LIMIT = 30; // 30 is the maximum limit :(
|
||||||
|
@ -275,7 +287,8 @@ function Notifications() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
function Notification({ notification, instance }) {
|
function Notification({ notification, instance }) {
|
||||||
const { id, type, status, account, _accounts } = notification;
|
const { id, status, account, _accounts } = notification;
|
||||||
|
let { type } = notification;
|
||||||
|
|
||||||
// status = Attached when type of the notification is favourite, reblog, status, mention, poll, or update
|
// status = Attached when type of the notification is favourite, reblog, status, mention, poll, or update
|
||||||
const actualStatusID = status?.reblog?.id || status?.id;
|
const actualStatusID = status?.reblog?.id || status?.id;
|
||||||
|
@ -284,6 +297,20 @@ function Notification({ notification, instance }) {
|
||||||
const isSelf = currentAccount === account?.id;
|
const isSelf = currentAccount === account?.id;
|
||||||
const isVoted = status?.poll?.voted;
|
const isVoted = status?.poll?.voted;
|
||||||
|
|
||||||
|
let favsCount = 0;
|
||||||
|
let reblogsCount = 0;
|
||||||
|
if (type === 'favourite+reblog') {
|
||||||
|
for (const account of _accounts) {
|
||||||
|
if (account._types?.includes('favourite')) {
|
||||||
|
favsCount++;
|
||||||
|
} else if (account._types?.includes('reblog')) {
|
||||||
|
reblogsCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!reblogsCount && favsCount) type = 'favourite';
|
||||||
|
if (!favsCount && reblogsCount) type = 'reblog';
|
||||||
|
}
|
||||||
|
|
||||||
const text =
|
const text =
|
||||||
type === 'poll'
|
type === 'poll'
|
||||||
? contentText[isSelf ? 'poll-self' : isVoted ? 'poll-voted' : 'poll']
|
? contentText[isSelf ? 'poll-self' : isVoted ? 'poll-voted' : 'poll']
|
||||||
|
@ -295,22 +322,18 @@ function Notification({ notification, instance }) {
|
||||||
class={`notification-type notification-${type}`}
|
class={`notification-type notification-${type}`}
|
||||||
title={new Date(notification.createdAt).toLocaleString()}
|
title={new Date(notification.createdAt).toLocaleString()}
|
||||||
>
|
>
|
||||||
<Icon
|
{type === 'favourite+reblog' ? (
|
||||||
icon={
|
<>
|
||||||
{
|
<Icon icon="rocket" size="xl" alt={type} class="reblog-icon" />
|
||||||
mention: 'comment',
|
<Icon icon="heart" size="xl" alt={type} class="favourite-icon" />
|
||||||
status: 'notification',
|
</>
|
||||||
reblog: 'rocket',
|
) : (
|
||||||
follow: 'follow',
|
<Icon
|
||||||
follow_request: 'follow-add',
|
icon={NOTIFICATION_ICONS[type] || 'notification'}
|
||||||
favourite: 'heart',
|
size="xl"
|
||||||
poll: 'poll',
|
alt={type}
|
||||||
update: 'pencil',
|
/>
|
||||||
}[type] || 'notification'
|
)}
|
||||||
}
|
|
||||||
size="xl"
|
|
||||||
alt={type}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="notification-content">
|
<div class="notification-content">
|
||||||
{type !== 'mention' && (
|
{type !== 'mention' && (
|
||||||
|
@ -358,6 +381,7 @@ function Notification({ notification, instance }) {
|
||||||
<a
|
<a
|
||||||
href={account.url}
|
href={account.url}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
class="account-avatar-stack"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
states.showAccount = account;
|
states.showAccount = account;
|
||||||
|
@ -379,6 +403,17 @@ function Notification({ notification, instance }) {
|
||||||
key={account.id}
|
key={account.id}
|
||||||
alt={`${account.displayName} @${account.acct}`}
|
alt={`${account.displayName} @${account.acct}`}
|
||||||
/>
|
/>
|
||||||
|
{type === 'favourite+reblog' && (
|
||||||
|
<div class="account-sub-icons">
|
||||||
|
{account._types.map((type) => (
|
||||||
|
<Icon
|
||||||
|
icon={NOTIFICATION_ICONS[type]}
|
||||||
|
size="s"
|
||||||
|
class={`${type}-icon`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</a>{' '}
|
</a>{' '}
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
|
@ -458,15 +493,30 @@ function groupNotifications(notifications) {
|
||||||
const notification = notifications[i];
|
const notification = notifications[i];
|
||||||
const { status, account, type, createdAt } = notification;
|
const { status, account, type, createdAt } = notification;
|
||||||
const date = new Date(createdAt).toLocaleDateString();
|
const date = new Date(createdAt).toLocaleDateString();
|
||||||
const key = `${status?.id}-${type}-${date}`;
|
let virtualType = type;
|
||||||
|
if (type === 'favourite' || type === 'reblog') {
|
||||||
|
virtualType = 'favourite+reblog';
|
||||||
|
}
|
||||||
|
const key = `${status?.id}-${virtualType}-${date}`;
|
||||||
const mappedNotification = notificationsMap[key];
|
const mappedNotification = notificationsMap[key];
|
||||||
if (type === 'follow_request') {
|
if (virtualType === 'follow_request') {
|
||||||
cleanNotifications[j++] = notification;
|
cleanNotifications[j++] = notification;
|
||||||
} else if (mappedNotification?.account) {
|
} else if (mappedNotification?.account) {
|
||||||
mappedNotification._accounts.push(account);
|
const mappedAccount = mappedNotification._accounts.find(
|
||||||
|
(a) => a.id === account.id,
|
||||||
|
);
|
||||||
|
if (mappedAccount) {
|
||||||
|
mappedAccount._types.push(type);
|
||||||
|
mappedAccount._types.sort().reverse();
|
||||||
|
} else {
|
||||||
|
account._types = [type];
|
||||||
|
mappedNotification._accounts.push(account);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
account._types = [type];
|
||||||
let n = (notificationsMap[key] = {
|
let n = (notificationsMap[key] = {
|
||||||
...notification,
|
...notification,
|
||||||
|
type: virtualType,
|
||||||
_accounts: [account],
|
_accounts: [account],
|
||||||
});
|
});
|
||||||
cleanNotifications[j++] = n;
|
cleanNotifications[j++] = n;
|
||||||
|
|
Loading…
Reference in a new issue