From 99114726091756350e28db3fe3fef9f2ac83d5ff Mon Sep 17 00:00:00 2001 From: david Date: Mon, 1 Oct 2018 18:56:25 +0200 Subject: [PATCH] added a namespace field in tab search component --- src/app/css/components/_search.scss | 8 +++++ .../js/components/search/NamespaceTextbar.js | 20 +++++++++++ src/app/js/components/search/RefreshIcon.js | 4 +-- src/app/js/components/search/Search.js | 5 +-- src/app/js/components/search/SearchView.js | 34 ++++++++++++++----- src/app/js/components/search/TextBar.js | 10 +++--- src/app/js/reducers/connections.js | 22 +++++++++--- src/app/js/socketManager.js | 12 ++++--- 8 files changed, 90 insertions(+), 25 deletions(-) create mode 100644 src/app/js/components/search/NamespaceTextbar.js diff --git a/src/app/css/components/_search.scss b/src/app/css/components/_search.scss index d353990..a66da97 100644 --- a/src/app/css/components/_search.scss +++ b/src/app/css/components/_search.scss @@ -44,4 +44,12 @@ border: none; outline: none; font-size: initial; +} + +.namespace-text { + flex: 0.2; + + input { + padding-left: 10px; + } } \ No newline at end of file diff --git a/src/app/js/components/search/NamespaceTextbar.js b/src/app/js/components/search/NamespaceTextbar.js new file mode 100644 index 0000000..ceffafe --- /dev/null +++ b/src/app/js/components/search/NamespaceTextbar.js @@ -0,0 +1,20 @@ +/** + * TextBar + * + * Renders the input field of the searchbar + * + * @property {String} namespace the current state of the input field + * @property {Function} changeNamespace handle inputchange + * @property {Function} setNamespaceAndUrl confirm namespace and url and save in redux store + */ + +import React from 'react' + +const NamespaceTextBar = ({namespace, changeNamespace, setNamespaceAndUrl}) => + +
+ +
+
+ +export default NamespaceTextBar diff --git a/src/app/js/components/search/RefreshIcon.js b/src/app/js/components/search/RefreshIcon.js index 500dcd8..4e04e87 100644 --- a/src/app/js/components/search/RefreshIcon.js +++ b/src/app/js/components/search/RefreshIcon.js @@ -2,8 +2,8 @@ import React from 'react' import RepeatIcon from '../../icons/Repeat' -const RefreshIcon = ({faded, setUrl}) => - +const RefreshIcon = ({faded, setNamespaceAndUrl}) => + diff --git a/src/app/js/components/search/Search.js b/src/app/js/components/search/Search.js index b0d9313..42266b6 100644 --- a/src/app/js/components/search/Search.js +++ b/src/app/js/components/search/Search.js @@ -15,10 +15,11 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { - setUrl (id, url) { + setNamespaceAndUrl (id, namespace, url) { dispatch({ - type: 'SET_URL', + type: 'SET_NAMESPACE_AND_URL', id, + namespace, url: makeSureItsGotHttp(url) }) } diff --git a/src/app/js/components/search/SearchView.js b/src/app/js/components/search/SearchView.js index 85dc067..c51a995 100644 --- a/src/app/js/components/search/SearchView.js +++ b/src/app/js/components/search/SearchView.js @@ -12,6 +12,7 @@ import React, { Component } from 'react' import RefreshIcon from './RefreshIcon' import TextBar from './TextBar' +import NamespaceTextBar from './NamespaceTextBar' class Search extends Component { @@ -22,18 +23,21 @@ class Search extends Component { this.state = { tab, - url: tab.url || '' + url: tab.url || '', + namespace: tab.namespace || '' } this.changeUrl = this.changeUrl.bind(this) - this.setUrl = this.setUrl.bind(this) + this.changeNamespace = this.changeNamespace.bind(this) + this.setNamespaceAndUrl = this.setNamespaceAndUrl.bind(this) } componentWillReceiveProps(nextProps) { const tab = this.getThisTab(nextProps) this.setState({ tab, - url: tab.url || '' + url: tab.url || '', + namespace: tab.namespace || '' }) } @@ -63,16 +67,29 @@ class Search extends Component { }) } + /** + * Update namespace in component state + * + * @param {Event} e + */ + changeNamespace (e) { + this.setState({ + namespace: e.target.value + }) + } + /** * Save new url to redux store * * @param {Event} e */ - setUrl (e) { + setNamespaceAndUrl (e) { e && e.preventDefault() const url = this.state.url - if ( url ) - this.props.setUrl(this.state.tab.id, url) + const namespace = this.state.namespace + if (url) + this.props.setNamespaceAndUrl(this.state.tab.id, namespace, url) + } render () { @@ -96,8 +113,9 @@ class Search extends Component { return (
- - + + +
) } diff --git a/src/app/js/components/search/TextBar.js b/src/app/js/components/search/TextBar.js index dfef5b7..2ba7a98 100644 --- a/src/app/js/components/search/TextBar.js +++ b/src/app/js/components/search/TextBar.js @@ -7,7 +7,7 @@ * @property {String} originalUrl the current url of the socket.io connection * @property {String} url the current state of the input field * @property {Function} changeUrl handle inputchange - * @property {Function} setUrl confirm url and save in redux store + * @property {Function} setNamespaceAndUrl confirm namespace and url and save in redux store */ import React from 'react' @@ -15,13 +15,13 @@ import React from 'react' import SearchIcon from '../../icons/Search' import ConnectionIcon from '../../icons/Connection' -const TextBar = ({url, originalUrl, changeUrl, setUrl, connected}) => +const TextBar = ({url, originalUrl, changeUrl, setNamespaceAndUrl, connected}) => - + {getIcon(originalUrl, connected)} -
- + +
diff --git a/src/app/js/reducers/connections.js b/src/app/js/reducers/connections.js index 867146d..3fd5afd 100644 --- a/src/app/js/reducers/connections.js +++ b/src/app/js/reducers/connections.js @@ -13,8 +13,8 @@ export default function connections (state = defaultState, action) { case 'REMOVE_CONNECTION': return removeConnection(state, action) - case 'SET_URL': - return setUrl(state, action) + case 'SET_NAMESPACE_AND_URL': + return setNamespaceAndUrl(state, action) case 'SET_CONNECTED': return setConnected(state, action, true) @@ -93,12 +93,21 @@ function removeConnection (state, action) { /** * Updates the url of a connection */ -function setUrl (state, action) { +function setNamespaceAndUrl (state, action) { const list = state.list.slice() - const id = action.id + // set namespace + if(action.namespace) { + const namespaceWithLeadingSlash = action.namespace.charAt(0) === '/' ? action.namespace : '/' + action.namespace + list[state.connections[id].index].namespace = namespaceWithLeadingSlash + } else { + list[state.connections[id].index].namespace = '' + } + + // set URL list[state.connections[id].index].url = action.url + return { connections: state.connections, list @@ -114,6 +123,11 @@ function setConnected (state, action, newValue) { const id = action.id list[state.connections[id].index].connected = newValue + + if(!newValue) { + list[state.connections[id].index].events = [] + } + return { connections: state.connections, list diff --git a/src/app/js/socketManager.js b/src/app/js/socketManager.js index d3f0168..a7dd981 100644 --- a/src/app/js/socketManager.js +++ b/src/app/js/socketManager.js @@ -75,9 +75,12 @@ function listenForChanges () { const connection = state.connections.list[state.connections.connections[id].index] const url = connection.url - if ( url !== storedConnections[id].url ) { + let namespace = connection.namespace || '' + + if ( url !== storedConnections[id].url || namespace !== storedConnections[id].namespace) { storedConnections[id].url = url + storedConnections[id].namespace = namespace let socket = storedConnection.socket @@ -88,12 +91,13 @@ function listenForChanges () { if ( url ) { const parsedURL = new URL(url); - socket = io(parsedURL.origin + parsedURL.search, { - path: parsedURL.pathname === '/' ? '/socket.io' : parsedURL.pathname, - }); + const path = parsedURL.pathname === '/' ? '/socket.io' : parsedURL.pathname + socket = io(parsedURL.origin + namespace, {path}); storedConnections[id].socket = socket socket.on('connect', function () { + store.dispatch({type: 'REMOVE_ALL_MESSAGES'}) + store.dispatch({type: 'REMOVE_ALL_SENTMESSAGES'}) store.dispatch({type: 'SET_CONNECTED', id}) }) socket.on('disconnect', function () {