📔 ComicVine matches populating in the flyout drawer
This commit is contained in:
@@ -6,7 +6,10 @@ import {
|
|||||||
IMS_COMICBOOK_METADATA_FETCHED,
|
IMS_COMICBOOK_METADATA_FETCHED,
|
||||||
IMS_SOCKET_CONNECTION_CONNECTED,
|
IMS_SOCKET_CONNECTION_CONNECTED,
|
||||||
IMS_RECENT_COMICS_FETCHED,
|
IMS_RECENT_COMICS_FETCHED,
|
||||||
|
CV_API_CALL_IN_PROGRESS,
|
||||||
|
CV_SEARCH_SUCCESS,
|
||||||
} from "../constants/action-types";
|
} from "../constants/action-types";
|
||||||
|
|
||||||
import { refineQuery } from "../shared/utils/nlp.utils";
|
import { refineQuery } from "../shared/utils/nlp.utils";
|
||||||
import { assign } from "lodash";
|
import { assign } from "lodash";
|
||||||
|
|
||||||
@@ -101,7 +104,7 @@ export const getRecentlyImportedComicBooks = (options) => async (dispatch) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchComicVineMatches = (searchPayload, options) => (dispatch) => {
|
export const fetchComicVineMatches = (searchPayload) => (dispatch) => {
|
||||||
try {
|
try {
|
||||||
const issueString = searchPayload.rawFileDetails.path.split("/").pop();
|
const issueString = searchPayload.rawFileDetails.path.split("/").pop();
|
||||||
let seriesSearchQuery = {};
|
let seriesSearchQuery = {};
|
||||||
@@ -111,10 +114,6 @@ export const fetchComicVineMatches = (searchPayload, options) => (dispatch) => {
|
|||||||
searchPayload.rawFileDetails.containedIn.split("/").pop(),
|
searchPayload.rawFileDetails.containedIn.split("/").pop(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
console.log({
|
|
||||||
issue: issueSearchQuery.searchParams,
|
|
||||||
series: seriesSearchQuery.searchParams,
|
|
||||||
});
|
|
||||||
axios
|
axios
|
||||||
.request({
|
.request({
|
||||||
url: "http://localhost:3080/api/comicvine/fetchseries",
|
url: "http://localhost:3080/api/comicvine/fetchseries",
|
||||||
@@ -130,9 +129,14 @@ export const fetchComicVineMatches = (searchPayload, options) => (dispatch) => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log("CV says to fuck off:", response);
|
dispatch({
|
||||||
|
type: CV_SEARCH_SUCCESS,
|
||||||
|
searchResults: response.data,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return { issueSearchQuery, series: seriesSearchQuery.searchParams };
|
{
|
||||||
|
/* return { issueSearchQuery, series: seriesSearchQuery.searchParams }; */
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16316,6 +16316,19 @@ readers do not read off random characters that represent icons */
|
|||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
.card .truncate {
|
||||||
|
width: 100px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.card img {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
.card-container {
|
.card-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
@@ -16324,23 +16337,56 @@ readers do not read off random characters that represent icons */
|
|||||||
}
|
}
|
||||||
.card-container .card {
|
.card-container .card {
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
|
margin: 0 0 15px 0;
|
||||||
}
|
}
|
||||||
.card-container .card .truncate {
|
.card-container .card .is-horizontal {
|
||||||
width: 100px;
|
flex-direction: row;
|
||||||
|
display: flex;
|
||||||
|
flex-basis: 50ex;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.card-container .card .is-horizontal .card-image {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.card-container .card .is-horizontal .card-image .image {
|
||||||
|
max-width: 60px;
|
||||||
|
}
|
||||||
|
.card-container .card .is-horizontal .card-image .image img {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-top-left-radius: 0.25em;
|
||||||
|
border-bottom-left-radius: 0.25em;
|
||||||
|
}
|
||||||
|
.card-container .card .is-horizontal .card-content {
|
||||||
|
align-self: center;
|
||||||
|
flex: 1;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
.card-container .card .is-horizontal .card-content ul li.status {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.card-container .card .is-horizontal .card-content .truncate {
|
||||||
|
width: 400px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
.card-container .card img {
|
.card-container .card .is-horizontal .is-divider {
|
||||||
max-width: 200px;
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-results-container {
|
.search-results-container {
|
||||||
margin: 15px 0 0 0;
|
margin: 15px 0 0 0;
|
||||||
border: 1px solid #fafafa;
|
|
||||||
border-radius: 10px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);
|
}
|
||||||
|
.search-results-container table {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.search-results-container > :nth-of-type(odd) {
|
.search-results-container > :nth-of-type(odd) {
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
|
|||||||
@@ -114,11 +114,11 @@ $border-color: red;
|
|||||||
// comicvine search results
|
// comicvine search results
|
||||||
.search-results-container {
|
.search-results-container {
|
||||||
margin: 15px 0 0 0;
|
margin: 15px 0 0 0;
|
||||||
border: 1px solid hsl(0, 0%, 98%);
|
|
||||||
border-radius: 10px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: $box-shadow;
|
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
> :nth-of-type(odd) {
|
> :nth-of-type(odd) {
|
||||||
background-color: hsl(0, 0%, 98%);
|
background-color: hsl(0, 0%, 98%);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import Card from "./Card";
|
import Card from "./Card";
|
||||||
|
import MatchResult from "./MatchResult";
|
||||||
import { isEmpty, isUndefined } from "lodash";
|
import { isEmpty, isUndefined } from "lodash";
|
||||||
import { IExtractedComicBookCoverFile } from "threetwo-ui-typings";
|
import { IExtractedComicBookCoverFile, RootState } from "threetwo-ui-typings";
|
||||||
import { fetchComicVineMatches } from "../actions/fileops.actions";
|
import { fetchComicVineMatches } from "../actions/fileops.actions";
|
||||||
import { Drawer } from "antd";
|
import { Drawer } from "antd";
|
||||||
import "antd/dist/antd.css";
|
import "antd/dist/antd.css";
|
||||||
|
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
type ComicDetailProps = {};
|
type ComicDetailProps = {};
|
||||||
|
|
||||||
export const ComicDetail = ({}: ComicDetailProps) => {
|
export const ComicDetail = ({}: ComicDetailProps) => {
|
||||||
@@ -16,15 +19,11 @@ export const ComicDetail = ({}: ComicDetailProps) => {
|
|||||||
const [comicDetail, setComicDetail] = useState<{
|
const [comicDetail, setComicDetail] = useState<{
|
||||||
rawFileDetails: IExtractedComicBookCoverFile;
|
rawFileDetails: IExtractedComicBookCoverFile;
|
||||||
}>();
|
}>();
|
||||||
|
const comicVineSearchResults = useSelector(
|
||||||
|
(state: RootState) => state.comicInfo.searchResults,
|
||||||
|
);
|
||||||
const { comicObjectId } = useParams<{ comicObjectId: string }>();
|
const { comicObjectId } = useParams<{ comicObjectId: string }>();
|
||||||
|
|
||||||
const showDrawer = () => {
|
|
||||||
setVisible(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onClose = () => {
|
|
||||||
setVisible(false);
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
axios
|
axios
|
||||||
.request({
|
.request({
|
||||||
@@ -36,12 +35,22 @@ export const ComicDetail = ({}: ComicDetailProps) => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log("fetched", response);
|
|
||||||
setComicDetail(response.data);
|
setComicDetail(response.data);
|
||||||
})
|
})
|
||||||
.catch((error) => console.log(error));
|
.catch((error) => console.log(error));
|
||||||
}, [page]);
|
}, [page]);
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const openDrawerWithCVMatches = useCallback(() => {
|
||||||
|
setVisible(true);
|
||||||
|
dispatch(fetchComicVineMatches(comicDetail));
|
||||||
|
}, [dispatch, comicDetail, comicVineSearchResults]);
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
setVisible(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
{!isEmpty(comicDetail) && !isUndefined(comicDetail) && (
|
{!isEmpty(comicDetail) && !isUndefined(comicDetail) && (
|
||||||
@@ -52,7 +61,7 @@ export const ComicDetail = ({}: ComicDetailProps) => {
|
|||||||
<Card comicBookCoversMetadata={comicDetail.rawFileDetails} />
|
<Card comicBookCoversMetadata={comicDetail.rawFileDetails} />
|
||||||
</div>
|
</div>
|
||||||
<div className="column">
|
<div className="column">
|
||||||
<button className="button" onClick={showDrawer}>
|
<button className="button" onClick={openDrawerWithCVMatches}>
|
||||||
<span className="icon">
|
<span className="icon">
|
||||||
<i className="fas fa-magic"></i>
|
<i className="fas fa-magic"></i>
|
||||||
</span>
|
</span>
|
||||||
@@ -69,9 +78,11 @@ export const ComicDetail = ({}: ComicDetailProps) => {
|
|||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
>
|
>
|
||||||
<p>Some contents...</p>
|
<div className="search-results-container">
|
||||||
<p>Some contents...</p>
|
{!isEmpty(comicVineSearchResults) && (
|
||||||
<p>Some contents...</p>
|
<MatchResult matchData={comicVineSearchResults} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//@ts-ignore
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { isUndefined } from "lodash";
|
import { isUndefined } from "lodash";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
|||||||
@@ -1,113 +1,42 @@
|
|||||||
import * as React from "react";
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
import { IComicVineSearchMatch, IFolderData } from "threetwo-ui-typings";
|
import { IComicVineSearchMatch, IFolderData } from "threetwo-ui-typings";
|
||||||
import _ from "lodash";
|
import { map } from "lodash";
|
||||||
import { autoMatcher } from "../shared/utils/query.transformer";
|
|
||||||
|
|
||||||
interface IProps {
|
interface MatchResultProps {
|
||||||
matchData: unknown;
|
matchData: any;
|
||||||
visible: boolean;
|
|
||||||
queryData: IFolderData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {}
|
export const MatchResult = (props: MatchResultProps) => {
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("match", props.matchData);
|
||||||
|
}, [props.matchData]);
|
||||||
|
|
||||||
class MatchResult extends React.Component<IProps, IState> {
|
return (
|
||||||
constructor(props: IProps) {
|
<>
|
||||||
super(props);
|
<table>
|
||||||
}
|
<thead>
|
||||||
|
<tr>
|
||||||
public componentDidMount() {
|
<th></th>
|
||||||
console.log(this.props);
|
</tr>
|
||||||
autoMatcher(this.props.queryData, this.props.matchData.results);
|
</thead>
|
||||||
}
|
<tbody>
|
||||||
|
{map(props.matchData, (match, idx) => {
|
||||||
public render() {
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
<table className="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Format</th>
|
|
||||||
<th>Is File</th>
|
|
||||||
</tr>
|
|
||||||
{!_.isUndefined(this.state.folderWalkResults) &&
|
|
||||||
this.state.folderWalkResults.map((result, idx) => (
|
|
||||||
<tr key={idx}>
|
|
||||||
<td>
|
|
||||||
{!result.isLink && !result.isFile ? (
|
|
||||||
<span className="icon-text">
|
|
||||||
<span className="icon">
|
|
||||||
<i className="fas fa-folder"></i>
|
|
||||||
</span>
|
|
||||||
<span>{result.name}</span>
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<span className="ml-5">{result.name}</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{this.state.searchPaneIndex === idx &&
|
|
||||||
!_.isUndefined(this.props.matches) ? (
|
|
||||||
<MatchResult
|
|
||||||
queryData={result}
|
|
||||||
matchData={this.props.matches}
|
|
||||||
visible={true}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{!_.isEmpty(result.extension) ? (
|
|
||||||
<span className="tag is-info">
|
|
||||||
{result.extension}
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
</td>
|
|
||||||
<td>{result.isFile.toString()}</td>
|
|
||||||
<td>
|
|
||||||
<button
|
|
||||||
key={idx}
|
|
||||||
className="button is-small is-primary is-outlined"
|
|
||||||
onClick={(e) => {
|
|
||||||
this.props.findMatches(e, result);
|
|
||||||
this.toggleSearchResultsPane(idx);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Find Match
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>
|
|
||||||
</table>
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
return this.props.visible ? (
|
|
||||||
<div>
|
|
||||||
<h3>Matches</h3>
|
|
||||||
<div className="search-results-container">
|
|
||||||
{this.props.matchData.results.map((result, idx) => {
|
|
||||||
return (
|
return (
|
||||||
<div key={idx} className="search-result">
|
<tr className="search-result">
|
||||||
<img className="cover-image" src={result.image.thumb_url} />
|
<td key={idx}>
|
||||||
<div className="search-result-details">
|
<img className="cover-image" src={match.image.thumb_url} />
|
||||||
<h5>{result.volume.name}</h5>
|
</td>
|
||||||
|
<td className="search-result-details">
|
||||||
{!_.isEmpty(result.extension) ? (
|
<h4>{match.name}</h4>
|
||||||
<span className="tag is-info">{result.extension}</span>
|
<h5>{match.volume.name}</h5>
|
||||||
) : null}
|
</td>
|
||||||
|
</tr>
|
||||||
<span className="tag is-info">
|
|
||||||
Issue Number: {result.issue_number}
|
|
||||||
</span>
|
|
||||||
<p>{result.site_detail_url}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</tbody>
|
||||||
</div>
|
</table>
|
||||||
) : null;
|
</>
|
||||||
}
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default MatchResult;
|
export default MatchResult;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
CV_SEARCH_SUCCESS,
|
CV_SEARCH_SUCCESS,
|
||||||
} from "../constants/action-types";
|
} from "../constants/action-types";
|
||||||
const initialState = {
|
const initialState = {
|
||||||
showResultsPane: false,
|
searchResults: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
function comicinfoReducer(state = initialState, action) {
|
function comicinfoReducer(state = initialState, action) {
|
||||||
@@ -12,13 +12,11 @@ function comicinfoReducer(state = initialState, action) {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
result: {},
|
result: {},
|
||||||
showResultsPane: false,
|
|
||||||
};
|
};
|
||||||
case CV_SEARCH_SUCCESS:
|
case CV_SEARCH_SUCCESS:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
searchResults: action.result,
|
searchResults: action.searchResults.results,
|
||||||
showResultsPane: true,
|
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|||||||
Reference in New Issue
Block a user