Fix snackbar

This commit is contained in:
6ea86b96 2017-05-23 11:21:21 +04:00
parent 666674888e
commit 53efd55890
No known key found for this signature in database
GPG key ID: B282D183E4931E8F
9 changed files with 148 additions and 71 deletions

View file

@ -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,
}
}

View file

@ -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 (
<div className="snack-bar">
{snack.message}
{snack.linkText && snack.linkTarget ?
<a className="snack-bar__action" href={snack.linkTarget}>{snack.linkText}</a> : ''}
</div>
);
}
}
export default SnackBar;

View file

@ -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)

View file

@ -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 (
<div className="snack-bar">
{message}
{linkText && linkTarget &&
<Link onClick={() => navigate(linkTarget)} label={linkText} />
}
</div>
);
}
}
export default SnackBar;

View file

@ -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'

View file

@ -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'

View file

@ -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);

View file

@ -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

View file

@ -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 || []
)