@nyris/nyris-webapp 0.3.3 → 0.3.6

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.
Files changed (205) hide show
  1. package/build/asset-manifest.json +18 -32
  2. package/build/index.html +1 -1
  3. package/build/{precache-manifest.01ce682577e62add75aa397b2a944b75.js → precache-manifest.bffed513ca17d8ac16af1cc3aaa7d908.js} +13 -89
  4. package/build/service-worker.js +1 -1
  5. package/build/static/css/2.43a1c8b7.chunk.css +2 -0
  6. package/build/static/css/2.43a1c8b7.chunk.css.map +1 -0
  7. package/build/static/css/main.2a76dc8a.chunk.css +2 -0
  8. package/build/static/css/main.2a76dc8a.chunk.css.map +1 -0
  9. package/build/static/js/2.4e9a4ce1.chunk.js +3 -0
  10. package/build/static/js/2.4e9a4ce1.chunk.js.LICENSE.txt +79 -0
  11. package/build/static/js/2.4e9a4ce1.chunk.js.map +1 -0
  12. package/build/static/js/main.ec93aa4d.chunk.js +2 -0
  13. package/build/static/js/main.ec93aa4d.chunk.js.map +1 -0
  14. package/build/static/js/{runtime-main.b418ff16.js → runtime-main.f5553a9b.js} +1 -1
  15. package/build/static/js/{runtime-main.b418ff16.js.map → runtime-main.f5553a9b.js.map} +1 -1
  16. package/package.json +7 -30
  17. package/src/App.css +64 -20
  18. package/src/App.tsx +253 -19
  19. package/src/AppMD.tsx +320 -0
  20. package/src/Demo2.tsx +220 -0
  21. package/src/actions/nyrisAppActions.ts +76 -0
  22. package/src/actions/searchActions.ts +218 -0
  23. package/src/components/ExampleImages.tsx +17 -32
  24. package/src/components/Feedback.tsx +48 -87
  25. package/src/components/FiltersList.tsx +69 -0
  26. package/src/components/Header.tsx +17 -32
  27. package/src/components/Result.tsx +113 -186
  28. package/src/components/Sidebar.tsx +40 -0
  29. package/src/defaults.ts +3 -4
  30. package/src/{Store/epics → epics}/feedback.ts +0 -0
  31. package/src/epics/index.ts +154 -0
  32. package/src/epics/search.ts +203 -0
  33. package/src/{Store/epics → epics}/types.ts +1 -1
  34. package/src/{common/assets/fonts → fonts}/roboto-bold-webfont.woff +0 -0
  35. package/src/{common/assets/fonts → fonts}/roboto-bold-webfont.woff2 +0 -0
  36. package/src/{common/assets/fonts → fonts}/roboto-italic-webfont.woff +0 -0
  37. package/src/{common/assets/fonts → fonts}/roboto-italic-webfont.woff2 +0 -0
  38. package/src/{common/assets/fonts → fonts}/roboto-regular-webfont.woff +0 -0
  39. package/src/{common/assets/fonts → fonts}/roboto-regular-webfont.woff2 +0 -0
  40. package/src/{common/assets/fonts → fonts}/robotocondensed-bold-webfont.woff +0 -0
  41. package/src/{common/assets/fonts → fonts}/robotocondensed-bold-webfont.woff2 +0 -0
  42. package/src/{common/assets/fonts → fonts}/robotocondensed-bolditalic-webfont.woff +0 -0
  43. package/src/{common/assets/fonts → fonts}/robotocondensed-bolditalic-webfont.woff2 +0 -0
  44. package/src/{common/assets/images → images}/fav/android-icon-192x192.png +0 -0
  45. package/src/{common/assets/images → images}/fav/apple-icon-114x114.png +0 -0
  46. package/src/{common/assets/images → images}/fav/apple-icon-120x120.png +0 -0
  47. package/src/{common/assets/images → images}/fav/apple-icon-144x144.png +0 -0
  48. package/src/{common/assets/images → images}/fav/apple-icon-152x152.png +0 -0
  49. package/src/{common/assets/images → images}/fav/apple-icon-180x180.png +0 -0
  50. package/src/{common/assets/images → images}/fav/apple-icon-57x57.png +0 -0
  51. package/src/{common/assets/images → images}/fav/apple-icon-60x60.png +0 -0
  52. package/src/{common/assets/images → images}/fav/apple-icon-72x72.png +0 -0
  53. package/src/{common/assets/images → images}/fav/apple-icon-76x76.png +0 -0
  54. package/src/{common/assets/images → images}/fav/browserconfig.xml +0 -0
  55. package/src/{common/assets/images → images}/fav/favicon-16x16.png +0 -0
  56. package/src/{common/assets/images → images}/fav/favicon-32x32.png +0 -0
  57. package/src/{common/assets/images → images}/fav/favicon-96x96.png +0 -0
  58. package/src/{common/assets/images → images}/fav/manifest.json +0 -0
  59. package/src/{common/assets/images → images}/ic_cam.png +0 -0
  60. package/src/{common/assets/images → images}/ic_cam.svg +0 -0
  61. package/src/{common/assets/images → images}/ic_cam_large.png +0 -0
  62. package/src/{common/assets/images → images}/ic_cam_large.svg +0 -0
  63. package/src/{common/assets/images → images}/ic_cam_large_noimage.png +0 -0
  64. package/src/{common/assets/images → images}/ic_close_feedback.png +0 -0
  65. package/src/{common/assets/images → images}/ic_close_feedback.svg +0 -0
  66. package/src/{common/assets/images → images}/ic_shopNow.png +0 -0
  67. package/src/{common/assets/images → images}/ic_shopNow.svg +0 -0
  68. package/src/{common/assets/images → images}/ic_shopNowLight.png +0 -0
  69. package/src/{common/assets/images → images}/ic_shopNowLight.svg +0 -0
  70. package/src/{common/assets/images → images}/nyris_logo.png +0 -0
  71. package/src/{common/assets/images → images}/rewe.svg +0 -0
  72. package/src/{common/assets/images → images}/sectionTransBack.png +0 -0
  73. package/src/{common/assets/images → images}/sectionTransBack.svg +0 -0
  74. package/src/{common/assets/images → images}/sectionTransTop.png +0 -0
  75. package/src/{common/assets/images → images}/sectionTransTop.svg +0 -0
  76. package/src/index.css +416 -573
  77. package/src/index.tsx +190 -39
  78. package/src/types.ts +3 -43
  79. package/tsconfig.json +8 -3
  80. package/build/js/settings.example.js +0 -31
  81. package/build/js/test.js +0 -56
  82. package/build/static/css/2.8285176a.chunk.css +0 -2
  83. package/build/static/css/2.8285176a.chunk.css.map +0 -1
  84. package/build/static/css/main.6676fe1f.chunk.css +0 -2
  85. package/build/static/css/main.6676fe1f.chunk.css.map +0 -1
  86. package/build/static/js/2.d1562c08.chunk.js +0 -3
  87. package/build/static/js/2.d1562c08.chunk.js.LICENSE.txt +0 -133
  88. package/build/static/js/2.d1562c08.chunk.js.map +0 -1
  89. package/build/static/js/main.5c08aba4.chunk.js +0 -2
  90. package/build/static/js/main.5c08aba4.chunk.js.map +0 -1
  91. package/build/static/media/Fill.37094b44.svg +0 -3
  92. package/build/static/media/Montserrat-Bold.5a052e98.otf +0 -0
  93. package/build/static/media/Montserrat-Light.21789e89.otf +0 -0
  94. package/build/static/media/Montserrat-Medium.a53e0373.otf +0 -0
  95. package/build/static/media/Montserrat-Regular.71cdc681.otf +0 -0
  96. package/build/static/media/Montserrat-SemiBold.f613d915.otf +0 -0
  97. package/build/static/media/Rectangle.4dd8b747.png +0 -0
  98. package/build/static/media/admin.9529c7f6.svg +0 -3
  99. package/build/static/media/bg-support-page.6ac55268.svg +0 -9
  100. package/build/static/media/book_mark.8e294c0b.svg +0 -3
  101. package/build/static/media/icon_dislike.94607ca6.svg +0 -3
  102. package/build/static/media/icon_like.a4fb1b18.svg +0 -3
  103. package/build/static/media/icon_modal_image.3068d0ea.svg +0 -21
  104. package/build/static/media/icon_search_image.c2c728c0.svg +0 -3
  105. package/build/static/media/nyris_logo.22d8f250.svg +0 -3
  106. package/build/static/media/reload_icon.4b579a74.svg +0 -3
  107. package/build/static/media/save_search.bebaeebf.svg +0 -3
  108. package/build/static/media/support.289c3a3c.svg +0 -3
  109. package/build/static/media/translate_icon.f0492297.svg +0 -3
  110. package/public/js/settings.example.js +0 -31
  111. package/public/js/test.js +0 -56
  112. package/src/Router.tsx +0 -97
  113. package/src/Store/Auth.ts +0 -44
  114. package/src/Store/Nyris.ts +0 -77
  115. package/src/Store/Search.ts +0 -269
  116. package/src/Store/Store.ts +0 -46
  117. package/src/Store/common.d.ts +0 -10
  118. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-Bold.otf +0 -0
  119. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-Light.otf +0 -0
  120. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-Medium.otf +0 -0
  121. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-Regular.otf +0 -0
  122. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-SemiBold.otf +0 -0
  123. package/src/common/assets/icons/Fill.png +0 -0
  124. package/src/common/assets/icons/Fill.svg +0 -3
  125. package/src/common/assets/icons/Icon_wechat.png +0 -0
  126. package/src/common/assets/icons/Icon_whatsapp.png +0 -0
  127. package/src/common/assets/icons/admin.png +0 -0
  128. package/src/common/assets/icons/admin.svg +0 -3
  129. package/src/common/assets/icons/book_mark.png +0 -0
  130. package/src/common/assets/icons/book_mark.svg +0 -3
  131. package/src/common/assets/icons/icon_barcode.png +0 -0
  132. package/src/common/assets/icons/icon_camera.png +0 -0
  133. package/src/common/assets/icons/icon_dislike.svg +0 -3
  134. package/src/common/assets/icons/icon_disslike.png +0 -0
  135. package/src/common/assets/icons/icon_email.png +0 -0
  136. package/src/common/assets/icons/icon_like.png +0 -0
  137. package/src/common/assets/icons/icon_like.svg +0 -3
  138. package/src/common/assets/icons/icon_modal_image.png +0 -0
  139. package/src/common/assets/icons/icon_modal_image.svg +0 -21
  140. package/src/common/assets/icons/icon_picture.png +0 -0
  141. package/src/common/assets/icons/icon_search_image.png +0 -0
  142. package/src/common/assets/icons/icon_search_image.svg +0 -3
  143. package/src/common/assets/icons/nyris_logo.svg +0 -3
  144. package/src/common/assets/icons/reload_icon.png +0 -0
  145. package/src/common/assets/icons/reload_icon.svg +0 -3
  146. package/src/common/assets/icons/save_search.png +0 -0
  147. package/src/common/assets/icons/save_search.svg +0 -3
  148. package/src/common/assets/icons/setting_search_icon.png +0 -0
  149. package/src/common/assets/icons/support.png +0 -0
  150. package/src/common/assets/icons/support.svg +0 -3
  151. package/src/common/assets/icons/translate_icon.png +0 -0
  152. package/src/common/assets/icons/translate_icon.svg +0 -3
  153. package/src/common/assets/icons/view_off.png +0 -0
  154. package/src/common/assets/images/Rectangle.png +0 -0
  155. package/src/common/assets/images/bg-support-page.svg +0 -9
  156. package/src/common/assets/images/image_test.png +0 -0
  157. package/src/components/CustomHits/index.tsx +0 -57
  158. package/src/components/DetailItem.tsx +0 -175
  159. package/src/components/DragDropFile.tsx +0 -188
  160. package/src/components/FilterComponent.tsx +0 -33
  161. package/src/components/Footer.tsx +0 -29
  162. package/src/components/FooterMD.tsx +0 -54
  163. package/src/components/FooterNewVersion.tsx +0 -12
  164. package/src/components/FooterResult.tsx +0 -47
  165. package/src/components/HeaderMd.tsx +0 -39
  166. package/src/components/HeaderNewVersion.tsx +0 -92
  167. package/src/components/Layout.tsx +0 -46
  168. package/src/components/LoadingScreen/index.tsx +0 -29
  169. package/src/components/Navigation.tsx +0 -34
  170. package/src/components/Panigation/Pagination.tsx +0 -140
  171. package/src/components/Panigation/cx.js +0 -3
  172. package/src/components/Panigation/isModifierClick.js +0 -10
  173. package/src/components/Saved/AllItem.tsx +0 -32
  174. package/src/components/Saved/Category.tsx +0 -16
  175. package/src/components/carousel/DefaultCarousel.tsx +0 -48
  176. package/src/components/common.d.ts +0 -9
  177. package/src/components/common.scss +0 -54
  178. package/src/components/default-select.tsx +0 -44
  179. package/src/components/hitItem/hits.tsx +0 -50
  180. package/src/components/hitItem/infinitiHits.tsx +0 -33
  181. package/src/components/input/inputSearch.tsx +0 -77
  182. package/src/components/modal/DefaultModal.tsx +0 -28
  183. package/src/components/preview/preview.tsx +0 -433
  184. package/src/components/results/ItemResult.tsx +0 -155
  185. package/src/components/search/ListSearch.tsx +0 -209
  186. package/src/modules/LandingPage/common.scss +0 -1304
  187. package/src/modules/LandingPage/indexApp.tsx +0 -492
  188. package/src/modules/LandingPage/indexAppMD.tsx +0 -501
  189. package/src/modules/LandingPage/indexNewVersion.tsx +0 -117
  190. package/src/page/Auth/login.tsx +0 -7
  191. package/src/page/Exception/404.tsx +0 -11
  192. package/src/page/History/index.tsx +0 -76
  193. package/src/page/Profile/index.tsx +0 -87
  194. package/src/page/Saved/MockData.ts +0 -223
  195. package/src/page/Saved/index.tsx +0 -166
  196. package/src/page/Support/index.tsx +0 -160
  197. package/src/page/result/MockData.ts +0 -36
  198. package/src/page/result/index.tsx +0 -473
  199. package/src/services/Feedback.ts +0 -65
  200. package/src/services/findByImage.ts +0 -24
  201. package/src/services/findRegionsCustom.ts +0 -212
  202. package/src/services/image.ts +0 -110
  203. package/src/services/nyris.ts +0 -123
  204. package/src/services/session.ts +0 -20
  205. package/src/services/types.ts +0 -96
