diff --git a/src/actions/stream.js b/src/actions/stream.js index f337412..a1ef949 100644 --- a/src/actions/stream.js +++ b/src/actions/stream.js @@ -1,8 +1,10 @@ import TwitterClient from '../utils/twitter-client'; -import { addTweet, removeTweet } from './tweets'; +import { addTweet, addTweetToTab, removeTweet } from './tweets'; export const SET_OPEN_STREAM = 'SET_OPEN_STREAM'; +export const SET_OPEN_FILTER = 'SET_OPEN_FILTER'; export const CLOSE_STREAM = 'CLOSE_STREAM'; +export const CLOSE_FILTER = 'CLOSE_FILTER'; export const setOpenStream = (stream, account) => { return { type: SET_OPEN_STREAM, stream, account } @@ -49,3 +51,40 @@ export const reconnectStreaming = (account) => { dispatch(startStreaming(account)); } } + +export const setOpenFilter = (stream, account) => { + return { type: SET_OPEN_FILTER, stream, account } +} + +export const closeFilter = (account) => { + return { type: CLOSE_FILTER, account } +} + +export const startFilter = (query, account) => { + return dispatch => { + const client = new TwitterClient(account); + client.filterStream(query, (stream) => { + stream.on('data', (data) => { + if (data['friends']) { + // noop + } else if (data['event']) { + // noop + } else if (data['delete']) { + // noop + } else if (data['created_at']) { + // This is a normal tweet + dispatch(addTweetToTab(data, account, 'search')); + } + }); + + dispatch(setOpenFilter(stream, account)); + }); + } +} + +export const reconnectFilter = (query, account) => { + return (dispatch) => { + dispatch(closeFilter(account)); + dispatch(startFilter(query, account)); + } +} diff --git a/src/containers/search-container.js b/src/containers/search-container.js index a46dd45..7a7b472 100644 --- a/src/containers/search-container.js +++ b/src/containers/search-container.js @@ -16,6 +16,7 @@ const mapDispatchToProps = (dispatch, props) => { event.preventDefault(); dispatch(Actions.setSearchQuery(event.target.value, props.account)); dispatch(Actions.loadSearch(event.target.value, props.account, true)) + dispatch(Actions.startFilter(event.target.value, props.account)); } } } diff --git a/src/reducers/filter-by-user-id.js b/src/reducers/filter-by-user-id.js new file mode 100644 index 0000000..c9601ef --- /dev/null +++ b/src/reducers/filter-by-user-id.js @@ -0,0 +1,21 @@ +import Actions from '../actions'; + +export const filterByUserId = (state = {}, action) => { + switch (action.type) { + case Actions.SET_OPEN_FILTER: + return { + ...state, + [action.account.id_str]: action.stream, + }; + case Actions.CLOSE_FILTER: + if (state[action.account.id_str]) { + state[action.account.id_str].destroy(); + } + return { + ...state, + [action.account.id_str]: null, + } + default: + return state; + } +} diff --git a/src/reducers/index.js b/src/reducers/index.js index 1b1984d..d2c9d70 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -3,6 +3,7 @@ import { accounts } from './accounts'; import { activeAccountIndex } from './active-account-index'; import { activeListIdByUserId } from './active-list-id-by-user-id'; import { editorFocused } from './editor-focused'; +import { filterByUserId } from './filter-by-user-id'; import { inReplyTo } from './in-reply-to'; import { listsByUserId } from './lists-by-user-id'; import { nowsByUserId } from './nows-by-user-id'; @@ -20,6 +21,7 @@ const rootReducer = combineReducers({ activeAccountIndex, activeListIdByUserId, editorFocused, + filterByUserId, inReplyTo, listsByUserId, nowsByUserId, diff --git a/src/utils/ipc-action.js b/src/utils/ipc-action.js index c3f12a4..b1347c9 100644 --- a/src/utils/ipc-action.js +++ b/src/utils/ipc-action.js @@ -61,7 +61,10 @@ export default class IpcAction { if (listId) this.dispatch(Actions.loadList(listId, account)); const query = this.state.activeSearchQuery(); - if (query) this.dispatch(Actions.loadSearch(query, account)); + if (query) { + this.dispatch(Actions.loadSearch(query, account)); + this.dispatch(Actions.reconnectFilter(query, account)); + } this.dispatch(Actions.reconnectStreaming(account)); }); diff --git a/src/utils/twitter-client.js b/src/utils/twitter-client.js index d29c6db..dbf30f2 100644 --- a/src/utils/twitter-client.js +++ b/src/utils/twitter-client.js @@ -46,6 +46,12 @@ export default class TwitterClient { }); } + filterStream(track, callback) { + this.client.stream('statuses/filter', { track: track }, (stream) => { + callback(stream); + }); + } + updateStatus(tweet, inReplyTo, callback) { if (tweet === '') return;