Skip to content

Commit

Permalink
Refactor ui state management (#185, #189) (#190)
Browse files Browse the repository at this point in the history
* Move helpers to separate modules

* Move file cache to separate package

* Move file matches state to separate package

* Move cluster state to separate package

* Move file-list state to separate package

* Collect reusable prop-types in a public package

* Extract entity fetching logic

* Refactor file-cluster state

Use generic approach to manage file-cluster state.

* Refactor file-matches state

Use generic approach to manage file-matches state.

* Update server client

* Update matches params (#189)

* Fix file cluster update

* Disable false-positive linting issue
  • Loading branch information
stepan-anokhin authored Nov 13, 2020
1 parent f973526 commit 0afa4d5
Show file tree
Hide file tree
Showing 87 changed files with 1,061 additions and 906 deletions.
4 changes: 2 additions & 2 deletions web/src/application/state/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export {} from "./actions";
export { initialState, appRootReducer } from "./reducers";
export { appRootSaga } from "./sagas";
export { default as appRootReducer } from "./reducers";
export { default as initialState } from "./initialState";
13 changes: 13 additions & 0 deletions web/src/application/state/initialState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import collInitialState from "../../collection/state/initialState";

/**
* The entire application initial state.
*/
const initialState = {
/**
* File collection management state.
*/
coll: collInitialState,
};

export default initialState;
13 changes: 4 additions & 9 deletions web/src/application/state/reducers.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import {
collRootReducer,
initialState as collInitialState,
} from "../../collection/state";
import { combineReducers } from "redux";
import collRootReducer from "../../collection/state/reducers";

export const initialState = {
coll: collInitialState,
};

export const appRootReducer = combineReducers({
const appRootReducer = combineReducers({
coll: collRootReducer,
});

export default appRootReducer;
2 changes: 1 addition & 1 deletion web/src/application/state/sagas.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { all } from "redux-saga/effects";
import { collRootSaga } from "../../collection/state";
import collRootSaga from "../../collection/state/sagas";

/**
* Application root saga. Initializes all other sagas.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { useIntl } from "react-intl";
import { MatchCategory } from "../../../state/MatchCategory";
import { MatchCategory } from "../../../state/fileList/MatchCategory";
import CategoryButton from "./CategoryButton";
import AllInclusiveOutlinedIcon from "@material-ui/icons/AllInclusiveOutlined";
import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default } from "./CategorySelector";
export { MatchCategory } from "../../../state/MatchCategory";
export { MatchCategory } from "../../../state/fileList/MatchCategory";
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import ViewSelector from "./ViewSelector";
import SortSelector from "./SortSelector";
import SquaredIconButton from "../../../../common/components/SquaredIconButton";
import { useIntl } from "react-intl";
import { FileSort } from "../../../state/FileSort";
import { FileSort } from "../../../state/fileList/FileSort";
import { Badge } from "@material-ui/core";
import FileListType from "../../../state/FileListType";
import FileListType from "../../../state/fileList/FileListType";

const useStyles = makeStyles((theme) => ({
actions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import InputLabel from "@material-ui/core/InputLabel";
import Select from "@material-ui/core/Select";
import MenuItem from "@material-ui/core/MenuItem";
import { useIntl } from "react-intl";
import { FileSort } from "../../../state/FileSort";
import { FileSort } from "../../../state/fileList/FileSort";

const useStyles = makeStyles(() => ({
select: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ListIcon from "@material-ui/icons/ViewStream";
import GridIcon from "@material-ui/icons/ViewModule";
import { useIntl } from "react-intl";
import IconSelect from "../../../../common/components/IconSelect";
import FileListType from "../../../state/FileListType";
import FileListType from "../../../state/fileList/FileListType";

function useMessages() {
const intl = useIntl();
Expand Down
36 changes: 20 additions & 16 deletions web/src/collection/components/FileBrowserPage/FileBrowserPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,27 @@ import FileLinearList from "./FileLinearList/FileLinearList";
import FileGridList from "./FileGridList";
import { useDispatch, useSelector } from "react-redux";
import {
selectCounts,
selectError,
selectFileList,
selectFileCounts,
selectFileError,
selectFiles,
selectFilters,
selectLoading,
selectFileFilters,
selectFileLoading,
} from "../../state/selectors";
import { fetchFiles, selectColl, updateFilters } from "../../state";
import Fab from "@material-ui/core/Fab";
import Zoom from "@material-ui/core/Zoom";
import VisibilitySensor from "react-visibility-sensor";
import { scrollIntoView } from "../../../common/helpers/scroll";
import { useHistory, useLocation } from "react-router-dom";
import { routes } from "../../../routing/routes";
import { useIntl } from "react-intl";
import { defaultFilters } from "../../state/reducers";
import FileListType from "../../state/FileListType";
import { changeFileListView } from "../../state/actions";
import FileListType from "../../state/fileList/FileListType";
import {
changeFileListView,
fetchFiles,
updateFilters,
} from "../../state/fileList/actions";
import { defaultFilters } from "../../state/fileList/initialState";

const useStyles = makeStyles((theme) => ({
container: {
Expand Down Expand Up @@ -127,17 +131,17 @@ function FileBrowserPage(props) {
const { className } = props;
const classes = useStyles();
const [showFilters, setShowFilters] = useState(false);
const collState = useSelector(selectColl);
const error = useSelector(selectError);
const loading = useSelector(selectLoading);
const fileListState = useSelector(selectFileList);
const error = useSelector(selectFileError);
const loading = useSelector(selectFileLoading);
const files = useSelector(selectFiles);
const filters = useSelector(selectFilters);
const counts = useSelector(selectCounts);
const filters = useSelector(selectFileFilters);
const counts = useSelector(selectFileCounts);
const dispatch = useDispatch();
const [top, setTop] = useState(true);
const topRef = useRef(null);
const history = useHistory();
const view = collState.fileListType;
const view = fileListState.fileListType;
const List = listComponent(view);
const intl = useIntl();
const showFiltersRef = useRef();
Expand All @@ -146,10 +150,10 @@ function FileBrowserPage(props) {
const activeFilters = FilterPane.useActiveFilters();

useEffect(() => {
if (!keepFilters || collState.neverLoaded) {
if (!keepFilters || fileListState.neverLoaded) {
dispatch(updateFilters(defaultFilters));
}
}, [keepFilters, collState.neverLoaded]);
}, [keepFilters, fileListState.neverLoaded]);

const handleFetchPage = useCallback(() => dispatch(fetchFiles()), []);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import { FileType } from "../FileType";
import { FileType } from "../../../prop-types/FileType";
import MediaPreview from "../../../../common/components/MediaPreview";
import VideocamOutlinedIcon from "@material-ui/icons/VideocamOutlined";
import MoreHorizOutlinedIcon from "@material-ui/icons/MoreHorizOutlined";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import { FileType } from "../FileType";
import { FileType } from "../../../prop-types/FileType";
import MoreHorizOutlinedIcon from "@material-ui/icons/MoreHorizOutlined";
import IconButton from "@material-ui/core/IconButton";
import { useIntl } from "react-intl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { useFilters } from "./useFilters";
import { useIntl } from "react-intl";
import RangeFilter from "./RangeFilter";
import { useSelector } from "react-redux";
import { selectFilters } from "../../../state/selectors";
import { selectFileFilters } from "../../../state/selectors";
import objectDiff from "../../../../common/helpers/objectDiff";
import { initialState } from "../../../state";
import { defaultFilters } from "../../../state/fileList/initialState";

/**
* Get i18n text
Expand All @@ -25,8 +25,8 @@ function useMessages() {
* Get count of active filters.
*/
function useActiveFilters() {
const filters = useSelector(selectFilters);
const diff = objectDiff(filters, initialState.filters);
const filters = useSelector(selectFileFilters);
const diff = objectDiff(filters, defaultFilters);
return Number(diff.length);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import FilterList from "./FilterList";
import DateRangeFilter from "./DateRangeFilter";
import BoolFilter from "./BoolFilter";
import { useIntl } from "react-intl";
import { initialState } from "../../../state";
import { defaultFilters } from "../../../state/fileList/initialState";
import objectDiff from "../../../../common/helpers/objectDiff";
import { useSelector } from "react-redux";
import { selectFilters } from "../../../state/selectors";
import { selectFileFilters } from "../../../state/selectors";

/**
* Get i18n text.
Expand All @@ -31,8 +31,8 @@ function useMessages() {
* Get count of active filters.
*/
function useActiveFilters() {
const filters = useSelector(selectFilters);
const diff = objectDiff(filters, initialState.filters);
const filters = useSelector(selectFileFilters);
const diff = objectDiff(filters, defaultFilters);
return diff.extensions + diff.date + diff.audio + diff.exif;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { isEqual, merge } from "lodash";
import { useDispatch, useSelector } from "react-redux";
import { selectFilters } from "../../../state/selectors";
import { selectFileFilters } from "../../../state/selectors";
import { useCallback, useEffect, useState } from "react";
import { updateFilters } from "../../../state";
import { updateFilters } from "../../../state/fileList/actions";

/**
* Hook to smoothly update hooks
*/
export function useFilters() {
// Access current redux state
const filters = useSelector(selectFilters);
const filters = useSelector(selectFileFilters);
const dispatch = useDispatch();

const [changes, setChanges] = useState({}); // unsaved changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function FileClusterPage(props) {
resumeLoading: loadCluster,
hasMore,
total,
} = useFileCluster({ fileId: id, hops: 2 });
} = useFileCluster({ fileId: id, filters: { hops: 2 } });

const handleLoadFile = useCallback(() => {
loadFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback, useState } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import { FileType } from "../../FileBrowserPage/FileType";
import { FileType } from "../../../prop-types/FileType";
import Paper from "@material-ui/core/Paper";
import CollapseButton from "../../../../common/components/CollapseButton";
import { useIntl } from "react-intl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback, useState } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import { FileType } from "../../FileBrowserPage/FileType";
import { FileType } from "../../../prop-types/FileType";
import VideoPlayerPane from "../../VideoDetailsPage/VideoPlayerPane";
import { seekTo } from "../../VideoDetailsPage/seekTo";
import FileDescriptionPane from "./FileDescriptionPane";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import FileSummary from "../../FileSummary/FileSummary";
import { FileType } from "../../FileBrowserPage/FileType";
import { FileType } from "../../../prop-types/FileType";
import Distance from "../../../../common/components/Distance";

const useStyles = makeStyles((theme) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import FileType from "../../FileBrowserPage/FileType";
import FileType from "../../../prop-types/FileType";
import FormControl from "@material-ui/core/FormControl";
import InputLabel from "@material-ui/core/InputLabel";
import Select from "@material-ui/core/Select";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import FileSummary from "../../FileSummary/FileSummary";
import { FileType } from "../../FileBrowserPage/FileType";
import { FileType } from "../../../prop-types/FileType";

const useStyles = makeStyles((theme) => ({
header: {
Expand Down
23 changes: 13 additions & 10 deletions web/src/collection/components/FileMatchesPage/FileMatchesPage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useState } from "react";
import React, { useCallback, useEffect, useState } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
Expand All @@ -18,9 +18,12 @@ import useFile from "../../hooks/useFile";
import FileLoadingHeader from "../FileLoadingHeader";
import { useDispatch, useSelector } from "react-redux";
import { selectFileMatches } from "../../state/selectors";
import { fetchFileMatches, updateFileMatchFilters } from "../../state/actions";
import LoadTrigger from "../../../common/components/LoadingTrigger/LoadTrigger";
import { routes } from "../../../routing/routes";
import {
fetchFileMatchesSlice,
updateFileMatchesParams,
} from "../../state/fileMatches/actions";

const useStyles = makeStyles((theme) => ({
root: {
Expand Down Expand Up @@ -74,18 +77,18 @@ function FileMatchesPage(props) {
const dispatch = useDispatch();
const history = useHistory();

useEffect(() => {
if (fileMatches.params.fileId !== id) {
dispatch(updateFileMatchesParams({ fileId: id }));
}
}, [id, fileMatches]);

const handleCompare = useCallback(
(file) => history.push(routes.collection.fileComparisonURL(id, file?.id)),
[id]
);

const handleLoad = useCallback(() => {
if (fileMatches.total == null || fileMatches.filters.fileId !== id) {
dispatch(updateFileMatchFilters({ fileId: id, hops: 1 }));
} else {
dispatch(fetchFileMatches());
}
}, [id, fileMatches]);
const handleLoad = useCallback(() => dispatch(fetchFileMatchesSlice()), []);

if (file == null) {
return (
Expand Down Expand Up @@ -151,7 +154,7 @@ function FileMatchesPage(props) {
hasMore={
fileMatches.total == null ||
fileMatches.matches.length < fileMatches.total ||
fileMatches.filters.fileId !== id
fileMatches.params.fileId !== id
}
container={MatchPreview.Container}
errorMessage={messages.loadError}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import FileType from "../../FileBrowserPage/FileType";
import FileType from "../../../prop-types/FileType";
import TableBody from "@material-ui/core/TableBody";
import Table from "@material-ui/core/Table";
import { useIntl } from "react-intl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import MoreHorizOutlinedIcon from "@material-ui/icons/MoreHorizOutlined";
import FileAttributes from "./FileAttributes";
import { useIntl } from "react-intl";
import ButtonBase from "@material-ui/core/ButtonBase";
import FileType from "../../FileBrowserPage/FileType";
import FileType from "../../../prop-types/FileType";
import Container from "./Container";
import Distance from "../../../../common/components/Distance";

Expand Down
2 changes: 1 addition & 1 deletion web/src/collection/components/FileSummary/CreationDate.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import { formatDate } from "../../../common/helpers/format";
import EventAvailableOutlinedIcon from "@material-ui/icons/EventAvailableOutlined";
import AttributeText from "../../../common/components/AttributeText";
import { FileType } from "../FileBrowserPage/FileType";
import { FileType } from "../../prop-types/FileType";
import { useIntl } from "react-intl";

function CreationDate(props) {
Expand Down
2 changes: 1 addition & 1 deletion web/src/collection/components/FileSummary/Duration.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import { formatDuration } from "../../../common/helpers/format";
import ScheduleOutlinedIcon from "@material-ui/icons/ScheduleOutlined";
import AttributeText from "../../../common/components/AttributeText";
import { FileType } from "../FileBrowserPage/FileType";
import { FileType } from "../../prop-types/FileType";

function Duration(props) {
const { file, className, ...other } = props;
Expand Down
2 changes: 1 addition & 1 deletion web/src/collection/components/FileSummary/FileSummary.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import Name from "./Name";
import { FileType } from "../FileBrowserPage/FileType";
import { FileType } from "../../prop-types/FileType";
import Divider from "./Divider";
import Spacer from "./Spacer";
import Fingerprint from "./Fingerprint";
Expand Down
Loading

0 comments on commit 0afa4d5

Please sign in to comment.