diff --git a/web/src/collection/components/FileBrowserPage/FileLinearList/FileLinearListItem.js b/web/src/collection/components/FileBrowserPage/FileLinearList/FileLinearListItem.js
index 6cb9ddf6..970ff82e 100644
--- a/web/src/collection/components/FileBrowserPage/FileLinearList/FileLinearListItem.js
+++ b/web/src/collection/components/FileBrowserPage/FileLinearList/FileLinearListItem.js
@@ -3,162 +3,91 @@ import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import { FileType } from "../FileType";
-import VideocamOutlinedIcon from "@material-ui/icons/VideocamOutlined";
-import ScheduleOutlinedIcon from "@material-ui/icons/ScheduleOutlined";
-import EventAvailableOutlinedIcon from "@material-ui/icons/EventAvailableOutlined";
-import VolumeOffOutlinedIcon from "@material-ui/icons/VolumeOffOutlined";
import MoreHorizOutlinedIcon from "@material-ui/icons/MoreHorizOutlined";
-import AttributeText from "../../../../common/components/AttributeText";
import IconButton from "@material-ui/core/IconButton";
-import {
- formatBool,
- formatDate,
- formatDuration,
-} from "../../../../common/helpers/format";
import { useIntl } from "react-intl";
-import ExifIcon from "../../../../common/components/icons/ExifIcon";
+import FileSummary from "../../FileSummary";
+import { useMediaQuery } from "@material-ui/core";
+import useTheme from "@material-ui/styles/useTheme";
const useStyles = makeStyles((theme) => ({
- decor: {
+ container: {
marginBottom: theme.spacing(2),
backgroundColor: theme.palette.background.paper,
borderRadius: 4,
borderStyle: "solid",
borderWidth: 1,
borderColor: theme.palette.border.light,
- },
- layout: {
display: "flex",
alignItems: "center",
padding: theme.spacing(3),
},
- buttonStyle: {
+ button: {
cursor: "pointer",
"&:hover": {
borderColor: theme.palette.primary.light,
},
},
- icon: {
- color: theme.palette.primary.contrastText,
- width: theme.spacing(3),
- height: theme.spacing(3),
- },
- iconContainer: {
- backgroundColor: theme.palette.primary.main,
- width: theme.spacing(4),
- height: theme.spacing(4),
- display: "flex",
- alignItems: "center",
- justifyContent: "center",
- },
- fileName: {
+ summary: {
flexGrow: 1,
minWidth: 0,
- marginLeft: theme.spacing(3),
- },
- volume: {
- color: theme.palette.action.textInactive,
- },
- attr: {
- marginLeft: theme.spacing(3),
- marginRight: theme.spacing(3),
- },
- divider: {
- borderLeftStyle: "solid",
- borderLeftColor: theme.palette.border.light,
- borderLeftWidth: 1,
- height: theme.spacing(4),
- },
- md: {
- [theme.breakpoints.down("md")]: {
- display: "none",
- },
- },
- sm: {
- [theme.breakpoints.down("sm")]: {
- display: "none",
- },
},
}));
-function useMessages(intl) {
+/**
+ * Get i18n text.
+ */
+function useMessages() {
+ const intl = useIntl();
return {
- attr: {
- filename: intl.formatMessage({ id: "file.attr.name" }),
- fingerprint: intl.formatMessage({ id: "file.attr.fingerprint" }),
- quality: intl.formatMessage({ id: "file.attr.quality" }),
- },
+ containerLabel: intl.formatMessage({ id: "actions.showFileDetails" }),
+ moreLabel: intl.formatMessage({ id: "actions.showMoreOptions" }),
};
}
+/**
+ * Get screen size.
+ */
+function useScreenSize() {
+ const theme = useTheme();
+ const medium = useMediaQuery(theme.breakpoints.up("md"));
+ const large = useMediaQuery(theme.breakpoints.up("lg"));
+ return { medium, large };
+}
+
const FileLinearListItem = React.memo(function FpLinearListItem(props) {
- const { file, button = false, highlight, onClick, className } = props;
- const intl = useIntl();
- const messages = useMessages(intl);
+ const {
+ file,
+ button = false,
+ highlight,
+ onClick,
+ className,
+ ...other
+ } = props;
+ const messages = useMessages();
+ const { large, medium } = useScreenSize();
const handleClick = useCallback(() => onClick(file), [file, onClick]);
const classes = useStyles();
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ {medium && }
+
+ {large && }
+ {large && }
+ {large && }
+
+
+
+
);
});
diff --git a/web/src/collection/components/FileComparisonPage/FileComparisonPage.js b/web/src/collection/components/FileComparisonPage/FileComparisonPage.js
index 4e14e328..2cc2b0e9 100644
--- a/web/src/collection/components/FileComparisonPage/FileComparisonPage.js
+++ b/web/src/collection/components/FileComparisonPage/FileComparisonPage.js
@@ -1,11 +1,12 @@
-import React from "react";
+import React, { useCallback } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import Grid from "@material-ui/core/Grid";
import MotherFile from "./MotherFile/MotherFile";
import MatchFiles from "./MatchFiles/MatchFiles";
-import { useParams } from "react-router-dom";
+import { useHistory, useParams } from "react-router-dom";
+import { routes } from "../../../routing/routes";
const useStyles = makeStyles((theme) => ({
root: {
@@ -16,9 +17,16 @@ const useStyles = makeStyles((theme) => ({
function FileComparisonPage(props) {
const { className } = props;
const classes = useStyles();
- const { id: rawId } = useParams();
+ const history = useHistory();
+ const { id: rawId, matchFileId } = useParams();
const id = Number(rawId);
+ const handleMatchFileChange = useCallback(
+ (newMatchFileId) =>
+ history.push(routes.collection.fileComparisonURL(id, newMatchFileId)),
+ [id]
+ );
+
return (
@@ -26,7 +34,11 @@ function FileComparisonPage(props) {
-
+
diff --git a/web/src/collection/components/FileComparisonPage/MatchFiles/MatchFiles.js b/web/src/collection/components/FileComparisonPage/MatchFiles/MatchFiles.js
index a319b029..1faf7804 100644
--- a/web/src/collection/components/FileComparisonPage/MatchFiles/MatchFiles.js
+++ b/web/src/collection/components/FileComparisonPage/MatchFiles/MatchFiles.js
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useCallback, useEffect } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
@@ -29,6 +29,14 @@ const useStyles = makeStyles((theme) => ({
marginTop: 0,
margin: theme.spacing(2),
},
+ errorMessage: {
+ minHeight: 150,
+ ...theme.mixins.title2,
+ color: theme.palette.action.textInactive,
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "center",
+ },
}));
/**
@@ -39,14 +47,21 @@ function useMessages() {
return {
title: intl.formatMessage({ id: "file.match" }),
loadError: intl.formatMessage({ id: "match.load.error" }),
+ notMatch: intl.formatMessage({ id: "match.notMatch" }),
+ noMatches: intl.formatMessage({ id: "match.noMatches" }),
};
}
function MatchFiles(props) {
- const { motherFileId, className, ...other } = props;
+ const {
+ motherFileId,
+ matchFileId,
+ onMatchFileChange,
+ className,
+ ...other
+ } = props;
const classes = useStyles();
const messages = useMessages();
- const [selected, setSelected] = useState(0);
const {
matches,
@@ -56,6 +71,23 @@ function MatchFiles(props) {
progress,
} = useDirectMatches(motherFileId);
+ // Move to the first element when matches are loaded
+ useEffect(() => {
+ if (!hasMore && matches.length > 0 && matchFileId == null) {
+ onMatchFileChange(matches[0].file.id);
+ }
+ }, [hasMore, onMatchFileChange, motherFileId]);
+
+ // Get index of the selected match file
+ const selected = matches.findIndex((match) => match.file.id === matchFileId);
+
+ const handleSelectionChange = useCallback(
+ (index) => {
+ onMatchFileChange(matches[index].file.id);
+ },
+ [hasMore, onMatchFileChange, motherFileId]
+ );
+
let content;
if (hasMore) {
content = (
@@ -67,7 +99,7 @@ function MatchFiles(props) {
progress={progress}
/>
);
- } else if (matches.length > 0) {
+ } else if (matches.length > 0 && selected >= 0) {
content = (
);
} else {
- content = null;
+ const errorMessage =
+ matches.length === 0 ? messages.noMatches : messages.notMatch;
+ content = {errorMessage}
;
}
return (
@@ -90,7 +124,7 @@ function MatchFiles(props) {
)}
@@ -104,6 +138,14 @@ MatchFiles.propTypes = {
* Mother file id.
*/
motherFileId: PropTypes.number.isRequired,
+ /**
+ * Match file id.
+ */
+ matchFileId: PropTypes.number,
+ /**
+ * Handle match file change.
+ */
+ onMatchFileChange: PropTypes.func.isRequired,
className: PropTypes.string,
};
diff --git a/web/src/collection/components/FileComparisonPage/MatchFiles/MatchSelector.js b/web/src/collection/components/FileComparisonPage/MatchFiles/MatchSelector.js
index 6b327716..2cb492f5 100644
--- a/web/src/collection/components/FileComparisonPage/MatchFiles/MatchSelector.js
+++ b/web/src/collection/components/FileComparisonPage/MatchFiles/MatchSelector.js
@@ -70,7 +70,7 @@ function MatchSelector(props) {
{messages.label}