package/src/AppMD.tsx ADDED
@@ -0,0 +1,320 @@
1
+ import {AppProps} from "./App";
2
+ import {useDropzone} from "react-dropzone";
3
+ import {
4
+ makeStyles,
5
+ AppBar,
6
+ Button, Card, CardActions, CardContent,
7
+ CardMedia, CircularProgress,
8
+ Container,
9
+ CssBaseline, Fab,
10
+ Grid, Hidden,
11
+ Link,
12
+ Toolbar,
13
+ Typography
14
+ } from "@material-ui/core";
15
+ import {PhotoCamera, ArrowBack, Image} from "@material-ui/icons";
16
+ import Icon from "@material-ui/core/Icon";
17
+ import * as React from "react";
18
+ import {NodeGroup} from "react-move";
19
+ import classNames from 'classnames';
20
+ import {Capture, Preview} from "@nyris/nyris-react-components";
21
+ import {cadExtensions} from "@nyris/nyris-api";
22
+
23
+
24
+ const useStyles = makeStyles(theme => ({
25
+ icon: {
26
+ marginRight: theme.spacing(2),
27
+ },
28
+ heroContent: {
29
+ backgroundColor: theme.palette.background.paper,
30
+ padding: theme.spacing(8, 0, 6),
31
+ transition: 'all 300ms',
32
+ overflow: 'hidden',
33
+ height: 500
34
+ },
35
+ heroContentClosed: {
36
+ height: 0,
37
+ padding: 0
38
+ },
39
+ heroButtons: {
40
+ marginTop: theme.spacing(4),
41
+ },
42
+ cardGrid: {
43
+ paddingTop: theme.spacing(8),
44
+ paddingBottom: theme.spacing(8),
45
+ minHeight: 600,
46
+ overflow: 'hidden',
47
+ transition: 'all 300ms',
48
+ },
49
+ cardGridCollapsed: {
50
+ height: 0,
51
+ opacity: 0,
52
+ minHeight: 0,
53
+ paddingTop: 0,
54
+ paddingBottom: 0,
55
+ },
56
+ card: {
57
+ height: '100%',
58
+ display: 'flex',
59
+ flexDirection: 'column',
60
+ },
61
+ cardMedia: {
62
+ paddingTop: '56.25%', // 16:9
63
+ backgroundSize: 'contain'
64
+ },
65
+ cardContent: {
66
+ flexGrow: 1,
67
+ paddingBottom: 0
68
+ },
69
+ footer: {
70
+ backgroundColor: theme.palette.background.paper,
71
+ padding: theme.spacing(6),
72
+ },
73
+ withElipsis: {
74
+ textOverflow: 'ellipsis',
75
+ overflow: 'hidden',
76
+ whiteSpace: 'nowrap'
77
+ },
78
+ loading: {
79
+ margin: theme.spacing(2),
80
+ },
81
+ fabContainer: {
82
+ position: 'fixed',
83
+ bottom: theme.spacing(2),
84
+
85
+ },
86
+ fab: {
87
+ marginLeft: theme.spacing(2),
88
+ },
89
+ }));
90
+
91
+ const makeFileHandler = (action: any) => (e: any) => {
92
+ let file = (e.dataTransfer && e.dataTransfer.files[0]) || e.target.files[0];
93
+ if (e.target && e.target.value) {
94
+ e.target.value = "";
95
+ }
96
+
97
+ if (file) {
98
+ action(file);
99
+ }
100
+ };
101
+
102
+ function Copyright() {
103
+ return (
104
+
105
+ <Typography variant="body2" color="textSecondary" align="center">
106
+ {'Powered by '}
107
+ <Link color="inherit" href="https://nyris.io/" component='a' target="_blank">
108
+ nyris.io
109
+ </Link>
110
+ </Typography>
111
+ );
112
+ }
113
+
114
+
115
+ const AppMD: React.FC<AppProps> = ({settings, handlers, showPart, previewImage, loading, search: {results, regions, previewSelection, requestId, duration}, mdSettings}) => {
116
+ const classes = useStyles();
117
+ const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop: (fs: File[]) => handlers.onFileDropped(fs[0])});
118
+
119
+ const minPreviewHeight = 400;
120
+ const halfOfTheScreenHeight = Math.floor(window.innerHeight * 0.45);
121
+ const maxPreviewHeight = Math.max(minPreviewHeight, halfOfTheScreenHeight);
122
+ const acceptTypes =
123
+ [ 'image/*' ].concat(
124
+ settings.cadSearch ? cadExtensions : []
125
+ ).join(',');
126
+
127
+ return (
128
+ <React.Fragment>
129
+ {mdSettings.resultLinkIcon && <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />}
130
+ <CssBaseline/>
131
+ {showPart === 'camera' &&
132
+ <Capture onCaptureComplete={handlers.onCaptureComplete} onCaptureCanceled={handlers.onCaptureCanceled}
133
+ useAppText='Use default camera app'/>}
134
+ <AppBar position={"relative"} style={{backgroundColor: mdSettings.appBarCustomBackgroundColor}}>
135
+
136
+ <Container maxWidth='md' style={{flexDirection: 'row', display: 'flex'}}>
137
+ <img src={mdSettings.appBarLogoUrl} style={{height: '2em', minHeight: '64px', display: 'flex'}} alt="Logo"/>
138
+ <Toolbar component="span">
139
+ <Typography style={{color: mdSettings.appBarCustomTextColor}}>
140
+ { mdSettings.appBarTitle }
141
+ </Typography>
142
+ </Toolbar>
143
+ </Container>
144
+ </AppBar>
145
+
146
+ <main>
147
+ <div
148
+ className={classNames(classes.heroContent, showPart === 'results' ? classes.heroContentClosed : null)}>
149
+ <Container maxWidth='md'>
150
+ <div>
151
+ <Hidden mdUp>
152
+ <div style={{textAlign: 'center'}}>
153
+ <PhotoCamera style={{fontSize: '20em', color: '#cccccc'}}/>
154
+ </div>
155
+ <div style={{textAlign: 'center'}}>
156
+ <Button variant={"contained"} color={"primary"} onClick={handlers.onCameraClick}>Take
157
+ a
158
+ picture</Button>
159
+ </div>
160
+ <div style={{textAlign: 'center'}}>
161
+ <Typography>
162
+ or
163
+ </Typography>
164
+ </div>
165
+ <div style={{textAlign: 'center'}}>
166
+ <input
167
+ accept={acceptTypes}
168
+ id="raised-button-file"
169
+ type="file"
170
+ onChange={makeFileHandler(handlers.onSelectFile)}
171
+ style={{width: '.1px', height: '.1px', overflow: 'hidden', opacity: 0}}
172
+ />
173
+ <label htmlFor="raised-button-file">
174
+ <Button variant={"contained"} color={"primary"} component="span">
175
+ Select a file
176
+ </Button>
177
+ </label>
178
+ </div>
179
+ </Hidden>
180
+ <Hidden smDown>
181
+ <div style={{borderStyle: 'dashed', borderWidth: 5, borderColor: isDragActive ? '#ccc' : '#eee', borderRadius: 10, padding: 10, paddingBottom: 30}}
182
+ {...getRootProps({ onClick: e => { e.stopPropagation() }}) }>
183
+ <div style={{textAlign: 'center'}}>
184
+ <Image style={{fontSize: '20em', color: '#cccccc'}}/>
185
+ </div>
186
+ <div style={{textAlign: 'center'}}>
187
+ <Typography variant='body2'>
188
+ DROP AN IMAGE
189
+ </Typography>
190
+ </div>
191
+ <div style={{textAlign: 'center'}}>
192
+ <Typography variant="subtitle2">
193
+ or
194
+ </Typography>
195
+ </div>
196
+ <div style={{textAlign: 'center'}}>
197
+ <input
198
+ accept={acceptTypes}
199
+ id="raised-button-file"
200
+ type="file"
201
+ {...getInputProps()}
202
+ onChange={makeFileHandler(handlers.onSelectFile)}
203
+ style={{width: '.1px', height: '.1px', overflow: 'hidden', opacity: 0}}
204
+ />
205
+ <label htmlFor="raised-button-file">
206
+ <Button variant={"contained"} color={"primary"} component="span">
207
+ Select an image
208
+ </Button>
209
+ </label>
210
+ </div>
211
+ </div>
212
+ </Hidden>
213
+ </div>
214
+ </Container>
215
+ </div>
216
+ <Container className={classNames(classes.cardGrid, showPart !== 'results' && classes.cardGridCollapsed)}
217
+ maxWidth="md">
218
+
219
+ { previewImage &&
220
+ <Card style={{marginBottom: '4em'}} raised={true}>
221
+ <Preview key={previewImage.id}
222
+ maxWidth={document.body.clientWidth}
223
+ maxHeight={maxPreviewHeight}
224
+ dotColor={mdSettings.primaryColor}
225
+ onSelectionChange={handlers.onSelectionChange} regions={regions}
226
+ selection={previewSelection} image={previewImage.canvas}/>
227
+ </Card>
228
+ }
229
+
230
+ {loading && <div style={{textAlign: 'center'}}>
231
+ <CircularProgress className={classes.loading}/>
232
+ </div>}
233
+
234
+ <Grid container spacing={4}>
235
+ <NodeGroup data={results}
236
+ keyAccessor={r => r.position + r.sku}
237
+ start={(r, i) => ({opacity: 0, translateX: -100})}
238
+ enter={(r, i) => ({
239
+ opacity: [1],
240
+ translateX: [0],
241
+ timing: {delay: i * 100, duration: 300}
242
+ })}>
243
+ {rs =>
244
+ <>
245
+ {rs.map(({key, data: result, state}) =>
246
+ <Grid item key={key} xs={12} sm={4} md={3}>
247
+ <Card className={classes.card} style={{
248
+ opacity: state.opacity,
249
+ position: 'relative',
250
+ transform: `translateX(${state.translateX}%)`
251
+ }}>
252
+ <CardMedia
253
+ className={classes.cardMedia}
254
+ image={(result.img && result.img.url) || settings.noImageUrl}
255
+ title={result.title}
256
+ />
257
+ <CardContent className={classes.cardContent}>
258
+ <Typography gutterBottom variant="subtitle2" component="h5"
259
+ className={classes.withElipsis}>
260
+ {result[mdSettings.resultFirstRowProperty]}
261
+ </Typography>
262
+ <Typography variant="body2" className={classes.withElipsis}>
263
+ {result[mdSettings.resultSecondRowProperty]}
264
+ </Typography>
265
+ </CardContent>
266
+ {result.l &&
267
+ <CardActions>
268
+ <Button variant="outlined" style={{marginLeft: 'auto'}}
269
+ size="small" color="primary"
270
+ onClick={() => handlers.onLinkClick(result.position, result.l)}
271
+ onAuxClick={() => handlers.onLinkClick(result.position, result.l)} >
272
+ { mdSettings.resultLinkIcon && <React.Fragment>
273
+ <Icon>{ mdSettings.resultLinkIcon }</Icon>
274
+ {' '}
275
+ </React.Fragment> }
276
+ {mdSettings.resultLinkText}
277
+ </Button>
278
+ </CardActions>
279
+ }
280
+ </Card>
281
+ </Grid>
282
+ )}
283
+ </>
284
+ }
285
+
286
+ </NodeGroup>
287
+
288
+ </Grid>
289
+
290
+ {results.length === 0 && showPart === 'results' && !loading && (
291
+ <Typography variant="h3" align="center">We did not find anything</Typography>
292
+ )}
293
+
294
+
295
+ </Container>
296
+ {showPart !== 'start' &&
297
+ <Container maxWidth='lg'>
298
+ <div className={classes.fabContainer}>
299
+ <Fab aria-label='back' className={classes.fab} color='primary' onClick={handlers.onShowStart}>
300
+ <ArrowBack/>
301
+ </Fab>
302
+ </div>
303
+ </Container>
304
+ }
305
+
306
+ </main>
307
+
308
+ <footer className={classes.footer}>
309
+
310
+ <Typography variant="subtitle1" align="center" color="textSecondary">
311
+ {requestId && showPart === 'results' && <div style={{textAlign: 'center', fontSize: '0.7em', paddingTop: '0.8em'}}>Request
312
+ identifier {requestId}</div>}
313
+ </Typography>
314
+ <Copyright/>
315
+ </footer>
316
+ </React.Fragment>
317
+ );
318
+ };
319
+
320
+ export default AppMD;
package/src/Demo2.tsx ADDED
@@ -0,0 +1,220 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { useDispatch } from "react-redux";
3
+ import { Animate, NodeGroup } from "react-move";
4
+ import { useDropzone} from "react-dropzone";
5
+ import {
6
+ Box,
7
+ Snackbar
8
+ } from "@material-ui/core";
9
+ import { Alert } from "@material-ui/lab";
10
+ import classNames from "classnames";
11
+ import { loadFilters } from "./actions/searchActions";
12
+ import {AppProps} from "./App";
13
+ import Result from "./components/Result";
14
+ import Sidebar from "./components/Sidebar";
15
+ import Header from "./components/Header";
16
+ import Feedback from "./components/Feedback";
17
+ import CategoryFilter from "./components/CategoryFilter";
18
+ import Codes from "./components/Codes";
19
+ import PredictedCategories from "./components/PredictedCategories";
20
+ import ExampleImages from "./components/ExampleImages";
21
+ import {makeFileHandler, Capture, Preview} from "@nyris/nyris-react-components";
22
+ import { RectCoords, cadExtensions} from "@nyris/nyris-api";
23
+
24
+ export interface AppHandlers {
25
+ onExampleImageClick: (url: string) => void,
26
+ onImageClick: (position: number, url: string) => void,
27
+ onLinkClick: (position: number, url: string) => void,
28
+ onFileDropped: (file: File) => void,
29
+ onCaptureComplete: (image: HTMLCanvasElement) => void,
30
+ onCaptureCanceled: () => void,
31
+ onSelectFile: (f: File) => void,
32
+ onCameraClick: () => void,
33
+ onShowStart: () => void,
34
+ onSelectionChange: (r: RectCoords) => void,
35
+ onPositiveFeedback: () => void,
36
+ onNegativeFeedback: () => void,
37
+ onCloseFeedback: () => void
38
+ }
39
+
40
+ const Demo2: React.FC<AppProps> = ({
41
+ search: {results, regions, previewSelection, requestId, duration, errorMessage, filterOptions, categoryPredictions, codes, toastErrorMessage, filters},
42
+ showPart, settings, handlers, loading, previewImage, feedbackState
43
+ }) => {
44
+
45
+ const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop: (fs: File[]) => handlers.onFileDropped(fs[0])});
46
+
47
+ const minPreviewHeight = 400;
48
+ const halfOfTheScreenHeight = Math.floor(window.innerHeight * 0.45);
49
+ const maxPreviewHeight = Math.max(minPreviewHeight, halfOfTheScreenHeight);
50
+ const [toastOpen, setToastOpen] = useState(false);
51
+ const dispatch = useDispatch();
52
+
53
+ const acceptTypes =[ 'image/*' ].concat( settings.cadSearch ? cadExtensions : [] ).join(',');
54
+
55
+
56
+ useEffect(() => {
57
+ if (toastErrorMessage !== '') {
58
+ setToastOpen(true);
59
+ }
60
+ }, [toastErrorMessage])
61
+
62
+ useEffect(() =>{
63
+ dispatch(loadFilters());
64
+ }, [dispatch])
65
+
66
+ return (
67
+ <React.Fragment>
68
+ <Header/>
69
+ <div className="wrapperBody">
70
+ <Sidebar filters={filters}/>
71
+
72
+ <div className="mainContent">
73
+ {showPart === 'camera' &&
74
+ <Capture onCaptureComplete={handlers.onCaptureComplete} onCaptureCanceled={handlers.onCaptureCanceled}
75
+ useAppText='Use default camera app'/>}
76
+
77
+
78
+ <div className={classNames('headSection', {hidden: showPart === 'results'})} id="headSection">
79
+ <div {...getRootProps({
80
+ onClick: e => {
81
+ e.stopPropagation();
82
+ }
83
+ })} className={classNames('wrapper', 'dragAndDropActionArea', {'fileIsHover': isDragActive})}>
84
+
85
+ <div className={classNames('contentWrap')}>
86
+ <Box display="flex" flexDirection="column" justifyContent="center" alignItems="center" minHeight="100vh">
87
+ <section className="uploadImage">
88
+ <input type="button" name="file" id="capture" className="inputfile" accept="image/*"
89
+ capture="environment" onClick={handlers.onCameraClick}/>
90
+ <input type="file" name="file" id="capture_file" className="inputfile" accept={acceptTypes}
91
+ capture="environment"/>
92
+ <input {...getInputProps()} type="file" name="file" id="select_file" className="inputfile"
93
+ accept={acceptTypes}
94
+ onChange={makeFileHandler(handlers.onSelectFile)}
95
+ />
96
+ <div className="onDesktop">
97
+ Drop an image
98
+ <div className="smallText">or</div>
99
+ </div>
100
+ <div className="onMobile camIcon">
101
+ <img src="./images/ic_cam_large.svg" alt="Camera"/>
102
+ </div>
103
+ <label htmlFor="capture" className="btn primary onMobile"
104
+ style={{marginBottom: '2em', width: '22em'}}>
105
+ <span className="onMobile">Take a picture</span>
106
+ </label>
107
+ <br/>
108
+ <label htmlFor="select_file" className="btn primary" style={{width: '22em'}}>
109
+ <span>Select a file</span>
110
+ </label>
111
+ <label htmlFor="capture" className="mobileUploadHandler onMobile"/>
112
+ </section>
113
+ <ExampleImages images={settings.exampleImages} onExampleImageClicked={handlers.onExampleImageClick}/>
114
+
115
+ </Box>
116
+ </div>
117
+ </div>
118
+
119
+ <div className="headerSeparatorTop"/>
120
+ <div className="headerSeparatorBack"/>
121
+ <div className={classNames('tryDifferent', {hidden: showPart !== 'results'})}
122
+ onClick={handlers.onShowStart}>
123
+ <div className="icIcon">
124
+ </div>
125
+ <div className="textDesc"> Try a different image</div>
126
+ <br style={{clear: 'both'}}/>
127
+ </div>
128
+ </div>
129
+
130
+ <section className={classNames({hideResults: showPart !== 'results'},'results', {resultsActive: showPart === 'results'}, (results.length === 1 ? 'singleProduct' : 'multipleProducts'))}>
131
+ {errorMessage &&
132
+ <div className="errorMsg">
133
+ {errorMessage}
134
+ <div style={{textAlign: 'center', fontSize: '0ß.7em', paddingTop: '0.8em'}}><span>Make sure to include the request ID when reporting a problem: {requestId}</span>
135
+ </div>
136
+ </div>
137
+ }
138
+ <Animate show={loading} start={{opacity: 0.0}} enter={{opacity: [1.0], timing: {duration: 300}}}
139
+ leave={{opacity: [0.0], timing: {duration: 300}}}>
140
+ {s =>
141
+ <div className="loadingOverlay" style={{...s}}>
142
+ <div className="loading"/>
143
+ </div>
144
+ }
145
+ </Animate>
146
+ {settings.preview && previewImage &&
147
+ <div className="preview">
148
+ <Preview key={previewImage.id}
149
+ maxWidth={document.body.clientWidth} maxHeight={maxPreviewHeight}
150
+ dotColor="#4C8F9F"
151
+ onSelectionChange={handlers.onSelectionChange} regions={regions}
152
+ selection={previewSelection} image={previewImage.canvas}/>
153
+ </div>
154
+ }
155
+ <div className="predicted-categories">
156
+ <PredictedCategories cs={categoryPredictions}/>
157
+ </div>
158
+ <div className="predicted-categories">
159
+ <Codes codes={codes}/>
160
+ </div>
161
+ <CategoryFilter cats={filterOptions}/>
162
+
163
+ <div className="wrapper">
164
+ <NodeGroup data={results}
165
+ keyAccessor={r => r.sku}
166
+ start={(r, i) => ({opacity: 0, translateX: -100})}
167
+ enter={(r, i) => ({
168
+ opacity: [1],
169
+ translateX: [0],
170
+ timing: {delay: i * 100, duration: 300}
171
+ })}
172
+ >
173
+ {rs => <>{rs.map(({key, data, state}) => <Result
174
+ key={key}
175
+ noImageUrl={settings.noImageUrl}
176
+ template={settings.resultTemplate}
177
+ onImageClick={handlers.onImageClick}
178
+ onLinkClick={handlers.onLinkClick}
179
+ result={data}
180
+ style={{opacity: state.opacity, transform: `translateX(${state.translateX}%)`}}/>)}</>}
181
+ </NodeGroup>
182
+
183
+ {results.length === 0 && showPart === 'results' && !loading && (
184
+
185
+ <div className="noResults">We did not find anything <span role="img"
186
+ aria-label="sad face">😕</span></div>
187
+ )}
188
+
189
+ <br style={{clear: 'both'}}/>
190
+
191
+ {duration && showPart === 'results' && (<div style={{textAlign: 'center', fontSize: '0.7em', paddingTop: '0.8em'}}>Search
192
+ took {duration.toFixed(2)} seconds</div>)}
193
+
194
+ {requestId && showPart === 'results' && <div style={{textAlign: 'center', fontSize: '0.7em', paddingTop: '0.8em'}}>Request
195
+ identifier {requestId}</div>}
196
+ </div>
197
+ </section>
198
+
199
+ <Snackbar open={toastOpen} autoHideDuration={3000} onClose={() => setToastOpen(false)}>
200
+ <Alert onClose={() => setToastOpen(false)} severity="error">
201
+ {toastErrorMessage}
202
+ </Alert>
203
+ </Snackbar>
204
+
205
+ </div>
206
+ </div>
207
+ <section className="footnote">
208
+ <div className="wrapper">
209
+ © 2017 - 2019 <a href="https://nyris.io">nyris GmbH</a> - All rights reserved - <a
210
+ href="https://nyris.io/imprint/">Imprint</a>
211
+ </div>
212
+ </section>
213
+ <Feedback feedbackState={feedbackState} onPositiveFeedback={handlers.onPositiveFeedback}
214
+ onNegativeFeedback={handlers.onNegativeFeedback} onClose={handlers.onCloseFeedback}/>
215
+
216
+ </React.Fragment>
217
+ );
218
+ }
219
+
220
+ export default Demo2;
@@ -0,0 +1,76 @@
1
+ import {AppAction} from "../types";
2
+
3
+
4
+ export type NyrisAppPart = 'start' | 'camera' | 'results';
5
+ export type NyrisFeedbackState = 'hidden' | 'question' | 'positive' | 'negative';
6
+
7
+
8
+ export interface NyrisAppState {
9
+ showPart: NyrisAppPart,
10
+ feedbackState: NyrisFeedbackState
11
+ }
12
+
13
+ export type NyrisAction =
14
+ | { type: 'SHOW_START' }
15
+ | { type: 'SHOW_CAMERA' }
16
+ | { type: 'SHOW_RESULTS' }
17
+ | { type: 'SHOW_FEEDBACK' }
18
+ | { type: 'HIDE_FEEDBACK' }
19
+ | { type: 'RESULT_LINK_CLICKED', position: number, url: string}
20
+ | { type: 'RESULT_IMAGE_CLICKED', position: number, url: string}
21
+
22
+
23
+ export const showCamera = () :NyrisAction => ({type: 'SHOW_CAMERA'});
24
+ export const showStart = () :NyrisAction => ({type: 'SHOW_START'});
25
+ export const showResults = () :NyrisAction => ({type: 'SHOW_RESULTS'});
26
+ export const showFeedback = () :NyrisAction => ({type: 'SHOW_FEEDBACK'});
27
+ export const hideFeedback = () :NyrisAction => ({type: 'HIDE_FEEDBACK'});
28
+
29
+ const initialNyrisState : NyrisAppState = {
30
+ showPart: 'start',
31
+ feedbackState: 'hidden'
32
+ };
33
+
34
+ export function reducer(state : NyrisAppState = initialNyrisState, action: AppAction) : NyrisAppState {
35
+ switch (action.type) {
36
+ case 'SHOW_START':
37
+ return {
38
+ ...state,
39
+ showPart: 'start'
40
+ };
41
+ case 'SHOW_CAMERA':
42
+ return {
43
+ ...state,
44
+ showPart: 'camera'
45
+ };
46
+ case 'SEARCH_REQUEST_START':
47
+ case 'REGION_REQUEST_START':
48
+ case 'SHOW_RESULTS':
49
+ return {
50
+ ...state,
51
+ showPart: 'results'
52
+ };
53
+ case 'SHOW_FEEDBACK':
54
+ return {
55
+ ...state,
56
+ feedbackState: 'question'
57
+ };
58
+ case 'HIDE_FEEDBACK':
59
+ return {
60
+ ...state,
61
+ feedbackState: 'hidden'
62
+ };
63
+ case 'FEEDBACK_SUBMIT_POSITIVE':
64
+ return {
65
+ ...state,
66
+ feedbackState: 'positive'
67
+ };
68
+ case 'FEEDBACK_SUBMIT_NEGATIVE':
69
+ return {
70
+ ...state,
71
+ feedbackState: 'negative'
72
+ };
73
+ default:
74
+ return state;
75
+ }
76
+ }