From 53efd55890b817a1d9cfffb0356549d276b685dd Mon Sep 17 00:00:00 2001 From: 6ea86b96 <6ea86b96@gmail.com> Date: Tue, 23 May 2017 11:21:21 +0400 Subject: [PATCH] Fix snackbar --- ui/js/actions/app.js | 13 +++++++ ui/js/component/snack-bar.js | 60 ------------------------------- ui/js/component/snackBar/index.js | 23 ++++++++++++ ui/js/component/snackBar/view.jsx | 49 +++++++++++++++++++++++++ ui/js/constants/action_types.js | 2 ++ ui/js/main.js | 2 +- ui/js/reducers/app.js | 38 ++++++++++++++++++++ ui/js/rewards.js | 22 ++++++------ ui/js/selectors/app.js | 10 ++++++ 9 files changed, 148 insertions(+), 71 deletions(-) delete mode 100644 ui/js/component/snack-bar.js create mode 100644 ui/js/component/snackBar/index.js create mode 100644 ui/js/component/snackBar/view.jsx diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index c10e33189..347e07cc2 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -213,3 +213,16 @@ export function doDaemonReady() { type: types.DAEMON_READY } } + +export function doShowSnackBar(data) { + return { + type: types.SHOW_SNACKBAR, + data, + } +} + +export function doRemoveSnackBarSnack() { + return { + type: types.REMOVE_SNACKBAR_SNACK, + } +} diff --git a/ui/js/component/snack-bar.js b/ui/js/component/snack-bar.js deleted file mode 100644 index 46dc3bd98..000000000 --- a/ui/js/component/snack-bar.js +++ /dev/null @@ -1,60 +0,0 @@ -import React from 'react'; - -export class SnackBar extends React.Component { - constructor(props) { - super(props); - - this._displayTime = 5; // in seconds - this._hideTimeout = null; - - this.state = { - snacks: [] - }; - } - - handleSnackReceived(event) { - // if (this._hideTimeout) { - // clearTimeout(this._hideTimeout); - // } - - let snacks = this.state.snacks; - snacks.push(event.detail); - this.setState({ snacks: snacks}); - } - - componentWillMount() { - document.addEventListener('globalNotice', this.handleSnackReceived); - } - - componentWillUnmount() { - document.removeEventListener('globalNotice', this.handleSnackReceived); - } - - render() { - if (!this.state.snacks.length) { - this._hideTimeout = null; //should be unmounting anyway, but be safe? - return null; - } - - let snack = this.state.snacks[0]; - - if (this._hideTimeout === null) { - this._hideTimeout = setTimeout(() => { - this._hideTimeout = null; - let snacks = this.state.snacks; - snacks.shift(); - this.setState({ snacks: snacks }); - }, this._displayTime * 1000); - } - - return ( -
- {snack.message} - {snack.linkText && snack.linkTarget ? - {snack.linkText} : ''} -
- ); - } -} - -export default SnackBar; \ No newline at end of file diff --git a/ui/js/component/snackBar/index.js b/ui/js/component/snackBar/index.js new file mode 100644 index 000000000..0d624ce87 --- /dev/null +++ b/ui/js/component/snackBar/index.js @@ -0,0 +1,23 @@ +import React from 'react' +import { + connect, +} from 'react-redux' +import { + doNavigate, + doRemoveSnackBarSnack, +} from 'actions/app' +import { + selectSnackBarSnacks, +} from 'selectors/app' +import SnackBar from './view' + +const perform = (dispatch) => ({ + navigate: (path) => dispatch(doNavigate(path)), + removeSnack: () => dispatch(doRemoveSnackBarSnack()), +}) + +const select = (state) => ({ + snacks: selectSnackBarSnacks(state), +}) + +export default connect(select, perform)(SnackBar) diff --git a/ui/js/component/snackBar/view.jsx b/ui/js/component/snackBar/view.jsx new file mode 100644 index 000000000..98206ae2b --- /dev/null +++ b/ui/js/component/snackBar/view.jsx @@ -0,0 +1,49 @@ +import React from 'react'; +import Link from 'component/link' + +class SnackBar extends React.Component { + constructor(props) { + super(props); + + this._displayTime = 5; // in seconds + this._hideTimeout = null; + } + + render() { + const { + navigate, + snacks, + removeSnack, + } = this.props + + if (!snacks.length) { + this._hideTimeout = null; //should be unmounting anyway, but be safe? + return null; + } + + const snack = snacks[0]; + const { + message, + linkText, + linkTarget, + } = snack + + if (this._hideTimeout === null) { + this._hideTimeout = setTimeout(() => { + this._hideTimeout = null; + removeSnack() + }, this._displayTime * 1000); + } + + return ( +
+ {message} + {linkText && linkTarget && + navigate(linkTarget)} label={linkText} /> + } +
+ ); + } +} + +export default SnackBar; \ No newline at end of file diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index 3607583e3..1d1dab869 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -2,6 +2,8 @@ export const CHANGE_PATH = 'CHANGE_PATH' export const OPEN_MODAL = 'OPEN_MODAL' export const CLOSE_MODAL = 'CLOSE_MODAL' export const HISTORY_BACK = 'HISTORY_BACK' +export const SHOW_SNACKBAR = 'SHOW_SNACKBAR' +export const REMOVE_SNACKBAR_SNACK = 'REMOVE_SNACKBAR_SNACK' export const DAEMON_READY = 'DAEMON_READY' diff --git a/ui/js/main.js b/ui/js/main.js index d02a965fa..8d6d1be1d 100644 --- a/ui/js/main.js +++ b/ui/js/main.js @@ -5,7 +5,7 @@ import lbryio from './lbryio.js'; import lighthouse from './lighthouse.js'; import App from 'component/app/index.js'; import SplashScreen from 'component/splash.js'; -import SnackBar from 'component/snack-bar.js'; +import SnackBar from 'component/snackBar'; import {AuthOverlay} from 'component/auth.js'; import { Provider } from 'react-redux'; import batchActions from 'util/batchActions' diff --git a/ui/js/reducers/app.js b/ui/js/reducers/app.js index e3070ed40..f80baae0b 100644 --- a/ui/js/reducers/app.js +++ b/ui/js/reducers/app.js @@ -93,6 +93,44 @@ reducers[types.DAEMON_READY] = function(state, action) { }) } +reducers[types.SHOW_SNACKBAR] = function(state, action) { + const { + message, + linkText, + linkTarget, + isError, + } = action.data + const snackBar = Object.assign({}, state.snackBar) + const snacks = Object.assign([], snackBar.snacks) + snacks.push({ + message, + linkText, + linkTarget, + isError, + }) + const newSnackBar = Object.assign({}, snackBar, { + snacks, + }) + + return Object.assign({}, state, { + snackBar: newSnackBar, + }) +} + +reducers[types.REMOVE_SNACKBAR_SNACK] = function(state, action) { + const snackBar = Object.assign({}, state.snackBar) + const snacks = Object.assign([], snackBar.snacks) + snacks.shift() + + const newSnackBar = Object.assign({}, snackBar, { + snacks, + }) + + return Object.assign({}, state, { + snackBar: newSnackBar, + }) +} + export default function reducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/ui/js/rewards.js b/ui/js/rewards.js index 9a2235130..eae27eb88 100644 --- a/ui/js/rewards.js +++ b/ui/js/rewards.js @@ -1,5 +1,8 @@ -import lbry from './lbry.js'; -import lbryio from './lbryio.js'; +import lbry from 'lbry'; +import lbryio from 'lbryio'; +import { + doShowSnackBar, +} from 'actions/app' function rewardMessage(type, amount) { return { @@ -40,14 +43,13 @@ rewards.claimReward = function (type) { }; // Display global notice - document.dispatchEvent(new CustomEvent('globalNotice', { - detail: { - message: message, - linkText: "Show All", - linkTarget: "/rewards", - isError: false, - }, - })); + const action = doShowSnackBar({ + message, + linkText: "Show All", + linkTarget: "/rewards", + isError: false, + }) + window.app.store.dispatch(action) // Add more events here to display other places diff --git a/ui/js/selectors/app.js b/ui/js/selectors/app.js index f0af3b5a1..6e9638a5d 100644 --- a/ui/js/selectors/app.js +++ b/ui/js/selectors/app.js @@ -191,4 +191,14 @@ export const selectDaemonReady = createSelector( export const selectObscureNsfw = createSelector( _selectState, (state) => !!state.obscureNsfw +) + +export const selectSnackBar = createSelector( + _selectState, + (state) => state.snackBar || {} +) + +export const selectSnackBarSnacks = createSelector( + selectSnackBar, + (snackBar) => snackBar.snacks || [] ) \ No newline at end of file