@nyris/nyris-webapp 0.3.12 → 0.3.15
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 +11 -11
- package/build/index.html +1 -1
- package/build/js/settings.example.js +30 -0
- package/build/{precache-manifest.1b00dd5c15aa0815244681503d6fa9da.js → precache-manifest.949663d44eccdb92670b8b19ac252ec8.js} +9 -9
- package/build/service-worker.js +1 -1
- package/build/static/css/{main.0c9239ba.chunk.css → main.5c640239.chunk.css} +2 -2
- package/build/static/css/main.5c640239.chunk.css.map +1 -0
- package/build/static/js/{2.520bb6d6.chunk.js → 2.39097849.chunk.js} +3 -3
- package/build/static/js/{2.520bb6d6.chunk.js.LICENSE.txt → 2.39097849.chunk.js.LICENSE.txt} +0 -0
- package/build/static/js/2.39097849.chunk.js.map +1 -0
- package/build/static/js/main.f8c5f638.chunk.js +2 -0
- package/build/static/js/main.f8c5f638.chunk.js.map +1 -0
- package/package.json +2 -2
- package/public/js/settings.example.js +30 -0
- package/src/App.css +1 -11
- package/src/App.tsx +141 -268
- package/src/actions/searchActions.ts +5 -19
- package/src/components/CategoryFilter.tsx +13 -16
- package/src/components/Codes.tsx +16 -20
- package/src/components/ExampleImages.tsx +17 -27
- package/src/components/Feedback.tsx +48 -78
- package/src/components/FiltersList.tsx +12 -18
- package/src/components/PredictedCategories.tsx +12 -15
- package/src/components/Result.tsx +113 -186
- package/src/components/SelectedFiltersSummary.tsx +1 -2
- package/src/components/Sidebar.tsx +17 -37
- package/src/epics/index.ts +94 -143
- package/src/epics/search.ts +75 -118
- package/src/index.css +15 -15
- package/src/index.tsx +55 -63
- package/build/static/css/main.0c9239ba.chunk.css.map +0 -1
- package/build/static/js/2.520bb6d6.chunk.js.map +0 -1
- package/build/static/js/main.ef6a9744.chunk.js +0 -2
- package/build/static/js/main.ef6a9744.chunk.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { RiMenuLine } from "react-icons/ri";
|
|
3
3
|
import { Filter } from "../../../nyris-api/index";
|
|
4
4
|
import FiltersList from "./FiltersList";
|
|
@@ -9,43 +9,23 @@ interface SidebarProps {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
const Sidebar: React.FC<SidebarProps> = ({ filters, selectedFilters }) => {
|
|
12
|
-
console.log(filters);
|
|
13
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
14
|
-
const handleToggler = () => {
|
|
15
|
-
if (isExpanded) {
|
|
16
|
-
setIsExpanded(false);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
setIsExpanded(true);
|
|
20
|
-
};
|
|
21
12
|
return (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{filters &&
|
|
39
|
-
filters.map((x) => {
|
|
40
|
-
let selectedValues = x.key
|
|
41
|
-
? selectedFilters.get(x.key)
|
|
42
|
-
: undefined;
|
|
43
|
-
return <FiltersList filter={x} selectedValues={selectedValues} />;
|
|
44
|
-
})}
|
|
45
|
-
{/* <FiltersList2/> */}
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
13
|
+
<div className = "sidebar">
|
|
14
|
+
<div className= "sidebarContent" >
|
|
15
|
+
<div className="sidebarHeader">
|
|
16
|
+
<RiMenuLine className="sidebar-icon" />
|
|
17
|
+
</div>
|
|
18
|
+
<div className="Sidebar-items" >
|
|
19
|
+
{filters &&
|
|
20
|
+
filters.map((x) => {
|
|
21
|
+
let selectedValues = x.key
|
|
22
|
+
? selectedFilters.get(x.key)
|
|
23
|
+
: undefined;
|
|
24
|
+
return <FiltersList filter={x} selectedValues={selectedValues} />;
|
|
25
|
+
})}
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
49
29
|
);
|
|
50
30
|
};
|
|
51
31
|
|
package/src/epics/index.ts
CHANGED
|
@@ -1,184 +1,135 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
ignoreElements,
|
|
6
|
-
map,
|
|
7
|
-
switchMap,
|
|
8
|
-
tap,
|
|
9
|
-
withLatestFrom,
|
|
10
|
-
} from "rxjs/operators";
|
|
11
|
-
import { showFeedback, showResults } from "../actions/nyrisAppActions";
|
|
12
|
-
import { EpicConf } from "./types";
|
|
1
|
+
import {combineEpics, ofType} from "redux-observable";
|
|
2
|
+
import {debounceTime, delay, ignoreElements, map, switchMap, tap, withLatestFrom} from "rxjs/operators";
|
|
3
|
+
import {showFeedback, showResults} from "../actions/nyrisAppActions";
|
|
4
|
+
import {EpicConf} from "./types";
|
|
13
5
|
import feedbackEpics from "./feedback";
|
|
14
6
|
import searchEpics from "./search";
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const historyEpic: EpicConf = (action$, state$, { history }) =>
|
|
24
|
-
action$.pipe(
|
|
25
|
-
ofType("SHOW_RESULTS", "SHOW_START"),
|
|
26
|
-
withLatestFrom(state$),
|
|
27
|
-
tap(([action, state]) => {
|
|
7
|
+
import {searchOffersForImage, searchOffersForCad, searchRegions} from "../actions/searchActions";
|
|
8
|
+
import {AppAction} from "../types";
|
|
9
|
+
import {selectFirstCenteredRegion} from "@nyris/nyris-api";
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const historyEpic: EpicConf = (action$, state$, {history}) => action$.pipe(
|
|
13
|
+
ofType('SHOW_RESULTS', 'SHOW_START'),
|
|
14
|
+
tap((action) => {
|
|
28
15
|
let { type } = action;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// action to clear all filters
|
|
32
|
-
if (type === "SHOW_RESULTS" && history.location.pathname !== "/results") {
|
|
33
|
-
history.push("/results");
|
|
16
|
+
if (type === 'SHOW_RESULTS' && history.location.pathname !== '/results') {
|
|
17
|
+
history.push('/results');
|
|
34
18
|
}
|
|
35
|
-
if (type ===
|
|
36
|
-
|
|
19
|
+
if (type === 'SHOW_START' && history.location.pathname !== '/') {
|
|
20
|
+
history.goBack();
|
|
37
21
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
22
|
+
}),
|
|
23
|
+
ignoreElements()
|
|
24
|
+
);
|
|
41
25
|
|
|
42
|
-
const onSearchSuccessShowResults: EpicConf = (action$) =>
|
|
43
|
-
|
|
26
|
+
const onSearchSuccessShowResults: EpicConf = (action$) => action$.pipe(
|
|
27
|
+
ofType('SEARCH_REQUEST_SUCCEED'),
|
|
28
|
+
map(showResults)
|
|
29
|
+
);
|
|
44
30
|
|
|
45
|
-
const onSearchSuccessRedirectToSite: EpicConf = (action$, state$) =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
action.type !== "SEARCH_REQUEST_SUCCEED" ||
|
|
52
|
-
!action.results ||
|
|
53
|
-
action.results.length !== 1
|
|
54
|
-
) {
|
|
55
|
-
return;
|
|
31
|
+
const onSearchSuccessRedirectToSite: EpicConf = (action$, state$) => action$.pipe(
|
|
32
|
+
ofType('SEARCH_REQUEST_SUCCEED'),
|
|
33
|
+
withLatestFrom(state$),
|
|
34
|
+
tap(([action, {settings}]) => {
|
|
35
|
+
if (action.type !== 'SEARCH_REQUEST_SUCCEED' || !action.results || action.results.length !== 1) {
|
|
36
|
+
return;
|
|
56
37
|
}
|
|
57
38
|
|
|
58
39
|
const firstLink = action.results[0].l;
|
|
59
40
|
const instantRedirectPatterns = settings.instantRedirectPatterns;
|
|
60
|
-
if (!instantRedirectPatterns.find(
|
|
61
|
-
|
|
41
|
+
if (!instantRedirectPatterns.find(r => new RegExp(r).test(firstLink))) {
|
|
42
|
+
return;
|
|
62
43
|
}
|
|
63
44
|
window.location.href = firstLink;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
45
|
+
}),
|
|
46
|
+
ignoreElements()
|
|
47
|
+
);
|
|
67
48
|
|
|
68
|
-
const onSearchSuccessShowFeedbackDelayed: EpicConf = (action$) =>
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
);
|
|
49
|
+
const onSearchSuccessShowFeedbackDelayed: EpicConf = (action$) => action$.pipe(
|
|
50
|
+
ofType('SEARCH_REQUEST_SUCCEED'),
|
|
51
|
+
delay(3000),
|
|
52
|
+
map(showFeedback)
|
|
53
|
+
);
|
|
74
54
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (action.type !==
|
|
81
|
-
|
|
55
|
+
|
|
56
|
+
const startSearchOnImageLoaded: EpicConf = (action$, state$) => action$.pipe(
|
|
57
|
+
ofType('IMAGE_LOADED'),
|
|
58
|
+
withLatestFrom(state$),
|
|
59
|
+
switchMap(async ([action, {settings}]) : Promise<AppAction> => {
|
|
60
|
+
if (action.type !== 'IMAGE_LOADED') {
|
|
61
|
+
throw new Error(`Wrong action type ${action.type}`);
|
|
82
62
|
}
|
|
83
63
|
|
|
84
64
|
let { image } = action;
|
|
85
65
|
|
|
86
66
|
if (settings.regions) {
|
|
87
|
-
|
|
67
|
+
return searchRegions(image.canvas);
|
|
88
68
|
}
|
|
89
69
|
return searchOffersForImage(image.canvas);
|
|
90
|
-
|
|
91
|
-
|
|
70
|
+
})
|
|
71
|
+
);
|
|
92
72
|
|
|
93
|
-
const startSearchOnCadLoaded: EpicConf = (action$, state$) =>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
throw new Error(`Wrong action type ${action.type}`);
|
|
73
|
+
const startSearchOnCadLoaded: EpicConf = (action$, state$) => action$.pipe(
|
|
74
|
+
ofType('CAD_LOADED'),
|
|
75
|
+
withLatestFrom(state$),
|
|
76
|
+
switchMap(async ([action, {settings}]) : Promise<AppAction> => {
|
|
77
|
+
if (action.type !== 'CAD_LOADED') {
|
|
78
|
+
throw new Error(`Wrong action type ${action.type}`);
|
|
100
79
|
}
|
|
101
80
|
let { file } = action;
|
|
102
81
|
return searchOffersForCad(file);
|
|
103
|
-
|
|
104
|
-
|
|
82
|
+
})
|
|
83
|
+
);
|
|
105
84
|
|
|
106
|
-
const startSearchOnRegionsSuccessful: EpicConf = (action$, state$) =>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
async ([
|
|
112
|
-
action,
|
|
113
|
-
{
|
|
114
|
-
search: { requestImage },
|
|
115
|
-
},
|
|
116
|
-
]): Promise<AppAction> => {
|
|
117
|
-
if (action.type !== "REGION_REQUEST_SUCCEED") {
|
|
85
|
+
const startSearchOnRegionsSuccessful: EpicConf = (action$, state$) => action$.pipe(
|
|
86
|
+
ofType('REGION_REQUEST_SUCCEED'),
|
|
87
|
+
withLatestFrom(state$),
|
|
88
|
+
switchMap(async ([action, { search: { requestImage}}]) : Promise<AppAction> => {
|
|
89
|
+
if (action.type !== 'REGION_REQUEST_SUCCEED') {
|
|
118
90
|
throw new Error(`Wrong action type ${action.type}`);
|
|
119
|
-
|
|
120
|
-
|
|
91
|
+
}
|
|
92
|
+
if (!requestImage) {
|
|
121
93
|
throw new Error(`No requestImage`);
|
|
122
|
-
}
|
|
123
|
-
let { regions } = action;
|
|
124
|
-
|
|
125
|
-
let selection = selectFirstCenteredRegion(regions, 0.3, {
|
|
126
|
-
x1: 0,
|
|
127
|
-
x2: 1,
|
|
128
|
-
y1: 0,
|
|
129
|
-
y2: 1,
|
|
130
|
-
});
|
|
131
|
-
return searchOffersForImage(requestImage.canvas, selection);
|
|
132
94
|
}
|
|
133
|
-
|
|
134
|
-
);
|
|
95
|
+
let { regions } = action;
|
|
135
96
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
]): Promise<AppAction> => {
|
|
147
|
-
if (action.type !== "REGION_REQUEST_FAIL") {
|
|
97
|
+
let selection = selectFirstCenteredRegion(regions, 0.3, {x1: 0, x2: 1, y1: 0, y2: 1});
|
|
98
|
+
return searchOffersForImage(requestImage.canvas, selection);
|
|
99
|
+
})
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const startSearchOnRegionsFailed: EpicConf = (action$, state$) => action$.pipe(
|
|
103
|
+
ofType('REGION_REQUEST_FAIL'),
|
|
104
|
+
withLatestFrom(state$),
|
|
105
|
+
switchMap(async ([action, { search: { requestImage}}]) : Promise<AppAction> => {
|
|
106
|
+
if (action.type !== 'REGION_REQUEST_FAIL') {
|
|
148
107
|
throw new Error(`Wrong action type ${action.type}`);
|
|
149
|
-
|
|
150
|
-
|
|
108
|
+
}
|
|
109
|
+
if (!requestImage) {
|
|
151
110
|
throw new Error(`No requestImage`);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return searchOffersForImage(requestImage.canvas);
|
|
155
111
|
}
|
|
156
|
-
)
|
|
157
|
-
);
|
|
158
112
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
},
|
|
170
|
-
]): Promise<AppAction> => {
|
|
171
|
-
if (action.type !== "REGION_CHANGED") {
|
|
113
|
+
return searchOffersForImage(requestImage.canvas);
|
|
114
|
+
})
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const startSearchOnRegionChange: EpicConf = (action$, state$) => action$.pipe(
|
|
118
|
+
ofType('REGION_CHANGED'),
|
|
119
|
+
debounceTime(1200),
|
|
120
|
+
withLatestFrom(state$),
|
|
121
|
+
switchMap(async ([action, { search: { requestImage}}]) : Promise<AppAction> => {
|
|
122
|
+
if (action.type !== 'REGION_CHANGED') {
|
|
172
123
|
throw new Error(`Wrong action type ${action.type}`);
|
|
173
|
-
|
|
174
|
-
|
|
124
|
+
}
|
|
125
|
+
if (!requestImage) {
|
|
175
126
|
throw new Error(`No requestImage`);
|
|
176
|
-
}
|
|
177
|
-
let { normalizedRect } = action;
|
|
178
|
-
return searchOffersForImage(requestImage.canvas, normalizedRect);
|
|
179
127
|
}
|
|
180
|
-
|
|
181
|
-
|
|
128
|
+
let { normalizedRect } = action;
|
|
129
|
+
return searchOffersForImage(requestImage.canvas, normalizedRect);
|
|
130
|
+
})
|
|
131
|
+
);
|
|
132
|
+
|
|
182
133
|
|
|
183
134
|
const startSearchOnFilterChange: EpicConf = (action$, state$) =>
|
|
184
135
|
action$.pipe(
|
package/src/epics/search.ts
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
isCadFile,
|
|
9
|
-
isImageFile,
|
|
10
|
-
Filter,
|
|
11
|
-
} from "@nyris/nyris-api";
|
|
12
|
-
import { imageLoaded, cadFileLoaded } from "../actions/searchActions";
|
|
1
|
+
import {EpicConf} from "./types";
|
|
2
|
+
import {combineEpics, ofType} from "redux-observable";
|
|
3
|
+
import {switchMap, withLatestFrom} from "rxjs/operators";
|
|
4
|
+
import {AppAction} from "../types";
|
|
5
|
+
import {ImageSearchOptions, urlOrBlobToCanvas, isCadFile, isImageFile, Filter} from "@nyris/nyris-api";
|
|
6
|
+
import {imageLoaded, cadFileLoaded} from "../actions/searchActions";
|
|
7
|
+
|
|
13
8
|
|
|
14
9
|
const imageSearch: EpicConf = (action$, state$, { api }) =>
|
|
15
10
|
action$.pipe(
|
|
@@ -22,7 +17,6 @@ const imageSearch: EpicConf = (action$, state$, { api }) =>
|
|
|
22
17
|
if ("image" in action) {
|
|
23
18
|
let { image, normalizedRect } = action;
|
|
24
19
|
|
|
25
|
-
// refactor this
|
|
26
20
|
let selectedFilters = new Array<Filter>();
|
|
27
21
|
if (state.search.selectedFilters.size > 0) {
|
|
28
22
|
state.search.selectedFilters.forEach((values, key) => {
|
|
@@ -40,51 +34,9 @@ const imageSearch: EpicConf = (action$, state$, { api }) =>
|
|
|
40
34
|
cropRect: normalizedRect,
|
|
41
35
|
};
|
|
42
36
|
|
|
43
|
-
try {
|
|
44
|
-
if (selectedFilters && selectedFilters.length > 0) {
|
|
45
|
-
console.log("With Filters");
|
|
46
|
-
const { results, duration, requestId, categoryPredictions, codes } =
|
|
47
|
-
await api.findByImageWithFilters(image, options, selectedFilters);
|
|
48
|
-
return {
|
|
49
|
-
type: "SEARCH_REQUEST_SUCCEED",
|
|
50
|
-
results,
|
|
51
|
-
requestId,
|
|
52
|
-
duration,
|
|
53
|
-
categoryPredictions,
|
|
54
|
-
codes,
|
|
55
|
-
};
|
|
56
|
-
} else {
|
|
57
|
-
console.log("Without Filters");
|
|
58
|
-
const { results, duration, requestId, categoryPredictions, codes } =
|
|
59
|
-
await api.findByImage(image, options);
|
|
60
|
-
return {
|
|
61
|
-
type: "SEARCH_REQUEST_SUCCEED",
|
|
62
|
-
results,
|
|
63
|
-
requestId,
|
|
64
|
-
duration,
|
|
65
|
-
categoryPredictions,
|
|
66
|
-
codes,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
} catch (e) {
|
|
70
|
-
console.warn("search failed", e);
|
|
71
|
-
return {
|
|
72
|
-
type: "SEARCH_REQUEST_FAIL",
|
|
73
|
-
reason: e.message,
|
|
74
|
-
exception: e,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if ("file" in action) {
|
|
80
|
-
console.log("file");
|
|
81
|
-
let { file } = action;
|
|
82
|
-
|
|
83
|
-
let options: ImageSearchOptions = {};
|
|
84
|
-
|
|
85
37
|
try {
|
|
86
38
|
const { results, duration, requestId, categoryPredictions, codes } =
|
|
87
|
-
await api.
|
|
39
|
+
await api.findByImage(image, options, selectedFilters);
|
|
88
40
|
return {
|
|
89
41
|
type: "SEARCH_REQUEST_SUCCEED",
|
|
90
42
|
results,
|
|
@@ -102,76 +54,86 @@ const imageSearch: EpicConf = (action$, state$, { api }) =>
|
|
|
102
54
|
};
|
|
103
55
|
}
|
|
104
56
|
}
|
|
105
|
-
|
|
57
|
+
|
|
58
|
+
if ('file' in action) {
|
|
59
|
+
let { file } = action;
|
|
60
|
+
|
|
61
|
+
let options : ImageSearchOptions = { };
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const {results, duration, requestId, categoryPredictions, codes} = await api.findByCad(file, options);
|
|
65
|
+
return ({ type: 'SEARCH_REQUEST_SUCCEED', results, requestId, duration, categoryPredictions, codes });
|
|
66
|
+
} catch (e) {
|
|
67
|
+
console.warn('search failed', e);
|
|
68
|
+
return ({ type: 'SEARCH_REQUEST_FAIL', reason: e.message, exception: e });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Wrong action content ${action}`);
|
|
72
|
+
|
|
106
73
|
})
|
|
107
74
|
);
|
|
108
75
|
|
|
109
|
-
const regionSearch: EpicConf = (action$, state$, {
|
|
110
|
-
|
|
111
|
-
ofType("REGION_REQUEST_START"),
|
|
76
|
+
const regionSearch: EpicConf = (action$, state$, {api}) => action$.pipe(
|
|
77
|
+
ofType('REGION_REQUEST_START'),
|
|
112
78
|
withLatestFrom(state$),
|
|
113
|
-
switchMap(async ([action, {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
79
|
+
switchMap(async ([action, {settings}]) : Promise<AppAction> => {
|
|
80
|
+
if (action.type !== 'REGION_REQUEST_START') {
|
|
81
|
+
throw new Error(`Wrong action type ${action.type}`);
|
|
82
|
+
}
|
|
117
83
|
|
|
118
|
-
|
|
84
|
+
let { image } = action;
|
|
119
85
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
86
|
+
try {
|
|
87
|
+
let regions = await api.findRegions(image);
|
|
88
|
+
return {type: 'REGION_REQUEST_SUCCEED', regions };
|
|
89
|
+
|
|
90
|
+
} catch (e) {
|
|
91
|
+
console.error(e);
|
|
92
|
+
return {type: 'REGION_REQUEST_FAIL', reason: e.message, exception: e};
|
|
93
|
+
}
|
|
127
94
|
})
|
|
128
|
-
|
|
95
|
+
);
|
|
129
96
|
|
|
130
|
-
const loadFile: EpicConf = (action$) =>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
throw new Error(`Wrong action type ${action.type}`);
|
|
136
|
-
}
|
|
137
|
-
const randomId = Math.random().toString();
|
|
138
|
-
if ("file" in action) {
|
|
139
|
-
const file = action.file;
|
|
140
|
-
if (isImageFile(file)) {
|
|
141
|
-
return imageLoaded(await urlOrBlobToCanvas(file), randomId);
|
|
97
|
+
const loadFile: EpicConf = (action$) => action$.pipe(
|
|
98
|
+
ofType('LOAD_FILE'),
|
|
99
|
+
switchMap(async (action) : Promise<AppAction> => {
|
|
100
|
+
if (action.type !== 'LOAD_FILE') {
|
|
101
|
+
throw new Error(`Wrong action type ${action.type}`);
|
|
142
102
|
}
|
|
143
|
-
|
|
144
|
-
|
|
103
|
+
const randomId = Math.random().toString();
|
|
104
|
+
if ('file' in action) {
|
|
105
|
+
const file = action.file;
|
|
106
|
+
if (isImageFile(file)) {
|
|
107
|
+
return imageLoaded(await urlOrBlobToCanvas(file), randomId);
|
|
108
|
+
}
|
|
109
|
+
if (isCadFile(file)) {
|
|
110
|
+
return cadFileLoaded(file, randomId);
|
|
111
|
+
}
|
|
145
112
|
}
|
|
146
|
-
|
|
147
|
-
throw new Error(
|
|
148
|
-
`LOAD_FILE action wrong properties ${Object.keys(action).join(",")}`
|
|
149
|
-
);
|
|
113
|
+
throw new Error(`LOAD_FILE action wrong properties ${Object.keys(action).join(',')}`);
|
|
150
114
|
})
|
|
151
|
-
|
|
115
|
+
);
|
|
152
116
|
|
|
153
|
-
const loadImage: EpicConf = (action$) =>
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
throw new Error(
|
|
171
|
-
`LOAD_IMAGE action wrong properties ${Object.keys(action).join(",")}`
|
|
172
|
-
);
|
|
117
|
+
const loadImage: EpicConf = (action$) => action$.pipe(
|
|
118
|
+
ofType('LOAD_IMAGE'),
|
|
119
|
+
switchMap(async (action) : Promise<AppAction> => {
|
|
120
|
+
if (action.type !== 'LOAD_IMAGE') {
|
|
121
|
+
throw new Error(`Wrong action type ${action.type}`);
|
|
122
|
+
}
|
|
123
|
+
const randomId = Math.random().toString();
|
|
124
|
+
if ('url' in action) {
|
|
125
|
+
return imageLoaded(await urlOrBlobToCanvas(action.url), randomId);
|
|
126
|
+
}
|
|
127
|
+
if ('file' in action) {
|
|
128
|
+
return imageLoaded(await urlOrBlobToCanvas(action.file), randomId);
|
|
129
|
+
}
|
|
130
|
+
if ('image' in action) {
|
|
131
|
+
return imageLoaded(action.image, randomId);
|
|
132
|
+
}
|
|
133
|
+
throw new Error(`LOAD_IMAGE action wrong properties ${Object.keys(action).join(',')}`);
|
|
173
134
|
})
|
|
174
|
-
|
|
135
|
+
);
|
|
136
|
+
|
|
175
137
|
|
|
176
138
|
const loadFilters: EpicConf = (action$, state$, { api }) =>
|
|
177
139
|
action$.pipe(
|
|
@@ -183,11 +145,7 @@ const loadFilters: EpicConf = (action$, state$, { api }) =>
|
|
|
183
145
|
}
|
|
184
146
|
try {
|
|
185
147
|
// use find filters
|
|
186
|
-
|
|
187
148
|
let filters = await api.getFilters();
|
|
188
|
-
|
|
189
|
-
filters = filters.slice(0, 3);
|
|
190
|
-
console.log(filters);
|
|
191
149
|
return { type: "LOAD_FILTERS_SUCCESS", filters };
|
|
192
150
|
} catch (e) {
|
|
193
151
|
console.error(e);
|
|
@@ -205,7 +163,6 @@ const searchFilters: EpicConf = (action$, state$, { api }) =>
|
|
|
205
163
|
throw new Error(`Wrong action type ${action.type}`);
|
|
206
164
|
}
|
|
207
165
|
try {
|
|
208
|
-
// use find filters
|
|
209
166
|
let { key, value } = action;
|
|
210
167
|
let values: string[] = [];
|
|
211
168
|
if (value) {
|