diff --git a/src/index.js b/src/index.js index 8f5c995..e9d1fc8 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,7 @@ import scss from '../scss/main.scss'; import { ws_init } from './socket'; import { filter_subscribe } from './actions/filter_subscribe'; import { socket_uri, socket_update, SOCKET_STATE } from './actions/socket'; -import search_criteria from './search'; +import { search_criteria } from './search'; import Main from './ui/main'; import Connection from './ui/connection'; diff --git a/src/search.js b/src/search.js index a735254..d1f649b 100644 --- a/src/search.js +++ b/src/search.js @@ -1,4 +1,7 @@ import numeral from "numeral"; +import query from 'query-string'; +import { filter_subscribe } from './actions/filter_subscribe'; +import { push_query } from './actions/routing'; // via https://stackoverflow.com/a/46946490 const ssplit = str => str.match(/\\?.|^$/g).reduce((p, c) => { @@ -12,7 +15,7 @@ const ssplit = str => str.match(/\\?.|^$/g).reduce((p, c) => { return p; }, {a: ['']}).a; -export default function search_criteria(text) { +export function search_criteria(text) { if (!text) { return []; } @@ -41,3 +44,21 @@ export default function search_criteria(text) { } ); } + +export function search_qs(text) { + const qs = query.stringify({ + ...query.parse(location.search), + s: text || undefined + }); + return `${ + location.pathname === "/" ? location.pathname : "" + }${qs && "?" + qs}`; +} + +export function update_filter(text, fs, location, dispatch) { + // there will always be one torrent filter + const tfilter = fs.filter(fs => fs.kind === "torrent")[0]; + const criteria = search_criteria(text); + dispatch(filter_subscribe("torrent", criteria, tfilter.serial)); + dispatch(push_query(search_qs(text))); +} diff --git a/src/ui/main.js b/src/ui/main.js index 0bb5da2..c221113 100644 --- a/src/ui/main.js +++ b/src/ui/main.js @@ -6,6 +6,7 @@ import TorrentTable from './torrent_table'; import AddTorrent from './add_torrent'; import TorrentDetails from './torrent_details'; import Server from './server'; +import SearchHelp from './search_help'; import ConnectionOverlay from './connection'; export default class Main extends Component { @@ -20,6 +21,7 @@ export default class Main extends Component {
+ diff --git a/src/ui/navigation.js b/src/ui/navigation.js index 835d59a..6f503ab 100644 --- a/src/ui/navigation.js +++ b/src/ui/navigation.js @@ -1,28 +1,9 @@ import React from 'react'; import { connect } from 'react-redux'; import { Link, NavLink } from 'react-router-dom'; -import { filter_subscribe } from '../actions/filter_subscribe'; -import { push_query } from '../actions/routing'; +import FontAwesome from 'react-fontawesome'; import query from 'query-string'; -import search_criteria from '../search'; - -function search_qs(text) { - const qs = query.stringify({ - ...query.parse(location.search), - s: text || undefined - }); - return `${ - location.pathname === "/" ? location.pathname : "" - }${qs && "?" + qs}`; -} - -function update_filter(text, fs, location, dispatch) { - // there will always be one torrent filter - const tfilter = fs.filter(fs => fs.kind === "torrent")[0]; - const criteria = search_criteria(text); - dispatch(filter_subscribe("torrent", criteria, tfilter.serial)); - dispatch(push_query(search_qs(text))); -} +import { search_criteria, search_qs, update_filter } from '../search'; function render(props) { const { dispatch, router } = props; @@ -65,6 +46,11 @@ function render(props) { value={qs.s} onChange={e => update(e.target.value)} /> + + + + +
; diff --git a/src/ui/search_help.js b/src/ui/search_help.js new file mode 100644 index 0000000..3c1bcac --- /dev/null +++ b/src/ui/search_help.js @@ -0,0 +1,81 @@ +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import query from 'query-string'; +import { search_criteria, search_qs, update_filter } from '../search'; + +function SearchHelp(props) { + const { dispatch, router } = props; + const qs = query.parse(router.location.search); + const update = text => update_filter( + text || "", props.filter_subscribe, router.location, dispatch); + const navto = where => e => { + e.preventDefault(); + update(where); + }; + const searchLink = target => + {target}; + const searchableProps = { + "name": "torrent name", + "path": "download path", + "status": "paused | pending | leeching | idle | seeding | hashing | error", + "size": "size in bytes", + "progress": "progress from 0 to 1", + "priority": "1-5, low to high", + "availability": "how much is available from the swarm, 0 to 1", + "rate_up": "rate up in bits/sec", + "rate_down": "rate down in bits/sec", + "throttle_up": "throttle up in bits/sec", + "throttle_down": "throttle down in bits/sec", + "transferred_up": "total transfer up in bits/sec", + "transferred_down": "total transfer down in bits/sec", + "peers": "number of peers", + "files": "number of files", + }; + + return ( +
+

+ Search help +

+

+ You can search for torrents using the search box at the top of the + page. By default, it will search through torrent titles. You can also + search other properties of torrents with + propertyoperatorvalue, where operator is + one of the following: +

+ +

+ The following torrent properties are searchable: +

+ +

+ Here are some example searches: +

+ +
+ ); +} + +export default connect(state => ({ + filter_subscribe: state.filter_subscribe, + router: state.router, +}))(SearchHelp);