2019-08-04 11:39:29 +00:00
|
|
|
import { isEqual } from "lodash";
|
2019-04-17 10:44:48 +00:00
|
|
|
import { Dispatch } from "redux";
|
2018-08-27 15:27:09 +00:00
|
|
|
|
2019-07-21 18:05:07 +00:00
|
|
|
import { push } from "connected-react-router";
|
2019-08-04 11:39:29 +00:00
|
|
|
import { ISearchFilter } from "../searchFilters";
|
2019-04-17 10:44:48 +00:00
|
|
|
import { getFromApi } from "../util";
|
2019-08-29 20:10:37 +00:00
|
|
|
import { ActionType, IAppState, IGraph, IInstanceDetails, IInstanceSort, ISearchResponse } from "./types";
|
2018-08-27 15:27:09 +00:00
|
|
|
|
2019-07-23 12:20:34 +00:00
|
|
|
// Instance details
|
2019-07-21 18:05:07 +00:00
|
|
|
const requestInstanceDetails = (instanceName: string) => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
|
|
|
payload: instanceName,
|
2019-07-21 18:05:07 +00:00
|
|
|
type: ActionType.REQUEST_INSTANCE_DETAILS
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2019-07-23 12:20:34 +00:00
|
|
|
const receiveInstanceDetails = (instanceDetails: IInstanceDetails) => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
2019-07-23 12:20:34 +00:00
|
|
|
payload: instanceDetails,
|
|
|
|
type: ActionType.RECEIVE_INSTANCE_DETAILS
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2019-07-23 12:20:34 +00:00
|
|
|
const instanceLoadFailed = () => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
2019-07-23 12:20:34 +00:00
|
|
|
type: ActionType.INSTANCE_LOAD_ERROR
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2019-07-23 12:20:34 +00:00
|
|
|
const deselectInstance = () => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
2019-07-23 12:20:34 +00:00
|
|
|
type: ActionType.DESELECT_INSTANCE
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2019-07-23 12:20:34 +00:00
|
|
|
|
|
|
|
// Graph
|
|
|
|
const requestGraph = () => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
|
|
|
type: ActionType.REQUEST_GRAPH
|
|
|
|
};
|
|
|
|
};
|
2019-07-23 12:20:34 +00:00
|
|
|
const receiveGraph = (graph: IGraph) => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
|
|
|
payload: graph,
|
|
|
|
type: ActionType.RECEIVE_GRAPH
|
|
|
|
};
|
|
|
|
};
|
2018-12-06 18:48:32 +00:00
|
|
|
const graphLoadFailed = () => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
|
|
|
type: ActionType.GRAPH_LOAD_ERROR
|
|
|
|
};
|
|
|
|
};
|
2018-12-06 18:48:32 +00:00
|
|
|
|
2019-08-27 13:50:16 +00:00
|
|
|
// Instance list
|
2019-08-29 20:10:37 +00:00
|
|
|
const requestInstanceList = (sort?: IInstanceSort) => ({
|
|
|
|
payload: sort,
|
2019-08-27 13:50:16 +00:00
|
|
|
type: ActionType.REQUEST_INSTANCES
|
|
|
|
});
|
|
|
|
const receiveInstanceList = (instances: IInstanceDetails[]) => ({
|
|
|
|
payload: instances,
|
|
|
|
type: ActionType.RECEIVE_INSTANCES
|
|
|
|
});
|
|
|
|
const instanceListLoadFailed = () => ({
|
|
|
|
type: ActionType.INSTANCE_LIST_LOAD_ERROR
|
|
|
|
});
|
|
|
|
|
2019-07-23 12:20:34 +00:00
|
|
|
// Search
|
2019-08-04 11:39:29 +00:00
|
|
|
const requestSearchResult = (query: string, filters: ISearchFilter[]) => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
2019-08-04 11:39:29 +00:00
|
|
|
payload: { query, filters },
|
2019-07-23 12:20:34 +00:00
|
|
|
type: ActionType.REQUEST_SEARCH_RESULTS
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2019-07-23 12:20:34 +00:00
|
|
|
const receiveSearchResults = (result: ISearchResponse) => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return {
|
2019-07-23 12:20:34 +00:00
|
|
|
payload: result,
|
|
|
|
type: ActionType.RECEIVE_SEARCH_RESULTS
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const searchFailed = () => {
|
|
|
|
return {
|
|
|
|
type: ActionType.SEARCH_RESULTS_ERROR
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2018-09-01 17:24:05 +00:00
|
|
|
|
2019-07-23 12:20:34 +00:00
|
|
|
const resetSearch = () => {
|
|
|
|
return {
|
|
|
|
type: ActionType.RESET_SEARCH
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2018-09-01 17:24:05 +00:00
|
|
|
|
2019-07-26 22:30:11 +00:00
|
|
|
export const setResultHover = (domain?: string) => {
|
|
|
|
return {
|
|
|
|
payload: domain,
|
|
|
|
type: ActionType.SET_SEARCH_RESULT_HOVER
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2019-07-23 12:20:34 +00:00
|
|
|
/** Async actions: https://redux.js.org/advanced/asyncactions */
|
|
|
|
|
2019-07-21 18:05:07 +00:00
|
|
|
export const loadInstance = (instanceName: string | null) => {
|
|
|
|
return (dispatch: Dispatch, getState: () => IAppState) => {
|
2019-04-17 10:44:48 +00:00
|
|
|
if (!instanceName) {
|
|
|
|
dispatch(deselectInstance());
|
2019-07-21 18:05:07 +00:00
|
|
|
if (getState().router.location.pathname.startsWith("/instance/")) {
|
|
|
|
dispatch(push("/"));
|
|
|
|
}
|
2019-04-17 10:44:48 +00:00
|
|
|
return;
|
2018-08-27 15:27:09 +00:00
|
|
|
}
|
2019-07-21 18:05:07 +00:00
|
|
|
dispatch(requestInstanceDetails(instanceName));
|
2019-04-17 10:44:48 +00:00
|
|
|
return getFromApi("instances/" + instanceName)
|
|
|
|
.then(details => dispatch(receiveInstanceDetails(details)))
|
2019-07-23 12:20:34 +00:00
|
|
|
.catch(() => dispatch(instanceLoadFailed()));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2019-08-04 11:39:29 +00:00
|
|
|
export const updateSearch = (query: string, filters: ISearchFilter[]) => {
|
2019-07-23 12:20:34 +00:00
|
|
|
return (dispatch: Dispatch, getState: () => IAppState) => {
|
2019-07-24 09:43:36 +00:00
|
|
|
query = query.trim();
|
|
|
|
|
2019-07-23 12:20:34 +00:00
|
|
|
if (!query) {
|
|
|
|
dispatch(resetSearch());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-08-04 11:39:29 +00:00
|
|
|
const prevQuery = getState().search.query;
|
|
|
|
const prevFilters = getState().search.filters;
|
|
|
|
const isNewQuery = prevQuery !== query || !isEqual(prevFilters, filters);
|
2019-07-26 22:30:11 +00:00
|
|
|
|
2019-07-23 12:20:34 +00:00
|
|
|
const next = getState().search.next;
|
|
|
|
let url = `search/?query=${query}`;
|
2019-07-26 22:30:11 +00:00
|
|
|
if (!isNewQuery && next) {
|
2019-07-23 12:20:34 +00:00
|
|
|
url += `&after=${next}`;
|
|
|
|
}
|
2019-08-04 11:39:29 +00:00
|
|
|
|
|
|
|
// Add filters
|
|
|
|
// The format is e.g. type_eq=mastodon or user_count_gt=1000
|
|
|
|
filters.forEach(filter => {
|
|
|
|
url += `&${filter.field}_${filter.relation}=${filter.value}`;
|
|
|
|
});
|
|
|
|
|
|
|
|
dispatch(requestSearchResult(query, filters));
|
2019-07-23 12:20:34 +00:00
|
|
|
return getFromApi(url)
|
|
|
|
.then(result => dispatch(receiveSearchResults(result)))
|
|
|
|
.catch(() => dispatch(searchFailed()));
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2018-09-01 13:32:04 +00:00
|
|
|
|
|
|
|
export const fetchGraph = () => {
|
2019-04-17 10:44:48 +00:00
|
|
|
return (dispatch: Dispatch) => {
|
|
|
|
dispatch(requestGraph());
|
2019-07-14 11:47:06 +00:00
|
|
|
return getFromApi("graph")
|
2019-04-17 10:44:48 +00:00
|
|
|
.then(graph => dispatch(receiveGraph(graph)))
|
2019-07-23 12:20:34 +00:00
|
|
|
.catch(() => dispatch(graphLoadFailed()));
|
2019-04-17 10:44:48 +00:00
|
|
|
};
|
|
|
|
};
|
2019-08-27 13:50:16 +00:00
|
|
|
|
2019-08-29 20:10:37 +00:00
|
|
|
export const loadInstanceList = (page?: number, sort?: IInstanceSort) => {
|
|
|
|
return (dispatch: Dispatch, getState: () => IAppState) => {
|
|
|
|
sort = sort ? sort : getState().data.instanceListSort;
|
|
|
|
dispatch(requestInstanceList(sort));
|
|
|
|
const params: string[] = [];
|
2019-08-27 13:50:16 +00:00
|
|
|
if (!!page) {
|
2019-08-29 20:10:37 +00:00
|
|
|
params.push(`page=${page}`);
|
|
|
|
}
|
|
|
|
if (!!sort) {
|
|
|
|
params.push(`sortField=${sort.field}`);
|
|
|
|
params.push(`sortDirection=${sort.direction}`);
|
2019-08-27 13:50:16 +00:00
|
|
|
}
|
2019-08-29 20:10:37 +00:00
|
|
|
const path = !!params ? `instances?${params.join("&")}` : "instances";
|
2019-08-27 13:50:16 +00:00
|
|
|
return getFromApi(path)
|
|
|
|
.then(instancesListResponse => dispatch(receiveInstanceList(instancesListResponse)))
|
|
|
|
.catch(() => dispatch(instanceListLoadFailed()));
|
|
|
|
};
|
|
|
|
};
|