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