You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vizality/renderer/src/builtins/notifications/index.js

83 lines
2.5 KiB

import { getOwnerInstance, forceUpdateElement, findInReactTree } from '@vizality/util/react';
import { getModuleByDisplayName, getModule } from '@vizality/webpack';
import { waitForElement } from '@vizality/util/dom';
import { patch, unpatch } from '@vizality/patcher';
import { Directories } from '@vizality/constants';
import { Builtin } from '@vizality/entities';
import { promises, existsSync } from 'fs';
import { join } from 'path';
import React from 'react';
const { unlink } = promises;
import NoticeContainer from './components/NoticeContainer';
import ToastContainer from './components/ToastContainer';
export default class Notifications extends Builtin {
async start () {
document.querySelector('.Toastify')?.remove();
this.injectStyles('styles/main.scss');
const injectedFile = join(Directories.SRC, '__injected.txt');
await this._patchNotices();
await this._patchToasts();
if (existsSync(injectedFile)) {
this._welcomeNewUser();
unlink(injectedFile);
}
}
stop () {
unpatch('vz-notices-notices');
unpatch('vz-notices-toast');
document.querySelector('.Toastify')?.remove();
}
/**
*
* @todo Figure out how to forceUpdate the app initially to render startup notices.
*/
async _patchNotices () {
const { base } = getModule('base', 'container');
const instance = getOwnerInstance(await waitForElement(`.${base.split(' ')[0]}`));
patch('vz-notices-notices', instance?.props?.children[0], 'type', (_, res) => {
try {
const { children } = findInReactTree(res, ({ className }) => className === base);
children.unshift(<NoticeContainer />);
} catch (err) {
return this.error(this._labels.concat('_patchNotices'), err);
}
});
}
/**
*
*/
async _patchToasts () {
const { app } = getModule('app', 'layers');
const Shakeable = getModuleByDisplayName('Shakeable');
patch('vz-notices-toast', Shakeable?.prototype, 'render', (_, res) => {
try {
if (!res.props?.children?.find(child => child.type?.name === 'ToastContainer')) {
res.props?.children?.push(
<ToastContainer settings={this.settings} />
);
}
} catch (err) {
return this.error(this._labels.concat('_patchToasts'), err);
}
});
forceUpdateElement(`.${app}`);
}
/**
*
*/
_welcomeNewUser () {
try {
return vizality.api.routes.navigateTo('dashboard');
} catch (err) {
return this.error(this._labels.concat('_welcomeNewUser'), err);
}
}
}