From 1fa75747f2f73ccf13950141cbe8f3cc03c7f536 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 30 Dec 2017 12:41:44 -0500 Subject: [PATCH] Implement filtering --- src/actions/filter_subscribe.js | 4 +- src/ui/navigation.js | 76 +++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/actions/filter_subscribe.js b/src/actions/filter_subscribe.js index 92e617f..5ca113e 100644 --- a/src/actions/filter_subscribe.js +++ b/src/actions/filter_subscribe.js @@ -3,9 +3,9 @@ import ws_send from '../socket'; export const FILTER_SUBSCRIBE = 'FILTER_SUBSCRIBE'; export const FILTER_UNSUBSCRIBE = 'FILTER_UNSUBSCRIBE'; -export function filter_subscribe(kind='torrent', criteria=[], serial=null) { +export function filter_subscribe(kind='torrent', criteria=[], _serial=null) { return dispatch => { - const serial = ws_send(FILTER_SUBSCRIBE, { kind, criteria }, null, serial); + const serial = ws_send(FILTER_SUBSCRIBE, { kind, criteria }, null, _serial); dispatch({ type: FILTER_SUBSCRIBE, serial, kind, criteria }); }; } diff --git a/src/ui/navigation.js b/src/ui/navigation.js index 1a19378..c3e1fb3 100644 --- a/src/ui/navigation.js +++ b/src/ui/navigation.js @@ -15,17 +15,61 @@ function search_qs(text) { }${qs && "?" + qs}`; } +// via https://stackoverflow.com/a/46946490 +const ssplit = str => str.match(/\\?.|^$/g).reduce((p, c) => { + if (c === '"') { + p.quote ^= 1; + } else if (!p.quote && c === ' ') { + p.a.push(''); + } else { + p.a[p.a.length-1] += c.replace(/\\(.)/,"$1"); + } + return p; +}, {a: ['']}).a; + +function search_criteria(text) { + const terms = ssplit(text); + return terms.map(t => { + if (t.indexOf("status:") === 0) { + return { + field: "status", + op: "==", + value: t.split(":")[1] + }; + } else { + return { + field: "name", + op: "ilike", + value: `%${t}%` + }; + } + }); +} + 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(search_qs(text))); } function render(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(); - dispatch(push(where)); + update(where); }; + const searchLink = (target, text) =>
  • + {text} +
  • ; return