diff --git a/assets/manifest.json b/assets/manifest.json
index b44911c..66891ed 100644
--- a/assets/manifest.json
+++ b/assets/manifest.json
@@ -44,6 +44,7 @@
"storage",
"activeTab",
"tabs",
+ "notifications",
"http://dict.youdao.com/",
"https://api.shanbay.com/"
]
diff --git a/build.pem b/build.pem
new file mode 100644
index 0000000..9eb6b41
--- /dev/null
+++ b/build.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCinep+LvPP9QVz
+cFTrWmSGIvEG9YId8DyYJJudIKtpZXtt7vAum7etFtJaVoEyC/ucVLvcvtDPBI+9
+ixgL1iMuITfBY8uk6UpjghkT0kl5HR+oa6U8aNMr1MFdcMXIwd753s9ci6a/2cjh
+Apvp82Wpkrhs+N/d/GbA5dyoawYZIXXgqBKKIP323PFjezmW1NGcwNoFY7GQeAqs
+M1VGAsiHzVoauWwPgcl+USvLfFJXd0m+zw00BRPbbmFEY+bivVvxI0Lapi8iO453
+L+WONScwQCrJvZlILD+aoxlEX9lS6ZJtmek30o0v/lxICBBqVG2BkzpOMuL3n6G+
+yDGPs9aDAgMBAAECggEAMSHXTKKxBZ75M6S385gPETwTaM/arWL9W9aLsdDCGYkQ
+3uk3Zk2kFEb17Vd/l3hpYBV14T9B5ZpyN4mEDWd4n6JnryWQzNWzpRcUrpl1m4NC
+ImfLt9HQI8kXVz0QdRSmYwZ/zm1fR03s1JcuNmRUzgRHdp1HPlHZVeTdY4FaiVLI
+cq4nMAayY14oXL8CmEjSQIP+cNUvhYrSHgZRPdH3Lul4Kh4qsg3uS9Btjp4uydCL
+TKKbFXGJ+AUtzfvIJUpwx3pjwBqBIvlUL8Mqp/kJMA3X50PNrZEq9RL5pnWvLbC1
+09EzgVCAnLDTGjYLiWQTjgGBNUp3FGLHXptZNdOAMQKBgQDQCprue7gAxS1xbAKd
+fjtT/LIX/6X3Ro1LO+LyuI+E2IOuH3wDR1SyFjzYx+LWtAFGPVb5mmPz5PaebzeU
+80kE3RfYkjoR9ldAKiFW/PJMf9ADrZPhwHvTc1zeGurbEi4hl9eRsdNWueolxjBp
+VUFXuGN997g5XXZRlUSsJ3wdmwKBgQDIGp34HAnUMk/exg2VAeQ5aMwmbbE1S5sw
+ec+Zbs6DwrlZMRVYimu9NOyg6JUBIHNmkAp1UGtcu6qclnLetuJSvD53qFzKWCqY
+yB65qCLKBeVglt9aJEUYVXtvnujMt+jqwhglJZM1NGVUcxAkIqrk1kT81BkZI7YE
+yIA6B+ctOQKBgQDNUiomRCQNXozC6/6IwRR8h2CdHsoFibPZFHmfY1cBnU4Ygyo5
+ciS8vgW/TUcq7uxzDgbQwPb0tnxPUSRh9NmT20C1lVuKbr0drnbJC0t3BI2fk6fn
+nbiXr7tv2NEA9KhiryEpwX76kPHt5fPRgTrEAE7w+5LtyrgDPHZSEYYFEQKBgBZA
+n4CP3afzUF59t9TyOOcJeGptmF9M4R0q7qMpZ13PsbzxcGZAPmr0D7x1INzXNv4Y
+1pDlOIs/c2GmeW+69sAsnuW/m1IFK/eBiakrwXKl5TQwkvX7QpPKLcfj7A+YBBbX
+LsgyvYQVJ4+UnB7onAiGq3VSQNhC2GL/yQKrDlJBAoGAQlyTpRpZZ/s27dI9J4Tj
+eVzcBdMVizt/vbnfCfmIGSahzmgOzIn2Zj76L9GSOvcgtRAd+sU2JXZLaKFBnS5P
+iXxq1OfKLZK7fwjC4Up4lYJ7vNqpYbSTR8a5HlMgKcV1ZJiHG/ThlZe1qyFqvdq4
+4hpG3DYVv7mEwtgMa516a0E=
+-----END PRIVATE KEY-----
diff --git a/src/components/add_word.js b/src/components/add_word.js
index 0add774..0548219 100644
--- a/src/components/add_word.js
+++ b/src/components/add_word.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import icons from './icons'
import { addNotebookWord } from '../message'
-const SHANBAY_URL = 'https://www.shanbay.com/bdc/learnings/library/'
+const SHANBAY_URL = 'https://web.shanbay.com/wordsweb/#/collection'
const styles = {
container: {
@@ -24,18 +24,33 @@ const styles = {
width: 8,
height: 8,
},
+ check: {
+ position: 'absolute',
+ left: 8,
+ bottom: 0,
+ width: 10,
+ height: 10,
+ },
+ invalid: {
+ position: 'absolute',
+ left: 8,
+ bottom: 0,
+ width: 10,
+ height: 10,
+ },
}
class AddWord extends Component {
constructor(props) {
super(props)
- const { defaultAdded } = props
+ const { defaultAdded, defaultInvalid } = props
this.addWord = this.addWord.bind(this)
this.state = {
added: defaultAdded,
+ invalid: defaultInvalid
}
}
@@ -45,17 +60,17 @@ class AddWord extends Component {
addWord() {
const { word } = this.props
-
addNotebookWord(word).then((response) => {
const { success, msg } = response
-
- if (!success) {
- throw new Error(msg)
+
+ if (!!success) {
+ this.setState({ added: true, })
+ } else if(msg == 'Invalid Token!') {
+ this.setState({ invalid: true, added: false })
+ } else {
+ throw new Error(msg);
}
- this.setState({
- added: true,
- })
}).catch((err) => {
this.props.flash(err.message)
})
@@ -64,32 +79,46 @@ class AddWord extends Component {
render() {
const { addWord } = this
const { word, showWordsPage } = this.props
- const { added } = this.state
+ const { added, invalid } = this.state
if (!word || !showWordsPage) {
return null
}
const content = (
-
-
![book]({icons.book})
- {!added ? (
+
+
+ { !!invalid ? (
+
![invalid]({icons.invalid})
+ ) : !added? (
![plus]({icons.plus})
- ) : null}
+ ) : (
+
![check]({icons.check})
+ ) }
+
+
)
return added ? (
{
- oauth.authorize(() => {
- resolve()
- })
- })
-}
-
-const ADD_WORD_URL = 'https://api.shanbay.com/bdc/learning/'
-const SEARCH_WORD_URL = 'https://api.shanbay.com/bdc/search/'
-
-function getWord(url) {
- return fetch(url).then(res => res.json()).then((res) => {
- const { data, msg } = res
-
- if (msg !== 'SUCCESS') {
- throw new Error(msg)
- }
-
- return data
- })
-}
-
-function clearShanbayToken() {
- oauth.clearToken()
-}
-
async function addWordToShanbay(data, sendRes) {
- // redirect
- if (!oauth.token_valid()) {
- await authorize()
- }
-
- const token = oauth.access_token()
-
- const searchURL = `${SEARCH_WORD_URL}?word=${data}&access_token=${token}`
let response = null
-
try {
- response = await getWord(searchURL)
+ // get shanbay word id
+ response = await lookUp(data)
+ const { id } = response
+
+ // add word
+ addWord(id)
+
+ sendRes({ success: true })
} catch (err) {
- // 如果token失效,清除token并重新添加
- if (err.message === 'Invalid token') {
- clearShanbayToken()
- await addWordToShanbay(data, sendRes)
+ if (err.msg == "单词没找到") {
+ sendRes({ success: false, msg: 'Shabay: Word Not Found!' })
return
}
- sendRes({
- success: false,
- msg: err.message,
- })
-
- return
- }
-
- const { id } = response
-
- const addWordURL = `${ADD_WORD_URL}?access_token=${token}`
-
- try {
- response = await fetch(addWordURL, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- id,
- access_token: token,
- }),
- }).then(res => res.json()).then((res) => {
- const { data: d, msg } = res
-
- if (msg !== 'SUCCESS') {
- throw new Error(msg)
- }
-
- return d
- })
- } catch (err) {
- sendRes({
- success: false,
- msg: err.message,
+ sendRes({ success: false, msg: 'Invalid Token!' })
+ notify({
+ title: '扇贝认证失败!',
+ message: '登录后才能使用生词本功能。\n点击此消息前往扇贝登录',
+ url: 'https://web.shanbay.com/web/account/login/'
})
-
- return
}
-
- sendRes({
- success: true,
- })
}
function openNewTab(word) {
@@ -125,8 +57,6 @@ function openNewTab(word) {
}
function init() {
- oauth = ShanbayOauth.initPage()
-
onMessage(SEARCH_WORD, (data, sendRes) => {
getWords(data, sendRes)
})
diff --git a/src/shanbay_api.js b/src/shanbay_api.js
new file mode 100644
index 0000000..07f503a
--- /dev/null
+++ b/src/shanbay_api.js
@@ -0,0 +1,109 @@
+/**
+ * @author maicss
+ * @file some licences file
+ * @copyright 2017-2020 maicss
+ * */
+
+/**
+ * chrome 通知处理方法, 传入的参数就是chrome notifications的参数
+ * @function notify
+ * @param {object} opt - chrome notifications 的参数
+ * @param {string} opt.title=人丑多读书 - notifications title
+ * @param {string} [opt.message=少壮不努力,老大背单词] - notifications message
+ * @param {string} [opt.url=https://www.shanbay.com/] - notifications url, notifications可以点击跳转
+ * */
+export const notify = (opt = {title: '人丑多读书', message: '少壮不努力,老大背单词', url: 'https://www.shanbay.com/'}) => {
+ let hasNotified = false
+ const options = {
+ type: 'basic',
+ title: opt.title,
+ message: opt.message,
+ iconUrl: './icons/icon48.png',
+ }
+ let noteID = Math.random().toString(36)
+ chrome.notifications.create(noteID, options, (notifyID) => {
+ hasNotified = true
+ })
+ chrome.notifications.onClicked.addListener(function (notifyID) {
+ chrome.notifications.clear(notifyID)
+ if (noteID === notifyID) {
+ chrome.tabs.create({
+ url: opt.url
+ })
+ }
+ hasNotified = false
+ })
+}
+
+/**
+ * 基于fetch的网络请求方法的封装,只有两种数据的返回,buffer和json,因为这个应用里面只用到了这两种
+ * @function request
+ * @see [use fetch API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch}
+ * @param {string} url - request url
+ * @param {object} [options] - fetch options
+ * @param {string} [options.type='buffer'] - whether need return buffer
+ * @return Promise
+ * */
+const request = (url, options = {}) => {
+ options = Object.assign(options, { credentials: 'include' })
+ return fetch(url, options).then(res => {
+ if (res.ok) {
+ if (options.type === 'buffer') return res.arrayBuffer()
+ return res.json()
+ } else {
+ return Promise.reject(res.json ? res.json() : res.text())
+ }
+ }).catch(e => {
+ if (e.status === 400) {
+ notify({
+ title: '扇贝认证失败',
+ message: '点击此消息登录',
+ url: 'https://web.shanbay.com/web/account/login/'
+ })
+ } else {
+ return e.then ? e.then(error => Promise.reject(error)) : Promise.reject(e)
+ }
+ })
+}
+
+/**
+ * shanbay API的需要用到的方法,没什么用,只是一个参考
+ * 扇贝开放API关闭之后,直接读取扇贝网的cookie,使用扇贝私有API
+ * @constant
+ * @readonly
+ * @enum {object}
+ * */
+const shanbayAPI = {
+ /** 查询单词*/
+ lookUp: {
+ method: 'GET',
+ url: 'https://apiv3.shanbay.com/abc/words/senses?vocabulary_content={word}',
+ params: ['word']
+ },
+ /** 添加生词和标记已添加生词已忘记 */
+ addWord: {
+ method: 'POST',
+ url: 'https://apiv3.shanbay.com/news/words',
+ params: [{"vocab_id":"","business_id":2,"paragraph_id":"1","sentence_id":"A1","source_content":"","article_id":"ca","source_name":"","summary":""}]
+ }
+}
+
+/**
+ * @description 查询单词
+ * @function lookUp
+ * @param {string} word - 需要查询的单词
+ * @return Promise