From 71aebe5cbd88136b2a10fd53e0358de430842553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E5=A4=A9?= Date: Thu, 7 Jan 2021 19:46:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B9=A6=E6=9C=AC=E8=A7=A3?= =?UTF-8?q?=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/css/app.css | 2 +- src/css/app.scss | 65 ++++----- src/css/float.css | 1 - src/css/float.scss | 97 -------------- src/css/view.css | 1 + src/css/view.scss | 233 +++++++++++++++++++++++++++++++++ src/index.html | 18 +-- src/js/app.js | 32 +++-- src/js/float.js | 94 -------------- src/js/view.js | 84 ++++++++++++ src/lib/chart/line.js | 253 ------------------------------------ src/lib/chart/rank.js | 141 -------------------- src/lib/code/index.js | 13 ++ src/lib/fetch/index.js | 1 + src/lib/fetch/lib/format.js | 1 + src/main.js | 11 +- src/tools/socket.js | 28 +++- src/tools/window.js | 32 ++--- src/view.html | 41 +++--- 19 files changed, 445 insertions(+), 703 deletions(-) delete mode 100644 src/css/float.css delete mode 100644 src/css/float.scss create mode 100644 src/css/view.css create mode 100644 src/css/view.scss delete mode 100644 src/js/float.js create mode 100644 src/js/view.js delete mode 100644 src/lib/chart/line.js delete mode 100644 src/lib/chart/rank.js create mode 100644 src/lib/code/index.js create mode 100644 src/lib/fetch/index.js create mode 100644 src/lib/fetch/lib/format.js diff --git a/src/css/app.css b/src/css/app.css index 17edc4e..f22fd40 100644 --- a/src/css/app.css +++ b/src/css/app.css @@ -1 +1 @@ -html{font-size:12.8px;width:100%;height:100vh}body{overflow:hidden;display:flex;flex-direction:column;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app-drag{-webkit-app-region:drag;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.app-nodrag{-webkit-app-region:no-drag}.app{position:relative;display:flex;height:100%}.app .category{width:200px;height:100%;background:#fff}.app .category .item{display:flex;justify-content:space-between;align-items:center;height:54px;padding:8px;border-bottom:1px solid var(--color-plain-1);background:#fff;transition:background 0.2s ease-in-out, color 0.2s ease-in-out;cursor:pointer}.app .category .item strong{max-width:150px}.app .category .item .num{display:flex;justify-content:center;align-items:center;min-width:16px;height:16px;padding:2px;line-height:1;border-radius:50%;font-size:12px;background:var(--color-grey-1);color:#fff}.app .category .item:last-child{border-bottom:0}.app .category .item:hover{color:var(--color-blue-1);background:var(--color-plain-1)}.app .category .item.active{color:var(--color-plain-1);background:var(--color-blue-1)}.app .category .item.active .num{background:#fff;color:var(--color-blue-1)}.app .detail{position:relative;flex:1;height:100%;border-left:1px solid var(--color-plain-2);background:rgba(255,255,255,0.5)}.app .detail .title{display:flex;justify-content:space-between;align-items:center;width:100%;height:35px;padding:0 16px;font-size:16px;font-weight:bold}.app .detail .title span{display:inline-flex}.app .detail .title wc-button{margin:0 6px}.app .detail .card{width:96%;padding:12px 12px 16px;margin:12px 2% 24px;border:0;background:#fff;box-shadow:0 0 8px rgba(0,0,0,0.075)}.app .detail .card legend{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#64b5f6}.app .drag-mask{display:flex;align-items:center;position:fixed;left:0;top:0;z-index:9999;width:100%;height:100%;background:linear-gradient(to right, transparent, transparent 200px, #fff3e3 200px)}.app .drag-mask::after{font-size:46px;text-indent:300px;content:'Drop epub file here...';color:var(--color-grey-1)}.app .book-loading{display:flex;align-items:center;justify-content:center;position:fixed;left:0;top:0;z-index:9999;width:100%;height:100%;font-size:20px;background:rgba(255,255,255,0.01);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.app .book-loading .loading{display:flex;flex-direction:column;align-items:center;justify-content:center}.app .book-loading .loading::before{content:'🌑';font-size:36px;-webkit-animation:loading 1s infinite;animation:loading 1s infinite}@-webkit-keyframes loading{1%,100%{content:'🌑'}12.5%{content:'🌒'}25%{content:'🌓'}37.5%{content:'🌔'}50%{content:'🌕'}62.5%{content:'🌖'}75%{content:'🌗'}87.5%{content:'🌘'}}@keyframes loading{1%,100%{content:'🌑'}12.5%{content:'🌒'}25%{content:'🌓'}37.5%{content:'🌔'}50%{content:'🌕'}62.5%{content:'🌖'}75%{content:'🌗'}87.5%{content:'🌘'}} +html{width:100%;height:100vh}body{overflow:hidden;display:flex;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app{position:relative;display:flex;height:100%}.app .category{width:200px;height:100%;background:#fff}.app .category .item{display:flex;justify-content:space-between;align-items:center;height:54px;padding:8px;border-bottom:1px solid var(--color-plain-1);background:#fff;transition:background 0.2s ease-in-out, color 0.2s ease-in-out;cursor:pointer}.app .category .item strong{max-width:150px}.app .category .item .num{display:flex;justify-content:center;align-items:center;min-width:16px;height:16px;padding:2px;line-height:1;border-radius:50%;font-size:12px;background:var(--color-grey-1);color:#fff}.app .category .item:last-child{border-bottom:0}.app .category .item:hover{color:var(--color-blue-1);background:var(--color-plain-1)}.app .category .item.active{color:var(--color-plain-1);background:var(--color-blue-1)}.app .category .item.active .num{background:#fff;color:var(--color-blue-1)}.app .books-scroll{flex:1;height:100%;border-left:1px solid var(--color-plain-2)}.app .books{display:flex;flex-wrap:wrap}.app .books .book{display:flex;flex-direction:column;width:128px;margin:24px;background:#fff;box-shadow:0 0 12px rgba(0,0,0,0.15);transition:box-shadow 0.1s ease-in;cursor:pointer}.app .books .book img{width:100%;height:160px;-o-object-fit:fill;object-fit:fill}.app .books .book:hover{box-shadow:0 0 12px rgba(0,0,0,0.35)}.app .drag-mask{display:flex;align-items:center;position:fixed;left:0;top:0;z-index:9999;width:100%;height:100%;background:linear-gradient(to right, transparent, transparent 200px, rgba(252,232,207,0.6) 200px)}.app .drag-mask::after{font-size:46px;text-indent:360px;content:'Drop epub file here...';color:var(--color-grey-1)}.app .book-loading{display:flex;align-items:center;justify-content:center;position:fixed;left:0;top:0;z-index:9999;width:100%;height:100%;font-size:20px;background:rgba(255,255,255,0.01);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.app .book-loading .loading{display:flex;flex-direction:column;align-items:center;justify-content:center}.app .book-loading .loading::before{content:'🌑';font-size:36px;-webkit-animation:loading 1s infinite;animation:loading 1s infinite}@-webkit-keyframes loading{1%,100%{content:'🌑'}12.5%{content:'🌒'}25%{content:'🌓'}37.5%{content:'🌔'}50%{content:'🌕'}62.5%{content:'🌖'}75%{content:'🌗'}87.5%{content:'🌘'}}@keyframes loading{1%,100%{content:'🌑'}12.5%{content:'🌒'}25%{content:'🌓'}37.5%{content:'🌔'}50%{content:'🌕'}62.5%{content:'🌖'}75%{content:'🌗'}87.5%{content:'🌘'}} diff --git a/src/css/app.scss b/src/css/app.scss index 2e9e38e..efd3c97 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -6,7 +6,6 @@ */ html { - font-size: 12.8px; width: 100%; height: 100vh; } @@ -14,7 +13,6 @@ html { body { overflow: hidden; display: flex; - flex-direction: column; width: 100%; height: 100%; line-height: 1.25; @@ -23,14 +21,6 @@ body { background: rgba(255, 255, 255, 0.3); } -.app-drag { - -webkit-app-region: drag; - user-select: none; -} -.app-nodrag { - -webkit-app-region: no-drag; -} - .app { position: relative; display: flex; @@ -90,43 +80,34 @@ body { } } - .detail { - position: relative; + .books-scroll { flex: 1; height: 100%; border-left: 1px solid var(--color-plain-2); - background: rgba(255, 255, 255, 0.5); + } - .title { + .books { + display: flex; + flex-wrap: wrap; + + .book { display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - height: 35px; - padding: 0 16px; - font-size: 16px; - font-weight: bold; - - span { - display: inline-flex; - } - wc-button { - margin: 0 6px; - } - } - - .card { - width: 96%; - padding: 12px 12px 16px; - margin: 12px 2% 24px; - border: 0; + flex-direction: column; + width: 128px; + margin: 24px; background: #fff; - box-shadow: 0 0 8px rgba(0, 0, 0, 0.075); + box-shadow: 0 0 12px rgba(0, 0, 0, 0.15); + transition: box-shadow 0.1s ease-in; + cursor: pointer; - legend { - -webkit-touch-callout: none; - user-select: none; - color: #64b5f6; + img { + width: 100%; + height: 160px; + object-fit: fill; + } + + &:hover { + box-shadow: 0 0 12px rgba(0, 0, 0, 0.35); } } } @@ -144,12 +125,12 @@ body { to right, transparent, transparent 200px, - #fff3e3 200px + rgba(252, 232, 207, 0.6) 200px ); &::after { font-size: 46px; - text-indent: 300px; + text-indent: 360px; content: 'Drop epub file here...'; color: var(--color-grey-1); } diff --git a/src/css/float.css b/src/css/float.css deleted file mode 100644 index 49cecd4..0000000 --- a/src/css/float.css +++ /dev/null @@ -1 +0,0 @@ -html{font-size:12.8px;width:100%;height:100vh}body{display:flex;flex-direction:column;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app-drag{-webkit-app-region:drag;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.app-nodrag{-webkit-app-region:no-drag}.app{position:relative;display:flex;flex-direction:column;height:100%;padding:6px 0}.app .list{flex:1}.app .list .item{display:flex;align-items:center;height:54px;padding:10px 12px;line-height:15px;border-bottom:1px solid rgba(155,155,155,0.3)}.app .list .item:last-child{border-bottom:0}.app .list .item .info{overflow:hidden;flex:1}.app .list .item .info h3{font-size:14px}.app .list .item .info cite{color:var(--color-grey-2)}.app .list .item .last-days{display:flex;width:64px;height:30px;margin:0 6px}.app .list .item .today{width:52px;font-size:12px;text-align:right}.app .list .item .today span{display:block;padding:0 4px}.app .list .item .today .percent{border-radius:2px;color:#fff}.app .list .item .today .percent.red{background:var(--color-red-1)}.app .list .item .today .percent.green{background:var(--color-green-3)} diff --git a/src/css/float.scss b/src/css/float.scss deleted file mode 100644 index fee5379..0000000 --- a/src/css/float.scss +++ /dev/null @@ -1,97 +0,0 @@ -@charset "UTF-8"; -/** - * 浮窗样式 - * @authors yutent - * @date 2018/12/16 17:15:07 - */ - -html { - font-size: 12.8px; - width: 100%; - height: 100vh; -} - -body { - display: flex; - flex-direction: column; - width: 100%; - height: 100%; - line-height: 1.25; - font-size: 14px; - color: var(--color-dark-1); - background: rgba(255, 255, 255, 0.3); -} - -.app-drag { - -webkit-app-region: drag; - user-select: none; -} -.app-nodrag { - -webkit-app-region: no-drag; -} - -.app { - position: relative; - display: flex; - flex-direction: column; - height: 100%; - padding: 6px 0; - - .list { - flex: 1; - - .item { - display: flex; - align-items: center; - height: 54px; - padding: 10px 12px; - line-height: 15px; - border-bottom: 1px solid rgba(155, 155, 155, 0.3); - - &:last-child { - border-bottom: 0; - } - - .info { - overflow: hidden; - flex: 1; - - h3 { - font-size: 14px; - } - cite { - color: var(--color-grey-2); - } - } - - .last-days { - display: flex; - width: 64px; - height: 30px; - margin: 0 6px; - } - - .today { - width: 52px; - font-size: 12px; - text-align: right; - - span { - display: block; - padding: 0 4px; - } - .percent { - border-radius: 2px; - color: #fff; - - &.red { - background: var(--color-red-1); - } - &.green { - background: var(--color-green-3); - } - } - } - } - } -} diff --git a/src/css/view.css b/src/css/view.css new file mode 100644 index 0000000..20a8033 --- /dev/null +++ b/src/css/view.css @@ -0,0 +1 @@ +html{width:100%;height:100vh}body{display:flex;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app{position:relative;display:flex;width:100%;height:100%}.app .toc{width:260px;height:100%}.app .toc item{display:flex;align-items:center;height:36px;padding:0 12px;border-bottom:1px solid var(--color-plain-1);cursor:pointer}.app .toc item.lev-0{font-weight:bold}.app .toc item.lev-1{padding-left:24px;font-weight:bold}.app .toc item.lev-2{padding-left:36px}.app .toc item.lev-3{padding-left:48px}.app .toc item:hover{color:var(--color-blue-1)}.app .toc item.active{color:#fff;background:var(--color-blue-1)}.app .toc item:last-child{border-bottom:0}.app .chapter-box{flex:1;height:100%;border-left:1px solid var(--color-plain-2)}.app .chapter{display:flex;justify-content:center;padding:8px 24px}.app .chapter .detail{max-width:768px;line-height:1.5;font-size:14px}.app .chapter .detail a{text-decoration:underline;color:var(--color-teal-2)}.app .chapter .detail a:hover{color:var(--color-teal-1);text-decoration:none}.app .chapter .detail em,.app .chapter .detail del{color:var(--color-grey-2)}.app .chapter .detail strong,.app .chapter .detail strong em,.app .chapter .detail strong{color:var(--color-dark-3)}.app .chapter .detail a strong,.app .chapter .detail a em{color:inherit}.app .chapter .detail em,.app .chapter .detail strong,.app .chapter .detail del{padding:0 2px}.app .chapter .detail img{max-width:100%}.app .chapter .detail blockquote{margin:10px 0;padding:5px 10px;line-height:1.5;border-left:5px solid var(--color-teal-1);background:#f2faf7;color:var(--color-grey-2)}.app .chapter .detail blockquote p{margin:0}.app .chapter .detail>p{margin:12px 0}.app .chapter .detail ol{margin-left:1em;list-style:decimal outside none}.app .chapter .detail ul{margin-left:1em;list-style:disc outside none}.app .chapter .detail li{margin:0.5em 0}.app .chapter .detail li ol{margin-left:1em}.app .chapter .detail li ul{margin-left:1em;list-style-type:circle}.app .chapter .detail li ol ul,.app .chapter .detail li ul ul{list-style-type:square}.app .chapter .detail h1,.app .chapter .detail h2,.app .chapter .detail h3,.app .chapter .detail h4,.app .chapter .detail h5,.app .chapter .detail h6{margin:15px 0;line-height:2;font-weight:bold;font-size:16px}.app .chapter .detail h1 code.inline,.app .chapter .detail h2 code.inline,.app .chapter .detail h3 code.inline,.app .chapter .detail h4 code.inline,.app .chapter .detail h5 code.inline,.app .chapter .detail h6 code.inline{background:none}.app .chapter .detail h1 a,.app .chapter .detail h2 a,.app .chapter .detail h3 a,.app .chapter .detail h4 a,.app .chapter .detail h5 a,.app .chapter .detail h6 a{text-decoration:none;color:#333}.app .chapter .detail h3 a::before,.app .chapter .detail h4 a::before,.app .chapter .detail h5 a::before,.app .chapter .detail h6 a::before{content:'∮ ';color:var(--color-teal-1);font-weight:normal}.app .chapter .detail h1{margin:0 0 30px;font-size:24px;text-align:center}.app .chapter .detail h2{margin:20px 0;font-size:22px;border-bottom:1px solid var(--color-plain-2)}.app .chapter .detail h3{margin:20px 0 15px;font-size:20px}.app .chapter .detail h4{font-size:18px}.app .chapter .detail table{width:100%;border-spacing:0;border-collapse:collapse}.app .chapter .detail table tr{background-color:#fff}.app .chapter .detail table thead tr{background:var(--color-plain-1)}.app .chapter .detail table th,.app .chapter .detail table td{padding:6px 13px;border:1px solid var(--color-plain-2)}.app .chapter .detail table th{font-weight:bold}.app .chapter .detail table tr:nth-child(2n){background-color:#fcfdff} diff --git a/src/css/view.scss b/src/css/view.scss new file mode 100644 index 0000000..31b0d40 --- /dev/null +++ b/src/css/view.scss @@ -0,0 +1,233 @@ +@charset "UTF-8"; +/** + * 浮窗样式 + * @authors yutent + * @date 2018/12/16 17:15:07 + */ + +html { + width: 100%; + height: 100vh; +} + +body { + display: flex; + width: 100%; + height: 100%; + line-height: 1.25; + font-size: 14px; + color: var(--color-dark-1); + background: rgba(255, 255, 255, 0.3); +} + +.app { + position: relative; + display: flex; + width: 100%; + height: 100%; + + .toc { + width: 260px; + height: 100%; + + item { + display: flex; + align-items: center; + height: 36px; + padding: 0 12px; + border-bottom: 1px solid var(--color-plain-1); + cursor: pointer; + + &.lev-0 { + font-weight: bold; + } + &.lev-1 { + padding-left: 24px; + font-weight: bold; + } + &.lev-2 { + padding-left: 36px; + } + &.lev-3 { + padding-left: 48px; + } + + &:hover { + color: var(--color-blue-1); + } + + &.active { + color: #fff; + background: var(--color-blue-1); + } + &:last-child { + border-bottom: 0; + } + } + } + + .chapter-box { + flex: 1; + height: 100%; + border-left: 1px solid var(--color-plain-2); + } + + .chapter { + display: flex; + justify-content: center; + padding: 8px 24px; + + .detail { + max-width: 768px; + line-height: 1.5; + font-size: 14px; + + a { + text-decoration: underline; + color: var(--color-teal-2); + } + a:hover { + color: var(--color-teal-1); + text-decoration: none; + } + + em, + del { + color: var(--color-grey-2); + } + strong, + strong em, + strong { + color: var(--color-dark-3); + } + a { + strong, + em { + color: inherit; + } + } + em, + strong, + del { + padding: 0 2px; + } + + img { + max-width: 100%; + } + + blockquote { + margin: 10px 0; + padding: 5px 10px; + line-height: 1.5; + border-left: 5px solid var(--color-teal-1); + background: #f2faf7; + color: var(--color-grey-2); + p { + margin: 0; + } + } + + > p { + margin: 12px 0; + // text-indent: 2em; + } + + ol { + margin-left: 1em; + list-style: decimal outside none; + } + ul { + margin-left: 1em; + list-style: disc outside none; + } + li { + margin: 0.5em 0; + } + li ol { + margin-left: 1em; + } + li ul { + margin-left: 1em; + list-style-type: circle; + } + li ol ul, + li ul ul { + list-style-type: square; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin: 15px 0; + line-height: 2; + font-weight: bold; + font-size: 16px; + + code.inline { + background: none; + } + a { + text-decoration: none; + color: #333; + } + } + h3, + h4, + h5, + h6 { + a { + &::before { + content: '∮ '; + color: var(--color-teal-1); + font-weight: normal; + } + } + } + h1 { + margin: 0 0 30px; + font-size: 24px; + text-align: center; + } + h2 { + margin: 20px 0; + font-size: 22px; + border-bottom: 1px solid var(--color-plain-2); + } + h3 { + margin: 20px 0 15px; + font-size: 20px; + } + h4 { + font-size: 18px; + } + + table { + width: 100%; + border-spacing: 0; + border-collapse: collapse; + + tr { + background-color: #fff; + } + thead tr { + background: var(--color-plain-1); + } + th, + td { + padding: 6px 13px; + border: 1px solid var(--color-plain-2); + } + th { + font-weight: bold; + } + tr:nth-child(2n) { + background-color: #fcfdff; + } + } + } + } +} diff --git a/src/index.html b/src/index.html index 238b420..c3eb069 100644 --- a/src/index.html +++ b/src/index.html @@ -25,15 +25,15 @@ -
- - - - {{it.title}} - - - -
+ + + + + + + + +
diff --git a/src/js/app.js b/src/js/app.js index dc3ad95..f43c2d6 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -7,14 +7,9 @@ */ import '/lib/anot.js' -import '/lib/form/button.js' -import '/lib/form/switch.js' import '/lib/scroll/index.js' -import '/lib/chart/rank.js' -import '/lib/chart/line.js' import layer from '/lib/layer/index.js' -import Utils from '/lib/utils.js' import app from '/lib/socket.js' @@ -37,14 +32,14 @@ Anot({ load: { num: 0, curr: 0 - } + }, + $db: {} }, watch: {}, mounted() { $doc.bind('dragover', ev => { - ev.stopPropagation() ev.preventDefault() this.isDragIn = true @@ -56,9 +51,8 @@ Anot({ }) $doc.bind('drop', ev => { - ev.stopPropagation() ev.preventDefault() - // clearTimeout(this.timer) + this.isDragIn = false let files = Array.from(ev.dataTransfer.files) @@ -73,20 +67,34 @@ Anot({ this.load.curr = 0 this.loading = true - console.time(1) while (this.load.curr < this.load.num) { this.load.curr++ let book = files.pop() let res = app.dispatch('parse-book', { book, cate: this.curr }) - console.log(res) + if (res) { this.books.push(res) } } - console.timeEnd(1) this.loading = false }) + + let db = app.dispatch('get-books') + let cates = [], + books + for (let k in db) { + cates.push({ name: k, num: db[k].length }) + // 默认选中第一个 + if (!books) { + this.curr = k + books = db[k] + } + } + // books = books.concat(books, books, books, books, books, books) + this.$db = db + this.cates = cates + this.books = books }, methods: {} }) diff --git a/src/js/float.js b/src/js/float.js deleted file mode 100644 index 0b70692..0000000 --- a/src/js/float.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * - * @author yutent - * @date 2020/12/10 19:53:05 - */ - -import '/lib/anot.js' - -import '/lib/scroll/index.js' -import layer from '/lib/layer/index.js' -import app from '/lib/socket.js' - -function getJsonp(str) { - if (~str.indexOf('jsonpgz')) { - return new Function(`function jsonpgz(d){return d}; return ${str}`)() - } - return false -} - -Anot({ - $id: 'app', - state: { - list: [] - }, - mounted() { - this.reloadGays() - - app.on('float-visible', data => { - var time = +Anot.ss('last_update') || 0 - var now = Date.now() - - // 有触发小窗口显示时, 更新通知提醒 - if (Anot.ls('notify') === '1') { - app.dispatch('notify') - } - - this.reloadGays() - setTimeout(() => { - // 如果离上次更新超过15分钟, 则自动更新 - if (now - time > 15 * 60 * 1000) { - this.updateGays() - Anot.ss('last_update', now) - } - }, 500) - }) - }, - methods: { - reloadGays() { - var gays = Anot.ls('gays') || '{}' - var list = [] - - gays = JSON.parse(gays) - - for (let code in gays) { - let { name, cm, cp, t } = gays[code] - list.push({ code, name, cm, cp, t }) - } - list.sort((a, b) => b.cp - a.cp) - - this.list = list - }, - - getGayStat(id) { - var res = app.dispatch( - 'fetch', - `https://fundgz.1234567.com.cn/js/${id}.js` - ) - return getJsonp(res) - }, - - updateGay(item) { - var info = this.getGayStat(item.code) - item.cm = +info.gsz - item.cp = +info.gszzl - }, - - updateGays() { - for (let it of this.list) { - this.updateGay(it) - } - this.list.sort((a, b) => b.cp - a.cp) - this.saveCache() - app.dispatch('data-reload') - }, - saveCache() { - var dict = {} - for (let it of this.list) { - var { code, name, cm, cp, t } = it - dict[code] = { name, cm, cp, t } - } - Anot.ls('gays', dict) - } - } -}) diff --git a/src/js/view.js b/src/js/view.js new file mode 100644 index 0000000..70367ab --- /dev/null +++ b/src/js/view.js @@ -0,0 +1,84 @@ +/** + * + * @author yutent + * @date 2020/12/10 19:53:05 + */ + +import '/lib/anot.js' + +import '/lib/scroll/index.js' +import '/lib/code/index.js' +import layer from '/lib/layer/index.js' +import fetch from '/lib/fetch/index.js' +import app from '/lib/socket.js' + +Anot({ + $id: 'app', + state: { + toc: [], + title: 'HTML5 canvas开发详解(第2版) (无)', + curr: '', + file: '', + chapter: '' + }, + mounted() { + // app.on('float-visible', data => {}) + + document.title = this.title + this.getToc() + }, + methods: { + getToc() { + fetch('book://cache/HTML5 canvas开发详解(第2版) (无)/toc.json') + .then(r => r.json()) + .then(list => { + for (let it of list) { + delete it.id + delete it.order + } + this.toc = list + + this.viewChapter(list[23]) + }) + }, + + viewChapter(item) { + let pathes = item.href.split('#') + let file = pathes.shift() + let hash = pathes.shift() + + this.curr = item.title + + if (this.file === file) { + if (hash) { + location.hash = hash + } else { + location.hash = '' + this.$refs.chapter.scrollTop = 0 + } + } else { + this.file = file + fetch('book://cache/HTML5 canvas开发详解(第2版) (无)/' + file) + .then(r => r.text()) + .then(txt => { + this.chapter = txt.replace( + /]*?src="(.*?)"[^>]*?\/?>/g, + (m, s1) => { + s1 = s1.replace('../', '') + return `` + } + ) + + setTimeout(() => { + if (hash) { + location.hash = hash + } else { + location.hash = '' + this.$refs.chapter.scrollTop = 0 + } + }, 100) + }) + } + } + } +}) diff --git a/src/lib/chart/line.js b/src/lib/chart/line.js deleted file mode 100644 index 83d738b..0000000 --- a/src/lib/chart/line.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - -import $ from '../utils.js' -import '../form/button.js' - -const DARK = '#62778d' -const BLUE = '#64b5f6' -const PLAIN = '#f2f5fc' - -export default class Line extends HTMLElement { - static get observedAttributes() { - return ['list'] - } - - props = { - list: [] - } - - state = { - key: 1, - list: [] - } - - constructor() { - super() - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` -
- -
- 1月 - 3月 - 半年 - 1年 - 3年 - 所有 -
-
-` - - var elem = this.root.children[1] - this.__SCENE__ = elem.firstElementChild - this.__FILTER__ = elem.lastElementChild - this.__CTX__ = this.__SCENE__.getContext('2d') - this.__SCENE__.width = 680 - this.__SCENE__.height = 230 - } - - _getTime(n) { - var now = new Date() - var time = { getTime: _ => 0 } - var Y = now.getFullYear() - var m = now.getMonth() - var d = now.getDate() - - switch (n) { - case 1: - time = new Date(Y, m - 1, d, 0, 0, 0) - break - case 3: - time = new Date(Y, m - 3, d, 0, 0, 0) - break - case 6: - time = new Date(Y, m - 6, d, 0, 0, 0) - break - case 12: - time = new Date(Y - 1, m, d, 0, 0, 0) - break - case 36: - time = new Date(Y - 3, m, d, 0, 0, 0) - break - } - return time.getTime() - } - - _filter(n) { - if (n < 999) { - var time = this._getTime(n) - this.state.list = this.props.list.filter(it => it.x >= time) - } else { - this.state.list = this.props.list.concat() - } - } - - draw() { - var { list, key } = this.state - var ctx = this.__CTX__ - var x = 36 - var max = 0 - var min = Number.MAX_SAFE_INTEGER - var step = 0 // 纵坐标间隔 - var dis = +(640 / list.length).toFixed(2) || 1 // 横坐标间隔 - var point - var p1, p2, p3, p4 - var format = key > 12 ? 'Y/m' : 'm/d' - - for (let it of list) { - if (max < it.y) { - max = it.y - } - if (min > it.y) { - min = it.y - } - } - - min = ~~(min / 100) - max = Math.ceil(max / 100) - step = ~~((max - min) / 3) - - p1 = Math.floor(list.length / 4) - p2 = Math.floor(list.length / 2) - p3 = Math.floor((list.length * 3) / 4) - p4 = list.length - 1 - - ctx.clearRect(0, 0, 680, 230) - - // 纵坐标数值 - ctx.font = '12px Arial' - ctx.textAlign = 'right' - ctx.fillStyle = DARK - ctx.fillText(min / 100, 32, 205) - ctx.fillText((min + step) / 100, 32, 155) - ctx.fillText((min + step + step) / 100, 32, 105) - ctx.fillText((min + step + step + step) / 100, 32, 55) - - ctx.font = '10px Arial' - ctx.textAlign = 'left' - ctx.fillText(new Date(list[0].x).format(format), x - 12, 225) - ctx.fillText(new Date(list[p1].x).format(format), x + dis * p1 - 12, 225) - ctx.fillText(new Date(list[p2].x).format(format), x + dis * p2 - 12, 225) - ctx.fillText(new Date(list[p3].x).format(format), x + dis * p3 - 12, 225) - ctx.fillText( - new Date(list[p4].x).format(format), - x + dis * p4 - 12 - (key > 12 ? 24 : 4), - 225 - ) - - // x轴参考线 - ctx.fillStyle = PLAIN - ctx.fillRect(x, 50, 648, 1) - ctx.fillRect(x, 100, 648, 1) - ctx.fillRect(x, 150, 648, 1) - ctx.fillRect(x, 200, 648, 1) - - // y轴参考 线 - ctx.fillRect(x, 0, 1, 210) - ctx.fillRect(x + dis * p1, 0, 1, 210) - ctx.fillRect(x + dis * p2, 0, 1, 210) - ctx.fillRect(x + dis * p3, 0, 1, 210) - ctx.fillRect(x + dis * p4, 0, 1, 210) - - point = list.shift() - - // 曲线 - ctx.beginPath() - ctx.strokeStyle = BLUE - ctx.lineWidth = 1 - ctx.moveTo(x, 200 - (((point.y / 100 - min) / step) * 50).toFixed(0)) - - while (list.length) { - let y - - point = list.shift() - - y = 200 - (((point.y / 100 - min) / step) * 50).toFixed(0) - x += dis - - ctx.lineTo(x, y) - } - ctx.stroke() - } - - connectedCallback() { - $.bind(this.__FILTER__, 'click', ev => { - var el = ev.target - if (this.props.list.length < 1) { - return - } - if (el.tagName === 'WC-BUTTON') { - var k = +el.dataset.key - - $.each(this.__FILTER__.children, function(it) { - it.removeAttribute('color') - }) - el.setAttribute('color', 'blue') - - this.state.key = k - this._filter(k) - this.draw() - } - }) - } - - attributeChangedCallback(name, old, val) { - if (val === null || old === val) { - return - } - switch (name) { - case 'list': - try { - var list = JSON.parse(val) - list.forEach(it => (it.x = it.x * 1000)) - this.props.list = list - this._filter(this.state.key) - this.removeAttribute('list') - this.draw() - } catch (e) {} - break - } - } -} - -if (!customElements.get('wc-line')) { - customElements.define('wc-line', Line) -} diff --git a/src/lib/chart/rank.js b/src/lib/chart/rank.js deleted file mode 100644 index d34a0b6..0000000 --- a/src/lib/chart/rank.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * - * @authors yutent (yutent.io@gmail.com) - * @date 2020-12-08 11:30:52 - * @version v1.0.0 - * - */ - -const RED = '#ff5061' -const GREEN = '#4caf50' -const BLUE = '#64b5f6' -const GREY = '#bdbdbd' -const PLAIN = '#f2f5fc' -const DARK = '#62778d' - -export default class Rank extends HTMLElement { - static get observedAttributes() { - return ['stat'] - } - - props = { - stat: {} - } - - constructor() { - super() - - Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), - writable: true, - enumerable: false, - configurable: true - }) - - this.root.innerHTML = ` - -` - - this.__SCENE__ = this.root.children[1] - this.__CTX__ = this.__SCENE__.getContext('2d') - this.__SCENE__.width = 680 - this.__SCENE__.height = 100 - } - - draw() { - var { rank, e1, e3, e6, e12, cm, cp } = this.props.stat - var ctx = this.__CTX__ - var x = 32 - - while (rank.length < 60) { - rank.unshift(0) - } - - ctx.clearRect(0, 0, 680, 101) - - ctx.font = '10px Arial' - ctx.textAlign = 'right' - ctx.fillStyle = RED - ctx.fillText('10%', 28, 10) - ctx.fillText('5%', 28, 30) - ctx.fillStyle = GREEN - ctx.fillText('-5%', 28, 80) - ctx.fillText('-10%', 28, 100) - - ctx.font = '10px menlo,Hiragino Sans GB' - ctx.textAlign = 'left' - ctx.fillStyle = DARK - ctx.fillText('60天红绿榜', 160, 10) - - ctx.font = '12px menlo,Hiragino Sans GB' - ctx.fillText(`最近1个月收益: ${e1}%`, 360, 25) - ctx.fillText(`最近3个月收益: ${e3}%`, 360, 45) - ctx.fillText(`最近半年收益: ${e6}%`, 528, 25) - ctx.fillText(`最近一年收益: ${e12}%`, 528, 45) - - ctx.fillStyle = cp > 0 ? RED : cp === 0 ? GREY : GREEN - ctx.fillRect(360, 65, 140, 20) - ctx.fillRect(526, 65, 140, 20) - ctx.fillStyle = '#fff' - ctx.font = 'bold 14px menlo,Hiragino Sans GB' - ctx.fillText(`实时净值: ¥${cm}`, 364, 80) - ctx.fillText(`实时涨跌: ${cp}%`, 532, 80) - - ctx.fillStyle = PLAIN - ctx.fillRect(28, 25, 320, 1) - ctx.fillRect(28, 75, 320, 1) - ctx.fillStyle = GREY - ctx.fillRect(28, 0, 1, 140) - ctx.fillRect(0, 50, 348, 1) - - while (rank.length) { - var n = rank.shift() - var y = Math.ceil(50 - (n / 10) * 50) - - ctx.fillStyle = n > 0 ? RED : GREEN - - if (y > 50) { - ctx.fillRect(x, 50, 3, y - 50) - } else { - ctx.fillRect(x, y, 3, 50 - y) - } - - x += 5 - } - } - - attributeChangedCallback(name, old, val) { - if (val === null || old === val) { - return - } - switch (name) { - case 'stat': - try { - var stat = JSON.parse(val) - this.props.stat = stat - this.removeAttribute('stat') - this.draw() - } catch (e) {} - break - } - } -} - -if (!customElements.get('wc-rank')) { - customElements.define('wc-rank', Rank) -} diff --git a/src/lib/code/index.js b/src/lib/code/index.js new file mode 100644 index 0000000..3cec96c --- /dev/null +++ b/src/lib/code/index.js @@ -0,0 +1,13 @@ +/** + * + * @authors yutent (yutent.io@gmail.com) + * @date 2020-12-23 15:31:02 + * @version v1.0.0 + * + */ + +import"../scroll/index.js";import"../layer/index.js";import $ from"../utils.js";export default class Code extends HTMLElement{static get observedAttributes(){return["dark","lang"]}props={dark:"",lang:""};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
';var e=this.root.children[1],o=e.children[0];this.__CODE__=e.children[1],this.__LANG__=o.children[1],this.__RUN__=o.children[2].firstElementChild,this.__CP__=o.children[2].lastElementChild}get value(){return this.props.content}set value(e){this.props.content=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),e=(e=e.replace(//g,">").split("\n")).map(e=>`

${e}

`).join(""),this.__CODE__.innerHTML=e}connectedCallback(){var e=this.innerHTML||this.textContent;this.value=e.replace(/^[\r\n]|\s{2,}$/g,""),this.textContent="",this._cpFN=$.bind(this.__CP__,"click",e=>{try{navigator.clipboard.writeText(this.value),layer.toast("复制到粘贴板成功","success")}catch(e){layer.toast("复制到粘贴板失败","error")}}),this._runFN=$.bind(this.__RUN__,"click",e=>{this.dispatchEvent(new CustomEvent("run",{detail:this.value}))})}unmounted(){$.unbind(this.__CP__,"click",this._cpFN),$.unbind(this.__RUN__,"click",this._runFN)}attributeChangedCallback(e,o,r){if(null!==r&&o!==r)switch(e){case"lang":this.props.lang=r.toLowerCase(),this.__LANG__.textContent=this.props.lang;break;case"value":this.value=r,this.removeAttribute("value")}}} + +if(!customElements.get('wc-code')){ + customElements.define('wc-code', Code) +} diff --git a/src/lib/fetch/index.js b/src/lib/fetch/index.js new file mode 100644 index 0000000..957263e --- /dev/null +++ b/src/lib/fetch/index.js @@ -0,0 +1 @@ +import{Format,toS}from"./lib/format.js";const noop=function(e,t){this.defer.resolve(t)},NOBODY_METHODS=["GET","HEAD"],FORM_TYPES={form:"application/x-www-form-urlencoded; charset=UTF-8",json:"application/json; charset=UTF-8",text:"text/plain; charset=UTF-8"},ERRORS={10001:"Argument url is required",10012:"Parse error",10100:"Request canceled",10104:"Request pending...",10200:"Ok",10204:"No content",10304:"Not modified",10500:"Internal Server Error",10504:"Connected timeout"};Promise.defer=function(){var e={};return e.promise=new Promise(function(t,s){e.resolve=t,e.reject=s}),e};class _Request{constructor(e="",t={},{BASE_URL:s,__INIT__:r}){if(!e)throw new Error(ERRORS[10001]);if(e=e.replace(/#.*$/,""),s&&(/^([a-z]+:|\/\/)/.test(e)||(e=s+e)),t.method=(t.method||"get").toUpperCase(),this.xhr=new XMLHttpRequest,this.defer=Promise.defer(),this.options={headers:{"X-Requested-With":"XMLHttpRequest","content-type":FORM_TYPES.form},body:null,cache:"default",credentials:!1,signal:null,timeout:3e4},!t.signal){var o=new AbortController;t.signal=o.signal}this.defer.promise.abort=function(){o.abort()};var i=this.options.headers;return r.headers&&Object.assign(i,r.headers),t.headers&&(Object.assign(i,t.headers),delete t.headers),Object.assign(this.options,r,t,{url:e,headers:i}),this.__next__(),this.defer.promise}__next__(){var e=this.options,t=null,s=!1,r=!1,o=NOBODY_METHODS.includes(e.method);if(e.signal.onabort=(e=>{this.cancel=!0,this.xhr.abort()}),e.body)switch(typeof e.body){case"number":case"string":this.__type__("text"),t=e.body;break;case"object":if("FORM"===e.body.nodeName)e.method=e.body.method.toUpperCase()||"POST",s=(t=Format.parseForm(e.body)).constructor===FormData;else if(e.body.constructor===FormData)s=!0,o&&(e.method="POST"),t=e.body;else{for(let t in e.body)if("[object File]"===toS.call(e.body[t])){s=!0;break}s?(o&&(e.method="POST"),t=Format.mkFormData(e.body)):t=e.body}}s&&delete e.headers["content-type"];try{let t=document.createElement("a");t.href=e.url,r=location.protocol!==t.protocol||location.host!==t.host}catch(e){}r&&(e.credentials?this.xhr.withCredentials=!0:delete e.headers["X-Requested-With"]),o?((t=Format.param(t))&&(e.url+=(~e.url.indexOf("?")?"&":"?")+t),"no-store"===e.cache&&(e.url+=(~e.url.indexOf("?")?"&":"?")+"_t_="+Date.now())):s||(t=~e.headers["content-type"].indexOf("json")?JSON.stringify(t):Format.param(t)),this.xhr.responseType="blob",this.xhr.onreadystatechange=(t=>{e.timeout>0&&(e["time"+this.xhr.readyState]=t.timeStamp,4===this.xhr.readyState&&(e.isTimeout=e.time4-e.time1>e.timeout)),4===this.xhr.readyState&&this.__dispatch__(e.isTimeout)}),this.xhr.open(e.method,e.url);for(let t in e.headers)this.xhr.setRequestHeader(t,e.headers[t]);this.xhr.send(t),e.timeout&&e.timeout>0&&(this.xhr.timeout=e.timeout)}__type__(e){this.options.headers["content-type"]=FORM_TYPES[e]}__dispatch__(e){let t={status:200,statusText:"ok",body:"",headers:Object.create(null)};if(this.cancel)return this.__cancel__();if(e)return this.__timeout__();let s=this.xhr.status>=200&&this.xhr.status<400,r=this.xhr.getAllResponseHeaders().split("\n")||[];for(let e of r)if(e=e.trim()){let s=(e=e.split(":")).shift().toLowerCase();e=e.join(":").trim(),t.headers[s]=e}s?(t.status=this.xhr.status,204===t.status?t.statusText=ERRORS[10204]:304===t.status&&(t.statusText=ERRORS[10304])):(t.status=this.xhr.status||500,t.statusText=this.xhr.statusText||ERRORS[10500]),t.body=this.xhr.response,this.__success__(s,t)}__success__(e,t){var s=new _Response(t.status,t.statusText,t.body,t.headers);e?this.defer.resolve(s):this.defer.reject(s),delete this.xhr,delete this.options,delete this.defer}__cancel__(e){var t=new _Response(0,ERRORS[10100],Object.create(null));this.defer.reject(t),delete this.xhr,delete this.options,delete this.defer}__timeout__(e){var t=new _Response(504,ERRORS[10504],Object.create(null));this.defer.reject(t),delete this.xhr,delete this.options,delete this.defer}}class _Response{constructor(e=200,t="OK",s=null,r={}){this.status=e,this.statusText=t,this.ok=e>=200&&e<400,this.headers=r,Object.defineProperty(this,"__R__",{value:s,writable:!0,enumerable:!1,configurable:!0})}text(){return this.__R__.text()}json(){return this.__R__.text().then(e=>JSON.parse(e))}blob(){return this.__R__}arrayBuffer(){return this.__R__.arrayBuffer()}}const _fetch=function(e,t){return new _Request(e,t,{BASE_URL:_fetch.BASE_URL,__INIT__:_fetch.__INIT__||Object.create(null)})};_fetch.create=function(e,t=Object.create(null)){return function(s,r){return new _Request(s,r,{BASE_URL:e,__INIT__:t})}};export default _fetch; \ No newline at end of file diff --git a/src/lib/fetch/lib/format.js b/src/lib/fetch/lib/format.js new file mode 100644 index 0000000..f3747b4 --- /dev/null +++ b/src/lib/fetch/lib/format.js @@ -0,0 +1 @@ +export const toS=Object.prototype.toString;export const encode=encodeURIComponent;export const decode=decodeURIComponent;function serialize(e,t,o){var a;if(Array.isArray(t))t.forEach(function(t,r){a=e?`${e}[${Array.isArray(t)?r:""}]`:r,"object"==typeof t?serialize(a,t,o):o(a,t)});else for(let r in t)a=e?`${e}[${r}]`:r,"object"==typeof t[r]?serialize(a,t[r],o):o(a,t[r])}export const Format={parseForm(e){let t={},o=!1;for(let a,r=0;a=e.elements[r++];)switch(a.type){case"select-one":case"select-multiple":if(a.name.length&&!a.disabled)for(let e,o=0;e=a.options[o++];)e.selected&&(t[a.name]=e.value||e.text);break;case"file":a.name.length&&!a.disabled&&(t[a.name]=a.files[0],o=!0);break;case void 0:case"submit":case"reset":case"button":break;case"radio":case"checkbox":if(!a.checked)break;default:a.name.length&&!a.disabled&&(t[a.name]=a.value)}return o?this.mkFormData(t):t},mkFormData(e){let t=new FormData;for(let o in e){let a=e[o];Array.isArray(a)?a.forEach(function(e){t.append(o+"[]",e)}):t.append(o,e[o])}return t},param(e){if(!e||"string"==typeof e||"number"==typeof e)return e;let t=[];return"object"==typeof e&&serialize("",e,function(e,o){/native code/.test(o)||(o="function"==typeof o?o():o,o="[object File]"===toS.call(o)?o:encode(o),t.push(encode(e)+"="+o))}),t.join("&")}}; \ No newline at end of file diff --git a/src/main.js b/src/main.js index 2cb7969..c6a5ffc 100644 --- a/src/main.js +++ b/src/main.js @@ -9,7 +9,7 @@ const path = require('path') const fs = require('iofs') require('./tools/init') -const { createMainWindow, createFloatWindow } = require('./tools/window') +const { createMainWindow, createViewWindow } = require('./tools/window') const createMenu = require('./tools/menu') const Socket = require('./tools/socket') @@ -50,7 +50,9 @@ protocol.registerSchemesAsPrivileged([ app.once('ready', () => { // 注册协议 protocol.registerStreamProtocol('app', function(req, cb) { - var file = decodeURIComponent(req.url.replace(/^app:\/\/local\//, '')) + var file = decodeURIComponent( + req.url.replace(/^app:\/\/local\//, '') + ).replace(/\#.*$/, '') var ext = path.extname(file) file = path.resolve(ROOT, file) @@ -69,7 +71,6 @@ app.once('ready', () => { var ext = path.extname(file) file = path.resolve(CACHE_DIR, file) - console.log(file) cb({ data: fs.origin.createReadStream(file), mimeType: MIME_TYPES[ext] || MIME_TYPES.all, @@ -81,14 +82,14 @@ app.once('ready', () => { // 创建浏览器窗口 app.__main__ = createMainWindow(path.resolve(ROOT, './images/app.png')) - // app.__float__ = createFloatWindow() + app.__view__ = createViewWindow() createMenu(app.__main__) Socket(app) app.__main__.on('closed', () => { app.__main__ = null - app.__float__ = null + app.__view__ = null app.exit() }) diff --git a/src/tools/socket.js b/src/tools/socket.js index 656da4b..104bf1e 100644 --- a/src/tools/socket.js +++ b/src/tools/socket.js @@ -45,13 +45,18 @@ module.exports = function(app) { }) break + case 'get-books': + ev.returnValue = JSON.parse(fs.cat(DB_FILE)) + break + case 'parse-book': let { book, cate } = conn.data let eb = new Epub(book.path) let cache = JSON.parse(fs.cat(DB_FILE)) eb.on('end', async _ => { - let { title, cover } = eb.metadata + let { title } = eb.metadata + let cover = 'cover' let dir = path.join(CACHE_DIR, title) function saveImage(id, name) { @@ -65,12 +70,21 @@ module.exports = function(app) { function saveHtml(id, name) { return new Promise(done => { - eb.getChapter(id, (err, txt) => { - // txt = (txt + '').replace( - // /<(?!img|image)([\w\-]+)[^>]*>/g, - // '<$1>' - // ) - fs.echo(txt, path.join(dir, name.replace('.xhtml', '.html'))) + eb.getChapterRaw(id, (err, txt) => { + let m = (txt + '').match(/]*?>([\w\W]+)<\/body>/) + if (m) { + let htm = m[1] + .replace( + /<(?!img|image)([\w\-]+)[^>]*?( id="[^\s]*?")?[^>]*?>/g, + '<$1$2>' + ) + .replace(/
/g, '')
+                    .replace(/<\/code><\/pre>/g, '')
+
+                  fs.echo(htm, path.join(dir, name.replace('.xhtml', '.html')))
+                } else {
+                  console.log(id, name, txt)
+                }
                 done()
               })
             })
diff --git a/src/tools/window.js b/src/tools/window.js
index f7ea2e3..864afc0 100644
--- a/src/tools/window.js
+++ b/src/tools/window.js
@@ -27,10 +27,10 @@ exports.createMainWindow = function(icon) {
 
   win.loadURL('app://local/index.html')
 
-  win.on('ready-to-show', _ => {
-    win.show()
-    win.openDevTools()
-  })
+  // win.on('ready-to-show', _ => {
+  //   win.show()
+  //   win.openDevTools()
+  // })
 
   win.on('close', ev => {
     ev.preventDefault()
@@ -41,16 +41,14 @@ exports.createMainWindow = function(icon) {
 }
 
 // 创建悬浮窗口
-exports.createFloatWindow = function() {
+exports.createViewWindow = function() {
   var win = new BrowserWindow({
-    width: 280,
-    height: 360,
-    resizable: false,
-    maximizable: false,
-    frame: false,
-    show: false,
-    vibrancy: 'hud',
-    visualEffectState: 'active',
+    width: 1024,
+    height: 768,
+    minWidth: 1024,
+    minHeight: 768,
+    // show: false,
+    title: 'E-pub Reader',
     webPreferences: {
       experimentalFeatures: true,
       nodeIntegration: true,
@@ -58,13 +56,9 @@ exports.createFloatWindow = function() {
     }
   })
 
-  // win.openDevTools()
+  win.openDevTools()
 
-  win.on('blur', ev => {
-    win.hide()
-  })
-
-  win.loadURL('app://local/float.html')
+  win.loadURL('app://local/view.html')
 
   return win
 }
diff --git a/src/view.html b/src/view.html
index 13184a1..5bee159 100644
--- a/src/view.html
+++ b/src/view.html
@@ -6,31 +6,28 @@
   
   
   
-  
-  
+  
+  
 
-
+
 
-  
- -
-
-

- -
+
+ + + + + -
- - - -
-
-
啥基都没有...
-
-
+ +
+
+
+
+