mirror of
https://github.com/cheeaun/phanpy.git
synced 2024-12-19 14:02:21 +03:00
223 lines
7.5 KiB
JavaScript
223 lines
7.5 KiB
JavaScript
// This is like very lame "type-checking" lol
|
|
const notificationTypeKeys = {
|
|
mention: ['account', 'status'],
|
|
status: ['account', 'status'],
|
|
reblog: ['account', 'status'],
|
|
follow: ['account'],
|
|
follow_request: ['account'],
|
|
favourite: ['account', 'status'],
|
|
poll: ['status'],
|
|
update: ['status'],
|
|
};
|
|
export function fixNotifications(notifications) {
|
|
return notifications.filter((notification) => {
|
|
const { type, id, createdAt } = notification;
|
|
if (!type) {
|
|
console.warn('Notification missing type', notification);
|
|
return false;
|
|
}
|
|
if (!id || !createdAt) {
|
|
console.warn('Notification missing id or createdAt', notification);
|
|
// Continue processing this despite missing id or createdAt
|
|
}
|
|
const keys = notificationTypeKeys[type];
|
|
if (keys?.length) {
|
|
return keys.every((key) => !!notification[key]);
|
|
}
|
|
return true; // skip other types
|
|
});
|
|
}
|
|
|
|
export function massageNotifications2(notifications) {
|
|
if (notifications?.notificationGroups) {
|
|
const {
|
|
accounts = [],
|
|
notificationGroups = [],
|
|
statuses = [],
|
|
} = notifications;
|
|
return notificationGroups.map((group) => {
|
|
const { sampleAccountIds, statusId } = group;
|
|
const sampleAccounts =
|
|
sampleAccountIds?.map((id) => accounts.find((a) => a.id === id)) || [];
|
|
const status = statuses?.find((s) => s.id === statusId) || null;
|
|
return {
|
|
...group,
|
|
sampleAccounts,
|
|
status,
|
|
};
|
|
});
|
|
}
|
|
return notifications;
|
|
}
|
|
|
|
export function groupNotifications2(groupNotifications) {
|
|
// Make grouped notifications to look like faux grouped notifications
|
|
const newGroupNotifications = groupNotifications.map((gn) => {
|
|
const {
|
|
latestPageNotificationAt,
|
|
mostRecentNotificationId,
|
|
sampleAccounts,
|
|
notificationsCount,
|
|
} = gn;
|
|
|
|
return {
|
|
id: '' + mostRecentNotificationId,
|
|
createdAt: latestPageNotificationAt,
|
|
account: sampleAccounts[0],
|
|
...gn,
|
|
};
|
|
});
|
|
|
|
// DISABLED FOR NOW.
|
|
// Merge favourited and reblogged of same status into a single notification
|
|
// - new type: "favourite+reblog"
|
|
// - sum numbers for `notificationsCount` and `sampleAccounts`
|
|
// const mappedNotifications = {};
|
|
// const newNewGroupNotifications = [];
|
|
// for (let i = 0; i < newGroupNotifications.length; i++) {
|
|
// const gn = newGroupNotifications[i];
|
|
// const { type, status, createdAt, notificationsCount, sampleAccounts } = gn;
|
|
// const date = createdAt ? new Date(createdAt).toLocaleDateString() : '';
|
|
// let virtualType = type;
|
|
// if (type === 'favourite' || type === 'reblog') {
|
|
// virtualType = 'favourite+reblog';
|
|
// }
|
|
// const key = `${status?.id}-${virtualType}-${date}`;
|
|
// const mappedNotification = mappedNotifications[key];
|
|
// if (mappedNotification) {
|
|
// const accountIDs = mappedNotification.sampleAccounts.map((a) => a.id);
|
|
// sampleAccounts.forEach((a) => {
|
|
// if (!accountIDs.includes(a.id)) {
|
|
// mappedNotification.sampleAccounts.push(a);
|
|
// }
|
|
// });
|
|
// mappedNotification.notificationsCount = Math.max(
|
|
// mappedNotification.notificationsCount,
|
|
// notificationsCount,
|
|
// mappedNotification.sampleAccounts.length,
|
|
// );
|
|
// } else {
|
|
// mappedNotifications[key] = {
|
|
// ...gn,
|
|
// type: virtualType,
|
|
// };
|
|
// newNewGroupNotifications.push(mappedNotifications[key]);
|
|
// }
|
|
// }
|
|
|
|
// 2nd pass.
|
|
// - Group 1 account favourte/reblog multiple posts
|
|
// - _statuses: [status, status, ...]
|
|
const notificationsMap2 = {};
|
|
const newGroupNotifications2 = [];
|
|
for (let i = 0; i < newGroupNotifications.length; i++) {
|
|
const gn = newGroupNotifications[i];
|
|
const { type, account, _accounts, sampleAccounts, createdAt } = gn;
|
|
const date = createdAt ? new Date(createdAt).toLocaleDateString() : '';
|
|
const hasOneAccount =
|
|
sampleAccounts?.length === 1 || _accounts?.length === 1;
|
|
if ((type === 'favourite' || type === 'reblog') && hasOneAccount) {
|
|
const key = `${account?.id}-${type}-${date}`;
|
|
const mappedNotification = notificationsMap2[key];
|
|
if (mappedNotification) {
|
|
mappedNotification._statuses.push(gn.status);
|
|
mappedNotification._ids += `-${gn.id}`;
|
|
} else {
|
|
let n = (notificationsMap2[key] = {
|
|
...gn,
|
|
type,
|
|
_ids: gn.id,
|
|
_statuses: [gn.status],
|
|
});
|
|
newGroupNotifications2.push(n);
|
|
}
|
|
} else {
|
|
newGroupNotifications2.push(gn);
|
|
}
|
|
}
|
|
|
|
return newGroupNotifications2;
|
|
}
|
|
|
|
export default function groupNotifications(notifications) {
|
|
// Filter out invalid notifications
|
|
notifications = fixNotifications(notifications);
|
|
|
|
// Create new flat list of notifications
|
|
// Combine sibling notifications based on type and status id
|
|
// Concat all notification.account into an array of _accounts
|
|
const notificationsMap = {};
|
|
const cleanNotifications = [];
|
|
for (let i = 0, j = 0; i < notifications.length; i++) {
|
|
const notification = notifications[i];
|
|
const { id, status, account, type, createdAt } = notification;
|
|
const date = createdAt ? new Date(createdAt).toLocaleDateString() : '';
|
|
let virtualType = type;
|
|
if (type === 'favourite' || type === 'reblog') {
|
|
virtualType = 'favourite+reblog';
|
|
}
|
|
const key = `${status?.id}-${virtualType}-${date}`;
|
|
const mappedNotification = notificationsMap[key];
|
|
if (virtualType === 'follow_request') {
|
|
cleanNotifications[j++] = notification;
|
|
} else if (mappedNotification?.account) {
|
|
const mappedAccount = mappedNotification._accounts.find(
|
|
(a) => a.id === account.id,
|
|
);
|
|
if (mappedAccount) {
|
|
mappedAccount._types.push(type);
|
|
mappedAccount._types.sort().reverse();
|
|
mappedNotification._ids += `-${id}`;
|
|
} else {
|
|
account._types = [type];
|
|
mappedNotification._accounts.push(account);
|
|
mappedNotification._ids += `-${id}`;
|
|
}
|
|
} else {
|
|
if (account) account._types = [type];
|
|
let n = (notificationsMap[key] = {
|
|
...notification,
|
|
type: virtualType,
|
|
_ids: id,
|
|
_accounts: account ? [account] : [],
|
|
});
|
|
cleanNotifications[j++] = n;
|
|
}
|
|
}
|
|
|
|
// 2nd pass to group "favourite+reblog"-type notifications by account if _accounts.length <= 1
|
|
// This means one acount has favourited and reblogged the multiple statuses
|
|
// The grouped notification
|
|
// - type: "favourite+reblog+account"
|
|
// - _statuses: [status, status, ...]
|
|
const notificationsMap2 = {};
|
|
const cleanNotifications2 = [];
|
|
for (let i = 0, j = 0; i < cleanNotifications.length; i++) {
|
|
const notification = cleanNotifications[i];
|
|
const { id, account, _accounts, type, createdAt } = notification;
|
|
const date = createdAt ? new Date(createdAt).toLocaleDateString() : '';
|
|
if (type === 'favourite+reblog' && account && _accounts.length === 1) {
|
|
const key = `${account?.id}-${type}-${date}`;
|
|
const mappedNotification = notificationsMap2[key];
|
|
if (mappedNotification) {
|
|
mappedNotification._statuses.push(notification.status);
|
|
mappedNotification._ids += `-${id}`;
|
|
} else {
|
|
let n = (notificationsMap2[key] = {
|
|
...notification,
|
|
type,
|
|
_ids: id,
|
|
_statuses: [notification.status],
|
|
});
|
|
cleanNotifications2[j++] = n;
|
|
}
|
|
} else {
|
|
cleanNotifications2[j++] = notification;
|
|
}
|
|
}
|
|
|
|
console.log({ notifications, cleanNotifications, cleanNotifications2 });
|
|
|
|
// return cleanNotifications;
|
|
return cleanNotifications2;
|
|
}
|