@steambrew/client
Version:
A support library for creating plugins with Millennium.
116 lines (115 loc) • 4.25 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import Toast from '../components/Toast';
import Logger from '../logger';
import { callOriginal, injectFCTrampoline, replacePatch } from '../utils';
import { findModuleExport } from '../webpack';
import { ErrorBoundary } from '../components';
// TODO export
var ToastType;
(function (ToastType) {
ToastType[ToastType["New"] = 0] = "New";
ToastType[ToastType["Update"] = 1] = "Update";
ToastType[ToastType["Remove"] = 2] = "Remove";
})(ToastType || (ToastType = {}));
class Toaster extends Logger {
constructor() {
super('Toaster');
window.__TOASTER_INSTANCE?.deinit?.();
window.__TOASTER_INSTANCE = this;
const ValveToastRenderer = findModuleExport((e) => e?.toString?.()?.includes(`controller:"notification",method:`));
// TODO find a way to undo this if possible?
const patchedRenderer = injectFCTrampoline(ValveToastRenderer);
this.toastPatch = replacePatch(patchedRenderer, 'component', (args) => {
if (args?.[0]?.group?.millennium || args?.[0]?.group?.notifications?.[0]?.millennium) {
return args[0].group.notifications.map((notification) => (_jsx(ErrorBoundary, { children: _jsx(Toast, { toast: notification.data, newIndicator: notification.bNewIndicator, location: args?.[0]?.location }) })));
}
return callOriginal;
});
this.log('Initialized');
}
toast(toast) {
if (toast.sound === undefined)
toast.sound = 6;
if (toast.playSound === undefined)
toast.playSound = true;
if (toast.showToast === undefined)
toast.showToast = true;
if (toast.timestamp === undefined)
toast.timestamp = new Date();
if (toast.showNewIndicator === undefined)
toast.showNewIndicator = true;
/* eType 13
13: {
proto: m.mu,
fnTray: null,
showToast: !0,
sound: f.PN.ToastMisc,
eFeature: l.uX
}
*/
let toastData = {
nNotificationID: window.NotificationStore.m_nNextTestNotificationID++,
bNewIndicator: toast.showNewIndicator,
rtCreated: Date.now(),
eType: toast.eType || 12,
eSource: 1,
nToastDurationMS: toast.duration || (toast.duration = 5e3),
data: toast,
millennium: true,
};
let group;
function fnTray(toast, tray) {
group = {
eType: toast.eType,
notifications: [toast],
};
tray.unshift(group);
}
const info = {
showToast: toast.showToast,
sound: toast.sound,
eFeature: 0,
toastDurationMS: toastData.nToastDurationMS,
bCritical: toast.critical,
fnTray,
};
const self = this;
let expirationTimeout;
const toastResult = {
data: toast,
dismiss() {
self.debug('Dismissing toast', toast);
// it checks against the id of notifications[0]
try {
expirationTimeout && clearTimeout(expirationTimeout);
group && window.NotificationStore.RemoveGroupFromTray(group);
}
catch (e) {
self.error('Error while dismissing toast:', e);
}
},
};
if (toast.expiration) {
expirationTimeout = window.setTimeout(() => {
self.debug('Dismissing expired toast', toast);
try {
group && window.NotificationStore.RemoveGroupFromTray(group);
}
catch (e) {
this.error('Error while dismissing expired toast:', e);
}
}, toast.expiration);
}
try {
window.NotificationStore.ProcessNotification(info, toastData, ToastType.New);
}
catch (e) {
this.error('Error while sending toast:', e);
}
return toastResult;
}
deinit() {
this.toastPatch?.unpatch();
}
}
export default Toaster;