Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Notifications #1357

Merged
merged 15 commits into from
Jan 12, 2024
6 changes: 5 additions & 1 deletion src/renderer/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import log from 'electron-log';
import { App } from './App';
import { kernelModel } from '@shared/core';
import { networkModel } from '@entities/network';
import { notificationModel } from '@entities/notification';
import { balanceSubscriptionModel } from '@features/balances';
import { assetsModel } from '@pages/Assets/Assets/model/assets-model';
import './i18n';
import './index.css';
import './styles/theme/default.css';
import { proxiesModel } from '@features/proxies';

log.variables.version = process.env.VERSION;
log.variables.env = process.env.NODE_ENV;
log.transports.console.format = '{y}/{m}/{d} {h}:{i}:{s}.{ms} [{env}#{version}]-{processType} [{level}] > {text}';
log.transports.console.useStyles = true;

Object.assign(console, log.functions);
// Object.assign(console, log.functions);
log.errorHandler.startCatching({
showDialog: false,
onError({ createIssue, error, processType, versions }) {
Expand All @@ -33,6 +35,8 @@ kernelModel.events.appStarted();
networkModel.events.networkStarted();
balanceSubscriptionModel.events.balancesSubscribed();
assetsModel.events.assetsStarted();
notificationModel.events.notificationsStarted();
proxiesModel.events.proxiesStarted();

createRoot(container).render(
<Router>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ jest.mock('@entities/multisig', () => ({
}),
}));

jest.mock('@entities/notification', () => ({
useNotification: jest.fn().mockReturnValue({
addNotification: jest.fn(),
}),
}));

jest.mock('@app/providers', () => ({
useMultisigChainContext: jest.fn(() => ({
addTask: () => undefined,
Expand Down
32 changes: 23 additions & 9 deletions src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,27 @@

import { getCreatedDateFromApi, toAddress, validateCallData } from '@shared/lib/utils';
import { useMultisigEvent, useMultisigTx } from '@entities/multisig';
import { MultisigNotificationType, useNotification } from '@entities/notification';
import { useMultisigChainContext } from '@app/providers';
import { contactModel } from '@entities/contact';
import type { Signatory, MultisigAccount, AccountId, Address, CallHash, ChainId } from '@shared/core';
import { walletModel, accountUtils } from '@entities/wallet';
import { networkModel } from '@entities/network';
import { notificationModel } from '@entities/notification';
import {
Signatory,
MultisigAccount,
AccountId,
Address,
CallHash,
ChainId,
NotificationType,
WalletType,
SigningType,
CryptoType,
ChainType,
AccountType,
MultisigInvite,
NoID,
} from '@shared/core';
import {
ApprovePayload,
BaseMultisigPayload,
Expand All @@ -28,9 +45,6 @@
SigningStatus,
useTransaction,
} from '@entities/transaction';
import { walletModel, accountUtils } from '@entities/wallet';
import { WalletType, SigningType, CryptoType, ChainType, AccountType } from '@shared/core';
import { networkModel } from '@entities/network';

type MatrixContextProps = {
matrix: ISecureMessenger;
Expand All @@ -48,7 +62,6 @@
const { addTask } = useMultisigChainContext();
const { getMultisigTx, addMultisigTx, updateMultisigTx, updateCallData } = useMultisigTx({ addTask });
const { decodeCallData } = useTransaction();
const { addNotification } = useNotification();
const { addEventWithQueue, updateEvent, getEvents } = useMultisigEvent({ addTask });

const apisRef = useRef(apis);
Expand Down Expand Up @@ -100,17 +113,18 @@
console.log(`No multisig account ${accountId} found. Joining room and adding wallet`);

await joinRoom(roomId, content);
await addNotification({

notificationModel.events.notificationsAdded([{

Check failure on line 117 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `⏎··········`

Check failure on line 117 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Insert `⏎··········`
smpRoomId: roomId,

Check failure on line 118 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `··`

Check failure on line 118 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Insert `··`
multisigAccountId: accountId,

Check failure on line 119 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `··`

Check failure on line 119 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Insert `··`
multisigAccountName: accountName,

Check failure on line 120 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `··········` with `············`

Check failure on line 120 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Replace `··········` with `············`
signatories,

Check failure on line 121 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `··`

Check failure on line 121 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Insert `··`
threshold,

Check failure on line 122 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `··`

Check failure on line 122 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Insert `··`
originatorAccountId: creatorAccountId,

Check failure on line 123 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `··`

Check failure on line 123 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Insert `··`
read: true,

Check failure on line 124 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `··`

Check failure on line 124 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Insert `··`
dateCreated: Date.now(),

Check failure on line 125 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `··········` with `············`

Check failure on line 125 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Replace `··········` with `············`
type: MultisigNotificationType.ACCOUNT_INVITED,
});
type: NotificationType.MULTISIG_INVITE,

Check failure on line 126 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `··`

Check failure on line 126 in src/renderer/app/providers/context/MatrixContext/MatrixContext.tsx

View workflow job for this annotation

GitHub Actions / check-localisation

Insert `··`
}] as NoID<MultisigInvite>[]);
} else {
console.log(`Multisig account ${accountId} already exists. Trying to change room to ${roomId}`);
await changeRoom(roomId, mstAccount, content, creatorAccountId);
Expand Down
14 changes: 7 additions & 7 deletions src/renderer/entities/network/model/network-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ type CreateProviderParams = {
providerType: ProviderType;
};
const createProviderFx = createEffect(({ chainId, providerType, nodes }: CreateProviderParams): ProviderInterface => {
const bindedConnected = scopeBind(connected, { safe: true });
const bindedDisconnected = scopeBind(disconnected, { safe: true });
const bindedFailed = scopeBind(failed, { safe: true });
const boundConnected = scopeBind(connected, { safe: true });
const boundDisconnected = scopeBind(disconnected, { safe: true });
const boundFailed = scopeBind(failed, { safe: true });

return networkService.createProvider(
chainId,
Expand All @@ -178,17 +178,17 @@ const createProviderFx = createEffect(({ chainId, providerType, nodes }: CreateP
() => {
console.info('🟢 provider connected ==> ', chainId);

bindedConnected(chainId);
boundConnected(chainId);
},
() => {
console.info('🔶 provider disconnected ==> ', chainId);

bindedDisconnected(chainId);
boundDisconnected(chainId);
},
() => {
console.info('🔴 provider error ==> ', chainId);

bindedFailed(chainId);
boundFailed(chainId);
},
);
});
Expand Down Expand Up @@ -219,8 +219,8 @@ sample({
sample({
clock: chainStarted,
source: {
connections: $connections,
chains: $chains,
connections: $connections,
},
filter: ({ connections }, chainId) => {
return !connections[chainId] || isEnabled(connections[chainId]);
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/entities/notification/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './lib';
export { notificationModel } from './model/notification-model';
57 changes: 0 additions & 57 deletions src/renderer/entities/notification/lib/common/types.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/renderer/entities/notification/lib/index.ts

This file was deleted.

27 changes: 27 additions & 0 deletions src/renderer/entities/notification/lib/notification-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { NotificationType } from '@shared/core';
import type { Notification, MultisigInvite, MultisigOperation, ProxyAction } from '@shared/core';

export const notificationUtils = {
isMultisigInvite,
isMultisigOperation,
isProxyCreation,
};

function isMultisigInvite(notification: Notification): notification is MultisigInvite {
return notification.type === NotificationType.MULTISIG_INVITE;
}

function isMultisigOperation(notification: Notification): notification is MultisigOperation {
const Operations = [
NotificationType.MULTISIG_CREATED,
NotificationType.MULTISIG_APPROVED,
NotificationType.MULTISIG_CANCELLED,
NotificationType.MULTISIG_EXECUTED,
];

return Operations.includes(notification.type);
}

function isProxyCreation(notification: Notification): notification is ProxyAction {
return notification.type === NotificationType.MULTISIG_INVITE;
}
33 changes: 0 additions & 33 deletions src/renderer/entities/notification/lib/notificationService.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { fork, allSettled } from 'effector';

import { Notification, NotificationType } from '@shared/core';
import { storageService } from '@shared/api/storage';
import { notificationModel } from '../notification-model';

const notifications = [
{
id: 1,
read: true,
dateCreated: Date.now(),
type: NotificationType.MULTISIG_INVITE,
},
] as Notification[];

const newNotifications = [{
id: 2,
read: true,
dateCreated: Date.now(),
type: NotificationType.MULTISIG_INVITE,
}] as Notification[];

describe('entities/notification/model/notification-model', () => {
afterEach(() => {
jest.restoreAllMocks();
});

test('should populate $notifications on notificationsStarted', async () => {
const spyReadAll = jest.spyOn(storageService.notifications, 'readAll').mockResolvedValue(notifications);

const scope = fork({
values: new Map().set(notificationModel.$notifications, []),
});

await allSettled(notificationModel.events.notificationsStarted, { scope });

expect(spyReadAll).toHaveBeenCalled();
expect(scope.getState(notificationModel.$notifications)).toEqual(notifications);
});

test('should add new notification on notificationsAdded', async () => {
const spyCreate = jest.spyOn(storageService.notifications, 'createAll').mockResolvedValue(newNotifications);

const scope = fork({
values: new Map().set(notificationModel.$notifications, []),
});

await allSettled(notificationModel.events.notificationsAdded, { scope, params: newNotifications });

expect(spyCreate).toHaveBeenCalled();
expect(scope.getState(notificationModel.$notifications)).toEqual(newNotifications);
});
});
Loading
Loading