palicanon.js 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334
  1. var _lang = "";
  2. var _langsetting = "";
  3. var _channelType = 'translation'
  4. var _progress = 0.9;
  5. var _view = "community";
  6. var main_tag = "";
  7. var list_tag = new Array();
  8. var currTagLevel0 = new Array();
  9. var allTags = new Array();
  10. var arrMyTerm = new Array();
  11. var _listView="list";
  12. var gBreadCrumbs=['','','','','','','','',''];
  13. var _nextPageStart = 0;
  14. var _pageSize = 20;
  15. var _channel = "";
  16. var _palicanonCategory,_palicanonCategoryCurrent,_palicanonCategoryPath;
  17. var _tags = "";
  18. var _channelList;
  19. palicanon_load_term();
  20. function getLangSetting(setting){
  21. switch (setting) {
  22. case 'auto':
  23. switch (getCookie("language")) {
  24. case 'zh-cn':
  25. return 'zh';
  26. break;
  27. case 'zh-tw':
  28. return 'zh';
  29. break;
  30. case '':
  31. return '';
  32. break;
  33. }
  34. break;
  35. default:
  36. return setting;
  37. break;
  38. }
  39. }
  40. function updateSetting(){
  41. _langsetting = $("#setting_lang").val();
  42. _lang = getLangSetting(_langsetting);
  43. _channelType = $("#setting_channel_type").val();
  44. _progress = $("#setting_progress").val();
  45. localStorage.setItem("pc_filter_setting",JSON.stringify({
  46. lang : _lang,
  47. lang_setting: $("#setting_lang").val(),
  48. channel_type : _channelType,
  49. progress:_progress,
  50. }))
  51. switch (_view) {
  52. case 'community':
  53. _nextPageStart = 0;
  54. LoadAllChannel();
  55. communityGetChapter();
  56. break;
  57. case 'category':
  58. break;
  59. default:
  60. break;
  61. }
  62. }
  63. /*
  64. 载入过滤器设置
  65. */
  66. function loadFilterSetting(){
  67. if (localStorage.getItem ("pc_filter_setting")) {
  68. let setting = JSON.parse(localStorage.getItem("pc_filter_setting"));
  69. _langsetting = setting.lang_setting;
  70. _lang = getLangSetting(_langsetting);
  71. _channel_type = setting.channel_type;
  72. _progress = setting.progress;
  73. }
  74. _nextPageStart = 0;
  75. }
  76. function community_onload() {
  77. $("#main_view").addClass("community");
  78. render_selected_filter_list();
  79. communityGetChapter();
  80. LoadAllChannel();
  81. LoadAllLanguage();
  82. }
  83. function palicanon_onload() {
  84. $("#main_view").addClass("category");
  85. LoadAllChannel();
  86. LoadAllLanguage();
  87. }
  88. function palicanon_load_term() {
  89. let lang =getCookie("language");
  90. switch (lang) {
  91. case 'zh-cn':
  92. lang = 'zh-hans';
  93. break;
  94. case 'zh-tw':
  95. lang = 'zh-hant';
  96. break;
  97. case '':
  98. lang = 'en';
  99. break;
  100. }
  101. $.get(
  102. "/api/v2/terms",
  103. {
  104. view:'hot-meaning',
  105. language: lang,
  106. },
  107. function (data) {
  108. if (data.ok) {
  109. arrMyTerm = data.data.rows;
  110. } else {
  111. alert(data.message);
  112. }
  113. }
  114. );
  115. }
  116. function tag_changed() {
  117. _nextPageStart= 0;
  118. let strTags = "";
  119. if (list_tag.length > 0) {
  120. _tags = list_tag.join();
  121. } else {
  122. _tags = "";
  123. }
  124. console.log(_tags);
  125. let lang = getCookie("language");
  126. switch (lang) {
  127. case 'zh-cn':
  128. lang = 'zh-hans';
  129. break;
  130. case 'zh-tw':
  131. lang = 'zh-hant';
  132. break;
  133. case '':
  134. lang = 'en';
  135. break;
  136. }
  137. switch (_view) {
  138. case "community":
  139. communityGetChapter()
  140. break;
  141. case "category":
  142. if(_tags == ""){
  143. updatePalicanonCategoryList();
  144. $("#palicanon-category").show();
  145. $("#chapter_shell").hide();
  146. }else{
  147. $("#palicanon-category").hide();
  148. $("#chapter_shell").show();
  149. palicanonGetChapter(_tags,lang);
  150. }
  151. break;
  152. case "my":
  153. break;
  154. default:
  155. break;
  156. }
  157. gBreadCrumbs =['','','','','','','','',''];
  158. RenderBreadCrumbs();
  159. updataHistory();
  160. }
  161. function updataHistory(){
  162. let url = "?view="+_view;
  163. if(_tags !== ""){
  164. url += "&tag=" + _tags;
  165. }
  166. if(_channel !== ""){
  167. url += "&channel=" + _channel;
  168. }
  169. history.pushState({view:_view,tag:_tags,channel:_channel}, 'title', url);
  170. }
  171. function communityGetChapter(offset=0){
  172. next_page_loader_show();
  173. let param = {
  174. tags: _tags,
  175. lang: _lang,
  176. channel: _channel,
  177. channel_type: _channelType,
  178. offset: offset
  179. };
  180. console.log("查询条件", param);
  181. $.getJSON(
  182. "/api/v2/progress?view=chapter",
  183. param
  184. )
  185. .done(function (data, status) {
  186. $("#filter_bar_left").html(data.data.count+"个章节");
  187. let arrChapterData = data.data.rows;
  188. let arrChapterList = new Array();
  189. let html = "";
  190. allTags = new Array();
  191. let arrChapter = new Array();
  192. for (const iterator of arrChapterData) {
  193. arrChapterList.push({
  194. book:iterator.book,
  195. para:iterator.para,
  196. level:2,
  197. title:iterator.toc,
  198. progress:{lang:'en',all_trans:iterator.progress},
  199. tag:'',
  200. trans_title:iterator.title,
  201. channel_id:iterator.channel_id,
  202. type:'article',
  203. channel_info:iterator.channel,
  204. path:JSON.parse(iterator.path),
  205. views:iterator.views,
  206. likes:iterator.likes,
  207. tags:iterator.tags,
  208. summary:iterator.summary,
  209. created_at:iterator.created_at
  210. });
  211. }
  212. for (const iterator of arrChapterList) {
  213. arrChapter.push(iterator);
  214. }
  215. if(_nextPageStart==0){
  216. palicanon_chapter_list_apply(0);
  217. $("#list-1").html(render_chapter_list(arrChapter));
  218. }else{
  219. $("#list-1").append(render_chapter_list(arrChapter));
  220. }
  221. next_page_loader_hide();
  222. })
  223. .fail(function(jqXHR, textStatus, errorThrown){
  224. switch (jqXHR.status) {
  225. case 404:
  226. $("#list-1").html("未找到");
  227. next_page_loader_hide();
  228. break;
  229. case 500:
  230. console.error('/api/v2/progress?view=chapter',textStatus);
  231. break;
  232. default:
  233. break;
  234. }
  235. });
  236. communityLoadChapterTag();
  237. }
  238. function communityLoadChapterTag(strTags="",lang=""){
  239. $.getJSON(
  240. "/api/v2/progress?view=chapter-tag",
  241. {
  242. tags: _tags,
  243. lang: _lang,
  244. channel:_channel
  245. },
  246. function (data, status) {
  247. let tagData = data.data.rows;
  248. allTags = new Array();
  249. let maxCount = tagData[0].count;
  250. for (const tag of tagData) {
  251. if(tag.count < maxCount){
  252. allTags[tag.name] = tag.count;
  253. }
  254. }
  255. tag_render_others();
  256. });
  257. }
  258. function palitextGetChapter(strTags=""){
  259. if(_tags==""){
  260. return;
  261. }
  262. $.getJSON(
  263. "/api/v2/palitext?view=chapter",
  264. {
  265. tags: _tags
  266. }
  267. )
  268. .done(function (data, status) {
  269. let arrChapterData = data.data.rows;
  270. let arrChapterList = new Array();
  271. let arrChapter = new Array();
  272. let lastParent = -1;
  273. for (let index = 0; index < arrChapterData.length; index++) {
  274. arrChapterData[index].children = new Array();
  275. }
  276. for (const it of arrChapterData) {
  277. if(arrChapterList.length==0){
  278. arrChapterList.push(it);
  279. continue;
  280. }
  281. if(lastParent>=0){
  282. //判断是否为这个章节的子章节
  283. if(arrChapterList[lastParent].book==it.book && arrChapterList[lastParent].paragraph == it.parent){
  284. arrChapterList[lastParent].children.push(it)
  285. }else{
  286. arrChapterList.push(it);
  287. lastParent = -1;
  288. }
  289. }else{
  290. //判断是否为最末尾章节的子章节
  291. if(arrChapterList[arrChapterList.length-1].book==it.book && arrChapterList[arrChapterList.length-1].paragraph == it.parent){
  292. lastParent = arrChapterList.length-1;
  293. arrChapterList[arrChapterList.length-1].children.push(it);
  294. }else{
  295. arrChapterList.push(it);
  296. }
  297. }
  298. }
  299. palicanon_chapter_list_apply(0);
  300. $("#list-1").html(render_chapter_list(arrChapterList));
  301. })
  302. .fail(function(jqXHR, textStatus, errorThrown){
  303. switch (jqXHR.status) {
  304. case 404:
  305. $("#list-1").html("未找到");
  306. next_page_loader_hide();
  307. break;
  308. case 500:
  309. console.error('/api/v2/progress?view=chapter',textStatus);
  310. break;
  311. default:
  312. break;
  313. }
  314. });
  315. palitextLoadChapterTag(strTags);
  316. }
  317. function palitextLoadChapterTag(strTags=""){
  318. $.getJSON(
  319. "/api/v2/palitext?view=chapter-tag",
  320. {
  321. tags: strTags,
  322. },
  323. function (data, status) {
  324. let tagData = data.data.rows;
  325. allTags = new Array();
  326. let maxCount = tagData[0].count;
  327. for (const tag of tagData) {
  328. if(tag.count < maxCount){
  329. allTags[tag.name] = tag.count;
  330. }
  331. }
  332. tag_render_others();
  333. });
  334. }
  335. function palicanonGetChapter(strTags,lang){
  336. palitextGetChapter(strTags);
  337. }
  338. function viewChanged(obj){
  339. _listView = $(obj).val();
  340. updateFirstListView();
  341. }
  342. function updateFirstListView(){
  343. if(_listView == "list"){
  344. $("#list_shell_1").removeClass("book_view");
  345. $("#list_shell_1").addClass("list_view");
  346. }else{
  347. $("#list_shell_1").addClass("book_view");
  348. $("#list_shell_1").removeClass("list_view");
  349. }
  350. }
  351. function palicanon_load_chapter(book, para, div_index = 1) {
  352. let lang = getCookie("language");
  353. if (lang == "zh-cn") {
  354. lang = "zh-hans";
  355. } else if (lang == "zh-tw") {
  356. lang = "zh-hant";
  357. } else if (lang == "") {
  358. lang = "en";
  359. }
  360. $.get(
  361. "../palicanon/get_chapter_info.php",
  362. {
  363. book: book,
  364. para: para,
  365. lang: lang,
  366. },
  367. function (data, status) {
  368. palicanon_chapter_list_apply(div_index);
  369. let arrChapterInfo = JSON.parse(data);
  370. let html = render_chapter_head(arrChapterInfo, div_index);
  371. $("#chapter_head_" + (parseInt(div_index) + 1)).html(html);
  372. let lang = getCookie("language");
  373. if (lang == "zh-cn") {
  374. lang = "zh-hans";
  375. } else if (lang == "zh-tw") {
  376. lang = "zh-hant";
  377. } else if (lang == "") {
  378. lang = "en";
  379. }
  380. $.get(
  381. "./get_chapter_children.php",
  382. {
  383. book: book,
  384. para: para,
  385. lang: lang,
  386. },
  387. function (data, status) {
  388. let arrChapterList = JSON.parse(data);
  389. $("#list-" + (parseInt(div_index) + 1)).html(render_chapter_list(arrChapterList));
  390. }
  391. );
  392. //获取章节的channel列表
  393. loadChapterChannel({
  394. book:book,
  395. para:para,
  396. readonly:true,
  397. target:$("#chapter_head_" + (parseInt(div_index) + 1)).find('.progress').first()
  398. });
  399. }
  400. );
  401. }
  402. function render_chapter_head(chapter_info, parent) {
  403. let html = "";
  404. html = "<div class='chapter_head_tool_bar'>";
  405. html +=
  406. "<div><span class='chapter_back_button' id='chapter_back_" +
  407. (parent + 1) +
  408. "' onclick=\"chapter_back('" +
  409. parent +
  410. "')\">back</span></div>";
  411. html +=
  412. "<div><button class='chapter_close_button' id='chapter_close_" +
  413. (parent + 1) +
  414. "' onclick=\"chapter_back('" +
  415. parent +
  416. "')\">⬅</button></div>";
  417. html += "</div>";
  418. let link = "../reader/?view=chapter&book=" + chapter_info.book + "&par=" + chapter_info.paragraph;
  419. html += "<div class='title'>";
  420. let sToc = chapter_info.toc;
  421. html += " <div class='title_1'>";
  422. if (typeof chapter_info.trans_title == "undefined") {
  423. html += "<a href='" + link + "' target='_blank'>" ;
  424. if(sToc == ""){
  425. html += "[unnamed]" ;
  426. }else{
  427. switch (getCookie('language')) {
  428. case 'my':
  429. html += roman_to_my(sToc);
  430. break;
  431. case 'si':
  432. html += roman_to_si(sToc);
  433. break;
  434. default:
  435. html += sToc ;
  436. break;
  437. }
  438. }
  439. html += "</a>";
  440. } else {
  441. html += "<a href='" + link + "' target='_blank'>" + chapter_info.trans_title + "</a>";
  442. }
  443. html += "</div>";
  444. html += "<div class='title_2'>" + sToc + "</div>";
  445. html += "</div>";
  446. html += "<div class='res res_more'>";
  447. html += "<h2>译文</h2>";
  448. html += "<div class='progress' id='chapter_progress'>";
  449. if (chapter_info.progress && chapter_info.progress.length > 0) {
  450. let r = 12;
  451. let perimeter = 2 * Math.PI * r;
  452. for (const iterator of chapter_info.progress) {
  453. let stroke1 = parseInt(perimeter * iterator.all_trans);
  454. let stroke2 = perimeter - stroke1;
  455. html += ' <div class="item">';
  456. html += '<svg class="progress_circle" width="30" height="30" viewbox="0,0,30,30">';
  457. html += '<circle class="progress_bg" cx="15" cy="15" r="12" stroke-width="5" fill="none"></circle>';
  458. html +=
  459. '<circle class="progress_color" cx="15" cy="15" r="12" stroke-width="5" fill="none" stroke-dasharray="' +
  460. stroke1 +
  461. " " +
  462. stroke2 +
  463. '"></circle>';
  464. html += "</svg>";
  465. html += "<div class='lang'>" + iterator.lang + "-" + parseInt(iterator.all_trans * 100) + "%</div>";
  466. html += " </div>";
  467. }
  468. } else {
  469. html += "无译文";
  470. }
  471. html += "</div>";
  472. html += "</div>";
  473. return html;
  474. }
  475. function render_chapter_list(chapterList) {
  476. let html = "";
  477. for (const iterator of chapterList) {
  478. html += palicanon_render_chapter_row(iterator);
  479. }
  480. return html;
  481. }
  482. function isChapterWithParent(list,item){
  483. }
  484. function palicanon_chapter_list_apply(div_index) {
  485. let iDiv = parseInt(div_index);
  486. let html = "";
  487. html += "<div id='chapter_head_" + (iDiv + 1) + "' class='chapter_head'></div>";
  488. html += "<ul id='list-" + (iDiv + 1) + "' class='grid' level='" + (iDiv + 1) + "'>";
  489. html += "</ul>";
  490. html += "<div id='more_chapter'>";
  491. html += '<div id="page_loader" class="lds-ellipsis" style="visibility: hidden;"><div></div><div></div><div></div><div></div></div>';
  492. html += "<div id='more_chapter_line'></div>";
  493. html += "<button id='btn_more_chapter' onclick='next_page()'>More</button>";
  494. html += "</div>";
  495. $("#list_shell_" + (iDiv + 1)).html(html);
  496. $("#list_shell_" + (iDiv + 1)).removeClass();
  497. $("#list_shell_" + (iDiv + 1)).addClass("show");
  498. //隐藏之后的列表
  499. for (let index = iDiv + 2; index <= 8; index++) {
  500. $("#list_shell_" + index).removeClass();
  501. $("#list_shell_" + index).addClass("hidden");
  502. }
  503. //收缩当前的
  504. $("#list-" + iDiv).removeClass();
  505. $("#list-" + iDiv).addClass("list");
  506. $("#list_shell_" + iDiv).removeClass();
  507. $("#list_shell_" + iDiv).addClass("list");
  508. updateFirstListView();
  509. }
  510. function next_page_loader_show(){
  511. $("#page_loader").css("visibility","visible");
  512. }
  513. function next_page_loader_hide(){
  514. $("#page_loader").css("visibility","hidden");
  515. }
  516. function next_page(){
  517. _nextPageStart += _pageSize;
  518. communityGetChapter(_nextPageStart);
  519. }
  520. function chapter_onclick(obj) {
  521. let objList = $(obj).parent().parent().parent().parent().parent();
  522. let book = $(objList).attr("book");
  523. let para = $(objList).attr("para");
  524. let channel = $(objList).attr("channel");
  525. let type = $(objList).attr("type");
  526. let level = parseInt($(objList).parent().attr("level"));
  527. let title1 = $(objList).find(".title_1").first().text();
  528. if(_view == "category" && level==1){
  529. $("#index_div").addClass("popup");
  530. }
  531. if(type=='article'){
  532. window.open("../article/index.php?view=chapter&book="+book+"&par="+para+"&channel="+channel,);
  533. }else{
  534. gBreadCrumbs[level] = {title1:title1,book:book,para:para,level:level};
  535. RenderBreadCrumbs();
  536. $(objList).siblings().removeClass("selected");
  537. $(objList).addClass("selected");
  538. $("#tag_list").slideUp();
  539. palicanon_load_chapter(book, para, level);
  540. }
  541. }
  542. function close_tag_list(){
  543. $("#tag_list").slideUp();
  544. $("#btn-filter").removeClass("active");
  545. }
  546. function renderProgress(progress=0,width=16,height=16){
  547. //绘制进度圈
  548. let r = 12;
  549. let perimeter = 2 * Math.PI * r;
  550. let stroke1 = parseInt(perimeter * progress);
  551. let stroke2 = perimeter - stroke1;
  552. let html="";
  553. html += '<svg class="progress_circle" width="16" height="16" viewbox="0,0,30,30">';
  554. html += '<circle class="progress_bg" cx="15" cy="15" r="12" stroke-width="5" fill="none"></circle>';
  555. html +=
  556. '<circle class="progress_color" cx="15" cy="15" r="12" stroke-width="5" fill="none" stroke-dasharray="' +
  557. stroke1 +
  558. " " +
  559. stroke2 +
  560. '"></circle>';
  561. html += "</svg>";
  562. return html;
  563. }
  564. function palicanon_render_chapter_row(chapter,isSub=false) {
  565. let html = "";
  566. let levelClass = "";
  567. if (chapter.level == 1) {
  568. //levelClass = " level_1";
  569. }
  570. let para=0;
  571. if(chapter.para){
  572. para=chapter.para;
  573. }else if(chapter.paragraph){
  574. para=chapter.paragraph;
  575. }
  576. html +='<li class="' + levelClass +'" book="' + chapter.book + '" para="' + para + '"';
  577. if(typeof chapter.type !== "undefined" && chapter.type==='article'){
  578. html += ' channel="' + chapter.channel_id + '" type="' + chapter.type + '"';
  579. }
  580. html += ' >';
  581. html += '<div class="main">';
  582. html += '<div class="left">';
  583. html += "<div class='left_items'>";
  584. if(typeof chapter.views != "undefined"){
  585. html += "<div class='left_item'>";
  586. html += "<span class='item'>";
  587. html += "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  588. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#eye'>";
  589. html += "</svg>" ;
  590. html += "<span class='text'>";
  591. html += chapter.views;
  592. html += "</span>";
  593. html += "</span>";
  594. html += "</div>"
  595. }
  596. if(typeof chapter.likes != "undefined"){
  597. html += "<div class='left_item'>";
  598. html += "<span class='item'>";
  599. html += "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  600. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#heart'>";
  601. html += "</svg>" ;
  602. html += "<span class='text'>";
  603. html += chapter.likes;
  604. html += "</span>";
  605. html += "</span>";
  606. html += "</div>"
  607. }
  608. //完成度
  609. if(chapter.progress && chapter.progress.all_trans){
  610. html += "<div class='left_item'>";
  611. html += "<span class='item'>";
  612. html += renderProgress(chapter.progress.all_trans);
  613. html += "<span class='text'>";
  614. if(chapter.progress){
  615. html += parseInt(chapter.progress.all_trans*100+1)+"%";
  616. }else{
  617. html += "无";
  618. }
  619. html += "</span>";
  620. html += "</span>";
  621. html += "</div>"
  622. }
  623. html += "<div class='left_item'></div>"
  624. html += "</div>";//end of left_items
  625. html += "<div class='chapter_icon'>";
  626. html += '<span class="" style="margin-right: 1em;padding: 4px 0;">';
  627. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  628. if(typeof chapter.type !== "undefined" && chapter.type==='article'){
  629. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#journal-text'>";
  630. }else{
  631. if (chapter.level == 1) {
  632. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#journal'>";
  633. }else{
  634. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#folder2-open'>";
  635. }
  636. }
  637. html += "</svg>" ;
  638. html += "</span>";
  639. html += "</div>";
  640. html += '</div>';//end of left
  641. html += '<div class="right">';
  642. html += '<div class="head_bar">';
  643. html += '<div class="title" >';
  644. html += '<div class="title_left" onclick="chapter_onclick(this)">';
  645. let sPaliTitle = chapter.title;
  646. if(chapter.title==""){
  647. sPaliTitle = "unnamed";
  648. }
  649. if (typeof chapter.trans_title == "undefined" || chapter.trans_title == "") {
  650. html += " <div class='title_1'>" ;
  651. switch (getCookie('language')) {
  652. case 'my':
  653. html += roman_to_my(sPaliTitle);
  654. break;
  655. case 'si':
  656. html += roman_to_si(sPaliTitle);
  657. break;
  658. default:
  659. html += sPaliTitle ;
  660. break;
  661. }
  662. html += "</div>";
  663. } else {
  664. html += " <div class='title_1'>" + chapter.trans_title + "</div>";
  665. }
  666. html += '<div class="title_2" lang="pali">' + sPaliTitle + "</div>";
  667. html += '<div class="title_2" lang="pali">';
  668. //书名
  669. if(chapter.path){
  670. let arrPath=false;
  671. if(Array.isArray(chapter.path)){
  672. arrPath = chapter.path;
  673. }else{
  674. try{
  675. arrPath = JSON.parse(chapter.path);
  676. }catch(e){
  677. console.error('json parse',chapter.path);
  678. }
  679. }
  680. if(arrPath && arrPath.length>0){
  681. html += "<span class='item'>";
  682. html += "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  683. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#journals'>";
  684. html += "</svg>" ;
  685. html += arrPath[0].title;
  686. html += "</span>";
  687. }
  688. }
  689. let chapterPara;
  690. if(chapter.paragraph){
  691. }
  692. html += "</div>";
  693. html += "</div>";
  694. html += '<div class="title_right" >';
  695. html += "<span></span>";
  696. /*
  697. if(isSub){
  698. html += "<span></span>";
  699. }else{
  700. html += "<img class='chapter_dynamic_svg' src='/api/v2/progress-img/-chapter_dynamic-";
  701. html += chapter.book + "-";
  702. if(chapter.paragraph){
  703. html += chapter.paragraph;
  704. }else{
  705. html += chapter.para;
  706. }
  707. if(chapter.channel_id){
  708. html += "-ch_" + chapter.channel_id;
  709. }else{
  710. html += "-global";
  711. }
  712. html += "' />";
  713. }
  714. */
  715. html += "</div>";
  716. html += "</div>";
  717. html += '<div class="resource">';
  718. if(chapter.summary){
  719. html += chapter.summary;
  720. }
  721. html += "</div>";
  722. html += '<div class="more_info">';
  723. //最下面一栏,左侧的标签列表
  724. html += "<div class='chapter_tag'>";
  725. if(chapter.tags){
  726. html += renderChapterTags(chapter.tags);
  727. }
  728. html += "</div>";
  729. html += "<div class='palicanon_chapter_info'>"
  730. if(typeof chapter.type !== "undefined" && chapter.type==='article'){
  731. html += "<span class='item channel'>";
  732. html += "<svg class='small_icon' style='width:16px;height:16px;fill: var(--box-bg-color1)'>";
  733. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#person-circle'>";
  734. html += "</svg>" ;
  735. html += "<span class='text' onclick=\"select_channel('"+chapter.channel_id+"')\">";
  736. html += chapter.channel_info.name;
  737. html += "</span>";
  738. html += "</span>";
  739. }
  740. if(chapter.created_at){
  741. html += "<span class='item'>";
  742. html += "<svg class='small_icon' style='width:16px;height:16px;fill: var(--box-bg-color1)'>";
  743. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#clock'>";
  744. html += "</svg>" ;
  745. html += "<span class='text'>";
  746. html += getPassDataTime(new Date(chapter.created_at));
  747. html += "</span>";
  748. html += "</span>";
  749. }
  750. if(chapter.children && chapter.children.length>0){
  751. html += "<span class='item' onclick=\"subchapter_slideToggle(this)\">";
  752. html += "<span class='text'>";
  753. html += "展开折叠子章节 " + chapter.children.length;
  754. html += "</span>";
  755. html += "</span>";
  756. }
  757. html += "</div>";
  758. html += "</div>";
  759. html += "</div>";//end of head bar
  760. html += "</div>";
  761. html += "</div>";//end of main
  762. html += "<div class='subchapter'>";
  763. if(chapter.children){
  764. html += "<ul class='subchapter_inner'>";
  765. for (const subchapter of chapter.children) {
  766. html +=palicanon_render_chapter_row(subchapter,true);
  767. }
  768. html += "</ul>";
  769. }
  770. html += "</div>";
  771. html += "</li>";
  772. return html;
  773. }
  774. function subchapter_slideToggle(obj){
  775. $(obj).parent().parent().parent().parent().parent().siblings(".subchapter").slideToggle();
  776. }
  777. function tag_get_local_word(word) {
  778. let termKey = term_lookup_my(word, "", getCookie("userid"), getCookie("language"));
  779. if (typeof termKey == 'undefined' || termKey === false || termKey === '') {
  780. switch (getCookie('language')) {
  781. case 'my':
  782. return roman_to_my(word);
  783. case 'si':
  784. return roman_to_si(word);
  785. default:
  786. return word;
  787. }
  788. } else {
  789. return termKey.meaning;
  790. }
  791. }
  792. function tag_render_others() {
  793. let strOthersTag = "";
  794. currTagLevel0 = new Array();
  795. $(".tag_others").html("");
  796. document.getElementById("main_tag").style.margin = 1 + "em";
  797. document.getElementById("main_tag").style.fontSize = 100 + "%";
  798. for (const key in allTags) {
  799. if (allTags.hasOwnProperty(key)) {
  800. let count = allTags[key]
  801. if ($("#tag_input").val().length > 0) {
  802. if (key.indexOf($("#tag_input").val()) >= 0) {
  803. strOthersTag =
  804. '<button class="canon-tag" onclick ="tag_click(\'' + key + "')\" >" + key + "("+count+ ")"+"</button>";
  805. }
  806. } else {
  807. let keyname = tag_get_local_word(key);
  808. strOthersTag =
  809. '<button class="canon-tag" title="' +
  810. key +
  811. '" onclick ="tag_click(\'' +
  812. key +
  813. "')\" >" +
  814. keyname + "("+count+ ")"+
  815. "</button>";
  816. }
  817. let thisLevel = 100;
  818. if (tag_level.hasOwnProperty(key)) {
  819. thisLevel = tag_level[key].level;
  820. if (tag_level[key].level == 0) {
  821. currTagLevel0[key] = 1;
  822. }
  823. }
  824. $(".tag_others[level='" + thisLevel + "']").html(
  825. $(".tag_others[level='" + thisLevel + "']").html() + strOthersTag
  826. );
  827. }
  828. }
  829. }
  830. function tag_click(tag) {
  831. list_tag.push(tag);
  832. render_selected_filter_list();
  833. tag_changed();
  834. }
  835. function tag_set(tag) {
  836. list_tag = new Array();
  837. if(Array.isArray(tag)){
  838. for (const iterator of tag) {
  839. list_tag.push(iterator);
  840. }
  841. }else{
  842. list_tag.push(tag);
  843. }
  844. _tags = list_tag.join();
  845. render_selected_filter_list();
  846. tag_changed();
  847. }
  848. function renderChapterTags(tags){
  849. let html = "";
  850. for (const iterator of tags) {
  851. html += '<tag onclick="tag_set(\''+iterator.name+'\')">';
  852. html += "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  853. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#tag'>";
  854. html += "</svg>"
  855. html += '<span class="textt" title="' + iterator.name + '">' + tag_get_local_word(iterator.name) + "</span>";
  856. //html += '<span class="tag-delete" onclick ="tag_remove(\'' + iterator + "')\">✕</span>";
  857. html += "</tag>";
  858. }
  859. return html;
  860. }
  861. function render_selected_filter_list() {
  862. refresh_selected_tag();
  863. refresh_selected_channel();
  864. }
  865. function refresh_selected_tag(){
  866. let strListTag="";
  867. for (const iterator of list_tag) {
  868. if(iterator!=''){
  869. strListTag += '<tag>';
  870. strListTag += "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  871. strListTag += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#tag'>";
  872. strListTag += "</svg>"
  873. strListTag += '<span class="textt" title="' + iterator + '">' + tag_get_local_word(iterator) + "</span>";
  874. strListTag += '<span class="tag-delete" onclick ="tag_remove(\'' + iterator + "')\">✕</span>";
  875. strListTag += "</tag>";
  876. }
  877. }
  878. $("#tag_selected").html(strListTag);
  879. }
  880. function refresh_selected_channel(){
  881. let channels = _channel.split(",");
  882. let html="";
  883. for (const iterator of channels) {
  884. if(_channelList){
  885. let item = _channelList.find(element => element.channel_id == iterator);
  886. if(item){
  887. html += '<tag>';
  888. html += '<span class="textt" title="">版本:' + item.channel.name + "</span>";
  889. html += '<span class="tag-delete" onclick ="channel_tag_remove(\'' + item.channel_id + "')\">✕</span>";
  890. html += "</tag>";
  891. }
  892. }
  893. }
  894. html +="</div>";
  895. $("#channel_selected").html(html);
  896. }
  897. function channel_tag_remove(channelId){
  898. let channels = _channel.split(',');
  899. if(channels.indexOf(channelId)>=0){
  900. channels.splice(channels.indexOf(channelId),1);
  901. _channel = channels.join();
  902. refresh_selected_channel();
  903. tag_changed();
  904. }
  905. }
  906. function tag_remove(tag) {
  907. for (let i = 0; i < list_tag.length; i++) {
  908. if (list_tag[i] == tag) {
  909. list_tag.splice(i, 1);
  910. }
  911. }
  912. render_selected_filter_list();
  913. tag_changed();
  914. }
  915. function sortNumber(a, b) {
  916. return b - a;
  917. }
  918. function tag_list_slide_toggle(element) {
  919. if ($("#tag_list").css("display") == 'none') {
  920. $(element).addClass("active");
  921. } else {
  922. $(element).removeClass("active");
  923. }
  924. $("#tag_list").slideToggle();
  925. }
  926. function chapter_back(parent) {
  927. if(_view == "category" && parent==1){
  928. $("#index_div").removeClass("popup");
  929. }
  930. let curr = parseInt(parent) + 1;
  931. let prt = parseInt(parent);
  932. //隐藏当前的
  933. for (let index = curr; index < 8; index++) {
  934. $("#list_shell_" + index).removeClass();
  935. $("#list_shell_" + index).addClass("hidden");
  936. gBreadCrumbs[index-1]='';
  937. }
  938. //展开上一个
  939. $("#list-" + prt).removeClass();
  940. $("#list-" + prt).addClass("grid");
  941. $("#list_shell_" + prt).removeClass();
  942. $("#list_shell_" + prt).addClass("show");
  943. RenderBreadCrumbs();
  944. }
  945. function categoryGoHome(){
  946. updatePalicanonCategoryList();
  947. $("#palicanon-category").show();
  948. $("#chapter_shell").hide();
  949. tag_set([]);
  950. }
  951. function updatePalicanonCategoryList(name="__home__") {
  952. switch (name) {
  953. case '__home__':
  954. _palicanonCategoryCurrent = _palicanonCategory.slice();
  955. _palicanonCategoryPath = new Array();
  956. _palicanonCategoryPath.push(_palicanonCategoryCurrent);
  957. break;
  958. case '__prev__':
  959. _palicanonCategoryPath.pop();
  960. _palicanonCategoryCurrent = _palicanonCategoryPath[_palicanonCategoryPath.length-1].slice();
  961. break;
  962. default:
  963. if(_palicanonCategoryCurrent.length>0){
  964. let next = _palicanonCategoryCurrent.find(element => element.name == name);
  965. if(typeof next !== "undefined"){
  966. if(next.children && next.children.length>0){
  967. //有子目录
  968. _palicanonCategoryCurrent = next.children.slice();
  969. _palicanonCategoryPath.push(_palicanonCategoryCurrent.slice());
  970. }else{
  971. //没有子目录
  972. tag_set(next.tag);
  973. $("#palicanon-category").hide();
  974. $("#chapter_shell").show();
  975. }
  976. }
  977. }else{
  978. }
  979. break;
  980. }
  981. $('#palicanon-category').html(renderPalicanonCategoryList());
  982. }
  983. function renderPalicanonCategoryList(){
  984. let html = "<ul class='chapter_list'>";
  985. if(_palicanonCategoryPath.length>1){
  986. html += "<li onclick=\"updatePalicanonCategoryList('__prev__')\">";
  987. html += "上一级";
  988. html += "</li>";
  989. }
  990. for (const item of _palicanonCategoryCurrent) {
  991. html += "<li onclick=\"updatePalicanonCategoryList('"+item.name+"')\">";
  992. html += "<div class='left_icon'>";
  993. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  994. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#folder'>";
  995. html += "</svg>" ;
  996. html += "</div>";
  997. html += "<div class='title'>";
  998. html += '<div class="title_left" onclick="chapter_onclick(this)">';
  999. html += '<div class="title_1">'+item.name+'</div>';
  1000. html += '<div class="title_2" lang="pali">'+item.name+'</div>';
  1001. html += "</div>";
  1002. html += '<div class="title_right">';
  1003. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  1004. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#chevron-right'>";
  1005. html += "</svg>" ;
  1006. html += '</div>';
  1007. html += "</div>";
  1008. html += "</li>";
  1009. }
  1010. html += "</ul>";
  1011. return html;
  1012. }
  1013. function loadTagCategory(name="defualt"){
  1014. $.getJSON("../palicanon/category/"+name+".json",function(result){
  1015. _palicanonCategory = result;
  1016. _palicanonCategoryCurrent = _palicanonCategory.slice();
  1017. _palicanonCategoryPath = new Array();
  1018. _palicanonCategoryPath.push(_palicanonCategoryCurrent.slice());
  1019. updatePalicanonCategoryList();
  1020. $("#tag-category").html("");
  1021. $("#tag-category").fancytree({
  1022. autoScroll: true,
  1023. selectMode: 1, // 1:single, 2:multi, 3:multi-hier
  1024. checkbox: false, // Show checkboxes.
  1025. source: tocGetTagCategory(result.slice()),
  1026. activate: function(e, data) {
  1027. console.log('tree',data);
  1028. tag_set(arrTagCategory[data.node.key]);
  1029. },
  1030. select: function(e, data) {
  1031. // Display list of selected nodes
  1032. currSelectNode = data.tree.getSelectedNodes();
  1033. }
  1034. });
  1035. });
  1036. }
  1037. var arrTagCategory = new Array();
  1038. function tocGetTagCategory(data){
  1039. let output = new Array();
  1040. for (const iterator of data) {
  1041. let item = {key:com_uuid(),title:iterator.name,tag:iterator.tag};
  1042. arrTagCategory[item.key] = iterator.tag;
  1043. if(typeof iterator.children !== "undefined"){
  1044. item.children = tocGetTagCategory(iterator.children);
  1045. }
  1046. output.push(item);
  1047. }
  1048. return output;
  1049. }
  1050. function loadTagCategoryIndex(){
  1051. $.getJSON("../palicanon/category/index.json",function(result){
  1052. let indexFilename = localStorage.getItem('palicanon_tag_category');
  1053. if(!indexFilename){
  1054. indexFilename = "defualt";
  1055. }
  1056. let html="";
  1057. for (const iterator of result) {
  1058. html += "<option ";
  1059. if(indexFilename==iterator.file){
  1060. html += " selected ";
  1061. }
  1062. html += " value='"+iterator.file+"'>"+iterator.name+"</option>";
  1063. }
  1064. $("#tag_category_index").html(html);
  1065. });
  1066. }
  1067. function TagCategoryIndexchange(obj){
  1068. localStorage.setItem('palicanon_tag_category',$(obj).val());
  1069. //loadTagCategory($(obj).val());
  1070. location.reload();
  1071. }
  1072. function RenderBreadCrumbs(){
  1073. let html = "";
  1074. html += "<span>";
  1075. html += '<a onclick="chapter_back(1)" title="'+gLocal.gui.close+'">';
  1076. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  1077. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#arrow-left-square'>";
  1078. html += "</svg>" ;
  1079. html += '</a>';
  1080. html += "</span>";
  1081. for (const iterator of gBreadCrumbs) {
  1082. if(iterator.title1){
  1083. html += "<span>";
  1084. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  1085. html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#chevron-right'>";
  1086. html += "</svg>" ;
  1087. html += "</span>";
  1088. html += "<span>";
  1089. html += '<a onclick="chapter_back('+(iterator.level+1)+')">';
  1090. html += iterator.title1;
  1091. html += '</a>';
  1092. html += "</span>";
  1093. }
  1094. }
  1095. $("#bread-crumbs").html(html);
  1096. }
  1097. function select_channel(id,obj=null){
  1098. _channel = id;
  1099. _nextPageStart = 0;
  1100. updataHistory();
  1101. communityGetChapter(_nextPageStart);
  1102. refresh_selected_channel();
  1103. console.log("change channel",_channel);
  1104. //$(obj).siblings.removeClass('active');
  1105. //$(obj).addClass('active');
  1106. }
  1107. function LoadAllChannel(){
  1108. $.getJSON(
  1109. "/api/v2/progress?view=channel",
  1110. {
  1111. lang:_lang,
  1112. channel_type: _channelType,
  1113. progress:_progress,
  1114. },
  1115. function (data, status) {
  1116. let html = "";
  1117. html += "<ul>"
  1118. _channelList = data.data.rows;
  1119. for (const iterator of data.data.rows) {
  1120. if(iterator.channel){
  1121. html += "<li onclick=\"select_channel('"+iterator.channel.uid+"',this)\">"
  1122. html += iterator.channel.name+"("+iterator.count+")";
  1123. html += "</li>"
  1124. }
  1125. }
  1126. html += "</ul>";
  1127. $("#filter-author").html(html);
  1128. refresh_selected_channel();
  1129. }
  1130. );
  1131. }
  1132. function LoadAllLanguage(){
  1133. $.getJSON(
  1134. "/api/v2/progress?view=lang",
  1135. {},
  1136. function (data, status) {
  1137. let html = "";
  1138. html += "<option value='auto'>自动选择语言</option>";
  1139. html += "<option value=''>全部语言</option>";
  1140. for (const iterator of data.data.rows) {
  1141. if(iterator.lang!=''){
  1142. html += "<option value='"+iterator.lang+"' ";
  1143. if(_langsetting==iterator.lang){
  1144. html +=" selected ";
  1145. }
  1146. html +=">";
  1147. html += iterator.lang+"("+iterator.count+")";
  1148. html += "</option>"
  1149. }
  1150. }
  1151. $("#setting_lang").html(html);
  1152. }
  1153. );
  1154. }
  1155. function ReanderMainMenu(){
  1156. let html ="";
  1157. html += "<span ";
  1158. if(_view=="community"){
  1159. html += "class='select'";
  1160. }
  1161. html +="><a href='index.php?view=community'>"+gLocal.gui.community_new+"</a></span>";
  1162. html += "<span ";
  1163. if(_view=="category"){
  1164. html += "class='select'";
  1165. }
  1166. html +="><a href='index.php?view=category' >"+gLocal.gui.pali_text+"</a></span>";
  1167. html += "<span ";
  1168. if(_view=="my"){
  1169. html += "class='select'";
  1170. }
  1171. html +="><a href='index.php?view=my' >"+gLocal.gui.my_read+"</a></span>";
  1172. $("#main_menu").html(html);
  1173. }
  1174. function loadContribution(){
  1175. $.getJSON(
  1176. "/api/v2/sent_history_contribution", function() {
  1177. console.log( "success" );
  1178. }
  1179. )
  1180. .done(function(data) {
  1181. let html = "";
  1182. html += "<ol>";
  1183. for (const item of data.data) {
  1184. html += "<li>";
  1185. html += item.username.nickname;
  1186. html += "—";
  1187. html += item.count;
  1188. html += "</li>";
  1189. }
  1190. html += "</ol>";
  1191. $("#contribution").find('.list').first().html(html);
  1192. })
  1193. .fail(function() {
  1194. console.log( "error" );
  1195. });
  1196. }