HonorLee 5 years ago
parent
commit
4d72be04cb
9 changed files with 239 additions and 84 deletions
  1. 1 1
      asset/css/main.css
  2. 29 7
      asset/less/main.less
  3. 0 4
      doc/englishWords.txt
  4. 88 47
      lib/main.js
  5. 17 12
      lib/popup.js
  6. 82 5
      main.js
  7. 1 1
      manifest.json
  8. 20 6
      windows/main.html
  9. 1 1
      windows/popup.html

File diff suppressed because it is too large
+ 1 - 1
asset/css/main.css


+ 29 - 7
asset/less/main.less

@@ -3,6 +3,13 @@ html{_background-image:url(about:blank);_background-attachment:fixed;}body{margi
 html,body{height:100%;width:100%}
 
 #main{
+    .title{
+        height:30px;background:#49A3D4;color:#fff;font-size:14px;text-align:center;line-height:30px;position:relative;;
+        span{-webkit-app-region: drag;}
+        a{position:absolute;height:14px;border-radius:10px;width:40px;top:8px;font-size:9px;line-height:12px;display:block;-webkit-app-region: nodrag;}
+        .minimize{background:#F9B148;right:10px;}
+        .close{background:#FF5858;left:10px}
+    }
     .tabs{
         display:flex;flex-flow:row;justify-content:center;align-items:stretch;height:40px;
         a{
@@ -11,7 +18,7 @@ html,body{height:100%;width:100%}
             span{font-size:12px;color:#999}
         }
     }
-    .content{position:absolute;bottom:0;left:0;right:0;top:40px;padding:20px;}
+    .content{position:absolute;bottom:0;left:0;right:0;top:70px;padding:20px;background:#fff;}
     .tabContent{
         display:none;height:100%;box-sizing:border-box;position:relative;
         &.on{display:block}
@@ -33,20 +40,24 @@ html,body{height:100%;width:100%}
         &.on{display:flex}
         p{color:#fff;line-height:40px;font-size:28px}
     }
+    .settings{
+        a.save{display:block;width:100px;height:40px;line-height:40px;background:#ff5858;color:#fff;text-align:center;margin:20px auto}
+    }
 }
 
 #popup{
     background:#49A3D4;color:#fff;padding:20px;box-sizing:border-box;overflow:scroll;
+    .info{-webkit-app-region: drag;}
     .loading{display:none;width:100%;height:100%;position: absolute;top:0;left:0;right:0;z-index:100;bottom:0;background:rgba(0,0,0,0.6);justify-content:center;align-items:center;
         &.on{display:flex}
         p{color:#fff;line-height:40px;font-size:16px}
     }
     a.close{
-        position: absolute;right:5px;top:5px;background:#FF5858;font-size:12px;display:block;width:20px;height:20px;border-radius:20px;text-align:center;line-height:20px;
+        position: absolute;right:5px;top:5px;background:#FF5858;font-size:10px;display:block;width:40px;height:14px;border-radius:20px;text-align:center;line-height:12px;
 
     }
     .word{
-        line-height:20px;height:49px;border-bottom:1px dashed #fff;position: relative;margin-bottom:5px;
+        line-height:20px;height:49px;border-bottom:1px solid #fff;position: relative;margin-bottom:10px;padding-bottom:5px;
         .w{font-size:24px;line-height:24px}
         .pron{font-size:14px;}
         a{
@@ -55,13 +66,24 @@ html,body{height:100%;width:100%}
         }
     }
     .def{
-        line-height:20px;font-size:12px;border-bottom:1px dashed #fff;margin-bottom:5px;padding-bottom:5px;
+        line-height:20px;font-size:12px;border-bottom:1px solid #fff;padding-bottom:10px;
     }
     .example{
         .ex{
-            border-bottom:1px dashed #e1e1e1;padding-bottom:5px;margin-bottom:5px;
-            &:last-child{border:none;padding:0;margin-bottom:10px}
-            p:first-child{line-height:12px;}
+            border-bottom:1px dashed #eee;padding:10px 0;
+            &:last-child{border:none;margin-bottom:10px}
+            &:hover{
+                background:rgba(255,255,255,0.3);
+                p:last-child{
+                    color:rgba(255,255,255,1);
+                    &:after{content:''}
+                }
+            }
+            p{line-height:12px;}
+            p:last-child{
+                padding-top:10px;color:rgba(255,255,255,0);position:relative;
+                &:after{content:'********************';position: absolute;left:0;right:0;top:10px;bottom:0;z-index:10;color:rgba(255,255,255,1);line-height:12px;}
+            }
         }
     }
     .from{

+ 0 - 4
doc/englishWords.txt

@@ -1765,7 +1765,6 @@ group
 grow
 growth
 guarantee
-保
 guard
 guess
 guest
@@ -2229,7 +2228,6 @@ letter
 letter-box
 level
 liable
-的
 liar
 liberal
 liberate
@@ -2349,7 +2347,6 @@ mask
 mass
 massive
 master
-师
 mat
 match
 mate
@@ -2408,7 +2405,6 @@ method
 Mexican
 Mexico
 microcomputer
-机
 microphone
 microscope
 microwave

+ 88 - 47
lib/main.js

@@ -1,37 +1,46 @@
+/**
+ * @Author  HonorLee (dev@honorlee.me)
+ * @Version 1.0 (2019-04-21)
+ * @License MIT
+ */
 var bg;
 $(function(){
-    $('.loading').addClass('on');
+    $('.loading').addClass('on').find('p').text('词库读取中,请稍后...');
     chrome.runtime.getBackgroundPage(function(background){
         bg = background;
-        if(bg.wordDataArr.length) bg.wordDataArr.forEach( function(word) {
-            $('.total .list ul').append('<li data-word="'+word+'">'+word+'<div class="btn"><a class="info" title="查看详情"><i class="fa fa-comment-o"></i></a><a class="del" title="移出词库"><i class="fa fa-trash-o"></i></a><a class="star" title="加入收藏"><i class="fa fa-star-o"></i></a></div></li>')
-        });
-        $('.tabs a:eq(0) span').text('('+bg.wordDataArr.length+')');
-        $('.loading').removeClass('on');
+        buildNormalList();
+        buildStarList();
+        $('.showTimeSets input').val(bg.setting.timerMin);
     });
+
+    chrome.runtime.onMessage.addListener(function(msg){
+        if(msg=="updateStarList") buildStarList();
+    })
+
     $('.tabContent .list').on('click','li a.info',function(){
-        
         var word = $(this).parents('li').data('word');
-        var oldWindow = chrome.app.window.get('popup');
-        if(oldWindow){
-            createPopup(oldWindow,word);
-        }else{
-            chrome.app.window.create('windows/popup.html', {
-                id:'popup',
-                resizable:false,
-                alwaysOnTop:true,
-                hidden:true,
-                frame:{type:'none'}
-            },function(popup){
-                createPopup(popup,word);
-            });
-        }
+        bg.showWordInfo(word);
+    });
+    $('.tabContent .list').on('click','li a.star',function(){
+        var word = $(this).parents('li').data('word');
+        var nowType = $(this).data('star');
+        if(nowType=='undefined') nowType = 0;
+        var toType = Math.abs(nowType-1);
+        bg.starWord(toType,word);
+        $(this).data('star',toType);
+        $(this).html('<i class="fa fa-star'+(toType==1?'':'-o')+'"></i>');
+
+    });
+    $('.title a.minimize').click(function(){
+        chrome.app.window.current().minimize();
+    });
+    $('.title a.close').click(function(){
+        chrome.app.window.current().close();
     });
     $('.tabContent .search').on('keyup',function(){
         var word = $(this).val();
         $(this).parent().find('.list li').hide().filter(":contains('"+word+"')").show();
     });
-
     $('.tabs a').click(function(){
         $(this).addClass('on').siblings().removeClass('on');
         $('.tabContent').removeClass('on').eq($(this).index()).addClass('on');
@@ -41,39 +50,71 @@ $(function(){
         $("#my_file").trigger('click');
     })
     $("#my_file").on('change',function(){
-        var wordsObj = {};
-        var wordsArr = [];
+        $('.loading').addClass('on').find('p').text('词库导入中,请稍后...');
+        var wordCount = 0;
         var file = $('#my_file')[0].files[0];
         var reader = new FileReader();
         reader.readAsText(file, "utf-8");
         reader.onload = function (e) {
-            wordsArr = e.target.result.split("\n");
-            if(wordsArr.length>0){
-                wordsArr.forEach(function(word) {
-                    wordsObj[word] = {testCount:0}
-                });
+            var tmpArr = e.target.result.split("\n");
+            var word;
+            if(tmpArr.length>0){
+                for(var i = 0;i<tmpArr.length;i++){
+                    word = (tmpArr[i]).toLowerCase();
+                    if(!bg.wordDataObj[word]){
+                        wordCount++;
+                        bg.wordDataObj[word] = {testCount:0}
+                        bg.wordDataArr.push(word);
+                    }
+                    // wordsObj[word] = {testCount:0}
+                };
+                if(wordCount>0) bg.wordDataArr.sort();
             }
-            chrome.storage.local.set({wordsArr:wordsArr,wordsObj:wordsObj},function(e){
-                bg.wordDataArr = wordsArr;
-                bg.wordDataObj = wordsObj;
-                console.log('导入完成',e)
+            chrome.storage.local.set({wordsArr:bg.wordDataArr,wordsObj:bg.wordDataObj},function(e){
+                chrome.notifications.create('importNotifi'+(new Date().getTime()),{iconUrl:'../asset/img/logo@x128.png',message:'词库导入成功\n本次共导入['+wordCount+']个新单词',type:'basic',title:'导入完成!'});
+                $('.loading').removeClass('on');
+                // console.log('导入完成',e);
+                buildNormalList();
             })
         }
-    })
+    });
+    $('.settings a.save').click(function(){
+        bg.setting = {
+            timerMin:$('input[name=showTime]').val()
+        }
+        chrome.storage.local.set({setting:bg.setting},function(e){
+            bg.setTimer();
+            chrome.notifications.create('importNotifi'+(new Date().getTime()),{iconUrl:'../asset/img/logo@x128.png',message:'设置已保存',type:'basic',title:'设置已保存!'});
+            $('.loading').removeClass('on');
+        })
+    });
 });
 
-function createPopup(popup,word){
-    var popWidth = 300,popHeight = 400;
-    bg.currentWord = word;
-    chrome.system.display.getInfo(function(display){
-        var displayOpt = display[0].workArea;
-        popup.outerBounds.left = displayOpt.width - popWidth - 20;
-        popup.outerBounds.top = 20 + displayOpt.top;
-        // popup.innerBounds = {width:popWidth,height:popHeight};
-        popup.show();
-        chrome.runtime.sendMessage('updateInfo');
-        popup.onClosed.addListener(function(){
-            chrome.storage.local.set({wordsObj:bg.wordDataObj,wordOpt:bg.wordOpt});
-        });
+function buildNormalList(listIndex){
+    $('.total .list ul').empty();
+    $('.loading').addClass('on').find('p').text('词库读取中,请稍后...');
+    var dom = ''
+    if(bg.wordDataArr.length) bg.wordDataArr.forEach( function(word) {
+        var starType = bg.wordDataObj[word]['isStar'];
+        if(starType==undefined) starType=0;
+        dom += '<li name="'+word+'" data-word="'+word+'">'+word+'<div class="btn"><a class="info" title="查看详情"><i class="fa fa-comment-o"></i></a><a class="star" data-star="'+starType+'" title="加入收藏"><i class="fa fa-star'+(starType==1?'':'-o')+'"></i></a><a class="del" title="移出词库"><i class="fa fa-trash-o"></i></a></div></li>';
+    });
+    $('.total .list ul').append(dom);
+    $('.tabs a:eq(0) span').text('('+bg.wordDataArr.length+')');
+    $('.loading').removeClass('on');
+}
+
+function buildStarList(listIndex){
+    $('.starList .list ul').empty();
+    $('.loading').addClass('on').find('p').text('收藏词库读取中,请稍后...');
+    var dom = ''
+    if(bg.wordStarArr.length) bg.wordStarArr.forEach( function(word) {
+        var starType = bg.wordDataObj[word]['isStar'];
+        if(starType==undefined) starType=0;
+        dom += '<li data-word="'+word+'">'+word+'<div class="btn"><a class="info" title="查看详情"><i class="fa fa-comment-o"></i></a><a class="star" data-star="'+starType+'" title="加入收藏"><i class="fa fa-star'+(starType==1?'':'-o')+'"></i></a><a class="del" title="移出词库"><i class="fa fa-trash-o"></i></a></div></li>'
     });
+    $('.starList .list ul').append(dom);
+    $('.tabs a:eq(1) span').text('('+bg.wordStarArr.length+')');
+    $('.loading').removeClass('on');
+    buildNormalList();
 }

+ 17 - 12
lib/popup.js

@@ -1,3 +1,8 @@
+/**
+ * @Author  HonorLee (dev@honorlee.me)
+ * @Version 1.0 (2019-04-21)
+ * @License MIT
+ */
 var bg,currentWord,wordObj;
 var wordInfoApi = 'https://api.shanbay.com/bdc/search/';
 var wordSentenceApi = 'https://api.shanbay.com/bdc/example/';
@@ -37,7 +42,6 @@ function initWordInfo(){
             dataType:'json',
             success:function(res){
                 if(res.msg=="SUCCESS"){
-                    console.log(res.data)
                     wordObj.info = {
                         id:res.data.id,
                         audio:res.data.audio,
@@ -45,7 +49,6 @@ function initWordInfo(){
                         definition:res.data.definition.split('\n')
                     }
                     chrome.storage.local.set({wordsObj:bg.wordDataObj});
-                    console.log(wordObj)
                     initWordSentence();
                 }else{
                     console.log(res.msg);
@@ -72,16 +75,17 @@ function initWordSentence(){
                 if(res.msg=="SUCCESS"){
                     var samples = res.data;
                     var exampleArr = [];
-                    console.log(samples)
-                    if(samples.length) for(var i = 0;i<samples.length;i++){
-                        var sentence = samples[i];
-                        console.log(sentence)
-                        exampleArr.push({
-                            sentence:sentence.annotation,
-                            trans:sentence.translation
-                        });
-                        if(i==4) break;
-                    };
+                    if(samples.length>0){
+                        // console.log(samples.length)
+                        for(var i = 0;i<samples.length;i++){
+                            var sentence = samples[i];
+                            exampleArr.push({
+                                sentence:sentence.annotation,
+                                trans:sentence.translation
+                            });
+                            if(i==4) break;
+                        }
+                    }
                     wordObj.example = exampleArr;
                     chrome.storage.local.set({wordsObj:bg.wordDataObj});
                 }else{
@@ -104,6 +108,7 @@ function fillContent(){
     $('.word .w').text(newWord);
     $('.word .pron span').text(wordObj.info.pron);
     $('.def').empty();
+    $('.example').empty();
     wordObj.info.definition.forEach(function(def){
         $('.def').append('<p>'+def+'</p>');
     });

+ 82 - 5
main.js

@@ -4,22 +4,99 @@
  * @License MIT
  */
 var mainWidth = 600,mainHeight = 800;
-var wordDataArr,wordDataObj,wordOpt,currentWord;
-chrome.storage.local.get(['wordsArr','wordsObj','wordOpt'],function(items){
+var wordDataArr,wordStarArr,wordDataObj,wordOpt,currentWord,setting;
+var autoShowTimer;
+chrome.storage.local.get(['wordsArr','starsArr','wordsObj','wordOpt','setting'],function(items){
     wordDataArr = items.wordsArr?items.wordsArr:[];
+    wordStarArr = items.starsArr?items.starsArr:[];
     wordDataObj = items.wordsObj?items.wordsObj:{};
     wordOpt     = items.wordOpt?items.wordOpt:{};
+    setting     = items.setting?items.setting:{timerMin:10};
+    setTimer();
 });
 chrome.app.runtime.onLaunched.addListener(function() {
     chrome.app.window.create('windows/main.html', {
         id:'main',
         innerBounds:{width:mainWidth,height:mainHeight},
         resizable:false,
-        // frame:{type:'none'}
+        frame:{type:'none'}
     },function(mainWindow){
         mainWindow.resizeTo(mainWidth,mainHeight);
         mainWindow.onClosed.addListener(function(){
-            chrome.storage.local.set({wordsArr:wordDataArr,wordsObj:wordDataObj,wordOpt:wordOpt});
+            chrome.storage.local.set({wordsArr:wordDataArr,starsArr:wordStarArr,wordsObj:wordDataObj,wordOpt:wordOpt,setting:setting});
         });
     });
-});
+});
+var showWordInfo = function(word){
+    var oldWindow = chrome.app.window.get('popup');
+    if(oldWindow){
+        createPopup(oldWindow,word);
+    }else{
+        chrome.app.window.create('windows/popup.html', {
+            id:'popup',
+            resizable:false,
+            alwaysOnTop:true,
+            hidden:true,
+            frame:{type:'none'}
+        },function(popup){
+            createPopup(popup,word);
+        });
+    }
+}
+
+function createPopup(popup,word){
+    var popWidth = 300,popHeight = 400;
+    currentWord = word;
+    chrome.system.display.getInfo(function(display){
+        var displayOpt = display[0].workArea;
+        popup.outerBounds.left = displayOpt.width - popWidth - 20;
+        popup.outerBounds.top = 20 + displayOpt.top;
+        // popup.innerBounds = {width:popWidth,height:popHeight};
+        popup.show();
+        chrome.runtime.sendMessage('updateInfo');
+        // popup.onClosed.addListener(function(){
+        //     chrome.storage.local.set({wordsObj:bg.wordDataObj,wordOpt:bg.wordOpt});
+        // });
+    });
+}
+
+function randomShow(){
+    console.log(1)
+    if(wordDataArr.length==0) return;
+    var mid = 3;
+    var percent = Math.floor(Math.random()*10);
+    var randomIndex = 0,word;
+    if(wordStarArr.length==0) percent = 0;
+    if(percent<=mid){
+        randomIndex = Math.floor(Math.random()*wordDataArr.length);
+        word = wordDataArr[randomIndex];
+    }else{
+        randomIndex = Math.floor(Math.random()*wordStarArr.length);
+        word = wordStarArr[randomIndex];
+    }
+    showWordInfo(word);
+}
+//0:unstar 1:star
+function starWord(type,word){
+    if(type==0){
+        var wi = wordStarArr.indexOf(word);
+        wordStarArr.splice(wi,1);
+    }else if(type==1){
+        wordStarArr.push(word);
+    }
+    wordDataObj[word]['isStar'] = type;
+    wordStarArr.sort();
+    chrome.storage.local.set({starsArr:wordStarArr,wordsObj:wordDataObj},function(e){
+        chrome.notifications.create('importNotifi'+(new Date().getTime()),{iconUrl:'../asset/img/logo@x128.png',message:'单词['+word+']已'+(type==0?'从收藏列表移除':'加入收藏'),type:'basic',title:'设置已保存!'});
+        chrome.runtime.sendMessage('updateStarList');
+    })
+}
+
+function setTimer(){
+    if(autoShowTimer) clearInterval(autoShowTimer);
+    autoShowTimer = setInterval(randomShow, setting.timerMin*1000*60);
+}
+
+
+
+

+ 1 - 1
manifest.json

@@ -17,7 +17,7 @@
         }
     },
     "permissions":[
-        "storage","unlimitedStorage","system.display","app.window.alwaysOnTop","https://api.shanbay.com/","https://media.shanbay.com/"
+        "storage","unlimitedStorage","system.display","notifications","app.window.alwaysOnTop","https://api.shanbay.com/","https://media.shanbay.com/"
     ],
     "externally_connectable": {
         "matches": ["*://*.shanbay.com/*"]

+ 20 - 6
windows/main.html

@@ -7,20 +7,34 @@
     <link rel="stylesheet" href="../asset/css/font-awesome.min.css">
 </head>
 <body id="main">
+<div class="title"><span>Random English Learning</span><a class="minimize">-</a><a class="close">x</a></div>
 <div class="tabs">
-    <a class="on">完整词库<span>(0)</span></a><a>收藏词库<span>(0)</span></a><a>错误词库<span>(0)</span></a><a>最近新增<span>(0)</span></a><a><i class="fa fa-gear"></i></a>
+    <a class="on">完整词库<span>(0)</span></a><a>收藏词库<span>(0)</span></a><!-- <a>错误词库<span>(0)</span></a><a>最近新增<span>(0)</span></a> --><a><i class="fa fa-gear"></i> 设置</a>
 </div>
 <div class="content">
     <div class="tabContent total on">
         <input type="text" class="search" placeholder="快速查找" />
         <div class="list"><ul></ul></div>
     </div>
-    <div class="tabContent stars"></div>
-    <div class="tabContent error"></div>
-    <div class="tabContent recent"></div>
+    <div class="tabContent starList">
+        <input type="text" class="search" placeholder="快速查找" />
+        <div class="list"><ul></ul></div>
+    </div>
+<!--     <div class="tabContent error"></div>
+    <div class="tabContent recent"></div> -->
     <div class="tabContent settings">
-        <input type="file" id="my_file" style="display: none;">
-        <button value="导入" id="clickme">导入</button>
+        <div class="showTimeSets">
+            <label for="showTime">单词随机信息弹出时间(分钟)</label>
+            <input type="text" id="showTime" name="showTime" value="10" />
+            <p>目前弹窗显示的英语单词中,完整词库与收藏词库的出现比例为3:7,若收藏词库为空,则默认显示普通词库</p>
+            <p>Chrome机制问题,即便在没有打开主窗口的情况下,弹窗依然会定时出现,若想停用请在Chrome扩展程序管理页面禁用本APP</p>
+        </div>
+        <a class="save">保存设置</a>
+        <div class="import">
+            <input type="file" accept="text/plain" id="my_file" style="display: none;">
+            <button value="导入" id="clickme">导入</button>
+            <p>目前仅支持导入TXT文件,文件内容为纯单词表,一行一个,建议使用UTF-8格式文件</p>
+        </div>
     </div>
 </div>
 <div class="loading">

+ 1 - 1
windows/popup.html

@@ -8,7 +8,7 @@
 </head>
 <body id="popup">
 <div class="info">
-    <a class="close"><i class="fa fa-close"></i></a>
+    <a class="close">-</a>
     <div class="word"><p class="w">transportation</p><p class="pron">[<span>[ˌtrænspɔːr'teɪʃn]</span>]<a class="audio"><i class="fa fa-play-circle"></i></a></p></div>
     <div class="def"></div>
     <div class="example"></div>