palicanon.js 39 KB

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