mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-23 01:57:29 +00:00
Use algolia for search
This commit is contained in:
parent
180827e27c
commit
f2a544e64c
6 changed files with 76 additions and 11 deletions
|
|
@ -7,6 +7,7 @@ import Skin from "./Skin";
|
|||
import FocusedSkin from "./FocusedSkin";
|
||||
import * as Utils from "./utils";
|
||||
import * as Selectors from "./redux/selectors";
|
||||
import * as Actions from "./redux/actionCreators";
|
||||
import { SKIN_WIDTH, SKIN_HEIGHT, SKIN_RATIO } from "./constants";
|
||||
|
||||
const OVERSCAN_ROWS_LEADING = 10;
|
||||
|
|
@ -166,7 +167,7 @@ const mapDispatchToProps = dispatch => ({
|
|||
dispatch({ type: "SELECT_SKIN", hash, position });
|
||||
},
|
||||
setSearchQuery(query) {
|
||||
dispatch({ type: "SET_SEARCH_QUERY", query });
|
||||
dispatch(Actions.searchQueryChanged(query));
|
||||
}
|
||||
});
|
||||
export default connect(
|
||||
|
|
|
|||
27
src/algolia.js
Normal file
27
src/algolia.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import algoliasearch from "algoliasearch";
|
||||
var client = algoliasearch("HQ9I5Z6IM5", "6466695ec3f624a5fccf46ec49680e51");
|
||||
|
||||
var index = client.initIndex("Skins");
|
||||
|
||||
export function search(query) {
|
||||
return new Promise((resolve, reject) => {
|
||||
index.search(
|
||||
{
|
||||
query,
|
||||
attributes: ["objectID"],
|
||||
attributesToHighlight: [],
|
||||
hitsPerPage: 1000,
|
||||
// https://www.algolia.com/doc/api-reference/api-parameters/typoTolerance/
|
||||
// min: Retrieve records with the smallest number of typos.
|
||||
typoTolerance: "min"
|
||||
},
|
||||
(err, content) => {
|
||||
if (err != null) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve(content);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
export function closeModal() {
|
||||
return { type: "CLOSE_MODAL" };
|
||||
}
|
||||
|
||||
export function searchQueryChanged(query) {
|
||||
return { type: "SEARCH_QUERY_CHANGED", query };
|
||||
}
|
||||
|
|
|
|||
26
src/redux/epics.js
Normal file
26
src/redux/epics.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { combineEpics } from "redux-observable";
|
||||
import { of, from } from "rxjs";
|
||||
import { filter, switchMap, map } from "rxjs/operators";
|
||||
import { search } from "../algolia";
|
||||
|
||||
const searchEpic = actions =>
|
||||
actions.pipe(
|
||||
filter(action => action.type === "SEARCH_QUERY_CHANGED"),
|
||||
switchMap(({ query }) => {
|
||||
if (query.length === 0) {
|
||||
return of({
|
||||
type: "GOT_NEW_MATCHING_HASHES",
|
||||
matchingHashes: null
|
||||
});
|
||||
}
|
||||
|
||||
return from(search(query)).pipe(
|
||||
map(content => {
|
||||
const matchingHashes = new Set(content.hits.map(hit => hit.objectID));
|
||||
return { type: "GOT_NEW_MATCHING_HASHES", matchingHashes };
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
export default combineEpics(searchEpic);
|
||||
|
|
@ -22,14 +22,10 @@ export function getSearchQuery(state) {
|
|||
export function getMatchingSkinHashes(state) {
|
||||
const hashes = Object.keys(skins);
|
||||
const searchQuery = getSearchQuery(state);
|
||||
if (searchQuery == null) {
|
||||
if (searchQuery == null || state.matchingHashes == null) {
|
||||
return hashes;
|
||||
}
|
||||
const normalizedSearchQuery = searchQuery.toLowerCase();
|
||||
return hashes.filter(hash => {
|
||||
const { fileName } = skins[hash];
|
||||
return fileName.toLowerCase().includes(normalizedSearchQuery);
|
||||
});
|
||||
return hashes.filter(hash => state.matchingHashes.has(hash));
|
||||
}
|
||||
|
||||
export function getUrl(state) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import { createStore as createReduxStore } from "redux";
|
||||
import { createStore as createReduxStore, applyMiddleware } from "redux";
|
||||
import { createEpicMiddleware } from "redux-observable";
|
||||
import * as Selectors from "./selectors";
|
||||
import rootEpic from "./epics";
|
||||
|
||||
const defaultState = {
|
||||
searchQuery: null,
|
||||
selectedSkinHash: null,
|
||||
selectedSkinPosition: null
|
||||
selectedSkinPosition: null,
|
||||
matchingHashes: null
|
||||
};
|
||||
|
||||
function reducer(state = defaultState, action) {
|
||||
|
|
@ -35,17 +38,25 @@ function reducer(state = defaultState, action) {
|
|||
};
|
||||
}
|
||||
return { ...defaultState, searchQuery };
|
||||
case "SET_SEARCH_QUERY":
|
||||
case "SEARCH_QUERY_CHANGED":
|
||||
return {
|
||||
...state,
|
||||
searchQuery: action.query
|
||||
};
|
||||
case "GOT_NEW_MATCHING_HASHES":
|
||||
return {
|
||||
...state,
|
||||
matchingHashes: action.matchingHashes
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
export function createStore() {
|
||||
const store = createReduxStore(reducer);
|
||||
const epicMiddleware = createEpicMiddleware();
|
||||
|
||||
const store = createReduxStore(reducer, applyMiddleware(epicMiddleware));
|
||||
epicMiddleware.run(rootEpic);
|
||||
let lastUrl = null;
|
||||
store.subscribe(() => {
|
||||
const state = store.getState();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue