Skip to content

Commit

Permalink
[DDW-814] Create LocalStorageFeatureProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
renanvalentin committed Nov 22, 2021
1 parent 113fe12 commit 160452c
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 55 deletions.
24 changes: 0 additions & 24 deletions source/renderer/app/api/utils/localStorageBridge.js

This file was deleted.

14 changes: 9 additions & 5 deletions source/renderer/app/containers/TopBarContainer.js
Expand Up @@ -15,13 +15,19 @@ import { matchRoute } from '../utils/routing';
import { ROUTES } from '../routes-config';
import { IS_TADA_ICON_AVAILABLE } from '../config/topBarConfig';
import topBarStyles from '../components/layout/TopBar.scss';
import { useDiscreetModeFeature } from '../features/discreet-mode';

const TopBarContainer = (
{ actions, stores }: InjectedProps = { actions: null, stores: null }
) => {
const { sidebar, app, networkStatus, wallets, newsFeed, appUpdate, staking } =
stores;
const {
sidebar,
app,
networkStatus,
wallets,
newsFeed,
appUpdate,
staking,
} = stores;
const {
isSynced,
syncPercentage,
Expand Down Expand Up @@ -76,8 +82,6 @@ const TopBarContainer = (

const hasUnreadNews = unread.length > 0;

const discreetModeFeature = useDiscreetModeFeature();

return (
<TopBar
leftIcon={leftIcon}
Expand Down
25 changes: 12 additions & 13 deletions source/renderer/app/features/discreet-mode/api/index.js
@@ -1,20 +1,19 @@
// @flow
import { localStorageBridge } from '../../../api/utils/localStorageBridge';
import { STORAGE_KEYS as storageKeys } from '../../../../../common/config/electron-store.config';
import type { LocalStorageApi } from '../../local-storage';

export class DiscreetModeApi {
getDiscreetModeSettings = async (): Promise<boolean> => {
const localStorage = await localStorageBridge();
return localStorage.get(storageKeys.DISCREET_MODE_ENABLED, false);
};
localStorage: LocalStorageApi;
constructor(localStorage: LocalStorageApi) {
this.localStorage = localStorage;
}

setDiscreetModeSettings = async (enabled: boolean): Promise<void> => {
const localStorage = await localStorageBridge();
localStorage.set(storageKeys.DISCREET_MODE_ENABLED, enabled);
};
getDiscreetModeSettings = () =>
this.localStorage.get(storageKeys.DISCREET_MODE_ENABLED, false);

unsetDiscreetModeSettings = async (): Promise<void> => {
const localStorage = await localStorageBridge();
localStorage.unset(storageKeys.DISCREET_MODE_ENABLED);
};
setDiscreetModeSettings = (enabled: boolean) =>
this.localStorage.set(storageKeys.DISCREET_MODE_ENABLED, enabled);

unsetDiscreetModeSettings = async () =>
this.localStorage.unset(storageKeys.DISCREET_MODE_ENABLED);
}
4 changes: 3 additions & 1 deletion source/renderer/app/features/discreet-mode/context.js
Expand Up @@ -7,6 +7,7 @@ import {
getFeatureFromContext,
useFeature,
} from '../../utils/mobx-features/hooks';
import { useLocalStorageFeature } from '../local-storage';

import { DiscreetMode } from './feature';
import { DiscreetModeApi } from './api';
Expand All @@ -20,8 +21,9 @@ interface Props {
}

export const DiscreetModeFeatureProvider = ({ children }: Props) => {
const localStorageFeature = useLocalStorageFeature();
const [discreetModeFeature] = useState<DiscreetMode>(() => {
const feature = new DiscreetMode(new DiscreetModeApi());
const feature = new DiscreetMode(new DiscreetModeApi(localStorageFeature));
window.daedalus = merge(window.daedalus, {
features: {
discreetModeFeature: feature,
Expand Down
11 changes: 7 additions & 4 deletions source/renderer/app/features/discreet-mode/feature.js
Expand Up @@ -2,6 +2,7 @@
import { observable, action, runInAction } from 'mobx';
import { Feature } from '../../utils/mobx-features/feature';
import Request from '../../stores/lib/LocalizedRequest';

import { DiscreetModeApi } from './api';
import { SENSITIVE_DATA_SYMBOL } from './config';
import { defaultReplacer } from './replacers/defaultReplacer';
Expand All @@ -12,11 +13,13 @@ export class DiscreetMode extends Feature {
@observable isDiscreetMode: boolean = false;
@observable openInDiscreetMode: boolean = false;

@observable getDiscreetModeSettingsRequest: Request<Promise<boolean>> =
new Request(this.api.getDiscreetModeSettings);
@observable getDiscreetModeSettingsRequest: Request<
Promise<boolean>
> = new Request(this.api.getDiscreetModeSettings);

@observable setDiscreetModeSettingsRequest: Request<Promise<boolean>> =
new Request(this.api.setDiscreetModeSettings);
@observable setDiscreetModeSettingsRequest: Request<
Promise<boolean>
> = new Request(this.api.setDiscreetModeSettings);

constructor(api: DiscreetModeApi) {
super();
Expand Down
1 change: 1 addition & 0 deletions source/renderer/app/features/index.js
@@ -1,3 +1,4 @@
// @flow

export * from './discreet-mode';
export * from './local-storage';
42 changes: 42 additions & 0 deletions source/renderer/app/features/local-storage/context.js
@@ -0,0 +1,42 @@
// @flow

import React, { useState } from 'react';
import type { Node } from 'react';
import { merge } from 'lodash/fp';
import { getFeatureFromContext } from '../../utils/mobx-features/hooks';

import { LocalStorageApi } from './types';

export const localStorageContext = React.createContext<LocalStorageApi | null>(
null
);

interface Props {
children: Node;
localStorage: LocalStorageApi;
}

export const LocalStorageFeatureProvider = ({
children,
localStorage,
}: Props) => {
const [localStorageFeature] = useState<LocalStorageApi>(() => {
window.daedalus = merge(window.daedalus, {
features: {
localStorage,
},
});

return localStorage;
});

return (
<localStorageContext.Provider value={localStorageFeature}>
{children}
</localStorageContext.Provider>
);
};

export function useLocalStorageFeature(): LocalStorageApi {
return getFeatureFromContext(localStorageContext);
}
5 changes: 5 additions & 0 deletions source/renderer/app/features/local-storage/index.js
@@ -0,0 +1,5 @@
// @flow

export { useLocalStorageFeature, LocalStorageFeatureProvider } from './context';
export { BrowserLocalStorageBridge } from './ui';
export type { LocalStorageApi } from './types';
7 changes: 7 additions & 0 deletions source/renderer/app/features/local-storage/types.js
@@ -0,0 +1,7 @@
// @flow

export type LocalStorageApi = {
get: (key: StorageKey, defaultValue: any) => boolean,
set: (key: StorageKey, value: any) => Promise<void>,
unset: (key: StorageKey) => Promise<void>,
};
@@ -0,0 +1,24 @@
// @flow

import React from 'react';
import { LocalStorageFeatureProvider } from '../context';

type Props = {
children: Node,
};

export function BrowserLocalStorageBridge({ children }: Props) {
return (
<LocalStorageFeatureProvider
localStorage={{
get: (key: string, defaultValue: any) =>
Promise.resolve<any>(localStorage.getItem(key) || defaultValue),
set: (key: string, value: any) =>
Promise.resolve(localStorage.setItem(key, value)),
unset: (key: string) => Promise.resolve(localStorage.removeItem(key)),
}}
>
{children}
</LocalStorageFeatureProvider>
);
}
3 changes: 3 additions & 0 deletions source/renderer/app/features/local-storage/ui/index.js
@@ -0,0 +1,3 @@
// @flow

export { BrowserLocalStorageBridge } from './BrowserLocalStorageBridge';
14 changes: 10 additions & 4 deletions source/renderer/app/index.js
Expand Up @@ -15,7 +15,11 @@ import Action from './actions/lib/Action';
import translations from './i18n/translations';
import '!style-loader!css-loader!sass-loader!./themes/index.global.scss'; // eslint-disable-line
import { setupApi } from './api/index';
import { DiscreetModeFeatureProvider } from './features';
import LocalStorageApi from './api/utils/localStorage';
import {
DiscreetModeFeatureProvider,
LocalStorageFeatureProvider,
} from './features';

// run MobX in strict mode
configure({
Expand Down Expand Up @@ -51,9 +55,11 @@ const initializeDaedalus = () => {
const rootElement = document.getElementById('root');
if (!rootElement) throw new Error('No #root element found.');
render(
<DiscreetModeFeatureProvider>
<App stores={stores} actions={actions} history={history} />
</DiscreetModeFeatureProvider>,
<LocalStorageFeatureProvider localStorage={LocalStorageApi}>
<DiscreetModeFeatureProvider>
<App stores={stores} actions={actions} history={history} />
</DiscreetModeFeatureProvider>
</LocalStorageFeatureProvider>,
rootElement
);
};
Expand Down
13 changes: 9 additions & 4 deletions storybook/stories/_support/StoryProvider.js
Expand Up @@ -8,7 +8,10 @@ import BigNumber from 'bignumber.js';
import moment from 'moment';
import actions from '../../../source/renderer/app/actions';
import { WalletSyncStateStatuses } from '../../../source/renderer/app/domains/Wallet.js';
import { DiscreetModeFeatureProvider } from '../../../source/renderer/app/features/discreet-mode/context';
import {
DiscreetModeFeatureProvider,
BrowserLocalStorageBridge,
} from '../../../source/renderer/app/features';

type Props = {
children: Node,
Expand Down Expand Up @@ -179,9 +182,11 @@ export default class StoryProvider extends Component<Props> {
actions={actions}
storiesProps={this.storiesProps}
>
<DiscreetModeFeatureProvider>
{this.props.children}
</DiscreetModeFeatureProvider>
<BrowserLocalStorageBridge>
<DiscreetModeFeatureProvider>
{this.props.children}
</DiscreetModeFeatureProvider>
</BrowserLocalStorageBridge>
</Provider>
);
}
Expand Down

0 comments on commit 160452c

Please sign in to comment.