/ src / modules / Submit / Submit.reducer.js
Submit.reducer.js
  1  import submitInitialState from '../../common/data/submit'
  2  import reducerUtil from '../../common/utils/reducer'
  3  import {
  4    onReceiveTransactionInfoAction,
  5    checkTransactionStatusAction,
  6    onStartProgressAction,
  7    hideAction,
  8  } from '../TransactionStatus/TransactionStatus.reducer'
  9  import {
 10    TYPE_SUBMIT,
 11    TYPE_UPDATE,
 12  } from '../TransactionStatus/TransactionStatus.utilities'
 13  import { showAlertAction } from '../Alert/Alert.reducer'
 14  
 15  import BlockchainSDK from '../../common/blockchain'
 16  
 17  const SHOW_SUBMIT_AFTER_CHECK = 'SUBMIT_SHOW_SUBMIT_AFTER_CHECK'
 18  const CLOSE_SUBMIT = 'SUBMIT_CLOSE_SUBMIT'
 19  const ON_INPUT_EMAIL = 'SUBMIT_ON_INPUT_EMAIL'
 20  const ON_INPUT_NAME = 'SUBMIT_ON_INPUT_NAME'
 21  const ON_INPUT_DESC = 'SUBMIT_ON_INPUT_DESC'
 22  const ON_INPUT_URL = 'SUBMIT_ON_INPUT_URL'
 23  const ON_SELECT_CATEGORY = 'SUBMIT_ON_SELECT_CATEGORY'
 24  const ON_IMG_READ = 'SUBMIT_ON_IMG_READ'
 25  const ON_IMG_ZOOM = 'SUBMIT_ON_IMG_ZOOM'
 26  const ON_IMG_MOVE_CONTROL = 'SUBMIT_ON_IMG_MOVE_CONTROL'
 27  const ON_IMG_MOVE = 'SUBMIT_ON_IMG_MOVE'
 28  const ON_IMG_CANCEL = 'SUBMIT_ON_IMG_CANCEL'
 29  const ON_IMG_DONE = 'SUBMIT_ON_IMG_DONE'
 30  
 31  const SWITCH_TO_RATING = 'SUBMIT_SWITCH_TO_RATING'
 32  const ON_INPUT_SNT_VALUE = 'SUBMIT_ON_INPUT_SNT_VALUE'
 33  
 34  const showSubmitAfterCheckAction = dapp => {
 35    window.location.hash = 'submit'
 36    return {
 37      type: SHOW_SUBMIT_AFTER_CHECK,
 38      payload: dapp,
 39    }
 40  }
 41  
 42  export const showSubmitAction = dapp => {
 43    return (dispatch, getState) => {
 44      const state = getState()
 45      if (
 46        state.transactionStatus.progress &&
 47        state.transactionStatus.dappTx !== ''
 48      ) {
 49        dispatch(
 50          showAlertAction(
 51            'There is an active transaction. Please wait for it to finish and then you could be able to create your Ðapp',
 52          ),
 53        )
 54      } else if (dapp !== undefined) {
 55        // convert dapp's image from url ot base64
 56        const toDataUrl = (url, callback) => {
 57          const xhr = new XMLHttpRequest()
 58          xhr.onload = () => {
 59            const reader = new FileReader()
 60            reader.onloadend = () => {
 61              callback(reader.result)
 62            }
 63            reader.readAsDataURL(xhr.response)
 64          }
 65          xhr.open('GET', url)
 66          xhr.responseType = 'blob'
 67          xhr.send()
 68        }
 69        toDataUrl(dapp.image, base64 => {
 70          dapp.image = base64
 71          dispatch(showSubmitAfterCheckAction(dapp))
 72        })
 73      } else dispatch(showSubmitAfterCheckAction(dapp))
 74    }
 75  }
 76  
 77  export const closeSubmitAction = () => {
 78    window.history.back()
 79    return {
 80      type: CLOSE_SUBMIT,
 81      payload: null,
 82    }
 83  }
 84  
 85  export const onInputEmailAction = email => ({
 86    type: ON_INPUT_EMAIL,
 87    payload: email,
 88  })
 89  
 90  export const onInputNameAction = name => ({
 91    type: ON_INPUT_NAME,
 92    payload: name,
 93  })
 94  
 95  export const onInputDescAction = desc => ({
 96    type: ON_INPUT_DESC,
 97    payload: desc.substring(0, 140),
 98  })
 99  
