diff --git a/package.json b/package.json index 422e85b..e94eacd 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "lint": "eslint ." }, "dependencies": { + "axios": "^0.19.2", "babel-preset-react-native": "^4.0.1", "native-base": "^2.13.8", "node-fetch": "^2.6.0", @@ -21,7 +22,10 @@ "redux": "^4.0.5", "redux-devtools-extension": "^2.13.8", "redux-thunk": "^2.3.0", - "remote-redux-devtools": "^0.5.16" + "remote-redux-devtools": "^0.5.16", + "unirest": "^0.6.0", + "urban-dictionary": "^2.2.1", + "urban-dictionary-client": "^3.0.1" }, "devDependencies": { "@babel/core": "^7.8.7", diff --git a/src/actions/api/dictionary.js b/src/actions/api/dictionary.js index e69de29..dfcb92e 100644 --- a/src/actions/api/dictionary.js +++ b/src/actions/api/dictionary.js @@ -0,0 +1,57 @@ +import {search} from 'urban-dictionary-client'; +import {SET_AVAILABLE_API} from '../../constants/api-constants'; +const fetch = require('node-fetch'); + +async function getResFromWordsAPI(word) { + const req = await fetch(`https://wordsapiv1.p.rapidapi.com/words/${word}`, { + method: 'GET', + headers: { + 'x-rapidapi-host': 'wordsapiv1.p.rapidapi.com', + 'x-rapidapi-key': 'e08b0f617cmsh74abbf9a3b01eb0p164f22jsnabea29750b15', + }, + }); + const json = await req.json(); + const res = {...json, source: 'wordsAPI'}; + if (res.success === false) { + // throw new Error(res.message); + return false; + } + return Promise.resolve(res); +} + +async function getResFromUrbanDictionary(word) { + const res = await search(word); + if (res.list.length === 0) { + // throw new Error('nothing was found'); + return false; + } + return Promise.resolve({...res, word, source: 'urbanDictionary'}); +} + +const getAvailableApi = (apiArray = []) => { + for (const api of apiArray) { + if (api) { + return api; + } + } + return false; +}; + +const setAvailableApi = api => ({ + type: SET_AVAILABLE_API, + payload: api, +}); +export const wordInfo = word => async dispatch => { + try { + const api1 = await getResFromWordsAPI(word); + const api2 = await getResFromUrbanDictionary(word); + const availableApi = getAvailableApi([api1, api2]); + console.log(availableApi); + if (availableApi === false) { + throw new Error('word not found'); + } + await dispatch(setAvailableApi(availableApi)); + } catch (e) { + console.log(e); + } +}; diff --git a/src/actions/api/urban-dictionary.js b/src/actions/api/urban-dictionary.js new file mode 100644 index 0000000..e69de29 diff --git a/src/actions/api/words-api.js b/src/actions/api/words-api.js new file mode 100644 index 0000000..e69de29 diff --git a/src/actions/api/yandex-dictionary.js b/src/actions/api/yandex-dictionary.js index e4334a2..6ca95f9 100644 --- a/src/actions/api/yandex-dictionary.js +++ b/src/actions/api/yandex-dictionary.js @@ -1,39 +1,39 @@ import fetch from 'node-fetch'; +import {SET_YANDEX_DICTIONARY_RESPONSE} from '../../constants/api-constants'; const yKey = - 'dict.1.1.20200313T141325Z.a8dfc0a8b66fb54c.f84fd712f759aa3abd7a7ecac35ac608181e2865'; + 'dict.1.1.20200313T141325Z.a8dfc0a8b66fb54c.f84fd712f759aa3abd7a7ecac35ac608181e2865'; const yDictionary = ( - word = String, - languages = 'en-ru', - apiKey = yKey, + word = String, + languages = 'en-ru', + apiKey = yKey, ) => async dispatch => { - try { - const res = await fetch( - `https://dictionary.yandex.net/api/v1/dicservice.json/lookup?key=${apiKey}&lang=${languages}&text=${word}`, { method: 'GET' }, - ); - const json = await res.json(); - await dispatch(findPartofSpeech(json.def)); - return json.def; - } catch (e) { - console.warn('err in yandex-dictionary.js: ', e); - } + try { + const res = await fetch( + `https://dictionary.yandex.net/api/v1/dicservice.json/lookup?key=${apiKey}&lang=${languages}&text=${word}`, + {method: 'GET'}, + ); + const json = await res.json(); + await dispatch(findPartofSpeech(json.def)); + return json.def; + } catch (e) { + console.warn('err in yandex-dictionary.js: ', e); + } }; const translateTemplate = (pos, tr) => ({ - pos, - tr, + pos, + tr, }); export const findPartofSpeech = dictionary => { - const amountOfMeanings = dictionary.length; - // return - console.log({ - type: '', //TODO create new Constant - translates: [ - //TODO create flexible field selector, by poses count - translateTemplate(dictionary[0].pos, dictionary[0].tr[0]), - translateTemplate(dictionary[1].pos, dictionary[1].tr[0]), - ], - }); + return { + type: SET_YANDEX_DICTIONARY_RESPONSE, + payload: [ + // TODO create flexible field selector, by poses count + translateTemplate(dictionary[0].pos, dictionary[0].tr[0].text), + translateTemplate(dictionary[1].pos, dictionary[1].tr[0].text), + ], + }; }; -export default yDictionary; \ No newline at end of file +export default yDictionary; diff --git a/src/components/anki-form.jsx b/src/components/anki-form.jsx index 2c75b7a..252c1ee 100644 --- a/src/components/anki-form.jsx +++ b/src/components/anki-form.jsx @@ -7,10 +7,12 @@ import {checkAnkiLanModelForExisting} from '../actions/anki-get-actions'; import InputWord from './view/translatable-word'; import SubmitButton from './view/submit-button'; import yDictionary from '../actions/api/yandex-dictionary'; +import {wordInfo} from "../actions/api/dictionary"; const AnkiForm = props => { useEffect(() => { props.yDictionary('wealth'); + props.wordInfo('suck') }, []); return ( @@ -33,5 +35,7 @@ export default connect( { checkAnkiLanModelForExisting, yDictionary, + wordInfo + }, )(AnkiForm); diff --git a/src/components/permissions.js b/src/components/permissions.js index 92478f4..e0f23ae 100644 --- a/src/components/permissions.js +++ b/src/components/permissions.js @@ -2,6 +2,7 @@ import React, {useState, useEffect} from 'react'; import {Text, Button, Grid} from 'native-base'; import {connect} from 'react-redux'; import {requestAnkiPermission} from '../actions/anki-get-actions'; + const Permissions = props => { useEffect(() => { props.requestAnkiPermission(); diff --git a/src/constants/api-constants.js b/src/constants/api-constants.js new file mode 100644 index 0000000..8601898 --- /dev/null +++ b/src/constants/api-constants.js @@ -0,0 +1,3 @@ +// export const c = 'c' +export const SET_YANDEX_DICTIONARY_RESPONSE = 'SET_YANDEX_DICTIONARY_RESPONSE'; +export const SET_AVAILABLE_API = 'SET_AVAILABLE_API'; diff --git a/src/reducers/api-reducer.js b/src/reducers/api-reducer.js index 5892772..20eba91 100644 --- a/src/reducers/api-reducer.js +++ b/src/reducers/api-reducer.js @@ -1,13 +1,30 @@ -const initialState = { - word: '', - translatedObject: {}, - wordSoundLink: '', - dictionaryInfo: {}, +import { + SET_AVAILABLE_API, + SET_YANDEX_DICTIONARY_RESPONSE, +} from '../constants/api-constants'; +const initialState = { + word: '', + translatedObject: {}, + wordSoundLink: '', + availableApi: {}, + availableApiName: '', + yandexDictionaryInfo: [], }; const apiReducer = (state = initialState, action) => { switch (action.type) { + case SET_YANDEX_DICTIONARY_RESPONSE: + return { + ...state, + yandexDictionaryInfo: action.payload, + }; + case SET_AVAILABLE_API: + return { + ...state, + availableApi: action.payload, + availableApiName: action.payload.source, + }; default: return state; } diff --git a/tools-start.sh b/tools-start.sh index 2897c53..ceeb635 100755 --- a/tools-start.sh +++ b/tools-start.sh @@ -1,3 +1,5 @@ +watchman watch-del-all +watchman shutdown-server react-native run-android react-native-debugger & scrcpy & diff --git a/yarn.lock b/yarn.lock index 9f0bac2..13f78ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1488,6 +1488,11 @@ async@^2.4.0: dependencies: lodash "^4.17.14" +async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1508,6 +1513,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== +axios@^0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -2511,6 +2523,13 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +combined-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-0.0.7.tgz#0137e657baa5a7541c57ac37ac5fc07d73b4dc1f" + integrity sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8= + dependencies: + delayed-stream "0.0.5" + command-exists@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" @@ -2736,6 +2755,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: dependencies: ms "2.0.0" +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -2799,6 +2825,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +delayed-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f" + integrity sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8= + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -3573,6 +3604,13 @@ fleximap@~0.9.10: resolved "https://registry.yarnpkg.com/fleximap/-/fleximap-0.9.10.tgz#1aa50ff6a8fea0037cc378e38ddacc091025ac10" integrity sha1-GqUP9qj+oAN8w3jjjdrMCRAlrBA= +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -3583,6 +3621,15 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.2.0.tgz#26f8bc26da6440e299cbdcfb69035c4f77a6e466" + integrity sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY= + dependencies: + async "~0.9.0" + combined-stream "~0.0.4" + mime-types "~2.0.3" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -5563,6 +5610,11 @@ mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== +mime-db@~1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.12.0.tgz#3d0c63180f458eb10d325aaa37d7c58ae312e9d7" + integrity sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc= + mime-db@~1.23.0: version "1.23.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659" @@ -5582,12 +5634,19 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.43.0" +mime-types@~2.0.3: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.0.14.tgz#310e159db23e077f8bb22b748dabfa4957140aa6" + integrity sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY= + dependencies: + mime-db "~1.12.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.4.1: +mime@^2.4.0, mime@^2.4.1: version "2.4.4" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== @@ -8054,6 +8113,15 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" +unirest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/unirest/-/unirest-0.6.0.tgz#289b5ae59cc9fa9fdfff3b5866e0dd50bf5eb280" + integrity sha512-BdYdcYJHXACqZ53k8Zz7QlNK/1W/HjCZlmg1OaaN/oTSp4FTWh0upXGSJsG88PljDBpSrNc2R649drasUA9NEg== + dependencies: + form-data "^0.2.0" + mime "^2.4.0" + request "^2.88.0" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -8072,6 +8140,18 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +urban-dictionary-client@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/urban-dictionary-client/-/urban-dictionary-client-3.0.1.tgz#87f531a35a378e7bfb9f8f3bb7c5555282fc2eb6" + integrity sha512-m9pYt7y8biC+/mkxbSbmvo7ToDzoK50Cs78gRCeu8F8uEscSAnRIMUKwhCyJ8ZEeko15NEwLg/yewn+AhGPV2w== + dependencies: + axios "^0.19.2" + +urban-dictionary@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/urban-dictionary/-/urban-dictionary-2.2.1.tgz#7d8bfb7d1aafb0e291f91eb17517985f3da88b3b" + integrity sha512-wnR3QWRlIXAtzf/QNaCHABsksdw05og/ZCEabB+S2C9G02wfDZvSz5l5Mh/Ip/Tk7mYNO09vbUaaFxH7MGHJsg== + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"