mirror of
https://github.com/netzbegruenung/jitsi-meet-electron.git
synced 2024-05-02 00:34:53 +02:00
Remove local avatar
The deployment will generate the right one based on the provided name and email. Fixes: https://github.com/jitsi/jitsi-meet-electron/issues/379
This commit is contained in:
parent
09345d6f0b
commit
8de41a414d
|
@ -31,11 +31,6 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_alwaysOnTopWindowEnabled: boolean;
|
_alwaysOnTopWindowEnabled: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* Avatar URL.
|
|
||||||
*/
|
|
||||||
_avatarURL: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email of user.
|
* Email of user.
|
||||||
*/
|
*/
|
||||||
|
@ -169,9 +164,6 @@ class Conference extends Component<Props, State> {
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
const { props } = this;
|
const { props } = this;
|
||||||
|
|
||||||
if (props._avatarURL !== prevProps._avatarURL) {
|
|
||||||
this._setAvatarURL(props._avatarURL);
|
|
||||||
}
|
|
||||||
if (props._email !== prevProps._email) {
|
if (props._email !== prevProps._email) {
|
||||||
this._setEmail(props._email);
|
this._setEmail(props._email);
|
||||||
}
|
}
|
||||||
|
@ -370,7 +362,6 @@ class Conference extends Component<Props, State> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onVideoConferenceJoined(conferenceInfo: Object) {
|
_onVideoConferenceJoined(conferenceInfo: Object) {
|
||||||
this._setAvatarURL(this.props._avatarURL);
|
|
||||||
this._setEmail(this.props._email);
|
this._setEmail(this.props._email);
|
||||||
this._setName(this.props._name);
|
this._setName(this.props._name);
|
||||||
|
|
||||||
|
@ -382,16 +373,6 @@ class Conference extends Component<Props, State> {
|
||||||
(params: Object) => this._onEmailChange(params, id));
|
(params: Object) => this._onEmailChange(params, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Avatar URL from settings to conference.
|
|
||||||
*
|
|
||||||
* @param {string} avatarURL - Avatar URL.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
_setAvatarURL(avatarURL: string) {
|
|
||||||
this._api.executeCommand('avatarUrl', avatarURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set email from settings to conference.
|
* Set email from settings to conference.
|
||||||
*
|
*
|
||||||
|
@ -422,9 +403,7 @@ class Conference extends Component<Props, State> {
|
||||||
*/
|
*/
|
||||||
function _mapStateToProps(state: Object) {
|
function _mapStateToProps(state: Object) {
|
||||||
return {
|
return {
|
||||||
_alwaysOnTopWindowEnabled:
|
_alwaysOnTopWindowEnabled: getSetting(state, 'alwaysOnTopWindowEnabled', true),
|
||||||
getSetting(state, 'alwaysOnTopWindowEnabled', true),
|
|
||||||
_avatarURL: state.settings.avatarURL,
|
|
||||||
_email: state.settings.email,
|
_email: state.settings.email,
|
||||||
_name: state.settings.name,
|
_name: state.settings.name,
|
||||||
_serverURL: state.settings.serverURL,
|
_serverURL: state.settings.serverURL,
|
||||||
|
|
|
@ -47,8 +47,7 @@ class EmailSettingSpotlight extends Component<Props, *> {
|
||||||
] }
|
] }
|
||||||
dialogPlacement = 'left top'
|
dialogPlacement = 'left top'
|
||||||
target = { 'email-setting' } >
|
target = { 'email-setting' } >
|
||||||
The email you enter here will be part of your user profile and
|
The email you enter here will be part of your user profile.
|
||||||
it will be used to display your stored avatar in gravatar.com .
|
|
||||||
</Spotlight>
|
</Spotlight>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,9 @@ import { createLogger } from 'redux-logger';
|
||||||
|
|
||||||
import { middleware as onboardingMiddleware } from '../onboarding';
|
import { middleware as onboardingMiddleware } from '../onboarding';
|
||||||
import { middleware as routerMiddleware } from '../router';
|
import { middleware as routerMiddleware } from '../router';
|
||||||
import { middleware as settingsMiddleware } from '../settings';
|
|
||||||
|
|
||||||
export default applyMiddleware(
|
export default applyMiddleware(
|
||||||
onboardingMiddleware,
|
onboardingMiddleware,
|
||||||
routerMiddleware,
|
routerMiddleware,
|
||||||
settingsMiddleware,
|
|
||||||
createLogger()
|
createLogger()
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,16 +19,6 @@ export const SET_ALWAYS_ON_TOP_WINDOW_ENABLED
|
||||||
*/
|
*/
|
||||||
export const SET_AUDIO_MUTED = Symbol('SET_AUDIO_MUTED');
|
export const SET_AUDIO_MUTED = Symbol('SET_AUDIO_MUTED');
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of (redux) action that sets the Avatar URL.
|
|
||||||
*
|
|
||||||
* @type {
|
|
||||||
* type: SET_AVATAR_URL,
|
|
||||||
* avatarURL: string
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
export const SET_AVATAR_URL = Symbol('SET_AVATAR_URL');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of (redux) action that sets the email of the user.
|
* The type of (redux) action that sets the email of the user.
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import {
|
import {
|
||||||
SET_ALWAYS_ON_TOP_WINDOW_ENABLED,
|
SET_ALWAYS_ON_TOP_WINDOW_ENABLED,
|
||||||
SET_AUDIO_MUTED,
|
SET_AUDIO_MUTED,
|
||||||
SET_AVATAR_URL,
|
|
||||||
SET_EMAIL,
|
SET_EMAIL,
|
||||||
SET_NAME,
|
SET_NAME,
|
||||||
SET_SERVER_URL,
|
SET_SERVER_URL,
|
||||||
|
@ -13,22 +12,6 @@ import {
|
||||||
|
|
||||||
import { normalizeServerURL } from '../utils';
|
import { normalizeServerURL } from '../utils';
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Avatar URL.
|
|
||||||
*
|
|
||||||
* @param {string} avatarURL - Avatar URL.
|
|
||||||
* @returns {{
|
|
||||||
* type: SET_AVATAR_URL,
|
|
||||||
* avatarURL: string
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
export function setAvatarURL(avatarURL: string) {
|
|
||||||
return {
|
|
||||||
type: SET_AVATAR_URL,
|
|
||||||
avatarURL
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the email of the user.
|
* Set the email of the user.
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,6 +9,7 @@ import type { Dispatch } from 'redux';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
|
|
||||||
import { setServerTimeout } from '../actions';
|
import { setServerTimeout } from '../actions';
|
||||||
|
import { Form } from '../styled';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ class ServerTimeoutField extends Component<Props, State> {
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<form onSubmit = { this._onServerTimeoutSubmit }>
|
<Form onSubmit = { this._onServerTimeoutSubmit }>
|
||||||
<FieldTextStateless
|
<FieldTextStateless
|
||||||
invalidMessage
|
invalidMessage
|
||||||
= { 'Invalid Timeout' }
|
= { 'Invalid Timeout' }
|
||||||
|
@ -77,7 +78,7 @@ class ServerTimeoutField extends Component<Props, State> {
|
||||||
shouldFitContainer = { true }
|
shouldFitContainer = { true }
|
||||||
type = 'number'
|
type = 'number'
|
||||||
value = { this.state.serverTimeout } />
|
value = { this.state.serverTimeout } />
|
||||||
</form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import config from '../../config';
|
||||||
import { getExternalApiURL } from '../../utils';
|
import { getExternalApiURL } from '../../utils';
|
||||||
|
|
||||||
import { setServerURL } from '../actions';
|
import { setServerURL } from '../actions';
|
||||||
|
import { Form } from '../styled';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ class ServerURLField extends Component<Props, State> {
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<form onSubmit = { this._onServerURLSubmit }>
|
<Form onSubmit = { this._onServerURLSubmit }>
|
||||||
<FieldTextStateless
|
<FieldTextStateless
|
||||||
invalidMessage
|
invalidMessage
|
||||||
= { 'Invalid Server URL or external API not enabled' }
|
= { 'Invalid Server URL or external API not enabled' }
|
||||||
|
@ -78,7 +79,7 @@ class ServerURLField extends Component<Props, State> {
|
||||||
shouldFitContainer = { true }
|
shouldFitContainer = { true }
|
||||||
type = 'text'
|
type = 'text'
|
||||||
value = { this.state.serverURL } />
|
value = { this.state.serverURL } />
|
||||||
</form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import Avatar from '@atlaskit/avatar';
|
|
||||||
import FieldText from '@atlaskit/field-text';
|
import FieldText from '@atlaskit/field-text';
|
||||||
import ArrowLeft from '@atlaskit/icon/glyph/arrow-left';
|
import ArrowLeft from '@atlaskit/icon/glyph/arrow-left';
|
||||||
import { AkCustomDrawer } from '@atlaskit/navigation';
|
import { AkCustomDrawer } from '@atlaskit/navigation';
|
||||||
|
@ -13,7 +12,7 @@ import type { Dispatch } from 'redux';
|
||||||
|
|
||||||
import { closeDrawer, DrawerContainer, Logo } from '../../navbar';
|
import { closeDrawer, DrawerContainer, Logo } from '../../navbar';
|
||||||
import { Onboarding, startOnboarding } from '../../onboarding';
|
import { Onboarding, startOnboarding } from '../../onboarding';
|
||||||
import { AvatarContainer, SettingsContainer, TogglesContainer } from '../styled';
|
import { Form, SettingsContainer, TogglesContainer } from '../styled';
|
||||||
import { setEmail, setName } from '../actions';
|
import { setEmail, setName } from '../actions';
|
||||||
|
|
||||||
import AlwaysOnTopWindowToggle from './AlwaysOnTopWindowToggle';
|
import AlwaysOnTopWindowToggle from './AlwaysOnTopWindowToggle';
|
||||||
|
@ -33,11 +32,6 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* Avatar URL.
|
|
||||||
*/
|
|
||||||
_avatarURL: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email of the user.
|
* Email of the user.
|
||||||
*/
|
*/
|
||||||
|
@ -101,32 +95,27 @@ class SettingsDrawer extends Component<Props, *> {
|
||||||
primaryIcon = { <Logo /> } >
|
primaryIcon = { <Logo /> } >
|
||||||
<DrawerContainer>
|
<DrawerContainer>
|
||||||
<SettingsContainer>
|
<SettingsContainer>
|
||||||
<AvatarContainer>
|
|
||||||
<Avatar
|
|
||||||
size = 'xlarge'
|
|
||||||
src = { this.props._avatarURL } />
|
|
||||||
</AvatarContainer>
|
|
||||||
<SpotlightTarget
|
<SpotlightTarget
|
||||||
name = 'name-setting'>
|
name = 'name-setting'>
|
||||||
<form onSubmit = { this._onNameFormSubmit }>
|
<Form onSubmit = { this._onNameFormSubmit }>
|
||||||
<FieldText
|
<FieldText
|
||||||
label = 'Name'
|
label = 'Name'
|
||||||
onBlur = { this._onNameBlur }
|
onBlur = { this._onNameBlur }
|
||||||
shouldFitContainer = { true }
|
shouldFitContainer = { true }
|
||||||
type = 'text'
|
type = 'text'
|
||||||
value = { this.props._name } />
|
value = { this.props._name } />
|
||||||
</form>
|
</Form>
|
||||||
</SpotlightTarget>
|
</SpotlightTarget>
|
||||||
<SpotlightTarget
|
<SpotlightTarget
|
||||||
name = 'email-setting'>
|
name = 'email-setting'>
|
||||||
<form onSubmit = { this._onEmailFormSubmit }>
|
<Form onSubmit = { this._onEmailFormSubmit }>
|
||||||
<FieldText
|
<FieldText
|
||||||
label = 'Email'
|
label = 'Email'
|
||||||
onBlur = { this._onEmailBlur }
|
onBlur = { this._onEmailBlur }
|
||||||
shouldFitContainer = { true }
|
shouldFitContainer = { true }
|
||||||
type = 'text'
|
type = 'text'
|
||||||
value = { this.props._email } />
|
value = { this.props._email } />
|
||||||
</form>
|
</Form>
|
||||||
</SpotlightTarget>
|
</SpotlightTarget>
|
||||||
<SpotlightTarget
|
<SpotlightTarget
|
||||||
name = 'server-setting'>
|
name = 'server-setting'>
|
||||||
|
@ -167,7 +156,7 @@ class SettingsDrawer extends Component<Props, *> {
|
||||||
_onEmailBlur: (*) => void;
|
_onEmailBlur: (*) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates Avatar URL in (redux) state when email is updated.
|
* Updates email in (redux) state when email is updated.
|
||||||
*
|
*
|
||||||
* @param {SyntheticInputEvent<HTMLInputElement>} event - Event by which
|
* @param {SyntheticInputEvent<HTMLInputElement>} event - Event by which
|
||||||
* this function is called.
|
* this function is called.
|
||||||
|
@ -196,7 +185,7 @@ class SettingsDrawer extends Component<Props, *> {
|
||||||
_onNameBlur: (*) => void;
|
_onNameBlur: (*) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates Avatar URL in (redux) state when name is updated.
|
* Updates name in (redux) state when name is updated.
|
||||||
*
|
*
|
||||||
* @param {SyntheticInputEvent<HTMLInputElement>} event - Event by which
|
* @param {SyntheticInputEvent<HTMLInputElement>} event - Event by which
|
||||||
* this function is called.
|
* this function is called.
|
||||||
|
@ -227,15 +216,10 @@ class SettingsDrawer extends Component<Props, *> {
|
||||||
* Maps (parts of) the redux state to the React props.
|
* Maps (parts of) the redux state to the React props.
|
||||||
*
|
*
|
||||||
* @param {Object} state - The redux state.
|
* @param {Object} state - The redux state.
|
||||||
* @returns {{
|
* @returns {Props}
|
||||||
* _avatarURL: string,
|
|
||||||
* _email: string,
|
|
||||||
* _name: string
|
|
||||||
* }}
|
|
||||||
*/
|
*/
|
||||||
function _mapStateToProps(state: Object) {
|
function _mapStateToProps(state: Object) {
|
||||||
return {
|
return {
|
||||||
_avatarURL: state.settings.avatarURL,
|
|
||||||
_email: state.settings.email,
|
_email: state.settings.email,
|
||||||
_name: state.settings.name
|
_name: state.settings.name
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,26 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import md5 from 'js-md5';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates an avatar URL for a user, given the name and email settings.
|
|
||||||
*
|
|
||||||
* @param {Object} state - The redux state.
|
|
||||||
* @returns {string} - The generated avatar URL.
|
|
||||||
*/
|
|
||||||
export function getAvatarURL(state: Object) {
|
|
||||||
const { email, name } = state.settings;
|
|
||||||
const encodedName = encodeURIComponent(name || '');
|
|
||||||
|
|
||||||
if (email) {
|
|
||||||
const md5email = md5.hex(email.trim().toLowerCase());
|
|
||||||
|
|
||||||
return `https://www.gravatar.com/avatar/${md5email}?d=https%3A%2F%2Fui-avatars.com%2Fapi%2F/${encodedName}/128`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `https://ui-avatars.com/api/?name=${encodedName}&size=128`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get's the value for the given setting, providing a default value.
|
* Get's the value for the given setting, providing a default value.
|
||||||
*
|
*
|
||||||
|
|
|
@ -4,5 +4,4 @@ export * from './components';
|
||||||
export * from './functions';
|
export * from './functions';
|
||||||
export * from './styled';
|
export * from './styled';
|
||||||
|
|
||||||
export { default as middleware } from './middleware';
|
|
||||||
export { default as reducer } from './reducer';
|
export { default as reducer } from './reducer';
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import { SET_EMAIL, SET_NAME } from './actionTypes';
|
|
||||||
import { setAvatarURL } from './actions';
|
|
||||||
import { getAvatarURL } from './functions';
|
|
||||||
|
|
||||||
export default (store: Object) => (next: Function) => (action: Object) => {
|
|
||||||
const result = next(action);
|
|
||||||
const state = store.getState();
|
|
||||||
|
|
||||||
switch (action.type) {
|
|
||||||
case SET_EMAIL:
|
|
||||||
case SET_NAME:
|
|
||||||
store.dispatch(setAvatarURL(getAvatarURL(state)));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
|
@ -3,31 +3,27 @@
|
||||||
import {
|
import {
|
||||||
SET_ALWAYS_ON_TOP_WINDOW_ENABLED,
|
SET_ALWAYS_ON_TOP_WINDOW_ENABLED,
|
||||||
SET_AUDIO_MUTED,
|
SET_AUDIO_MUTED,
|
||||||
SET_AVATAR_URL,
|
|
||||||
SET_EMAIL,
|
SET_EMAIL,
|
||||||
SET_NAME,
|
SET_NAME,
|
||||||
SET_SERVER_URL,
|
SET_SERVER_URL,
|
||||||
SET_SERVER_TIMEOUT,
|
SET_SERVER_TIMEOUT,
|
||||||
SET_VIDEO_MUTED
|
SET_VIDEO_MUTED
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
import { getAvatarURL } from './functions';
|
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
avatarURL: string,
|
alwaysOnTopWindowEnabled: boolean,
|
||||||
email: string,
|
email: string,
|
||||||
name: string,
|
name: string,
|
||||||
serverURL: ?string,
|
serverURL: ?string,
|
||||||
serverTimeout: ?number,
|
serverTimeout: ?number,
|
||||||
startWithAudioMuted: boolean,
|
startWithAudioMuted: boolean,
|
||||||
startWithVideoMuted: boolean,
|
startWithVideoMuted: boolean
|
||||||
alwaysOnTopWindowEnabled: boolean,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const username = window.jitsiNodeAPI.osUserInfo().username;
|
const username = window.jitsiNodeAPI.osUserInfo().username;
|
||||||
|
|
||||||
const DEFAULT_STATE = {
|
const DEFAULT_STATE = {
|
||||||
alwaysOnTopWindowEnabled: true,
|
alwaysOnTopWindowEnabled: true,
|
||||||
avatarURL: getAvatarURL({ settings: { name: username } }),
|
|
||||||
email: '',
|
email: '',
|
||||||
name: username,
|
name: username,
|
||||||
serverURL: undefined,
|
serverURL: undefined,
|
||||||
|
@ -57,12 +53,6 @@ export default (state: State = DEFAULT_STATE, action: Object) => {
|
||||||
startWithAudioMuted: action.startWithAudioMuted
|
startWithAudioMuted: action.startWithAudioMuted
|
||||||
};
|
};
|
||||||
|
|
||||||
case SET_AVATAR_URL:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
avatarURL: action.avatarURL
|
|
||||||
};
|
|
||||||
|
|
||||||
case SET_EMAIL:
|
case SET_EMAIL:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
export default styled.div`
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
`;
|
|
7
app/features/settings/styled/Form.js
Normal file
7
app/features/settings/styled/Form.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
export default styled.form`
|
||||||
|
margin: 0;
|
||||||
|
`;
|
|
@ -1,4 +1,4 @@
|
||||||
export { default as AvatarContainer } from './AvatarContainer';
|
export { default as Form } from './Form';
|
||||||
export { default as Label } from './Label';
|
export { default as Label } from './Label';
|
||||||
export { default as SettingsContainer } from './SettingsContainer';
|
export { default as SettingsContainer } from './SettingsContainer';
|
||||||
export { default as ToggleContainer } from './ToggleContainer';
|
export { default as ToggleContainer } from './ToggleContainer';
|
||||||
|
|
|
@ -83,7 +83,6 @@
|
||||||
"readmeFilename": "README.md",
|
"readmeFilename": "README.md",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@atlaskit/avatar": "14.1.7",
|
|
||||||
"@atlaskit/button": "10.1.1",
|
"@atlaskit/button": "10.1.1",
|
||||||
"@atlaskit/css-reset": "3.0.5",
|
"@atlaskit/css-reset": "3.0.5",
|
||||||
"@atlaskit/droplist": "7.0.17",
|
"@atlaskit/droplist": "7.0.17",
|
||||||
|
@ -146,7 +145,6 @@
|
||||||
"file-loader": "6.0.0",
|
"file-loader": "6.0.0",
|
||||||
"flow-bin": "0.109.0",
|
"flow-bin": "0.109.0",
|
||||||
"html-webpack-plugin": "4.0.4",
|
"html-webpack-plugin": "4.0.4",
|
||||||
"js-md5": "0.7.3",
|
|
||||||
"patch-package": "6.2.2",
|
"patch-package": "6.2.2",
|
||||||
"precommit-hook": "3.0.0",
|
"precommit-hook": "3.0.0",
|
||||||
"style-loader": "1.1.3",
|
"style-loader": "1.1.3",
|
||||||
|
|
Loading…
Reference in a new issue