100  export const onInputUrlAction = url => ({
101    type: ON_INPUT_URL,
102    payload: url,
103  })
104  
105  export const onSelectCategoryAction = category => ({
106    type: ON_SELECT_CATEGORY,
107    payload: category,
108  })
109  
110  export const onImgReadAction = imgBase64 => ({
111    type: ON_IMG_READ,
112    payload: imgBase64,
113  })
114  
115  export const onImgZoomAction = zoom => ({
116    type: ON_IMG_ZOOM,
117    payload: zoom,
118  })
119  
120  export const onImgMoveControlAction = move => ({
121    type: ON_IMG_MOVE_CONTROL,
122    payload: move,
123  })
124  
125  export const onImgMoveAction = (x, y) => ({
126    type: ON_IMG_MOVE,
127    payload: { x, y },
128  })
129  
130  export const onImgCancelAction = () => ({
131    type: ON_IMG_CANCEL,
132    payload: null,
133  })
134  
135  export const onImgDoneAction = imgBase64 => ({
136    type: ON_IMG_DONE,
137    payload: imgBase64,
138  })
139  
140  export const submitAction = (dapp, sntValue) => {
141    return async dispatch => {
142      dispatch(closeSubmitAction())
143      dispatch(
144        onStartProgressAction(
145          dapp.name,
146          dapp.image,
147          dapp.description,
148          TYPE_SUBMIT,
149        ),
150      )
151      try {
152        const blockchain = await BlockchainSDK.getInstance()
153        const { tx, id } = await blockchain.DiscoverService.createDApp(
154          sntValue,
155          {
156            name: dapp.name,
157            url: dapp.url,
158            description: dapp.description,
159            category: dapp.category,
160            image: dapp.image,
161            dateAdded: dapp.dateAdded,
162          },
163          dapp.email,
164        )
165        if (sntValue === '0') {
166          dispatch(checkTransactionStatusAction())
167          return
168        }
169        dispatch(onReceiveTransactionInfoAction(id, tx))
170        dispatch(checkTransactionStatusAction(tx, 'Published'))
171      } catch (e) {
172        dispatch(hideAction())
173        dispatch(showAlertAction(e.message))
174      }
175    }
176  }
177  
178  export const updateAction = (dappId, metadata, email) => {
179    return async dispatch => {
180      dispatch(closeSubmitAction())
181      dispatch(
182        onStartProgressAction(
183          metadata.name,
184          metadata.image,
185          metadata.description,
186          TYPE_UPDATE,
187        ),
188      )
189      try {
190        const blockchain = await BlockchainSDK.getInstance()
191        const tx = await blockchain.DiscoverService.setMetadata(
192          dappId,
193          {
194            name: metadata.name,
195            url: metadata.url,
196            description: metadata.description,
197            category: metadata.category,
198            image: metadata.image,
199            dateAdded: metadata.dateAdded,
200          },
201          metadata.email,
202        )
203        dispatch(onReceiveTransactionInfoAction(dappId, tx))
204        dispatch(checkTransactionStatusAction(tx, 'Updated'))
205      } catch (e) {
206        dispatch(hideAction())
207        dispatch(showAlertAction(e.message))
208      }
209    }
210  }
211  
212  export const switchToRatingAction = () => ({
213    type: SWITCH_TO_RATING,
214    paylaod: null,
215  })
216  
217  export const onInputSntValueAction = sntValue => ({
218    type: ON_INPUT_SNT_VALUE,
219    payload: sntValue,
220  })
221  
222  const showSubmitAfterCheck = (state, dapp) => {
223    return Object.assign({}, state, {
224      visible_submit: true,
225      visible_rating: false,
226      id: dapp !== undefined ? dapp.id : '',
227      email: dapp !== undefined ? dapp.email : '',
228      name: dapp !== undefined ? dapp.name : '',
229      desc: dapp !== undefined ? dapp.description : '',
230      url: dapp !== undefined ? dapp.url : '',
231      img: dapp !== undefined ? dapp.image : '',
232      category: dapp !== undefined ? dapp.category : '',
233      imgControl: false,
234      imgControlZoom: 0,
235      imgControlMove: false,
236      imgControlX: 0,
237      imgControlY: 0,
238      sntValue: '0',
239    })
240  }
241  
242  const closeSubmit = state => {
243    return Object.assign({}, state, {
244      visible: false,
245    })
246  }
247  
248  const onInputEmail = (state, email) => {
249    return Object.assign({}, state, {
250      email,
251    })
252  }
253  
254  const onInputName = (state, name) => {
255    return Object.assign({}, state, {
256      name,
257    })
258  }
259  
260  const onInputDesc = (state, desc) => {
261    return Object.assign({}, state, {
262      desc,
263    })
264  }
265  
266  const onInputUrl = (state, url) => {
267    return Object.assign({}, state, {
268      url,
269    })
270  }
271  
272  const onSelectCategory = (state, category) => {
273    return Object.assign({}, state, {
274      category,
275    })
276  }
277  
278  const onImgRead = (state, imgBase64) => {
279    return Object.assign({}, state, {
280      img: imgBase64,
281      imgControl: true,
282      imgControlZoom: 0,
283      imgControlMove: false,
284      imgControlX: 0,
285      imgControlY: 0,
286    })
287  }
288  
289  const onImgZoom = (state, zoom) => {
290    return Object.assign({}, state, {
291      imgControlZoom: zoom,
292    })
293  }
294  
295  const onImgMoveControl = (state, move) => {
296    return Object.assign({}, state, {
297      imgControlMove: move,
298    })
299  }
300  
301  const onImgMove = (state, payload) => {
302    return Object.assign({}, state, {
303      imgControlX: payload.x,
304      imgControlY: payload.y,
305    })
306  }
307  
308  const onImgCancel = state => {
309    return Object.assign({}, state, {
310      img: '',
311      imgControl: false,
312    })
313  }
314  
315  const onImgDone = (state, imgBase64) => {
316    return Object.assign({}, state, {
317      img: imgBase64,
318      imgControl: false,
319    })
320  }
321  
322  const switchToRating = state => {
323    return Object.assign({}, state, {
324      visible_submit: false,
325      visible_rating: true,
326    })
327  }
328  
329  const onInputSntValue = (state, sntValue) => {
330    return Object.assign({}, state, {
331      sntValue,
332    })
333  }
334  
335  const map = {
336    [SHOW_SUBMIT_AFTER_CHECK]: showSubmitAfterCheck,
337    [CLOSE_SUBMIT]: closeSubmit,
338    [ON_INPUT_EMAIL]: onInputEmail,
339    [ON_INPUT_NAME]: onInputName,
340    [ON_INPUT_DESC]: onInputDesc,
341    [ON_INPUT_URL]: onInputUrl,
342    [ON_SELECT_CATEGORY]: onSelectCategory,
343    [ON_IMG_READ]: onImgRead,
344    [ON_IMG_ZOOM]: onImgZoom,
345    [ON_IMG_MOVE_CONTROL]: onImgMoveControl,
346    [ON_IMG_MOVE]: onImgMove,
347    [ON_IMG_CANCEL]: onImgCancel,
348    [ON_IMG_DONE]: onImgDone,
349    [SWITCH_TO_RATING]: switchToRating,
350    [ON_INPUT_SNT_VALUE]: onInputSntValue,
351  }
352  
353  export default reducerUtil(map, submitInitialState)