@nyris/nyris-webapp 0.3.2 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/asset-manifest.json +8 -8
- package/build/index.html +1 -1
- package/build/js/test.js +14 -20
- package/build/{precache-manifest.8f85a4fff2063a7498a608ec69549bb1.js → precache-manifest.bbb31f2ce7710d7eb3175b1b48241d24.js} +9 -9
- package/build/service-worker.js +1 -1
- package/build/static/js/2.4a55bc61.chunk.js +3 -0
- package/build/static/js/{2.efc0ab83.chunk.js.LICENSE.txt → 2.4a55bc61.chunk.js.LICENSE.txt} +0 -9
- package/build/static/js/2.4a55bc61.chunk.js.map +1 -0
- package/build/static/js/main.2660f94a.chunk.js +2 -0
- package/build/static/js/main.2660f94a.chunk.js.map +1 -0
- package/package.json +3 -3
- package/public/js/test.js +14 -20
- package/src/App.tsx +3 -7
- package/src/Store/Nyris.ts +7 -7
- package/src/Store/Search.ts +48 -74
- package/src/Store/Store.ts +12 -5
- package/src/components/CustomHits/index.tsx +57 -0
- package/src/components/DragDropFile.tsx +27 -23
- package/src/components/ExampleImages.tsx +2 -2
- package/src/components/Feedback.tsx +2 -2
- package/src/components/Footer.tsx +1 -1
- package/src/components/HeaderMd.tsx +4 -5
- package/src/index.tsx +2 -1
- package/src/modules/LandingPage/{indexApp.tsx → App.tsx} +52 -208
- package/src/modules/LandingPage/{indexAppMD.tsx → AppMD.tsx} +52 -147
- package/src/modules/LandingPage/index.tsx +169 -0
- package/src/modules/LandingPage/indexNewVersion.tsx +14 -21
- package/src/modules/LandingPage/propsType.ts +43 -0
- package/src/page/result/index.tsx +51 -106
- package/src/services/Feedback.ts +46 -47
- package/src/services/image.ts +28 -98
- package/src/services/session.ts +13 -16
- package/src/services/types.ts +2 -48
- package/src/types.ts +12 -8
- package/build/static/js/2.efc0ab83.chunk.js +0 -3
- package/build/static/js/2.efc0ab83.chunk.js.map +0 -1
- package/build/static/js/main.3bfed050.chunk.js +0 -2
- package/build/static/js/main.3bfed050.chunk.js.map +0 -1
- package/src/App.test.tsx +0 -49
- package/src/Store/common.d.ts +0 -10
- package/src/Store/epics/feedback.ts +0 -59
- package/src/Store/epics/types.ts +0 -12
- package/src/components/preview/preview.tsx +0 -433
- package/src/services/findByImage.ts +0 -24
- package/src/services/findRegionsCustom.ts +0 -212
- package/src/services/nyris.ts +0 -123
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
RectCoords,
|
|
4
|
+
cadExtensions,
|
|
5
|
+
isCadFile,
|
|
6
|
+
} from "@nyris/nyris-api";
|
|
7
|
+
|
|
8
|
+
import { useAppDispatch, useAppSelector } from "Store/Store";
|
|
9
|
+
import {
|
|
10
|
+
setSearchResults,
|
|
11
|
+
loadingActionResults,
|
|
12
|
+
searchFileImageNonRegion, selectionChanged, setRequestImage, setRegions, setSelectedRegion, setError,
|
|
13
|
+
} from "Store/Search";
|
|
14
|
+
import {
|
|
15
|
+
feedbackNegative,
|
|
16
|
+
feedbackSubmitPositive,
|
|
17
|
+
hideFeedback,
|
|
18
|
+
showCamera,
|
|
19
|
+
showFeedback, showResults,
|
|
20
|
+
showStart,
|
|
21
|
+
} from "Store/Nyris";
|
|
22
|
+
import {createImage, findByCadFile, findByImage, findRegions} from "services/image";
|
|
23
|
+
import { debounce } from "lodash";
|
|
24
|
+
import {feedbackClickEpic, feedbackRegionEpic, feedbackSuccessEpic} from "services/Feedback";
|
|
25
|
+
import AppMD from "./AppMD";
|
|
26
|
+
import App from "./App";
|
|
27
|
+
import {AppHandlers, AppProps} from "./propsType";
|
|
28
|
+
import {defaultMdSettings} from "../../defaults";
|
|
29
|
+
|
|
30
|
+
const defaultSelection = {x1: 0.1, x2: 0.9, y1: 0.1, y2: 0.9};
|
|
31
|
+
|
|
32
|
+
const LandingPageApp = () => {
|
|
33
|
+
const dispatch = useAppDispatch();
|
|
34
|
+
const searchState = useAppSelector((state) => state);
|
|
35
|
+
const [selection, setSelection] = useState<RectCoords>(defaultSelection);
|
|
36
|
+
|
|
37
|
+
const { settings, search, nyris } = searchState;
|
|
38
|
+
const {
|
|
39
|
+
fetchingRegions,
|
|
40
|
+
fetchingResults,
|
|
41
|
+
requestImage,
|
|
42
|
+
selectedRegion,
|
|
43
|
+
} = search;
|
|
44
|
+
const { showPart } = nyris;
|
|
45
|
+
|
|
46
|
+
// update selection, if it is not the default one
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (selectedRegion) {
|
|
49
|
+
setSelection(selectedRegion);
|
|
50
|
+
} else {
|
|
51
|
+
setSelection(defaultSelection);
|
|
52
|
+
}
|
|
53
|
+
}, [selectedRegion]);
|
|
54
|
+
|
|
55
|
+
const acceptTypes = ["image/*"]
|
|
56
|
+
.concat(settings.cadSearch ? cadExtensions : [])
|
|
57
|
+
.join(",");
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
function scrollTop() {
|
|
61
|
+
// TODO might require polyfill for ios and edge
|
|
62
|
+
window.scrollTo({ top: 0, left: 0, behavior: "smooth" });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const onLinkClick = (_position: number, url: string) => {
|
|
66
|
+
feedbackClickEpic(searchState, _position).catch(console.warn);
|
|
67
|
+
if (url) {
|
|
68
|
+
window.open(url);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const startSearch = async (file: File | HTMLCanvasElement | string) => {
|
|
73
|
+
try {
|
|
74
|
+
dispatch(loadingActionResults());
|
|
75
|
+
dispatch(showResults());
|
|
76
|
+
if (file instanceof File && isCadFile(file)) {
|
|
77
|
+
let res = await findByCadFile(file, settings);
|
|
78
|
+
dispatch(setSearchResults(res));
|
|
79
|
+
} else {
|
|
80
|
+
let image = await createImage(file);
|
|
81
|
+
dispatch(setRequestImage(image));
|
|
82
|
+
let searchRegion : RectCoords | undefined;
|
|
83
|
+
if (settings.regions) {
|
|
84
|
+
let {
|
|
85
|
+
regions: foundRegions,
|
|
86
|
+
selectedRegion: suggestedRegion
|
|
87
|
+
} = await findRegions(image, settings);
|
|
88
|
+
searchRegion = suggestedRegion;
|
|
89
|
+
dispatch(setRegions(foundRegions));
|
|
90
|
+
dispatch(setSelectedRegion(searchRegion))
|
|
91
|
+
}
|
|
92
|
+
return findByImage(image, searchState.settings, searchRegion).then((res) => {
|
|
93
|
+
dispatch(setSearchResults(res));
|
|
94
|
+
dispatch(showFeedback());
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
} catch (e) {
|
|
98
|
+
// TODO show error messages
|
|
99
|
+
dispatch(setError("There was an error while performing the request. Please try again later."));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const debouncedSetRectCoords = useCallback(
|
|
105
|
+
debounce(value => {
|
|
106
|
+
dispatch(selectionChanged(value));
|
|
107
|
+
feedbackRegionEpic(searchState, value);
|
|
108
|
+
findByImage(requestImage!!.canvas, settings, value).then((res) => {
|
|
109
|
+
dispatch(searchFileImageNonRegion(res));
|
|
110
|
+
dispatch(showFeedback());
|
|
111
|
+
}).catch(e => console.warn('catch', e));
|
|
112
|
+
}, 1200),
|
|
113
|
+
[requestImage, searchState]
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const handlers : AppHandlers = {
|
|
117
|
+
onExampleImageClick: url => {
|
|
118
|
+
startSearch(url);
|
|
119
|
+
},
|
|
120
|
+
onCameraClick: () => dispatch(showCamera),
|
|
121
|
+
onCaptureCanceled: () => dispatch(showStart),
|
|
122
|
+
onCaptureComplete: (i) => startSearch(i),
|
|
123
|
+
onCloseFeedback: () => dispatch(hideFeedback),
|
|
124
|
+
onFileDropped: (f) => startSearch(f),
|
|
125
|
+
onImageClick: (position, url) => {
|
|
126
|
+
startSearch(url);
|
|
127
|
+
feedbackClickEpic(searchState, position);
|
|
128
|
+
},
|
|
129
|
+
onLinkClick: onLinkClick,
|
|
130
|
+
onPositiveFeedback: () => {
|
|
131
|
+
dispatch(feedbackSubmitPositive());
|
|
132
|
+
feedbackSuccessEpic(searchState, true);
|
|
133
|
+
},
|
|
134
|
+
onNegativeFeedback: () => {
|
|
135
|
+
dispatch(feedbackNegative());
|
|
136
|
+
feedbackSuccessEpic(searchState, false);
|
|
137
|
+
},
|
|
138
|
+
onSelectFile: (f) => startSearch(f),
|
|
139
|
+
onSelectionChange: r => {
|
|
140
|
+
setSelection(r);
|
|
141
|
+
debouncedSetRectCoords(r);
|
|
142
|
+
},
|
|
143
|
+
onShowStart: () => {
|
|
144
|
+
dispatch(showStart());
|
|
145
|
+
scrollTop();
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
let props : AppProps = {
|
|
150
|
+
search: {
|
|
151
|
+
...search,
|
|
152
|
+
previewSelection: selection
|
|
153
|
+
},
|
|
154
|
+
settings,
|
|
155
|
+
previewImage: search.requestImage,
|
|
156
|
+
acceptTypes,
|
|
157
|
+
showPart,
|
|
158
|
+
handlers,
|
|
159
|
+
loading: fetchingRegions || fetchingResults,
|
|
160
|
+
mdSettings: settings.themePage.materialDesign || defaultMdSettings,
|
|
161
|
+
feedbackState: nyris.feedbackState,
|
|
162
|
+
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
return settings.themePage.materialDesign?.active? <AppMD {...props}/> : <App {...props}/>;
|
|
166
|
+
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export default LandingPageApp;
|
|
@@ -14,36 +14,28 @@ import {
|
|
|
14
14
|
} from "react-instantsearch-dom";
|
|
15
15
|
import algoliasearch from "algoliasearch/lite";
|
|
16
16
|
import CustomSearchBox from "components/input/inputSearch";
|
|
17
|
-
import
|
|
17
|
+
import {createSessionByApi} from "../../services/session";
|
|
18
|
+
import {AlgoliaSettings} from "../../types";
|
|
18
19
|
|
|
19
20
|
interface Props {}
|
|
20
21
|
|
|
21
22
|
function AppNewVersion(props: Props) {
|
|
22
23
|
const dispatch = useAppDispatch();
|
|
23
24
|
const history = useHistory();
|
|
24
|
-
const
|
|
25
|
-
const { settings, search }: any = searchState;
|
|
25
|
+
const { settings, search } = useAppSelector((state) => state);
|
|
26
26
|
const [searchStateInput, setSearchStateInput] = useState<any>({});
|
|
27
27
|
const [isLoading, setLoading] = useState<boolean>(false);
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
searchClient.initIndex(indexNameAlgolia);
|
|
28
|
+
const { apiKey, appId, indexName } = settings.algolia as AlgoliaSettings;
|
|
29
|
+
const searchClient = algoliasearch(appId, apiKey);
|
|
30
|
+
searchClient.initIndex(indexName);
|
|
32
31
|
|
|
33
32
|
useEffect(() => {
|
|
34
33
|
const createSession = async () => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const payload: any = {
|
|
38
|
-
sessionId: res.data.session,
|
|
39
|
-
requestId: res.data.id,
|
|
40
|
-
};
|
|
41
|
-
dispatch(setUpdateSession(payload));
|
|
42
|
-
});
|
|
43
|
-
} catch (error) {}
|
|
34
|
+
let payload = await createSessionByApi(settings);
|
|
35
|
+
dispatch(setUpdateSession(payload));
|
|
44
36
|
};
|
|
45
37
|
|
|
46
|
-
createSession();
|
|
38
|
+
createSession().catch(console.log);
|
|
47
39
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
40
|
}, []);
|
|
49
41
|
|
|
@@ -64,9 +56,10 @@ function AppNewVersion(props: Props) {
|
|
|
64
56
|
const nonEmptyFilter: any[] = !search?.requestImage
|
|
65
57
|
? []
|
|
66
58
|
: ["sku:DOES_NOT_EXIST<score=1>"];
|
|
59
|
+
// Build filter using reverse position for stable item order
|
|
67
60
|
const filterSkus: any = search?.results
|
|
68
|
-
? search?.results.map(
|
|
69
|
-
(f: any) => `sku:'${f.sku}'<score=${
|
|
61
|
+
? search?.results.slice().reverse().map(
|
|
62
|
+
(f: any, i: number) => `sku:'${f.sku}'<score=${i}>`
|
|
70
63
|
)
|
|
71
64
|
: "";
|
|
72
65
|
const filtersString = [...nonEmptyFilter, ...filterSkus].join(" OR ");
|
|
@@ -74,10 +67,10 @@ function AppNewVersion(props: Props) {
|
|
|
74
67
|
return (
|
|
75
68
|
<Box className={`box-content-main ${isLoading ? "loading" : ""}`}>
|
|
76
69
|
<InstantSearch
|
|
77
|
-
indexName={
|
|
70
|
+
indexName={indexName}
|
|
78
71
|
searchClient={searchClient}
|
|
79
72
|
searchState={searchStateInput}
|
|
80
|
-
onSearchStateChange={(state
|
|
73
|
+
onSearchStateChange={(state) => {
|
|
81
74
|
setSearchStateInput(state);
|
|
82
75
|
dispatch(changeValueTextSearch(state));
|
|
83
76
|
history.push("/result");
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {CategoryPrediction, Code, RectCoords, Region} from "@nyris/nyris-api";
|
|
2
|
+
import {AppSettings, CanvasWithId, MDSettings} from "../../types";
|
|
3
|
+
import {NyrisAppPart, NyrisFeedbackState} from "../../Store/Nyris";
|
|
4
|
+
|
|
5
|
+
export interface AppHandlers {
|
|
6
|
+
onExampleImageClick: (url: string) => void;
|
|
7
|
+
onImageClick: (position: number, url: string) => void;
|
|
8
|
+
onLinkClick: (position: number, url: string) => void;
|
|
9
|
+
onFileDropped: (file: File) => void;
|
|
10
|
+
onCaptureComplete: (image: HTMLCanvasElement) => void;
|
|
11
|
+
onCaptureCanceled: () => void;
|
|
12
|
+
onSelectFile: (f: File) => void;
|
|
13
|
+
onCameraClick: () => void;
|
|
14
|
+
onShowStart: () => void;
|
|
15
|
+
onSelectionChange: (r: RectCoords) => void;
|
|
16
|
+
onPositiveFeedback: () => void;
|
|
17
|
+
onNegativeFeedback: () => void;
|
|
18
|
+
onCloseFeedback: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export interface AppProps {
|
|
23
|
+
search: {
|
|
24
|
+
results: any[];
|
|
25
|
+
requestId?: string;
|
|
26
|
+
duration?: number;
|
|
27
|
+
categoryPredictions: CategoryPrediction[];
|
|
28
|
+
codes: Code[];
|
|
29
|
+
filterOptions: string[];
|
|
30
|
+
errorMessage?: string;
|
|
31
|
+
regions: Region[];
|
|
32
|
+
previewSelection: RectCoords;
|
|
33
|
+
toastErrorMessage?: string;
|
|
34
|
+
};
|
|
35
|
+
acceptTypes: string,
|
|
36
|
+
previewImage?: CanvasWithId;
|
|
37
|
+
settings: AppSettings;
|
|
38
|
+
loading: boolean;
|
|
39
|
+
showPart: NyrisAppPart;
|
|
40
|
+
feedbackState: NyrisFeedbackState;
|
|
41
|
+
handlers: AppHandlers;
|
|
42
|
+
mdSettings: MDSettings;
|
|
43
|
+
}
|
|
@@ -10,15 +10,6 @@ import React, { useEffect, useState } from "react";
|
|
|
10
10
|
import IconWhatsApp from "common/assets/icons/Icon_whatsapp.png";
|
|
11
11
|
import IconEmail from "common/assets/icons/icon_email.png";
|
|
12
12
|
import IconWeChat from "common/assets/icons/Icon_wechat.png";
|
|
13
|
-
// import FilterComponent from "components/FilterComponent";
|
|
14
|
-
// import {
|
|
15
|
-
// dataFieldFive,
|
|
16
|
-
// dataFieldFour,
|
|
17
|
-
// dataFieldOne,
|
|
18
|
-
// dataFieldSix,
|
|
19
|
-
// dataFieldThree,
|
|
20
|
-
// dataFieldTow,
|
|
21
|
-
// } from "./MockData";
|
|
22
13
|
import ItemResult from "components/results/ItemResult";
|
|
23
14
|
import { useAppDispatch, useAppSelector } from "Store/Store";
|
|
24
15
|
import { debounce } from "lodash";
|
|
@@ -31,11 +22,10 @@ import DetailItem from "components/DetailItem";
|
|
|
31
22
|
import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined";
|
|
32
23
|
import { RectCoords } from "@nyris/nyris-api";
|
|
33
24
|
import {
|
|
34
|
-
|
|
25
|
+
setSearchResults,
|
|
35
26
|
loadingActionResults,
|
|
36
|
-
searchFileImageNonRegion,
|
|
37
27
|
selectionChanged,
|
|
38
|
-
updateResultChangePosition,
|
|
28
|
+
updateResultChangePosition, setRegions, setSelectedRegion,
|
|
39
29
|
} from "Store/Search";
|
|
40
30
|
import { showFeedback, showResults } from "Store/Nyris";
|
|
41
31
|
import algoliasearch from "algoliasearch/lite";
|
|
@@ -46,37 +36,35 @@ import {
|
|
|
46
36
|
Configure,
|
|
47
37
|
} from "react-instantsearch-dom";
|
|
48
38
|
import CustomSearchBox from "components/input/inputSearch";
|
|
49
|
-
import {
|
|
39
|
+
import {feedbackClickEpic, feedbackSuccessEpic, feedbackTextSearchEpic} from "services/Feedback";
|
|
50
40
|
import {
|
|
51
|
-
|
|
52
|
-
serviceImage,
|
|
53
|
-
serviceImageNonRegion,
|
|
41
|
+
createImage, findByImage, findRegions,
|
|
54
42
|
} from "services/image";
|
|
55
|
-
import Preview from "components/preview/preview";
|
|
56
|
-
import NyrisAPI from "@nyris/nyris-api";
|
|
57
43
|
import LoadingScreenCustom from "components/LoadingScreen";
|
|
44
|
+
import { Preview } from "@nyris/nyris-react-components";
|
|
45
|
+
import {AlgoliaResult, AlgoliaSettings} from "../../types";
|
|
58
46
|
|
|
59
47
|
interface Props {}
|
|
60
48
|
|
|
49
|
+
const defaultSelection = {x1: 0.1, x2: 0.9, y1: 0.1, y2: 0.9};
|
|
61
50
|
function ResultComponent(props: Props) {
|
|
62
51
|
const dispatch = useAppDispatch();
|
|
63
|
-
const
|
|
52
|
+
const stateGlobal = useAppSelector((state) => state);
|
|
64
53
|
const [showColLeft, setToggleShowColLeft] = useState<boolean>(false);
|
|
65
54
|
const [showImageCanvas, setShowImageCanvas] = useState<boolean>(true);
|
|
66
55
|
const [isOpenModalImage, setOpenModalImage] = useState<boolean>(false);
|
|
67
56
|
const [numberResult, setNumberResult] = useState<number>(0);
|
|
68
57
|
const [isOpenModalShare, setOpenModalShare] = useState<boolean>(false);
|
|
69
|
-
const { search, settings }
|
|
70
|
-
const { results, requestImage, regions, selectedRegion }
|
|
58
|
+
const { search, settings } = stateGlobal;
|
|
59
|
+
const { results, requestImage, regions, selectedRegion } = search;
|
|
71
60
|
const { valueTextSearch } = search;
|
|
72
61
|
const [dataResult, setDataResult] = useState<any[]>([]);
|
|
73
62
|
const [dataImageModal, setDataImageModal] = useState<any>();
|
|
74
63
|
const [searchStateInput, setSearchStateInput] = useState<any>({});
|
|
75
|
-
const apiNyris = new NyrisAPI(settings);
|
|
76
64
|
const [isLoading, setLoading] = useState<any>(false);
|
|
77
|
-
const {
|
|
78
|
-
const searchClient = algoliasearch(
|
|
79
|
-
const index = searchClient.initIndex(
|
|
65
|
+
const { apiKey, appId, indexName } = settings.algolia as AlgoliaSettings;
|
|
66
|
+
const searchClient = algoliasearch(appId, apiKey);
|
|
67
|
+
const index = searchClient.initIndex(indexName);
|
|
80
68
|
|
|
81
69
|
useEffect(() => {
|
|
82
70
|
if (!valueTextSearch) {
|
|
@@ -127,101 +115,64 @@ function ResultComponent(props: Props) {
|
|
|
127
115
|
const handlerRectCoords = debounce((value: any) => {
|
|
128
116
|
dispatch(selectionChanged(value));
|
|
129
117
|
setLoading(true);
|
|
130
|
-
return
|
|
118
|
+
return findItemsInSelection(value);
|
|
131
119
|
}, 500);
|
|
132
120
|
|
|
133
121
|
// TODO: Search offers for image:
|
|
134
|
-
const
|
|
122
|
+
const findItemsInSelection = (r: RectCoords) => {
|
|
135
123
|
if (!requestImage) {
|
|
136
124
|
return;
|
|
137
125
|
}
|
|
138
126
|
const { canvas }: any = requestImage;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return dispatch(showFeedback(""));
|
|
148
|
-
});
|
|
149
|
-
} else {
|
|
150
|
-
serviceImageNonRegion(canvas, StateGlobal, null).then((res: any) => {
|
|
151
|
-
const payload = {
|
|
152
|
-
...res,
|
|
153
|
-
requestImage: requestImage,
|
|
154
|
-
};
|
|
155
|
-
dispatch(updateResultChangePosition(payload));
|
|
156
|
-
return dispatch(showFeedback(""));
|
|
157
|
-
});
|
|
158
|
-
}
|
|
127
|
+
findByImage(canvas, stateGlobal.settings, r).then((res) => {
|
|
128
|
+
const payload = {
|
|
129
|
+
...res,
|
|
130
|
+
};
|
|
131
|
+
dispatch(updateResultChangePosition(payload));
|
|
132
|
+
setLoading(false);
|
|
133
|
+
return dispatch(showFeedback());
|
|
134
|
+
});
|
|
159
135
|
};
|
|
160
136
|
|
|
161
137
|
// TODO: Search text
|
|
162
138
|
const searchTextByApiAndFilter = async (searchState: any) => {
|
|
163
139
|
try {
|
|
164
140
|
if (searchState?.query !== "") {
|
|
165
|
-
const data = await index.search(searchState.query, {});
|
|
166
|
-
const productIds = data.hits.map((hit
|
|
167
|
-
|
|
168
|
-
query: data.query,
|
|
169
|
-
page: data.page,
|
|
170
|
-
product_ids: productIds,
|
|
171
|
-
};
|
|
172
|
-
const textSearchEvent: any = { event: "text-search", data: eventData };
|
|
173
|
-
await apiNyris.sendFeedback(
|
|
174
|
-
search?.sessionId,
|
|
175
|
-
search?.requestId,
|
|
176
|
-
textSearchEvent
|
|
177
|
-
);
|
|
141
|
+
const data = await index.search<AlgoliaResult>(searchState.query, {});
|
|
142
|
+
const productIds = data.hits.map((hit) => hit.sku);
|
|
143
|
+
await feedbackTextSearchEpic(stateGlobal, data.query, data.page, productIds);
|
|
178
144
|
}
|
|
179
|
-
} catch (error
|
|
145
|
+
} catch (error) {
|
|
180
146
|
console.log("searchTextByApi", error);
|
|
181
147
|
return;
|
|
182
148
|
}
|
|
183
149
|
};
|
|
184
150
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
try {
|
|
188
|
-
const action = type === "like" ? true : false;
|
|
189
|
-
const payload: any = {
|
|
190
|
-
event: "feedback",
|
|
191
|
-
data: {
|
|
192
|
-
success: action,
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
await apiNyris.sendFeedback(
|
|
196
|
-
search?.sessionId,
|
|
197
|
-
search?.requestId,
|
|
198
|
-
payload
|
|
199
|
-
);
|
|
200
|
-
} catch (error) {}
|
|
201
|
-
};
|
|
151
|
+
const sendFeedBackAction = async (type: string) =>
|
|
152
|
+
feedbackSuccessEpic(stateGlobal, type === "like");
|
|
202
153
|
|
|
203
154
|
// Search image with url or file
|
|
204
|
-
const getUrlToCanvasFile = (url: string, position?: number) => {
|
|
205
|
-
dispatch(showResults(
|
|
206
|
-
dispatch(loadingActionResults(
|
|
155
|
+
const getUrlToCanvasFile = async (url: string, position?: number) => {
|
|
156
|
+
dispatch(showResults());
|
|
157
|
+
dispatch(loadingActionResults());
|
|
158
|
+
let image = await createImage(url);
|
|
207
159
|
if (position) {
|
|
208
|
-
feedbackClickEpic(
|
|
160
|
+
feedbackClickEpic(stateGlobal, position);
|
|
209
161
|
return;
|
|
210
162
|
}
|
|
163
|
+
let searchRegion : RectCoords | undefined = undefined;
|
|
211
164
|
if (settings.regions) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
return;
|
|
219
|
-
} else {
|
|
220
|
-
serviceImageNonRegion(url, StateGlobal, undefined).then((res) => {
|
|
221
|
-
dispatch(searchFileImageNonRegion(res));
|
|
222
|
-
});
|
|
223
|
-
return;
|
|
165
|
+
let res = await findRegions(image, settings);
|
|
166
|
+
searchRegion = res.selectedRegion;
|
|
167
|
+
dispatch(setRegions(res.regions));
|
|
168
|
+
dispatch(setSelectedRegion(searchRegion));
|
|
224
169
|
}
|
|
170
|
+
|
|
171
|
+
findByImage(image, settings, searchRegion).then((res ) => {
|
|
172
|
+
dispatch(setSearchResults(res));
|
|
173
|
+
setLoading(false);
|
|
174
|
+
return dispatch(showFeedback());
|
|
175
|
+
});
|
|
225
176
|
};
|
|
226
177
|
|
|
227
178
|
// Todo: item result.
|
|
@@ -247,12 +198,12 @@ function ResultComponent(props: Props) {
|
|
|
247
198
|
);
|
|
248
199
|
};
|
|
249
200
|
|
|
250
|
-
const nonEmptyFilter: any[] = !
|
|
201
|
+
const nonEmptyFilter: any[] = !requestImage
|
|
251
202
|
? []
|
|
252
203
|
: ["sku:DOES_NOT_EXIST<score=1>"];
|
|
253
204
|
const filterSkus: any = search?.results
|
|
254
|
-
|
|
255
|
-
|
|
205
|
+
? search?.results.slice().reverse().map(
|
|
206
|
+
(f: any, i: number) => `sku:'${f.sku}'<score=${i}>`
|
|
256
207
|
)
|
|
257
208
|
: "";
|
|
258
209
|
const filtersString = [...nonEmptyFilter, ...filterSkus].join(" OR ");
|
|
@@ -267,10 +218,10 @@ function ResultComponent(props: Props) {
|
|
|
267
218
|
</Box>
|
|
268
219
|
)}
|
|
269
220
|
<InstantSearch
|
|
270
|
-
indexName={
|
|
221
|
+
indexName={indexName}
|
|
271
222
|
searchClient={searchClient}
|
|
272
223
|
searchState={searchStateInput}
|
|
273
|
-
onSearchStateChange={(state
|
|
224
|
+
onSearchStateChange={(state) => {
|
|
274
225
|
setSearchStateInput(state);
|
|
275
226
|
searchTextByApiAndFilter(state);
|
|
276
227
|
}}
|
|
@@ -313,13 +264,7 @@ function ResultComponent(props: Props) {
|
|
|
313
264
|
return;
|
|
314
265
|
}}
|
|
315
266
|
image={requestImage?.canvas}
|
|
316
|
-
|
|
317
|
-
!selectedRegion
|
|
318
|
-
? regions[0]
|
|
319
|
-
? regions[0]
|
|
320
|
-
: { x1: 0, x2: 1, y1: 0, y2: 1 }
|
|
321
|
-
: selectedRegion
|
|
322
|
-
}
|
|
267
|
+
selection={selectedRegion|| defaultSelection}
|
|
323
268
|
regions={regions}
|
|
324
269
|
maxWidth={400}
|
|
325
270
|
maxHeight={500}
|
package/src/services/Feedback.ts
CHANGED
|
@@ -1,65 +1,64 @@
|
|
|
1
|
-
import NyrisAPI from "@nyris/nyris-api";
|
|
1
|
+
import NyrisAPI, {FeedbackEventPayload, NyrisAPISettings, RectCoords} from "@nyris/nyris-api";
|
|
2
|
+
import {RootState} from "../Store/Store";
|
|
2
3
|
|
|
3
|
-
export const feedbackSuccessEpic = async (state:
|
|
4
|
+
export const feedbackSuccessEpic = async (state: RootState, success: boolean) => {
|
|
4
5
|
const { search, settings } = state;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
return await sendFeedbackByApi(settings, search.sessionId, search.requestId, {
|
|
7
|
+
event: 'feedback',
|
|
8
|
+
data: { success }
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const feedbackClickEpic = async (state: RootState, position: number) => {
|
|
13
|
+
const { search, settings } = state;
|
|
14
|
+
return await sendFeedbackByApi(settings, search.sessionId, search.requestId, {
|
|
15
|
+
event: "click",
|
|
16
|
+
data: { positions: [position] },
|
|
17
|
+
});
|
|
15
18
|
};
|
|
16
19
|
|
|
17
|
-
export const
|
|
20
|
+
export const feedbackTextSearchEpic = async (state: RootState, query: string, page: number, productIds: string[]) => {
|
|
18
21
|
try {
|
|
19
22
|
const { search, settings } = state;
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
const eventData = {
|
|
24
|
+
query,
|
|
25
|
+
page,
|
|
26
|
+
product_ids: productIds,
|
|
27
|
+
};
|
|
28
|
+
const textSearchEvent = { event: "text-search", data: eventData };
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
return await sendFeedbackByApi(settings, search.sessionId, search.requestId, textSearchEvent);
|
|
28
31
|
} catch (error) {
|
|
29
|
-
console.log("error
|
|
32
|
+
console.log("error feedbackTextSearchEpic", error);
|
|
30
33
|
}
|
|
31
34
|
};
|
|
32
35
|
|
|
33
|
-
export const feedbackRegionEpic = async (state:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const { x1, x2, y1, y2 } = region;
|
|
39
|
-
if (sessionId && search.requestId) {
|
|
40
|
-
await api.sendFeedback(sessionId, search.requestId, {
|
|
36
|
+
export const feedbackRegionEpic = async (state: RootState, region: RectCoords) => {
|
|
37
|
+
const {settings, search} = state;
|
|
38
|
+
const {sessionId, requestId } = search;
|
|
39
|
+
const { x1, x2, y1, y2 } = region;
|
|
40
|
+
const payload : FeedbackEventPayload = {
|
|
41
41
|
event: "region",
|
|
42
|
-
data: { rect: { x: x1, y: y1, w: x2 - x1, h: y2 - y1 } }
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.log("error feedbackRegionEpic", error);
|
|
47
|
-
}
|
|
42
|
+
data: { rect: { x: x1, y: y1, w: x2 - x1, h: y2 - y1 } }
|
|
43
|
+
};
|
|
44
|
+
return await sendFeedbackByApi(settings, sessionId, requestId, payload);
|
|
48
45
|
};
|
|
49
46
|
|
|
50
47
|
export const sendFeedbackByApi = async (
|
|
51
|
-
settings:
|
|
52
|
-
sessionId:
|
|
53
|
-
requestId:
|
|
54
|
-
payload:
|
|
48
|
+
settings: NyrisAPISettings,
|
|
49
|
+
sessionId: string | undefined,
|
|
50
|
+
requestId: string | undefined,
|
|
51
|
+
payload: FeedbackEventPayload
|
|
55
52
|
) => {
|
|
56
53
|
const api = new NyrisAPI(settings);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
if (sessionId && requestId) {
|
|
55
|
+
try {
|
|
56
|
+
const dataByApi = await api
|
|
57
|
+
.sendFeedback(sessionId, requestId, payload)
|
|
58
|
+
.then((res) => {});
|
|
59
|
+
console.log("dataByApi", dataByApi);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.log("error sendFeedbackByApi321", error);
|
|
62
|
+
}
|
|
64
63
|
}
|
|
65
64
|
};
|