diff --git a/src/client/actions/NotifyActions.ts b/src/client/actions/NotifyActions.ts index e34b520..f6ed8ae 100644 --- a/src/client/actions/NotifyActions.ts +++ b/src/client/actions/NotifyActions.ts @@ -70,57 +70,6 @@ export const clear = (): NotificationClearAction => ({ type: constants.NOTIFY_CLEAR, }) -export interface Alert { - action?: string - dismissable: boolean - message: string - type: NotifyType -} - -export interface AlertAddAction { - type: 'ALERT' - payload: Alert -} - -export function alert (message: string, dismissable = false): AlertAddAction { - return { - type: constants.ALERT, - payload: { - action: dismissable ? 'Dismiss' : undefined, - dismissable: !!dismissable, - message, - type: 'warning', - }, - } -} - -export interface AlertDismissAction { - type: 'ALERT_DISMISS' - payload: Alert -} - -export const dismissAlert = (alert: Alert): AlertDismissAction => { - return { - type: constants.ALERT_DISMISS, - payload: alert, - } -} - -export interface AlertClearAction { - type: 'ALERT_CLEAR' -} - -export const clearAlerts = (): AlertClearAction => { - return { - type: constants.ALERT_CLEAR, - } -} - -export type AlertActionType = - AlertAddAction | - AlertDismissAction | - AlertClearAction - export type NotificationActionType = NotificationAddAction | NotificationDismissAction | diff --git a/src/client/components/Alerts.tsx b/src/client/components/Alerts.tsx index 168b207..8cece5d 100644 --- a/src/client/components/Alerts.tsx +++ b/src/client/components/Alerts.tsx @@ -1,48 +1,29 @@ import React from 'react' -import classnames from 'classnames' -import { Alert as AlertType } from '../actions/NotifyActions' export interface AlertProps { - alert: AlertType - dismiss: (alert: AlertType) => void + children: React.ReactNode } -export class Alert extends React.PureComponent { - dismiss = () => { - const { alert, dismiss } = this.props - dismiss(alert) - } - render () { - const { alert } = this.props - +export const Alert = React.memo( + function Alert(props: AlertProps) { return ( -
- {alert.message} - {alert.dismissable && ( - - )} +
+ {props.children}
) - } -} + }, +) export interface AlertsProps { - alerts: AlertType[] - dismiss: (alert: AlertType) => void + children: React.ReactNode } -export default class Alerts extends React.PureComponent { - render () { - const { alerts, dismiss } = this.props +export const Alerts = React.memo( + function Alerts(props: AlertsProps) { return (
- {alerts.map((alert, i) => ( - - ))} + {props.children}
) - } -} + }, +) diff --git a/src/client/components/App.tsx b/src/client/components/App.tsx index d692742..90c9d7f 100644 --- a/src/client/components/App.tsx +++ b/src/client/components/App.tsx @@ -2,11 +2,10 @@ import map from 'lodash/map' import React from 'react' import Peer from 'simple-peer' import { Message } from '../actions/ChatActions' -import { Alert, Notification, dismissNotification } from '../actions/NotifyActions' +import { Notification, dismissNotification } from '../actions/NotifyActions' import { TextMessage } from '../actions/PeerActions' import { AddStreamPayload } from '../actions/StreamActions' import * as constants from '../constants' -import Alerts from './Alerts' import Chat from './Chat' import Notifications from './Notifications' import Toolbar from './Toolbar' @@ -15,8 +14,6 @@ import { Media } from './Media' export interface AppProps { active: string | null - alerts: Alert[] - dismissAlert: (alert: Alert) => void dismissNotification: typeof dismissNotification init: () => void notifications: Record @@ -62,8 +59,6 @@ export default class App extends React.PureComponent { render () { const { active, - alerts, - dismissAlert, dismissNotification, notifications, messages, @@ -87,7 +82,6 @@ export default class App extends React.PureComponent { onSendFile={onSendFile} stream={streams[constants.ME]} /> - + The browser has blocked video autoplay on this page. To continue with your call, please press the play button:   -
+ ) }, ) @@ -114,6 +115,14 @@ export const AutoplayMessage = React.memo( export const Media = c(React.memo(function Media(props: MediaProps) { return (
+ + {props.autoplayError && ( + + + + )} + + {props.autoplayError && }
diff --git a/src/client/containers/App.test.tsx b/src/client/containers/App.test.tsx index f2a22c4..d6945b4 100644 --- a/src/client/containers/App.test.tsx +++ b/src/client/containers/App.test.tsx @@ -8,7 +8,6 @@ import TestUtils from 'react-dom/test-utils' import { Provider } from 'react-redux' import { AnyAction, applyMiddleware, createStore } from 'redux' import { init } from '../actions/CallActions' -import { Alert } from '../actions/NotifyActions' import * as constants from '../constants' import reducers from '../reducers' import { middlewares, State, Store } from '../store' @@ -66,7 +65,6 @@ describe('App', () => { }) describe('state', () => { - let alert: Alert beforeEach(async () => { state.streams = { test: { @@ -85,28 +83,9 @@ describe('App', () => { type: 'warning', }, } - alert = { - dismissable: true, - action: 'Dismiss', - message: 'test alert', - type: 'info', - } - state.alerts = [alert] await render() }) - describe('alerts', () => { - it('can be dismissed', () => { - const dismiss = node.querySelector('.action-alert-dismiss')! - dispatchSpy.mockReset() - TestUtils.Simulate.click(dismiss) - expect(dispatchSpy.mock.calls).toEqual([[{ - type: constants.ALERT_DISMISS, - payload: alert, - }]]) - }) - }) - describe('video', () => { it('can be activated', () => { dispatchSpy.mockReset() diff --git a/src/client/containers/App.tsx b/src/client/containers/App.tsx index 3984fc2..5ccbee9 100644 --- a/src/client/containers/App.tsx +++ b/src/client/containers/App.tsx @@ -1,7 +1,7 @@ import { connect } from 'react-redux' import { init } from '../actions/CallActions' import { play } from '../actions/MediaActions' -import { dismissAlert, dismissNotification } from '../actions/NotifyActions' +import { dismissNotification } from '../actions/NotifyActions' import { sendFile, sendMessage } from '../actions/PeerActions' import { toggleActive } from '../actions/StreamActions' import App from '../components/App' @@ -11,7 +11,6 @@ function mapStateToProps (state: State) { return { streams: state.streams, peers: state.peers, - alerts: state.alerts, notifications: state.notifications, messages: state.messages.list, messagesCount: state.messages.count, @@ -22,7 +21,6 @@ function mapStateToProps (state: State) { const mapDispatchToProps = { toggleActive, sendMessage, - dismissAlert: dismissAlert, dismissNotification, init, onSendFile: sendFile, diff --git a/src/client/reducers/alerts.test.ts b/src/client/reducers/alerts.test.ts deleted file mode 100644 index 321e635..0000000 --- a/src/client/reducers/alerts.test.ts +++ /dev/null @@ -1,106 +0,0 @@ -import * as NotifyActions from '../actions/NotifyActions' -import { applyMiddleware, createStore, Store, bindActionCreators } from 'redux' -import { create } from '../middlewares' -import reducers from './index' -import values from 'lodash/values' - -jest.useFakeTimers() - -describe('reducers/alerts', () => { - - let store: Store - let notifyActions: typeof NotifyActions - beforeEach(() => { - store = createStore( - reducers, - applyMiddleware(...create()), - ) - notifyActions = bindActionCreators(NotifyActions, store.dispatch) - }) - - - describe('clearAlert', () => { - - [true, false].forEach(dismissable => { - beforeEach(() => { - notifyActions.clearAlerts() - }) - it('adds alert to store', () => { - notifyActions.alert('test', dismissable) - expect(store.getState().alerts).toEqual([{ - action: dismissable ? 'Dismiss' : undefined, - dismissable, - message: 'test', - type: 'warning', - }]) - }) - }) - - }) - - describe('dismissAlert', () => { - - it('removes an alert', () => { - store.dispatch(NotifyActions.alert('test', true)) - expect(store.getState().alerts.length).toBe(1) - store.dispatch(NotifyActions.dismissAlert(store.getState().alerts[0])) - expect(store.getState().alerts.length).toBe(0) - }) - - it('does not remove an alert when not found', () => { - store.dispatch(NotifyActions.alert('test', true)) - expect(store.getState().alerts.length).toBe(1) - store.dispatch(NotifyActions.dismissAlert({ - action: undefined, - dismissable: false, - message: 'bla', - type: 'error', - })) - expect(store.getState().alerts.length).toBe(1) - }) - - }) - - const methods: Array<'info' | 'warning' | 'error'> = [ - 'info', - 'warning', - 'error', - ] - - methods.forEach(type => { - - describe(type, () => { - - beforeEach(() => { - notifyActions[type]('Hi {0}!', 'John') - }) - - it('adds a notification', () => { - expect(values(store.getState().notifications)).toEqual([{ - id: jasmine.any(String), - message: 'Hi John!', - type, - }]) - }) - - it('does not fail when no arguments', () => { - notifyActions[type]() - }) - - }) - - }) - - describe('clear', () => { - - it('clears all alerts', () => { - notifyActions.info('Hi {0}!', 'John') - notifyActions.warning('Hi {0}!', 'John') - notifyActions.error('Hi {0}!', 'John') - store.dispatch(NotifyActions.clear()) - expect(store.getState().notifications).toEqual({}) - }) - - }) - -}) diff --git a/src/client/reducers/alerts.ts b/src/client/reducers/alerts.ts deleted file mode 100644 index 6e9771d..0000000 --- a/src/client/reducers/alerts.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as constants from '../constants' -import { AlertActionType, Alert } from '../actions/NotifyActions' - -export type AlertState = Alert[] - -const defaultState: AlertState = [] - -export default function alerts (state = defaultState, action: AlertActionType) { - switch (action.type) { - case constants.ALERT: - return [...state, action.payload] - case constants.ALERT_DISMISS: - return state.filter(a => a !== action.payload) - case constants.ALERT_CLEAR: - return defaultState - default: - return state - } -} diff --git a/src/client/reducers/index.ts b/src/client/reducers/index.ts index 835325a..e7ce5c4 100644 --- a/src/client/reducers/index.ts +++ b/src/client/reducers/index.ts @@ -1,5 +1,4 @@ import active from './active' -import alerts from './alerts' import notifications from './notifications' import messages from './messages' import peers from './peers' @@ -9,7 +8,6 @@ import { combineReducers } from 'redux' export default combineReducers({ active, - alerts, notifications, messages, media, diff --git a/src/scss/_media.scss b/src/scss/_media.scss index b9a325a..54be6c3 100644 --- a/src/scss/_media.scss +++ b/src/scss/_media.scss @@ -1,20 +1,3 @@ -.media-container .autoplay { - background-color: rgba(0, 0, 0, 0.3); - left: 0; - right: 0; - top: 0; - z-index: 1000; - position: absolute; - color: $color-warning; - text-align: center; - padding: 0.5rem; - - button { - padding: 0.5rem; - @include button($color-primary, $color-warning); - } -} - .media-container form.media { max-width: 440px; text-align: center;