-
Notifications
You must be signed in to change notification settings - Fork 285
Expand file tree
/
Copy pathLocalBookReader-Bd1IWb8V.js
More file actions
5 lines (4 loc) · 13.2 KB
/
LocalBookReader-Bd1IWb8V.js
File metadata and controls
5 lines (4 loc) · 13.2 KB
1
2
3
4
5
import{_ as se,c as R,r as i,w as re,a as H,b as Le,o as w,d as I,e as c,f as u,g as N,u as E,I as te,h as oe,i as Pe,j as $,k as Re,t as L,F as ie,l as ue,m as ae,n as Ee,p as Ae,M as z,q as Me,s as Fe,v as He,x as Ve,y as le,R as ze,z as V,A as Ne,B as Ue,C as Ke,D as K,E as J}from"./index-Cs9-8tRv.js";const We={class:"bookmark-dialog"},Oe={class:"add-bookmark-section"},qe={class:"section-title"},Je={class:"add-bookmark-form"},je={class:"bookmarks-section"},Xe={class:"section-title"},Ge={key:0,class:"empty-state"},Qe={key:1,class:"bookmark-list"},Ye=["onClick"],Ze={class:"bookmark-content"},et={class:"bookmark-title"},tt={class:"bookmark-meta"},ot={class:"bookmark-progress"},at={class:"bookmark-time"},lt={class:"bookmark-actions"},nt={__name:"BookmarkDialog",props:{visible:{type:Boolean,default:!1},bookmarks:{type:Array,default:()=>[]}},emits:["update:visible","bookmark-selected","bookmark-added","bookmark-deleted","bookmark-updated"],setup(g,{emit:d}){const b=g,_=d,x=R({get:()=>b.visible,set:l=>_("update:visible",l)}),v=i(""),n=i(!1),s=i(null),a=i(""),p=R(()=>[...b.bookmarks].sort((l,r)=>r.createdAt-l.createdAt)),C=()=>{x.value=!1},B=()=>{v.value.trim()||(v.value=`书签 ${b.bookmarks.length+1}`),_("bookmark-added",{title:v.value.trim()}),v.value=""},j=l=>{_("bookmark-selected",l)},f=l=>{s.value=l,a.value=l.title,n.value=!0},m=()=>{if(!a.value.trim()){z.warning("书签标题不能为空");return}_("bookmark-updated",{id:s.value.id,title:a.value.trim()}),n.value=!1,s.value=null,a.value=""},y=()=>{n.value=!1,s.value=null,a.value=""},D=l=>{_("bookmark-deleted",l)},P=l=>{const r=new Date(l),t=new Date-r;return t<6e4?"刚刚":t<36e5?`${Math.floor(t/6e4)}分钟前`:t<864e5?`${Math.floor(t/36e5)}小时前`:t<6048e5?`${Math.floor(t/864e5)}天前`:r.toLocaleDateString()};return re(x,l=>{l||(v.value="")}),(l,r)=>{const k=H("a-input"),t=H("a-button"),A=H("a-modal");return w(),Le(A,{visible:x.value,"onUpdate:visible":r[3]||(r[3]=h=>x.value=h),title:"书签管理",width:"600px",footer:!1,onCancel:C},{default:I(()=>[c("div",We,[c("div",Oe,[c("div",qe,[u(E(te)),r[4]||(r[4]=N(" 添加书签 ",-1))]),c("div",Je,[u(k,{modelValue:v.value,"onUpdate:modelValue":r[0]||(r[0]=h=>v.value=h),placeholder:"输入书签标题(可选)",class:"bookmark-input",onKeyup:oe(B,["enter"])},null,8,["modelValue"]),u(t,{type:"primary",onClick:B},{icon:I(()=>[u(E(Pe))]),default:I(()=>[r[5]||(r[5]=N(" 添加 ",-1))]),_:1})])]),c("div",je,[c("div",Xe,[u(E(Re)),N(" 书签列表 ("+L(g.bookmarks.length)+") ",1)]),g.bookmarks.length===0?(w(),$("div",Ge,[u(E(te)),r[6]||(r[6]=c("p",null,"暂无书签",-1)),r[7]||(r[7]=c("p",{class:"empty-tip"},"在阅读时添加书签,方便快速定位",-1))])):(w(),$("div",Qe,[(w(!0),$(ie,null,ue(p.value,h=>(w(),$("div",{key:h.id,class:"bookmark-item",onClick:W=>j(h)},[c("div",Ze,[c("div",et,L(h.title),1),c("div",tt,[c("span",ot,L(h.percentage.toFixed(1))+"%",1),c("span",at,L(P(h.createdAt)),1)])]),c("div",lt,[u(t,{type:"text",size:"small",onClick:ae(W=>f(h),["stop"]),title:"编辑"},{icon:I(()=>[u(E(Ee))]),_:1},8,["onClick"]),u(t,{type:"text",size:"small",status:"danger",onClick:ae(W=>D(h.id),["stop"]),title:"删除"},{icon:I(()=>[u(E(Ae))]),_:1},8,["onClick"])])],8,Ye))),128))]))])]),u(A,{visible:n.value,"onUpdate:visible":r[2]||(r[2]=h=>n.value=h),title:"编辑书签",width:"400px",onOk:m,onCancel:y},{default:I(()=>[u(k,{modelValue:a.value,"onUpdate:modelValue":r[1]||(r[1]=h=>a.value=h),placeholder:"输入书签标题",onKeyup:oe(m,["enter"])},null,8,["modelValue"])]),_:1},8,["visible"])]),_:1},8,["visible"])}}},st=se(nt,[["__scopeId","data-v-ebf5cb56"]]),rt=[/^第[零一二三四五六七八九十百千万\d]+[章回节部分]/,/^第[零一二三四五六七八九十百千万\d]+[章回节部分][\s\S]*$/,/^[第]?[零一二三四五六七八九十百千万\d]+[、\s]*[章回节部分]/,/^第\d+章/,/^第\d+回/,/^第\d+节/,/^第\d+部分/,/^\d+[、\.\s]*[章回节部分]/,/^Chapter\s*\d+/i,/^Ch\.\s*\d+/i,/^序章/,/^楔子/,/^引子/,/^前言/,/^后记/,/^尾声/,/^终章/,/^番外/,/^外传/,/^附录/,/^Chapter\s+[IVX]+/i,/^Part\s+\d+/i,/^Section\s+\d+/i,/^【.*】$/,/^〖.*〗$/,/^《.*》$/,/^「.*」$/,/^『.*』$/];function it(g){const d=g.trim();if(!d||d.length>50)return!1;for(const b of rt)if(b.test(d))return!0;if(/^\d+$/.test(d)&&d.length<=3)return!0;if(d.length<=20&&!d.includes("。")&&!d.includes(",")){const b=["章","回","节","部","篇","Chapter","Part"];for(const _ of b)if(d.includes(_))return!0}return!1}function ut(g,d={}){const{minChapterLength:b=500,maxChapters:_=1e3,autoDetect:x=!0}=d;if(!g||typeof g!="string")return[];const v=g.split(/\r?\n/),n=[];let s=null,a=0,p=!1;for(let C=0;C<v.length;C++){const B=v[C].trim();if(x&&it(B)?(p=!0,s&&s.content.trim().length>=b&&(n.push(s),a++),s={id:a,title:B||`第${a+1}章`,content:"",startLine:C,endLine:C}):B&&(s||(s={id:a,title:`第${a+1}章`,content:"",startLine:C,endLine:C}),s.content&&(s.content+=`
`),s.content+=B,s.endLine=C),n.length>=_)break}return s&&s.content.trim().length>=b&&n.push(s),!p&&g.length>b||n.length<2&&g.length>b*2?ne(g,d):n}function ne(g,d={}){const{chapterLength:b=3e3,minChapterLength:_=500}=d,x=[],v=g.split(/\n\s*\n/).filter(a=>a.trim());let n={id:0,title:"第1章",content:"",startLine:0,endLine:0},s=0;for(let a=0;a<v.length;a++){const p=v[a].trim();n.content.length+p.length>b&&n.content.length>=_?(x.push(n),s++,n={id:s,title:`第${s+1}章`,content:p,startLine:a,endLine:a}):(n.content&&(n.content+=`
`),n.content+=p,n.endLine=a)}return n.content.trim()&&x.push(n),x}const ct={key:0,class:"loading-container"},dt={key:1,class:"error-container"},vt={class:"chapter-navigation"},pt={class:"chapter-progress"},ft={key:3,class:"empty-container"},mt={key:0,class:"progress-bar"},kt={class:"progress-text"},ht={__name:"LocalBookReader",setup(g){const d=Me(),b=Fe(),_=i(!0),x=i(!0),v=i(""),n=i(!1),s=i(!1),a=i(d.params.bookId),p=i(null),C=i(""),B=i(""),j=i(""),f=i([]),m=i(0),y=i(null),D=i(0),P=i(0),l=i([]),r=i(Date.now()),k=i(null),t=i({fontSize:16,lineHeight:1.8,fontFamily:"system-ui",backgroundColor:"#ffffff",textColor:"#333333",maxWidth:800,theme:"light",padding:40,showProgress:!0,autoSave:!0,saveInterval:3e4}),A=R(()=>{let e=t.value.backgroundColor,o=t.value.textColor;if(t.value.theme!=="custom"){const T={light:{backgroundColor:"#ffffff",textColor:"#333333"},dark:{backgroundColor:"#1a1a1a",textColor:"#e6e6e6"},sepia:{backgroundColor:"#f4f1e8",textColor:"#5c4b37"},green:{backgroundColor:"#c7edcc",textColor:"#2d5016"},parchment:{backgroundColor:"#fdf6e3",textColor:"#657b83"},night:{backgroundColor:"#2b2b2b",textColor:"#c9aa71"},blue:{backgroundColor:"#e8f4f8",textColor:"#1e3a5f"},pink:{backgroundColor:"#fdf2f8",textColor:"#831843"}}[t.value.theme];T&&(e=T.backgroundColor,o=T.textColor)}return{backgroundColor:e,color:o,fontFamily:t.value.fontFamily}}),h=R(()=>({maxWidth:`${t.value.maxWidth}px`,margin:"0 auto",padding:`${t.value.padding}px`})),W=R(()=>({fontSize:`${t.value.fontSize+4}px`,lineHeight:t.value.lineHeight,fontFamily:t.value.fontFamily,color:A.value.color})),ce=R(()=>({fontSize:`${t.value.fontSize}px`,lineHeight:t.value.lineHeight,color:A.value.color,maxWidth:`${t.value.maxWidth}px`,margin:"0 auto"})),de=R(()=>y.value?.content?y.value.content.split(`
`).filter(e=>e.trim()).map(e=>e.trim()):[]);R(()=>{const o=Date.now()-r.value,S=Math.floor(o/6e4);if(S<1)return"刚开始阅读";if(S<60)return`${S}分钟`;const T=Math.floor(S/60),F=S%60;return`${T}小时${F}分钟`});const X=async()=>{try{x.value=!0,v.value="";const e=K.getBookById(a.value);if(!e)throw new Error("未找到指定的图书");p.value=e,C.value=e.content,B.value=e.title,j.value=e.author,await ve(),e.readingProgress&&(D.value=e.readingProgress.position||0,P.value=e.readingProgress.percentage||0,e.readingProgress.chapterIndex!==void 0&&f.value[e.readingProgress.chapterIndex]&&(m.value=e.readingProgress.chapterIndex,y.value=f.value[e.readingProgress.chapterIndex])),l.value=e.bookmarks||[],await J(),D.value>0&&be()}catch(e){console.error("加载图书失败:",e),v.value=e.message||"加载图书失败"}finally{x.value=!1}},ve=async()=>{try{if(!C.value)return;const e=ut(C.value);f.value=e.map(o=>({...o,name:o.title||o.name||`第${o.id+1}章`})),f.value.length>0&&(y.value=f.value[0],m.value=0),console.log(`成功解析 ${f.value.length} 个章节`)}catch(e){console.error("章节解析失败:",e),f.value=[{title:B.value||"全文",name:B.value||"全文",content:C.value,startIndex:0,endIndex:C.value.length}],y.value=f.value[0],m.value=0}},G=()=>{m.value<f.value.length-1?(m.value++,y.value=f.value[m.value],J(()=>{k.value&&(k.value.scrollTop=0)}),M()):z.info("已经是最后一章了")},Q=()=>{m.value>0?(m.value--,y.value=f.value[m.value],J(()=>{k.value&&(k.value.scrollTop=0)}),M()):z.info("已经是第一章了")},pe=e=>{e>=0&&e<f.value.length&&(m.value=e,y.value=f.value[e],J(()=>{k.value&&(k.value.scrollTop=0)}),M())},fe=()=>{X()},Y=()=>{M(),_.value=!1,b.push("/book-gallery")},Z=e=>{e&&e.showDialog,n.value=!0},me=e=>{t.value={...t.value,...e},$e()},ke=()=>{s.value=!0},he=()=>{document.fullscreenElement?document.exitFullscreen():document.documentElement.requestFullscreen()},ge=()=>{if(!k.value)return;const e=k.value,o=e.scrollTop,S=e.scrollHeight,T=e.clientHeight,F=o/(S-T)*100;P.value=Math.min(100,Math.max(0,F)),D.value=o,t.value.autoSave&&Se()},M=()=>{if(!p.value)return;const e={position:D.value,percentage:P.value,chapterIndex:m.value,lastReadTime:Date.now()};K.updateReadingProgress(a.value,e)},be=()=>{k.value&&D.value>0&&(k.value.scrollTop=D.value)},Ce=e=>{k.value&&(k.value.scrollTop=e.position,D.value=e.position),s.value=!1},ye=e=>{l.value.push({id:Date.now(),title:e.title||`书签 ${l.value.length+1}`,position:D.value,percentage:P.value,createdAt:Date.now()}),p.value&&(p.value.bookmarks=l.value,K.updateBook(a.value,{bookmarks:l.value})),z.success("书签已添加")},_e=e=>{const o=l.value.findIndex(S=>S.id===e);o!==-1&&(l.value.splice(o,1),p.value&&(p.value.bookmarks=l.value,K.updateBook(a.value,{bookmarks:l.value})),z.success("书签已删除"))},xe=e=>{const o=l.value.findIndex(S=>S.id===e.id);o!==-1&&(l.value[o].title=e.title,p.value&&(p.value.bookmarks=l.value,K.updateBook(a.value,{bookmarks:l.value})),z.success("书签已更新"))};let U=null;const Se=()=>{U&&clearTimeout(U),U=setTimeout(()=>{M()},1e3)},we=()=>{try{const e=localStorage.getItem("drplayer_reading_settings");if(e){const o=JSON.parse(e);t.value={...t.value,...o}}}catch(e){console.warn("加载阅读设置失败:",e)}},$e=()=>{try{localStorage.setItem("drplayer_reading_settings",JSON.stringify(t.value))}catch(e){console.warn("保存阅读设置失败:",e)}},ee=e=>{switch(e.key){case"Escape":e.preventDefault(),Y();break;case"F11":e.preventDefault(),he();break;case"s":e.ctrlKey&&(e.preventDefault(),Z());break;case"b":e.ctrlKey&&(e.preventDefault(),ke());break}};let O=null;const Be=()=>{t.value.autoSave&&t.value.saveInterval>0&&(O=setInterval(()=>{M()},t.value.saveInterval))},Ie=()=>{O&&(clearInterval(O),O=null)};return re(()=>d.params.bookId,e=>{e&&e!==a.value&&(a.value=e,X())}),He(()=>{we(),X(),Be(),document.addEventListener("keydown",ee)}),Ve(()=>{M(),Ie(),document.removeEventListener("keydown",ee),U&&clearTimeout(U)}),(e,o)=>{const S=H("a-spin"),T=H("a-result"),F=H("a-button"),De=H("a-empty");return _.value?(w(),$("div",{key:0,class:"local-book-reader",style:V(A.value)},[u(ze,{"book-title":p.value?.title||"","chapter-name":y.value?.name||y.value?.title||"",chapters:f.value,"current-chapter-index":m.value,visible:!0,"reading-settings":t.value,onClose:Y,onSettingsChange:Z,onNextChapter:G,onPrevChapter:Q,onChapterSelected:pe},null,8,["book-title","chapter-name","chapters","current-chapter-index","reading-settings"]),c("div",{class:"reader-content",style:V(A.value),onScroll:ge,ref_key:"contentRef",ref:k},[x.value?(w(),$("div",ct,[u(S,{size:40}),o[2]||(o[2]=c("div",{class:"loading-text"},"正在加载章节内容...",-1))])):v.value?(w(),$("div",dt,[u(T,{status:"error",title:v.value},null,8,["title"]),u(F,{type:"primary",onClick:fe},{default:I(()=>[...o[3]||(o[3]=[N("重新加载",-1)])]),_:1})])):y.value?(w(),$("div",{key:2,class:"chapter-container",style:V(h.value)},[c("h1",{class:"chapter-title",style:V(W.value)},L(y.value.title||y.value.name),5),c("div",{class:"chapter-text",style:V(ce.value)},[(w(!0),$(ie,null,ue(de.value,(q,Te)=>(w(),$("div",{key:Te,class:"paragraph"},L(q),1))),128))],4),c("div",vt,[u(F,{disabled:m.value<=0,onClick:Q,class:"nav-btn prev-btn"},{icon:I(()=>[u(E(Ne))]),default:I(()=>[o[4]||(o[4]=N(" 上一章 ",-1))]),_:1},8,["disabled"]),c("span",pt,L(m.value+1)+" / "+L(f.value.length),1),u(F,{disabled:m.value>=f.value.length-1,onClick:G,class:"nav-btn next-btn"},{icon:I(()=>[u(E(Ue))]),default:I(()=>[o[5]||(o[5]=N(" 下一章 ",-1))]),_:1},8,["disabled"])])],4)):(w(),$("div",ft,[u(De,{description:"暂无章节内容"})]))],36),t.value.showProgress?(w(),$("div",mt,[c("div",{class:"progress-fill",style:V({width:`${P.value}%`})},null,4),c("div",kt,L(Math.round(P.value))+"%",1)])):le("",!0),u(Ke,{visible:n.value,settings:t.value,onClose:o[0]||(o[0]=q=>n.value=!1),onSettingsChange:me},null,8,["visible","settings"]),u(st,{visible:s.value,"onUpdate:visible":o[1]||(o[1]=q=>s.value=q),bookmarks:l.value,onBookmarkSelected:Ce,onBookmarkAdded:ye,onBookmarkDeleted:_e,onBookmarkUpdated:xe},null,8,["visible","bookmarks"])],4)):le("",!0)}}},bt=se(ht,[["__scopeId","data-v-88379142"]]);export{bt as default};