Pārlūkot izejas kodu

Merge branch 'staging' of https://github.com/iapt-platform/mint into staging

bhikkhu-kosalla-china 3 gadi atpakaļ
vecāks
revīzija
448caffbeb

+ 5 - 5
app/Console/Commands/UpgradeChapterDynamic.php

@@ -16,7 +16,7 @@ class UpgradeChapterDynamic extends Command
      *
      * @var string
      */
-    protected $signature = 'upgrade:chapterdynamic {--one}';
+    protected $signature = 'upgrade:chapterdynamic {--test}';
 
     /**
      * The console command description.
@@ -84,7 +84,7 @@ class UpgradeChapterDynamic extends Command
             Storage::disk('local')->put("public/images/chapter_dynamic/{$filename}", $svg);
             $bar->advance();
 
-            if($this->option('one')){
+            if($this->option('test')){
                 break; //调试代码
             }
 
@@ -93,7 +93,7 @@ class UpgradeChapterDynamic extends Command
 
         $this->info('用时'.(time()-$start));
         $start = time();
-        
+
         $this->info('更新缺的章节空白图');
         // 更新缺的章节空白图
         $chapters = PaliText::select('book','paragraph')
@@ -108,7 +108,7 @@ class UpgradeChapterDynamic extends Command
             }
             $bar->advance();
 
-            if($this->option('one')){
+            if($this->option('test')){
                 break; //调试代码
             }
         }
@@ -148,7 +148,7 @@ class UpgradeChapterDynamic extends Command
             Storage::disk('local')->put("public/images/chapter_dynamic/{$filename}", $svg);
             $bar->advance();
 
-            if($this->option('one')){
+            if($this->option('test')){
                 break; //调试代码
             }
         }

+ 27 - 1
app/Console/Commands/UpgradeDaily.php

@@ -3,6 +3,8 @@
 namespace App\Console\Commands;
 
 use Illuminate\Console\Command;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Http;
 
 class UpgradeDaily extends Command
 {
@@ -37,12 +39,36 @@ class UpgradeDaily extends Command
      */
     public function handle()
     {
-        $this->call('upgrade:palitext');
+        $start = time();
+		$this->call('message:webhook',[
+			'listener' => 'dingtalk',
+			'url' => 'dingtalk1',
+			'title' => "后台任务",
+			'message' => " wikipali: 每日统计后台任务开始执行。",
+		]);
+        # 刷巴利语句子uuid 仅调用一次
         $this->call('upgrade:palitextid');
+        //巴利原文段落库目录结构改变时运行
+        $this->call('upgrade:palitext'); 
+        #巴利段落标签
         $this->call('upgrade:palitexttag');
+        #译文进度
         $this->call('upgrade:progress');
         $this->call('upgrade:progresschapter');
+        # 段落更新图
+        $this->call('upgrade:chapterdynamic');
+        # 逐词译数据库分析
         $this->call('upgrade:wbwanalyses');
+
+        $time = time()-$start;
+
+		$this->call('message:webhook',[
+			'listener' => 'dingtalk',
+			'url' => 'dingtalk1',
+			'title' => "后台任务",
+			'message' => "wikipali: 每日统计后台任务执行完毕。用时{$time}",
+		]);;
+
         return 0;
     }
 }

+ 0 - 9
app/Console/Commands/UpgradeProgressChapter.php

@@ -117,15 +117,6 @@ class UpgradeProgressChapter extends Command
                             'book'=>$book->book_id,
                             'para'=>$chapter->paragraph,
                             'channel_id'=>$final->channel_id];
-                    $value = [
-                            'lang'=>$lang,
-                            'all_trans'=>$final->cp_len/$chapter_strlen,
-                            'public'=>$final->cp_len/$chapter_strlen,
-                            'progress'=>$final->cp_len/$chapter_strlen,
-                            'title'=>mb_substr($title,0,255,"UTF-8"),
-                            'created_at'=>$finalAt,
-                            'updated_at'=>$updateAt
-                        ];
                     
                     $rules = array(
                         'book' => 'integer',

+ 66 - 0
app/Console/Commands/WebHook.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+
+class WebHook extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'message:webhook {listener} {url} {title} {message}';
+	protected $url = [
+		"dingtalk1"=>"https://oapi.dingtalk.com/robot/send?access_token=34143dbec80a8fc09c1cb5897a5639ee3a9a32ecfe31835ad29bf7013bdb9fdf",
+		"weixin1"=>"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=9693cceb-bd2e-40c9-8c0c-3260b2c50aa8",
+	];
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '发送消息到一个服务器机器人,';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+		switch ($this->argument('listener')) {
+			case 'weixin':
+				# code...
+				break;
+			case 'dingtalk':
+				# code...
+				$url = $url[$this->argument('url')];
+				$param = [
+				"markdown"=> [
+					"title"=> $this->argument('title'), 
+					"text"=> $this->argument('message'), 
+				], 
+				"msgtype"=>"markdown"
+				];
+				break;				
+			default:
+				# code...
+				break;
+		}
+		$response = Http::post($url, $param);
+        return 0;
+    }
+}

+ 5 - 0
app/Console/Kernel.php

@@ -16,6 +16,11 @@ class Kernel extends ConsoleKernel
     protected function schedule(Schedule $schedule)
     {
         // $schedule->command('inspire')->hourly();
+        $schedule->timezone('Asia/Shanghai')
+                 ->command('upgrade:daily')
+                 ->dailyAt('00:00')
+                 ->emailOutputTo('kosalla1987@126.com');
+				 //->emailOutputOnFailure()
     }
 
     /**

+ 4 - 0
app/Http/Controllers/DhammaTermController.php

@@ -20,6 +20,9 @@ class DhammaTermController extends Controller
 		$indexCol = ['id','guid','word','word_en','meaning','other_meaning','note','language','channal','updated_at'];
 
 		switch ($request->get('view')) {
+            case 'show':
+                return $this->ok(DhammaTerm::find($request->get('id')));
+                break;
 			case 'user':
 				# code...
                 $userUid = $_COOKIE['user_uid'];
@@ -165,6 +168,7 @@ class DhammaTermController extends Controller
     public function show(DhammaTerm $dhammaTerm)
     {
         //
+        return $dhammaTerm;
     }
 
     /**

+ 25 - 6
app/Http/Controllers/ProgressChapterController.php

@@ -149,6 +149,7 @@ class ProgressChapterController extends Controller
                     $all_count = count($chapters);
                 break;
             case 'lang':
+                
                 $chapters = ProgressChapter::select('lang')
                                             ->selectRaw('count(*) as count')
                                             ->where("progress",">",$minProgress)
@@ -163,12 +164,19 @@ class ProgressChapterController extends Controller
             总共有多少channel
             */
                 $chapters = ProgressChapter::select('channel_id')
-                                            ->selectRaw('count(*) as count')
-                                            ->with(['channel' => function($query) {  //city对应上面province模型中定义的city方法名  闭包内是子查询
+                                           ->selectRaw('count(*) as count')
+                                           ->with(['channel' => function($query) {  //city对应上面province模型中定义的city方法名  闭包内是子查询
                                                 return $query->select('*');
                                             }])
-                                            ->where("progress",">",$minProgress)
-                                            ->groupBy('channel_id')
+                                           ->leftJoin('channels','progress_chapters.channel_id', '=', 'channels.uid')
+                                           ->where("progress",">",$minProgress);
+                if(!empty($request->get('channel_type'))){
+                    $chapters =  $chapters->where('channels.type',$request->get('channel_type'));
+                }
+                if(!empty($request->get('lang'))){
+                    $chapters =  $chapters->where('progress_chapters.lang',$request->get('lang'));
+                }
+                $chapters =  $chapters->groupBy('channel_id')
                                             ->orderBy('count','desc')
                                             ->get();
                 $all_count = count($chapters);
@@ -242,9 +250,20 @@ class ProgressChapterController extends Controller
                     $channel = "";
                 }
 
+
+
                 $param[] = $minProgress;
+
+                if(!empty($request->get('lang'))){
+                    $whereLang = " and pc.lang = ? ";
+                    $param[] = $request->get('lang');
+                }else{
+                    $whereLang = "   ";
+                }                
                 $param_count = $param;
                 $param[] = $offset;
+
+
                 $query = "
                 select tpc.uid, tpc.book ,tpc.para,tpc.channel_id,tpc.title,pt.toc,pt.path,tpc.progress,tpc.summary,tpc.created_at,tpc.updated_at 
                     from (
@@ -261,7 +280,7 @@ class ProgressChapterController extends Controller
                         ) CID 
                         left join $pc as pc on CID.cid = pc.uid 
                         where pc.progress > ? 
-                        $channel
+                        $channel  $whereLang
                         order by created_at desc
                         limit 20 offset ?
                     ) tpc 
@@ -293,7 +312,7 @@ class ProgressChapterController extends Controller
                         ) CID 
                         left join $pc as pc on CID.cid = pc.uid 
                         where pc.progress > ? 
-                        $channel
+                        $channel   $whereLang
                 ";
                 $count = DB::select($query,$param_count);
                 $all_count = $count[0]->count;

+ 27 - 14
app/Http/Controllers/SentenceInfoController.php

@@ -124,6 +124,7 @@ class SentenceInfoController extends Controller
                             ->where('paragraph','<=',$to)
                             ->sum('length');            
             $para_strlen = 0;
+            
             foreach ($sentFinished as $sent) {
                 # code...
                 if($request->get('cache')=="1"){
@@ -157,8 +158,8 @@ class SentenceInfoController extends Controller
                     $resulte = $strlen / $pageStrLen;
                 }
                 break;
-            case 'percent':
-                $resulte = $percent;
+            case 'percent': //百分比
+                $resulte = sprintf('%.2f',$percent);
                 break;
             case 'strlen':
             default:
@@ -176,23 +177,35 @@ class SentenceInfoController extends Controller
      *
      * @param  \App\Models\Sentence  $sentence
      * @return \Illuminate\Http\Response
-     * http://127.0.0.1:8000/api/sentence/progress/image?channel=00ae2c48-c204-4082-ae79-79ba2740d506&&book=168&from=916&to=926&view=page
+     * http://127.0.0.1:8000/api/sentence/progress/image?channel=00ae2c48-c204-4082-ae79-79ba2740d506&&book=168&from=916&to=926&view=percent
      */
     public function showprogress(Request $request)
     {
-        ob_clean();
-        ob_start();
         $resulte = $this->getSentProgress($request);
-        $img = imagecreate(strlen($resulte)*10,22) or die('create image fail ');
-        imagecolorallocate($img,255,255,255);
-        $color = imagecolorallocate($img,0,0,0);
-        imagestring($img,5,0,0,$resulte,$color);
-        imagegif($img);
-        imagedestroy($img);
+        $svg = "<svg  xmlns='http://www.w3.org/2000/svg'  xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 100 25'>";
 
-        $content = ob_get_clean();
-        return response($content,200,[
-            'Content-Type'=>'image/gif'
+        switch ($request->get('view')) {
+            case 'percent':
+                # code...
+                $resulte = $resulte*100;
+                $svg .= "<rect id='frontground' x='0' y='0' width='100' height='25' fill='#cccccc' ></rect>";
+                $svg .= "<text id='bg_text'  x='5' y='21' fill='#006600' style='font-size:25px;'>$resulte%</text>";
+                $svg .= "<rect id='background' x='0' y='0' width='100' height='25' fill='#006600' clip-path='url(#textClipPath)'></rect>";
+                $svg .= "<text id='bg_text'  x='5' y='21' fill='#ffffff' style='font-size:25px;' clip-path='url(#textClipPath)'>$resulte%</text>";
+                $svg .= "<clipPath id='textClipPath'>";
+                $svg .= "    <rect x='0' y='0' width='$resulte' height='25'></rect>";
+                $svg .= "</clipPath>";
+                break;
+            case 'strlen':
+            case 'page':
+            default:
+                $svg .= "<text id='bg_text'  x='5' y='21' fill='#006600' style='font-size:25px;'>$resulte</text>";
+                break;
+        }
+        $svg .= "</svg>";
+
+        return response($svg,200,[
+            'Content-Type'=>'image/svg+xml'
         ]);
     }
 

+ 7 - 0
app/Models/DhammaTerm.php

@@ -8,4 +8,11 @@ use Illuminate\Database\Eloquent\Model;
 class DhammaTerm extends Model
 {
     use HasFactory;
+
+    protected $primaryKey = 'guid';
+    public  $incrementing = false;
+    //protected $keyType = "string";
+    protected $casts = [
+        'guid' => 'string'
+    ];
 }

+ 5 - 0
public/app/article/index.php

@@ -9,10 +9,12 @@ require_once "../pcdl/html_head.php";
 	</script>
 
 	<script  src="./article.js"></script>
+	<script  src="./term.js"></script>
 
 	<script src="../widget/like.js"></script>
 	<link type="text/css" rel="stylesheet" href="../widget/like.css"/>
 	<script src="../palicanon/chapter_channel.js"></script>
+	<link type="text/css" rel="stylesheet" href="../palicanon/chapter_channel.css"/>
 
 	<script src="../widget/click_dropdown.js"></script>
 	<link type="text/css" rel="stylesheet" href="../widget/click_dropdown.css"/>
@@ -474,6 +476,9 @@ function set_toc_visible(isVisible){
 		case "sim":
 			palicanon_load();
 			break;
+        case 'term':
+            term_load();
+            break;
 		default:
 			break;
 	}

+ 43 - 0
public/app/article/term.js

@@ -0,0 +1,43 @@
+function term_load(){
+    let params = new URLSearchParams(document.location.search.substring(1));
+    if(params.get("view") != 'term'){
+        return;
+    }
+    $.getJSON("/api/v2/terms?view=show&id="+params.get("id"))
+    .done(function(data){
+        let result = data.data;
+						_article_date = result;
+						$("#article_title").html(result.word);
+						//$("#article_path_title").html(result.meaning);
+						$("#page_title").text(result.title);
+						$("#article_subtitle").html(result.meaning + "; " + result.other_meaning);
+                        /*
+						let article_author = result.username.nickname + "@" + result.username.username;
+						if(result.lang !== "false"){
+							article_author += result.lang;
+						}else{
+							result.lang = "en";
+						}
+						
+						$("#article_author").html( article_author );
+*/
+						//将绝对链接转换为 用户连接的主机链接
+						//result.content = result.content.replace(/www-[A-z]*.wikipali.org/g,location.host);
+
+						$("#contents").html(note_init(result.note,"",result.owner,result.language));
+						//处理<code>标签作为气泡注释
+						popup_init();
+						guide_init();
+						note_refresh_new(function(){
+                            $.get('templiates/glossary.tpl',function(data){
+                                let TermData = term_get_used();
+                                let rendered = Mustache.render(data,TermData);
+                                $("#glossary").html(rendered);                                
+                            });
+                        });
+
+    })
+    .fail(function(){
+
+    });
+}

+ 3 - 0
public/app/channal/function.php

@@ -10,6 +10,9 @@ class Channal extends Table
     }
 
     public function getChannal($id){
+        if(empty($id)){
+            return false;
+        }
         $query = "SELECT * FROM ".$this->table." WHERE uid =? ";
         $stmt = $this->dbh->prepare($query);
         $stmt->execute(array($id));

+ 7 - 7
public/app/palicanon/category/cscd.json

@@ -4,11 +4,11 @@
         "tag":["mūla"],
         "children":[
             {
-                "name":"sutta piṭaka",
+                "name":"Sutta Piṭaka",
                 "tag":["mūla","sutta"],
                 "children":[
                     {
-                        "name":"dīghanikāya",
+                        "name":"Dīghanikāya",
                         "tag":["mūla","sutta","dīghanikāya"],
                         "children":[
                             {
@@ -44,7 +44,7 @@
                         ]
                     },
                     {
-                        "name":"saṃyuttanikāya",
+                        "name":"Saṃyuttanikāya",
                         "tag":["mūla","sutta","saṃyuttanikāya"],
                         "children":[
                             {
@@ -70,7 +70,7 @@
                         ]
                     },
                     {
-                        "name":"aṅguttaranikāya",
+                        "name":"Aṅguttaranikāya",
                         "tag":["mūla","sutta","aṅguttaranikāya"],
                         "children":[
                             {
@@ -120,7 +120,7 @@
                         ]
                     },
                     {
-                        "name":"khuddakanikāya",
+                        "name":"Khuddakanikāya",
                         "tag":["mūla","sutta","khuddakanikāya"],
                         "children":[
                             {
@@ -200,7 +200,7 @@
                 ]
             },
             {
-                "name":"vinaya piṭaka",
+                "name":"Vinaya Piṭaka",
                 "tag":["mūla","vinaya"],
                 "children":[
                     {
@@ -226,7 +226,7 @@
                 ]
             },
             {
-                "name":"abhidhamma piṭaka",
+                "name":"Abhidhamma Piṭaka",
                 "tag":["mūla","abhidhamma"],
                 "children":[
                     {

+ 342 - 10
public/app/palicanon/category/defualt.json

@@ -1,6 +1,6 @@
 [
            {
-                "name":"sutta",
+                "name":"Sutta Piṭaka",
                 "tag":["sutta"],
                 "children":[
                     {
@@ -196,7 +196,7 @@
                 ]
             },
             {
-                "name":"vinaya piṭaka",
+                "name":"Vinaya Piṭaka",
                 "tag":["vinaya"],
                 "children":[
                     {
@@ -222,37 +222,369 @@
                 ]
             },
             {
-                "name":"abhidhamma piṭaka",
+                "name":"Abhidhamma Piṭaka",
                 "tag":["abhidhamma"],
                 "children":[
                     {
-                        "name":"dhammasaṅgaṇī",
+                        "name":"Dhammasaṅgaṇī",
                         "tag":["abhidhamma","dhammasaṅgaṇī"]
                     },
                     {
-                        "name":"vibhaṅga",
+                        "name":"Vibhaṅga",
                         "tag":["abhidhamma","vibhaṅga"]
                     },
                     {
-                        "name":"dhātukathā",
+                        "name":"Dhātukathā",
                         "tag":["abhidhamma","dhātukathā"]
                     },
                                 {
-                        "name":"puggalapaññatti",
+                        "name":"Puggalapaññatti",
                         "tag":["abhidhamma","puggalapaññatti"]
                     },
                                 {
-                        "name":"kathāvatthu",
+                        "name":"Kathāvatthu",
                         "tag":["abhidhamma","kathāvatthu"]
                     },
                     {
-                        "name":"yamaka",
+                        "name":"Yamaka",
                         "tag":["abhidhamma","yamaka"]
                     },
                     {
-                        "name":"paṭṭhāna",
+                        "name":"Paṭṭhāna",
                         "tag":["abhidhamma","paṭṭhāna"]
                     }
                 ]
+            },
+    {
+        "name":"Añña",
+        "tag":["añña"],
+        "children":[
+            {
+                "name":"Visuddhimagga",
+                "tag":["añña","visuddhimagga"],
+                "children":[
+                    {
+                        "name":"Visuddhimagga-1",
+                        "tag":["añña","visuddhimagga","aṭṭhakathā","paṭhamo bhāgo"]
+                    },
+                    {
+                        "name":"Visuddhimagga-2",
+                        "tag":["añña","visuddhimagga","aṭṭhakathā","dutiyo bhāgo"]
+                    },
+                    {
+                        "name":"Visuddhimagga-mahāṭīkā-1",
+                        "tag":["añña","visuddhimagga","ṭīkā","paṭhamo bhāgo"]
+                    },
+                    {
+                        "name":"Visuddhimagga-mahāṭīkā-2",
+                        "tag":["añña","visuddhimagga","ṭīkā","dutiyo bhāgo"]
+                    },
+                    {
+                        "name":"Visuddhimagga-nidānakathā",
+                        "tag":["añña","visuddhimagga","nidānakathā"]
+                    }
+                ]
+            },
+            {
+                "name":"Saṃgāyanassa-Pucchā Vissajjanā",
+                "tag":["añña","saṃgāyanassa pucchā vissajjanā"],
+                "children":[
+                    {
+                        "name":"Dīghanikāya(Pu-Vi)",
+                        "tag":["añña","saṃgāyanassa pucchā vissajjanā","dīghanikāya"]
+                    },
+                    {
+                        "name":"Majjhimanikāya(Pu-Vi)",
+                        "tag":["añña","saṃgāyanassa pucchā vissajjanā","majjhimanikāya"]
+                    },
+                    {
+                        "name":"Saṃyuttanikāya(Pu-Vi)",
+                        "tag":["añña","saṃgāyanassa pucchā vissajjanā","saṃyuttanikāya"]
+                    },
+                    {
+                        "name":"Aṅguttaranikāya(Pu-Vi)",
+                        "tag":["añña","saṃgāyanassa pucchā vissajjanā","aṅguttaranikāya"]
+                    },
+                    {
+                        "name":"Vinayapiṭaka(Pu-Vi)",
+                        "tag":["añña","saṃgāyanassa pucchā vissajjanā","vinayapiṭaka"]
+                    },
+                    {
+                        "name":"Abhidhammapiṭaka(Pu-Vi)",
+                        "tag":["añña","saṃgāyanassa pucchā vissajjanā","abhidhammapiṭaka"]
+                    },
+                    {
+                        "name":"Aṭṭhakathā(Pu-Vi)",
+                        "tag":["añña","saṃgāyanassa pucchā vissajjanā","aṭṭhakathā"]
+                    }
+                ]
+            },
+            {
+                "name":"Leḍī Sayādo Gantha-Saṅgaho",
+                "tag":["añña","leḍī sayādo"],
+                "children":[
+                    {
+                        "name":"Niruttidīpanīpāṭha",
+                        "tag":["añña","leḍī sayādo","niruttidīpanīpāṭha"]
+                    },
+                    {
+                        "name":"Paramatthadīpanī",
+                        "tag":["añña","leḍī sayādo","paramatthadīpanī"]
+                    },
+                    {
+                        "name":"Anudīpanīpāṭha",
+                        "tag":["añña","leḍī sayādo","anudīpanīpāṭha"]
+                    },
+                    {
+                        "name":"Paṭṭhānuddesa dīpanīpāṭha",
+                        "tag":["añña","leḍī sayādo","paṭṭhānuddesa dīpanīpāṭha"]
+                    }
+                ]
+            },
+            {
+                "name":"Buddha-Vandana Gantha-Saṅgaho",
+                "tag":["añña","buddha-vandana"],
+                "children":[
+                    {
+                        "name":"Namakkāratīkā",
+                        "tag":["añña","buddha-vandana","namakkāra"]
+                    },
+                    {
+                        "name":"Mahāpaṇāmapāṭha",
+                        "tag":["añña","buddha-vandana","mahāpaṇāmapāṭha"]
+                    },
+                    {
+                        "name":"Lakkhaṇāto Buddhathomanāgāthā",
+                        "tag":["añña","buddha-vandana","lakkhaṇāto"]
+                    },
+                    {
+                        "name":"Suttavandanā",
+                        "tag":["añña","buddha-vandana","suttavandanā"]
+                    },
+                    {
+                        "name":"Jinālaṅkāra",
+                        "tag":["añña","buddha-vandana","jinālaṅkāra"]
+                    },
+                    {
+                        "name":"Kamalāñjali",
+                        "tag":["añña","buddha-vandana","kamalāñjali"]
+                    },
+                    {
+                        "name":"Pajjamadhu",
+                        "tag":["añña","buddha-vandana","pajjamadhu"]
+                    },
+                    {
+                        "name":"Buddhaguṇagāthāvalī",
+                        "tag":["añña","buddha-vandana","buddhaguṇagāthāvalī"]
+                    }
+                ]
+            },
+            {
+                "name":"Vaṃsa Gantha-Saṅgaho",
+                "tag":["añña","vaṃsa"],
+                "children":[
+                    {
+                        "name":"Cūḷaganthavaṃsa",
+                        "tag":["añña","vaṃsa","Cūḷaganthavaṃsapāḷi"]
+                    },
+                    {
+                        "name":"sāsanavaṃsa",
+                        "tag":["añña","vaṃsa","sāsanavaṃsappadīpikā"]
+                    },
+                    {
+                        "name":"Mahāvaṃsa",
+                        "tag":["añña","vaṃsa","mahāvaṃsapāḷi"]
+                    }
+                ]
+            },
+            {
+                "name":"Byākaraṇa Gantha-Saṅgaho",
+                "tag":["añña","byākaraṇa ganthasaṅgaha"],
+                "children":[
+                    {
+                        "name":"Moggallānabyākaraṇa",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","moggallānasuttapāṭha"]
+                    },
+                    {
+                        "name":"Kaccāyanabyākaraṇaṃ",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","kaccāyanabyākaraṇa"]
+                    },
+                    {
+                        "name":"Saddanītippakaraṇaṃ (padamālā)",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","padamālā"]
+                    },
+                    {
+                        "name":"Saddanītippakaraṇaṃ (Dhātumālā)",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","dhātumālā"]
+                    },
+                    {
+                        "name":"Padarūpasiddhi",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","padarūpasiddhi"]
+                    },
+                    {
+                        "name":"Moggallānapañcikā",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","moggallānapañcikā"]
+                    },
+                    {
+                        "name":"Payogasiddhipāṭha",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","payogasiddhipāḷi"]
+                    },
+                    {
+                        "name":"Vuttodayapāṭha",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","vuttodaya"]
+                    },
+                    {
+                        "name":"Abhidhānappadīpikāpāṭha",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","abhidhānappadīpikā"]
+                    },
+                    {
+                        "name":"Abhidhānappadīpikāṭīkā",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","abhidhānappadīpikāṭīkā"]
+                    },
+                    {
+                        "name":"Subodhālaṅkārapāṭha",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","subodhālaṅkāra"]
+                    },
+                    {
+                        "name":"Subodhālaṅkāraṭīkā",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","subodhālaṅkāraṭīkā"]
+                    },
+                    {
+                        "name":"Bālāvatāra",
+                        "tag":["añña","byākaraṇa ganthasaṅgaha","bālāvatāra"]
+                    }
+                ]
+            },
+            {
+                "name":"Nīti-Gantha-Saṅgaho",
+                "tag":["añña","nīti"],
+                "children":[
+                    {
+                        "name":"Kavidappaṇanīti",
+                        "tag":["añña","nīti","kavidappaṇanīti"]
+                    },
+                    {
+                        "name":"Nītimañjarī",
+                        "tag":["añña","nīti","nītimañjarī"]
+                    },
+                    {
+                        "name":"Dhammanīti",
+                        "tag":["añña","nīti","dhammanīti"]
+                    },
+                    {
+                        "name":"Mahārahanīti",
+                        "tag":["añña","nīti","mahārahanīti"]
+                    },
+                    {
+                        "name":"Lokanīti",
+                        "tag":["añña","nīti","lokanīti"]
+                    },
+                    {
+                        "name":"Suttantanīti",
+                        "tag":["añña","nīti","suttantanīti"]
+                    },
+                    {
+                        "name":"Sūrassatīnīti",
+                        "tag":["añña","nīti","sūrassatīnīti"]
+                    },
+                    {
+                        "name":"Cāṇakyanītipāḷi",
+                        "tag":["añña","nīti","cāṇakyanītipāḷi"]
+                    },
+                    {
+                        "name":"Naradakkhadīpanī",
+                        "tag":["añña","nīti","naradakkhadīpanī"]
+                    },
+                    {
+                        "name":"Caturārakkhadīpanī",
+                        "tag":["añña","nīti","caturārakkhadīpanī"]
+                    }
+                ]
+            },
+            {
+                "name":"Pakiṇṇaka-Gantha-Saṅgaho",
+                "tag":["añña","pakiṇṇaka"],
+                "children":[
+                    {
+                        "name":"Rasavāhinī",
+                        "tag":["añña","pakiṇṇaka","rasavāhinī"]
+                    },
+                    {
+                        "name":"Sīmavisodhanī",
+                        "tag":["añña","pakiṇṇaka","sīmavisodhanī"]
+                    },
+                    {
+                        "name":"Vessantarāgīti",
+                        "tag":["añña","pakiṇṇaka","vessantarāgīti"]
+                    }
+                ]
+            },
+            {
+                "name":"Sihaḷa-Gantha-Saṅgaho",
+                "tag":["añña","sihaḷa"],
+                "children":[
+                    {
+                        "name":"Moggallāna vuttivivaraṇapañcikā",
+                        "tag":["añña","sihaḷa","moggallāna vuttivivaraṇapañcikā"]
+                    },
+                    {
+                        "name":"Thupavaṃsa",
+                        "tag":["añña","sihaḷa","thupavaṃsa"]
+                    },
+                    {
+                        "name":"Dāṭhāvaṃsa",
+                        "tag":["añña","sihaḷa","Dāṭhāvaṃsa"]
+                    },
+                    {
+                        "name":"Dhātupāṭha vilāsiniyā",
+                        "tag":["añña","sihaḷa","dhātupāṭha vilāsiniyā"]
+                    },
+                    {
+                        "name":"Dhātuvaṃsa",
+                        "tag":["añña","sihaḷa","dhātuvaṃsa"]
+                    },
+                    {
+                        "name":"Hatthavanagallavihāravaṃsa",
+                        "tag":["añña","sihaḷa","hatthavanagallavihāravaṃsa"]
+                    },
+                    {
+                        "name":"Jinacaritaya",
+                        "tag":["añña","sihaḷa","jinacaritaya"]
+                    },
+                    {
+                        "name":"Jinavaṃsadīpaṃ",
+                        "tag":["añña","sihaḷa","jinavaṃsadīpa"]
+                    },
+                    {
+                        "name":"Telakaṭāhagāthā",
+                        "tag":["añña","nīti","telakaṭāhagāthā"]
+                    },
+                    {
+                        "name":"Milidaṭīkā",
+                        "tag":["añña","nīti","milidaṭīkā"]
+                    },
+                    {
+                        "name":"Padamañjarī",
+                        "tag":["añña","nīti","padamañjarī"]
+                    },
+                    {
+                        "name":"Padasādhana",
+                        "tag":["añña","nīti","padasādhana"]
+                    },
+                    {
+                        "name":"saddabindupakaraṇa",
+                        "tag":["añña","nīti","saddabindupakaraṇa"]
+                    },
+                    {
+                        "name":"Kaccāyanadhātumañjūsā",
+                        "tag":["añña","nīti","kaccāyanadhātumañjūsā"]
+                    },
+                    {
+                        "name":"Samantakūṭavaṇṇanā",
+                        "tag":["añña","nīti","samantakūṭavaṇṇanā"]
+                    }
+                ]
             }
+        ]
+    }
 ]

+ 22 - 0
public/app/palicanon/chapter_channel.css

@@ -0,0 +1,22 @@
+ul.chapter_info_list>li{
+	display:flex;
+}
+ul.chapter_info_list>li .channel_name{
+	flex:3;
+}
+ul.chapter_info_list>li .progress_bar{
+	flex:3;
+}
+ul.chapter_info_list>li .views{
+	flex:1;
+}
+ul.chapter_info_list>li .likes{
+	flex:1;
+}
+ul.chapter_info_list>li>.updated_at{
+	flex:3;
+}
+
+.progress_bar>svg{
+	width:80px;
+}

+ 81 - 9
public/app/palicanon/chapter_channel.js

@@ -19,8 +19,12 @@ function loadChapterChannel(param){
     },
     function (data, status) {
         let arrChannelList = data.data.rows;
-        $(param.target).html(render_chapter_progress_list(arrChannelList,param));
-        Like();
+		if(typeof param.readonly != "undefined" && param.readonly == true){
+			$(param.target).html(render_chapter_progress_list_readonly(arrChannelList,param));
+		}else{
+			$(param.target).html(render_chapter_progress_list(arrChannelList,param));
+			Like();
+		}
     }
     );
 }
@@ -28,7 +32,8 @@ function loadChapterChannel(param){
 //章节已经有译文的channel 列表
 function render_chapter_progress_list(chapterList,param) {
 	let html = "";
-    html += "<ul>";
+    html += "<ul class='chapter_info_list'>";
+
 	for (const iterator of chapterList) {
         if(iterator.channel){
             if(param.showchannel){
@@ -37,21 +42,65 @@ function render_chapter_progress_list(chapterList,param) {
                 }
             }
             html += "<li>";
-            html += "<span>";
+            html += "<span clsss='channel_name' style='flex:2;'>";
             html += "<a href='../article/?view=chapter&book="+iterator.book+"&par="+iterator.para+"&channel="+iterator.channel.uid+"' target='_blanck'>";
             html += iterator.channel.name;
             html += "</a>";
             html += "</span>";
-            html += "<span>";
-            html += iterator.progress;
+            html += "<span class='progress_bar'>";
+            html += renderProgressBar(iterator.progress);
             html += "</span>";
-            html += "<span>";
+            html += "<span class='views' >";
             html += iterator.views;
             html += "</span>";
-            html += "<span class='likes'>";
+            html += "<span class='likes' style='flex:5;'>";
             html += renderChannelLikes(iterator.likes,'progress_chapter',iterator.uid);
             html += "</span>";
-            html += "<span title='"+iterator.updated_at+"'>";
+            html += "<span class='updated_at' title='"+iterator.updated_at+"' >";
+            html += getPassDataTime(new Date(iterator.updated_at));
+            html += "</span>";
+            html += "</li>";
+        }
+	}
+    html += "</ul>";
+
+	return html;
+}
+
+function render_chapter_progress_list_readonly(chapterList,param) {
+	let html = "";
+    html += "<ul class='chapter_info_list'>";
+	html += "<li>";
+	html += "<span clsss='channel_name' >版本</span>";
+	html += "<span clsss='progress_bar' >进度</span>";
+	html += "<span clsss='views' >阅读</span>";
+	html += "<span clsss='likes' >点赞</span>";
+	html += "<span clsss='updated_at' >更新于</span>";
+	html += "</li>";
+
+	for (const iterator of chapterList) {
+        if(iterator.channel){
+            if(param.showchannel){
+                if(!param.showchannel.includes(iterator.channel.uid)){
+                    continue;
+                }
+            }
+            html += "<li>";
+            html += "<span clsss='channel_name' style='flex:3;'>";
+            html += "<a href='../article/?view=chapter&book="+iterator.book+"&par="+iterator.para+"&channel="+iterator.channel.uid+"' target='_blanck'>";
+            html += iterator.channel.name;
+            html += "</a>";
+            html += "</span>";
+            html += "<span class='progress_bar'>";
+            html += renderProgressBar(iterator.progress);
+            html += "</span>";
+            html += "<span class='views' >";
+            html += iterator.views;
+            html += "</span>";
+            html += "<span class='likes' >";
+            html += getChapterLikeCount(iterator.likes,'like');
+            html += "</span>";
+            html += "<span class='updated_at' title='"+iterator.updated_at+"' >";
             html += getPassDataTime(new Date(iterator.updated_at));
             html += "</span>";
             html += "</li>";            
@@ -62,6 +111,14 @@ function render_chapter_progress_list(chapterList,param) {
 	return html;
 }
 
+function getChapterLikeCount(info,likeType){
+	for (const item of info) {
+		if(item.type==likeType){
+			return item.count;
+		}
+	}
+	return 0;
+}
 function renderChannelLikes(info,restype,resid){
     /*
     点赞 like
@@ -89,4 +146,19 @@ function renderChannelLikes(info,restype,resid){
         html += ">"+count+"</like>";
     }
     return html;
+}
+
+function renderProgressBar(progress){
+	let html = "<svg  xmlns='http://www.w3.org/2000/svg'  xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 100 25'>";
+	let resulte = Math.round(progress*100);
+	let clipPathId = "ClipPath_"+com_uuid();
+	html += "<rect id='frontground' x='0' y='0' width='100' height='25' fill='#cccccc' ></rect>";
+	html += "<text id='bg_text'  x='5' y='19' fill='#006600' style='font-size:20px;'>"+resulte+"%</text>";
+	html += "<rect id='background' x='0' y='0' width='100' height='25' fill='#006600' clip-path='url(#"+clipPathId+")'></rect>";
+	html += "<text id='bg_text'  x='5' y='19' fill='#ffffff' style='font-size:20px;' clip-path='url(#"+clipPathId+")'>"+resulte+"%</text>";
+	html += "<clipPath id='"+clipPathId+"'>";
+	html += "    <rect x='0' y='0' width='"+resulte+"' height='25'></rect>";
+	html += "</clipPath>";
+	html += "</svg>";
+	return html;
 }

+ 298 - 82
public/app/palicanon/index.php

@@ -6,8 +6,8 @@ require_once "../pcdl/html_head.php";
     <script src="../palicanon/palicanon.js"></script>
     <script src="../term/term.js"></script>
 
-    <?php
-require_once "../pcdl/head_bar.php";
+<?php
+    require_once "../pcdl/head_bar.php";
 ?>
 
 	<link type="text/css" rel="stylesheet" href="../palicanon/style.css" />
@@ -17,7 +17,7 @@ require_once "../pcdl/head_bar.php";
     <script>
         var tag_level = <?php echo file_get_contents("../public/book_tag/tag_list.json"); ?>;
     </script>
-    <?php
+<?php
 //
 
 require_once "../config.php";
@@ -25,93 +25,309 @@ require_once "../public/_pdo.php";
 require_once '../media/function.php';
 require_once '../public/function.php';
 ?>
-    <div id='course_head_bar' style='background-color:var(--tool-bg-color1);padding:1em 10px 10px 10px;'>
-    <div class='index_inner '>
-    <div style='font-size:140%'>
-    </div>
-    <div id="main_tag"  style="">
-    <span tag="sutta" title="sutta"></span>
-    <span tag="vinaya"  title="vinaya"></span>
-    <span tag="abhidhamma" title="abhidhamma"></span>
-    <span tag="mūla" title="mūla"></span>
-    <span tag="aṭṭhakathā" title="aṭṭhakathā"></span>
-    <span tag="ṭīkā" title="ṭīkā"></span>
-    <span tag="añña" title="añña"></span>
-	</div>
-
-	<div id="select_bar" >
-		<div id="tag_selected"></div>
-		<div>
-			<button onclick="tag_list_slide_toggle(this)">
-				⮝
-			</button>
-		</div>
-	</div>
-	<div>
-
-		<div id="tag_list">
-			<div level="0" class="tag_others"></div>
-			<div level="1" class="tag_others"></div>
-			<div level="2" class="tag_others"></div>
-			<div level="3" class="tag_others"></div>
-			<div level="4" class="tag_others"></div>
-			<div level="5" class="tag_others"></div>
-			<div level="100" class="tag_others"></div>
-			<div level="8" class="tag_others"></div>
-		</div>
-	</div>
-    </div>
+
+<link href="../../node_modules/jquery.fancytree/dist/skin-win7/ui.fancytree.css" rel="stylesheet" type="text/css" class="skinswitcher">
+<script src="../tree/jquery.fancytree.js" type="text/javascript"></script>
+
+	<script src="../widget/like.js"></script>
+	<link type="text/css" rel="stylesheet" href="../widget/like.css"/>
+	<script src="../palicanon/chapter_channel.js"></script>
+	<link type="text/css" rel="stylesheet" href="../palicanon/chapter_channel.css"/>
+	<link type="text/css" rel="stylesheet" href="../palicanon/loading.css"/>
+
+    <script src="router.js"></script>
+    <script src="test.js"></script>
+
+<style>
+
+
+</style>
+
+<?php
+    if(isset($_GET["view"])){
+        $_view = $_GET["view"];
+    }else{
+        $_view = "community";
+    }
+?>
+
+<div id='main_view' >
+    <div id='left-bar' >
+        <div id='left-bar-inner'>
+            <div class="filter submenu">
+                <div class="title submenu_title" style="flex;">
+                    <span>分类</span>
+                    <span>
+                        <select id="tag_category_index" onchange="TagCategoryIndexchange(this)"></select>
+                    </span>
+                </div>
+                <div class='inner' style='max-height: unset;'>
+                    <div id='tag-category' ></div>
+                </div>
+            </div>
+            <div class="filter submenu">
+                <div class="title submenu_title"><span>作者</span></div>
+                <div class='inner' id='filter-author' >
+                    <div  class="lds-ellipsis" ><div></div><div></div><div></div><div></div></div>
+                </div>
+            </div>
+        </div>
     </div>
+    <div id='course_head_bar' >
+        <div class='index_inner '>
+            <div style='display:flex;justify-content: space-between;display:none;'>
+                <div> </div>
+                <div style=''>
+                    <select onchange='viewChanged(this)'>
+                        <option value='list'>列表</option>                    
+                        <option value='card'>卡片</option>
+                    </select>
+                </div>
+            </div>
+            <div>
+                <div class='main_menu' id = 'main_menu'>
+
+                </div>
+            </div>
+            <div id="main_tag"  style="display:none;">
+                <span tag="sutta" title="sutta"></span>
+                <span tag="vinaya"  title="vinaya"></span>
+                <span tag="abhidhamma" title="abhidhamma"></span>
+                <span tag="mūla" title="mūla"></span>
+                <span tag="aṭṭhakathā" title="aṭṭhakathā"></span>
+                <span tag="ṭīkā" title="ṭīkā"></span>
+                <span tag="añña" title="añña"></span>
+            </div>
+
+            <div id="select_bar" >
+                <div id="select_bar_home" onclick='categoryGoHome()'>
+                <span>
+                    <svg class='icon' style='fill: var(--box-bg-color1)'>
+                        <use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#house'>
+                    </svg>
+                </span>
+                <span>
+                    <svg class='icon' style='fill: var(--box-bg-color1)'>
+                        <use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#chevron-compact-right'>
+                    </svg>
+                </span>
+                </div>
+                <div id="channel_selected"></div>
+                <div id="tag_selected"></div>
+            </div>
+
+            <div id='palicanon-category'></div>
 
-	<div class='index_inner'>
-
-	<div id="chapter_shell" class="chapter_list" >
-	<div id="list_shell_1" class="show" level="1">
-		<ul id="list-1" class="grid" level="1" >
-		</ul>
-	</div>
-
-	<div id="list_shell_2" level="2">
-		<ul id="list-2" class="hidden" level="2"  >
-		</ul>
-	</div>
-
-	<div id="list_shell_3" level="3">
-		<ul id="list-3" class="hidden" level="3" >
-		</ul>
-	</div>
-
-	<div id="list_shell_4" level="4">
-		<ul id="list-4" class="hidden" level="4" >
-		</ul>
-	</div>
-
-	<div id="list_shell_5" level="5">
-		<ul id="list-5" class="hidden" level="5" >
-		</ul>
-	</div>
-
-	<div id="list_shell_6" level="6">
-		<ul id="list-6" class="hidden" level="6" >
-		</ul>
-	</div>
-
-	<div id="list_shell_7" level="7">
-		<ul id="list-7" class="hidden" level="7" >
-		</ul>
-	</div>
-
-	<div id="list_shell_8" level="8">
-		<ul id="list-8" class="hidden" level="8" >
-		</ul>
-	</div>
+            
+            <div id='filter_bar'>
+                <div id='filter_bar_left'></div>
+                <div id='filter_bar_right'>
+                    <button id='btn-filter' onclick="tag_list_slide_toggle(this)">
+                        <svg class='icon' style='fill: var(--box-bg-color1)'>
+                        <use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#filter'>
+                        </svg>
+                    </button>
+                </div>
+            </div>
+            <div>
+                <div id="tag_list" style='display:none;'>
+                    <div id="tag_list_head" style="display:flex;justify-content: space-between;border-bottom: 1px solid var(--border-line-color);">
+                        <div style='width:20em;'>
+                            
+                        </div>
+                        <div>
+                            <button id="btn-tag_list_close" onclick='close_tag_list()'>X</button>
+                        </div>
+                    </div>
 
+                    <div id='tag_list_inner'>
+                        <div id='tag_list_tag_div'>
+                            <h2>标签</h2>
+                            <div><input id="tag_input" type="input" placeholder="tag search" size="20"></div>
+                            <div level="0" class="tag_others"></div>
+                            <div level="1" class="tag_others"></div>
+                            <div level="2" class="tag_others"></div>
+                            <div level="3" class="tag_others"></div>
+                            <div level="4" class="tag_others"></div>
+                            <div level="5" class="tag_others"></div>
+                            <div level="100" class="tag_others"></div>
+                            <div level="8" class="tag_others"></div>
+                        </div>
+                        <div id='tag_list_setting_div'>
+                            <h2>设定</h2>
+                            <div class='inner' id='filter-setting' >
+                                <div class='settting-item'>
+                                    <span>语言</span>
+                                    <span>
+                                        <select id='setting_lang'>
+                                            <option value='auto'>自动</option>
+                                            <option value=''>全部</option>
+                                            <option value='zh'>中文</option>
+                                            <option value='en'>英文</option>
+                                        </select>
+                                    </span>
+                                </div>
+                                <div class='settting-item'>
+                                    <span>内容类型</span>
+                                    <span>
+                                        <select id='setting_channel_type'>
+                                            <option value=''>全部</option>
+                                            <option value='translation' selected >译文</option>
+                                            <option value='nissaya'>Nissaya</option>
+                                            <option value='commentray'>注疏</option>
+                                        </select>
+                                    </span>
+                                </div>
+                                <div class='settting-item'>
+                                    <span>完成度</span>
+                                    <span>
+                                        <select id='setting_progress'>
+                                            <option value='0.9'>90</option>
+                                            <option value='0.8'>80</option>
+                                            <option value='0.5'>50</option>
+                                            <option value='0.2'>20</option>
+                                        </select>
+                                    </span>
+                                </div>
+                                <div style='display:flex;justify-content: space-between;'><button>还原默认</button><button onclick="updateSetting()">应用</button></div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+			<div id="index_div">
+				<div id='file_background'></div>
+				<div id = "file_list_div">
+					<div id='bread-crumbs'></div>
+					<div class='index_inner'>
+						<div id="chapter_shell" class="chapter_list" >
+							<div id="list_shell_1" class="show" level="1">
+								<ul id="list-1" class="grid" level="1" >
+								</ul>
+							</div>
+
+							<div id="list_shell_2" level="2">
+								<ul id="list-2" class="hidden" level="2"  >
+								</ul>
+							</div>
+
+							<div id="list_shell_3" level="3">
+								<ul id="list-3" class="hidden" level="3" >
+								</ul>
+							</div>
+
+							<div id="list_shell_4" level="4">
+								<ul id="list-4" class="hidden" level="4" >
+								</ul>
+							</div>
+
+							<div id="list_shell_5" level="5">
+								<ul id="list-5" class="hidden" level="5" >
+								</ul>
+							</div>
+
+							<div id="list_shell_6" level="6">
+								<ul id="list-6" class="hidden" level="6" >
+								</ul>
+							</div>
+
+							<div id="list_shell_7" level="7">
+								<ul id="list-7" class="hidden" level="7" >
+								</ul>
+							</div>
+
+							<div id="list_shell_8" level="8">
+								<ul id="list-8" class="hidden" level="8" >
+								</ul>
+							</div>
+
+						</div>
+					</div>
+				</div>
+			</div>
+        </div>
     </div>
+    <div style="flex:2;">
+    <div class='bangdan' id = "user_recent">
+        <div class='title'>最近阅读</div>
+        <div class='list'>
+            <div class="lds-ellipsis" ><div></div><div></div><div></div><div></div></div>
+        </div>
     </div>
+    <div class='bangdan'>
+        <div class='title'>求助</div>
+        <div class='list'>
+            <ul>
+                <li>zuixin-1</li>
+            </ul>
+        </div>
+    </div>
+    <div class='bangdan'>
+        <div class='title'>社区推荐</div>
+        <div class='list'>
+            <ul>
+                <li>zuixin-1</li>
+            </ul>
+        </div>
+    </div>
+    <div class='bangdan' id='contribution'>
+        <div class='title'>月度贡献</div>
+        <div class='list'>
+            <div class="lds-ellipsis" ><div></div><div></div><div></div><div></div></div>
+        </div>
+    </div>
+    </div>
+</div>
+
+
 
     <script>
         $(document).ready(function() {
-            palicanon_onload();
+            
+            let indexFilename = localStorage.getItem('palicanon_tag_category');
+            if(!indexFilename){
+                indexFilename = "defualt";
+            }
+            loadTagCategory(indexFilename);
+            loadTagCategoryIndex();
+            loadFilterSetting();//载入上次的过滤器配置
+            LoadAllLanguage();
+            <?php
+            if(isset($_GET["view"])){
+                echo "_view = '{$_GET["view"]}';";
+            }else{
+                echo "_view = 'community';";
+                echo "updataHistory();";
+            }
+
+            if(isset($_GET["tag"])){
+                echo "_tags = '{$_GET["tag"]}';";
+            }
+            if(isset($_GET["channel"])){
+                echo "_channel = '{$_GET["channel"]}';";
+            }
+            
+            switch ($_view) {
+                case 'community':
+                    //echo "community_onload();";
+                    break;
+                case 'category':
+                    //echo "palicanon_onload();";
+                    break;
+                case 'my';
+                default:
+                    # code...
+                    break;
+            }
+            ?>
+            list_tag = _tags.split(',');
+            refresh_selected_tag();
+            ReanderMainMenu();
+            updateFirstListView();
+            //载入用户最近的阅读列表
+            loadUserRecent();
+            loadContribution();
+            
         });
     </script>
     <?php

+ 130 - 280
public/app/palicanon/index1.php

@@ -38,180 +38,7 @@ require_once '../public/function.php';
     <script src="test.js"></script>
 
 <style>
-.chapter_list ul {
-    margin-left: 0;
-}
-.head_bar{
-    display: flex;
-    flex-direction: column;
-}
-#left-bar{
-    flex: 2;
-    background-color: var(--box-bg-color2);
-}
 
-.chapter_list ul li .main{
-    display:flex;
-}
-.book_view  ul li{
-    display:block;
-}
-.book_view .level_1{
-    background:unset;
-}
-
-.book_view ul li{
-    border:unset;
-    width: 30%;
-    height:90px;
-}
-.chapter_list .list {
-    display: none;
-}
-.chapter_list .show {
-    display: block;
-    width: 100%;
-}
-.chapter_list .grid {
-    width: 100%;
-}
-.chapter_list > div {
-    max-height: unset;
-    overflow-y: unset; 
-}
-
-.chapter_list .more_info{
-    display:flex;
-    font-size:80%;
-    color: var(--main-color1);
-    justify-content: space-between;
-}
-
-
-}
-.more_info>.palicanon_chapter_info>.item{
-    margin-right:1em;
-}
-.left_item>.item{
-    margin-right:1em;
-}
-.filter>.inner {
-    max-height: 200px;
-    overflow-y: auto;
-    background-color: var(--input-bg-color);
-}
-
-.main_menu {
-    font-size: 100%;
-    text-align: center;
-    margin: 0 1em;
-    transition: all 600ms ease;
-    text-transform: capitalize;
-}
-.main_menu>span {
-    margin: 2px;
-    padding: 2px 12px;
-    font-weight: 500;
-    transition-duration: 0.2s;
-    cursor: pointer;
-    font-size: 120%;
-    border: unset;
-    border-radius: 0;
-    border-bottom: 2px solid var(--nocolor);
-    display: inline-block;
-}
-.main_menu>.select {
-    border-bottom: 2px solid var(--link-color);
-}
-.main_menu>span>a {
-    color:unset;
-}
-.main_menu span:hover {
-    background-color: unset;
-    color: unset;
-    border-color: var(--link-hover-color);
-}
-.submenu select>option {
-    background-color: gray;
-}
-button.active {
-    background-color: gray;
-}
-
-.chapter_list ul li>.main>.left{
-    width: 100px;
-    display: flex;
-    flex-direction: row;
-    justify-content: space-between;
-}
-.chapter_list ul li>.main>.right{
-    width:100%;
-}
-.chapter_tag {
-    width: 475px;
-    padding: 5px 0;
-    overflow-y: visible;
-    overflow-x: auto;
-    display: flex;
-    flex-wrap: wrap;
-}
-.left_item {
-    margin: 4px 0;
-}
-.left_item>.item>.small_icon{
-    width:16px;
-    height:16px;
-}
-.left_item>.item>.text{
-    padding:5px;
-}
-
-div#tag_list {
-    background-color: var(--btn-color);
-    padding: 5px;
-    display: none;
-}
-
-#more_chapter {
-    text-align: center;
-}
-#more_chapter_line {
-    border-bottom: 1px solid var(--border-line-color);
-    height: 1em;
-}
-#btn_more_chapter{
-        position: absolute;
-    margin-top: -1.1em;
-    background-color: var(--link-color);
-    color: var(--bg-color);
-    border: none;
-    padding: 2px 40px;
-    margin-left: -5em;
-}
-#filter-author li.active{
-    background-color:gray;
-}
-
-#filter_bar {
-    display: flex;
-    justify-content: space-between;
-}
-div#filter_bar {
-    font-size: 120%;
-}
-
-span.channel:hover {
-    background-color: wheat;
-}
-span.channel {
-    cursor: pointer;
-}
-
-.settting-item {
-    display: flex;
-    justify-content: space-between;
-    padding: 2px;
-}
 
 </style>
 
@@ -223,49 +50,12 @@ span.channel {
     }
 ?>
 
-<div style="display:flex;">
+<div id='main_view' >
     <div id='left-bar' >
         <div id='left-bar-inner'>
-            <div class="filter submenu">
-                <div class="title submenu_title">设定</div>
-                <div class='inner' id='filter-setting' >
-                    <div class='settting-item'>
-                        <span>内容类型</span>
-                        <span>
-                            <select>
-                                <option value=''>全部</option>
-                                <option value='translation'>译文</option>
-                                <option value='nissaya'>Nissaya</option>
-                                <option value='commentray'>注疏</option>
-                            </select>
-                        </span>
-                    </div>
-                    <div class='settting-item'>
-                        <span>完成度阈值</span>
-                        <span>
-                            <select>
-                                <option value='0.9'>90</option>
-                                <option value='0.8'>80</option>
-                                <option value='0.7'>70</option>
-                            </select>
-                        </span>
-                    </div>
-                    <div class='settting-item'>
-                        <span>语言</span>
-                        <span>
-                            <select>
-                                <option value=''>全部</option>
-                                <option value='zh'>中文</option>
-                                <option value='en'>英文</option>
-                            </select>
-                        </span>
-                    </div>
-                    <div><button>还原默认</button><button>应用</button></div>
-                </div>
-            </div>
             <div class="filter submenu">
                 <div class="title submenu_title" style="flex;">
-                    <span>分类标签</span>
+                    <span>分类</span>
                     <span>
                         <select id="tag_category_index" onchange="TagCategoryIndexchange(this)"></select>
                     </span>
@@ -275,20 +65,14 @@ span.channel {
                 </div>
             </div>
             <div class="filter submenu">
-                <div class="title submenu_title">作者</div>
-                <div class='inner' id='filter-author' ></div>
-            </div>
-            <div class="filter submenu">
-                <div class="title submenu_title">语言</div>
-                <div class='inner' id='filter-lang' ></div>
-            </div>
-            <div class="filter submenu">
-                <div class="title submenu_title">类型</div>
-                <div class='inner' id='filter-type' ></div>
+                <div class="title submenu_title"><span>作者</span></div>
+                <div class='inner' id='filter-author' >
+                    <div  class="lds-ellipsis" ><div></div><div></div><div></div><div></div></div>
+                </div>
             </div>
         </div>
     </div>
-    <div id='course_head_bar' style='flex:6;padding:0 10px 10px 10px;'>
+    <div id='course_head_bar' >
         <div class='index_inner '>
             <div style='display:flex;justify-content: space-between;display:none;'>
                 <div> </div>
@@ -315,11 +99,25 @@ span.channel {
             </div>
 
             <div id="select_bar" >
+                <div id="select_bar_home" onclick='categoryGoHome()'>
+                <span>
+                    <svg class='icon' style='fill: var(--box-bg-color1)'>
+                        <use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#house'>
+                    </svg>
+                </span>
+                <span>
+                    <svg class='icon' style='fill: var(--box-bg-color1)'>
+                        <use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#chevron-compact-right'>
+                    </svg>
+                </span>
+                </div>
                 <div id="channel_selected"></div>
                 <div id="tag_selected"></div>
             </div>
 
-            <div id='bread-crumbs'></div>
+            <div id='palicanon-category'></div>
+
+            
             <div id='filter_bar'>
                 <div id='filter_bar_left'></div>
                 <div id='filter_bar_right'>
@@ -334,74 +132,125 @@ span.channel {
                 <div id="tag_list" style='display:none;'>
                     <div id="tag_list_head" style="display:flex;justify-content: space-between;border-bottom: 1px solid var(--border-line-color);">
                         <div style='width:20em;'>
-                            <input id="tag_input" type="input" placeholder="tag search" size="20">
+                            
                         </div>
                         <div>
                             <button id="btn-tag_list_close" onclick='close_tag_list()'>X</button>
                         </div>
                     </div>
-                    <div level="0" class="tag_others"></div>
-                    <div level="1" class="tag_others"></div>
-                    <div level="2" class="tag_others"></div>
-                    <div level="3" class="tag_others"></div>
-                    <div level="4" class="tag_others"></div>
-                    <div level="5" class="tag_others"></div>
-                    <div level="100" class="tag_others"></div>
-                    <div level="8" class="tag_others"></div>
-                </div>
-            </div>
-            <div class='index_inner'>
-                <div id="chapter_shell" class="chapter_list" >
-                    <div id="list_shell_1" class="show" level="1">
-                        <ul id="list-1" class="grid" level="1" >
-                        </ul>
-                        <button>More</button>
-                    </div>
-
-                    <div id="list_shell_2" level="2">
-                        <ul id="list-2" class="hidden" level="2"  >
-                        </ul>
-                    </div>
-
-                    <div id="list_shell_3" level="3">
-                        <ul id="list-3" class="hidden" level="3" >
-                        </ul>
-                    </div>
-
-                    <div id="list_shell_4" level="4">
-                        <ul id="list-4" class="hidden" level="4" >
-                        </ul>
-                    </div>
-
-                    <div id="list_shell_5" level="5">
-                        <ul id="list-5" class="hidden" level="5" >
-                        </ul>
-                    </div>
 
-                    <div id="list_shell_6" level="6">
-                        <ul id="list-6" class="hidden" level="6" >
-                        </ul>
-                    </div>
-
-                    <div id="list_shell_7" level="7">
-                        <ul id="list-7" class="hidden" level="7" >
-                        </ul>
-                    </div>
-
-                    <div id="list_shell_8" level="8">
-                        <ul id="list-8" class="hidden" level="8" >
-                        </ul>
+                    <div id='tag_list_inner'>
+                        <div id='tag_list_tag_div'>
+                            <h2>标签</h2>
+                            <div><input id="tag_input" type="input" placeholder="tag search" size="20"></div>
+                            <div level="0" class="tag_others"></div>
+                            <div level="1" class="tag_others"></div>
+                            <div level="2" class="tag_others"></div>
+                            <div level="3" class="tag_others"></div>
+                            <div level="4" class="tag_others"></div>
+                            <div level="5" class="tag_others"></div>
+                            <div level="100" class="tag_others"></div>
+                            <div level="8" class="tag_others"></div>
+                        </div>
+                        <div id='tag_list_setting_div'>
+                            <h2>设定</h2>
+                            <div class='inner' id='filter-setting' >
+                                <div class='settting-item'>
+                                    <span>语言</span>
+                                    <span>
+                                        <select id='setting_lang'>
+                                            <option value='auto'>自动</option>
+                                            <option value=''>全部</option>
+                                            <option value='zh'>中文</option>
+                                            <option value='en'>英文</option>
+                                        </select>
+                                    </span>
+                                </div>
+                                <div class='settting-item'>
+                                    <span>内容类型</span>
+                                    <span>
+                                        <select id='setting_channel_type'>
+                                            <option value=''>全部</option>
+                                            <option value='translation' selected >译文</option>
+                                            <option value='nissaya'>Nissaya</option>
+                                            <option value='commentray'>注疏</option>
+                                        </select>
+                                    </span>
+                                </div>
+                                <div class='settting-item'>
+                                    <span>完成度</span>
+                                    <span>
+                                        <select id='setting_progress'>
+                                            <option value='0.9'>90</option>
+                                            <option value='0.8'>80</option>
+                                            <option value='0.5'>50</option>
+                                            <option value='0.2'>20</option>
+                                        </select>
+                                    </span>
+                                </div>
+                                <div style='display:flex;justify-content: space-between;'><button>还原默认</button><button onclick="updateSetting()">应用</button></div>
+                            </div>
+                        </div>
                     </div>
-
                 </div>
             </div>
+			<div id="index_div">
+				<div id='file_background'></div>
+				<div id = "file_list_div">
+					<div id='bread-crumbs'></div>
+					<div class='index_inner'>
+						<div id="chapter_shell" class="chapter_list" >
+							<div id="list_shell_1" class="show" level="1">
+								<ul id="list-1" class="grid" level="1" >
+								</ul>
+							</div>
+
+							<div id="list_shell_2" level="2">
+								<ul id="list-2" class="hidden" level="2"  >
+								</ul>
+							</div>
+
+							<div id="list_shell_3" level="3">
+								<ul id="list-3" class="hidden" level="3" >
+								</ul>
+							</div>
+
+							<div id="list_shell_4" level="4">
+								<ul id="list-4" class="hidden" level="4" >
+								</ul>
+							</div>
+
+							<div id="list_shell_5" level="5">
+								<ul id="list-5" class="hidden" level="5" >
+								</ul>
+							</div>
+
+							<div id="list_shell_6" level="6">
+								<ul id="list-6" class="hidden" level="6" >
+								</ul>
+							</div>
+
+							<div id="list_shell_7" level="7">
+								<ul id="list-7" class="hidden" level="7" >
+								</ul>
+							</div>
+
+							<div id="list_shell_8" level="8">
+								<ul id="list-8" class="hidden" level="8" >
+								</ul>
+							</div>
+
+						</div>
+					</div>
+				</div>
+			</div>
         </div>
     </div>
     <div style="flex:2;">
     <div class='bangdan' id = "user_recent">
         <div class='title'>最近阅读</div>
         <div class='list'>
-            <div id="page_loader" class="lds-ellipsis" style="visibility: hidden;"><div></div><div></div><div></div><div></div></div>
+            <div class="lds-ellipsis" ><div></div><div></div><div></div><div></div></div>
         </div>
     </div>
     <div class='bangdan'>
@@ -423,9 +272,7 @@ span.channel {
     <div class='bangdan' id='contribution'>
         <div class='title'>月度贡献</div>
         <div class='list'>
-            <ul>
-                <li>zuixin-1</li>
-            </ul>
+            <div class="lds-ellipsis" ><div></div><div></div><div></div><div></div></div>
         </div>
     </div>
     </div>
@@ -442,6 +289,8 @@ span.channel {
             }
             loadTagCategory(indexFilename);
             loadTagCategoryIndex();
+            loadFilterSetting();//载入上次的过滤器配置
+            LoadAllLanguage();
             <?php
             if(isset($_GET["view"])){
                 echo "_view = '{$_GET["view"]}';";
@@ -477,6 +326,7 @@ span.channel {
             //载入用户最近的阅读列表
             loadUserRecent();
             loadContribution();
+            
         });
     </script>
     <?php

+ 219 - 41
public/app/palicanon/palicanon.js

@@ -1,3 +1,9 @@
+
+var _lang = "";
+var _langsetting = "";
+var _channelType = 'translation'
+var  _progress = 0.9;
+
 var _view = "community";
 var main_tag = "";
 var list_tag = new Array();
@@ -9,13 +15,76 @@ var gBreadCrumbs=['','','','','','','','',''];
 var _nextPageStart = 0;
 var _pageSize = 20;
 var _channel = "";
-var _lang = "";
+var _palicanonCategory,_palicanonCategoryCurrent,_palicanonCategoryPath;
+
 var _tags = "";
 var _channelList;
 
 palicanon_load_term();
 
+function getLangSetting(setting){
+    switch (setting) {
+        case 'auto':
+            switch (getCookie("language")) {
+                case 'zh-cn':
+                    return 'zh';
+                    break;
+                case 'zh-tw':
+                    return 'zh';
+                    break;    
+                case '':
+                    return '';
+                    break;
+            }
+            break;
+        default:
+            return  setting;
+            break;
+    }
+}
+function updateSetting(){
+    _langsetting = $("#setting_lang").val();
+    _lang = getLangSetting(_langsetting);
+    _channelType = $("#setting_channel_type").val();
+    _progress = $("#setting_progress").val();
+
+    localStorage.setItem("pc_filter_setting",JSON.stringify({
+        lang : _lang,
+        lang_setting: $("#setting_lang").val(),
+        channel_type : _channelType,
+        progress:_progress,
+    }))
+
+    switch (_view) {
+        case 'community':
+            _nextPageStart = 0;
+            LoadAllChannel();
+            communityGetChapter();
+            break;
+        case 'category':
+            
+            break;    
+        default:
+            break;
+    }
+    
+}
+
+/*
+载入过滤器设置
+*/
+function loadFilterSetting(){
+    if (localStorage.getItem ("pc_filter_setting")) {
+        let setting = JSON.parse(localStorage.getItem("pc_filter_setting"));
+        _langsetting = setting.lang_setting;
+        _lang = getLangSetting(_langsetting);
+        _channel_type = setting.channel_type;
+        _progress = setting.progress;
+    }
+    _nextPageStart = 0;
+}
 function community_onload() {
+	$("#main_view").addClass("community");
 	$("span[tag]").click(function () {
 		$(this).siblings().removeClass("select");
 		$(this).addClass("select");
@@ -36,6 +105,7 @@ function community_onload() {
 }
 
 function palicanon_onload() {
+	$("#main_view").addClass("category");
 	$("span[tag]").click(function () {
 		$(this).siblings().removeClass("select");
 		$(this).addClass("select");
@@ -49,6 +119,8 @@ function palicanon_onload() {
 		tag_render_others();
 	});
     render_main_tag();
+	LoadAllChannel();
+	LoadAllLanguage();
 }
 
 function palicanon_load_term() {
@@ -115,7 +187,13 @@ function tag_changed() {
             communityGetChapter()
             break;
         case "category":
-            palicanonGetChapter(_tags,lang)
+			if(_tags == ""){
+				updatePalicanonCategoryList();
+				$("#palicanon-category").show();
+				$("#chapter_shell").hide();
+			}else{
+				palicanonGetChapter(_tags,lang);
+			}
             break;
         case "my":
             break;
@@ -139,25 +217,6 @@ function updataHistory(){
 }
 
 function communityGetChapter(offset=0){
-    let strTags = "";
-	if (list_tag.length > 0) {
-		strTags = main_tag + "," + list_tag.join();
-	} else {
-		strTags = main_tag;
-	}
-	console.log(strTags);
-	let lang = getCookie("language");
-    switch (lang) {
-        case 'zh-cn':
-            lang = 'zh-hans';
-            break;
-        case 'zh-tw':
-            lang = 'zh-hant';
-            break;    
-        case '':
-            lang = 'en';
-            break;
-    }
     next_page_loader_show();
     $.getJSON(
 		"/api/v2/progress?view=chapter",
@@ -165,6 +224,7 @@ function communityGetChapter(offset=0){
 			tags: _tags,
 			lang: _lang,
             channel: _channel,
+            channel_type: _channelType,
             offset: offset
 		}
 	)
@@ -222,15 +282,15 @@ function communityGetChapter(offset=0){
             }
         });
 
-    communityLoadChapterTag(strTags,lang);
+    communityLoadChapterTag();
 }
 
 function communityLoadChapterTag(strTags="",lang=""){
     $.getJSON(
 		"/api/v2/progress?view=chapter-tag",
 		{
-			tags: strTags,
-			lang: lang,
+			tags: _tags,
+			lang: _lang,
             channel:_channel
 		},
 		function (data, status) {
@@ -248,6 +308,9 @@ function communityLoadChapterTag(strTags="",lang=""){
 }
 
 function palitextGetChapter(strTags=""){
+	if(_tags==""){
+		return;
+	}
     $.getJSON(
 		"/api/v2/palitext?view=chapter",
 		{
@@ -395,6 +458,7 @@ function palicanon_load_chapter(book, para, div_index = 1) {
             loadChapterChannel({
                 book:book,
                 para:para,
+				readonly:true,
                 target:$("#chapter_head_" + (parseInt(div_index) + 1)).find('.progress').first()
             });
 		}
@@ -541,6 +605,10 @@ function chapter_onclick(obj) {
 	let type = $(objList).attr("type");
 	let level =  parseInt($(objList).parent().attr("level"));
     let title1 = $(objList).find(".title_1").first().text();
+
+	if(_view == "category" && level==1){
+		$("#index_div").addClass("popup");
+	}
     if(type=='article'){
         window.open("../article/index.php?view=chapter&book="+book+"&par="+para+"&channel="+channel,);
     }else{
@@ -981,6 +1049,9 @@ function tag_list_slide_toggle(element) {
 	$("#tag_list").slideToggle();
 }
 function chapter_back(parent) {
+	if(_view == "category" && parent==1){
+		$("#index_div").removeClass("popup");
+	}
 	let curr = parseInt(parent) + 1;
 	let prt = parseInt(parent);
 	//隐藏当前的
@@ -1000,19 +1071,102 @@ function chapter_back(parent) {
     RenderBreadCrumbs();
 }
 
+function categoryGoHome(){
+    updatePalicanonCategoryList();
+    $("#palicanon-category").show();
+    $("#chapter_shell").hide();
+    tag_set([]);
+}
+
+function updatePalicanonCategoryList(name="__home__") {
+    switch (name) {
+        case '__home__':
+            _palicanonCategoryCurrent = _palicanonCategory.slice();
+            _palicanonCategoryPath = new Array();
+            _palicanonCategoryPath.push(_palicanonCategoryCurrent);
+            break;
+        case '__prev__':
+            _palicanonCategoryPath.pop();
+            _palicanonCategoryCurrent = _palicanonCategoryPath[_palicanonCategoryPath.length-1].slice();
+            break;
+        default:
+            if(_palicanonCategoryCurrent.length>0){
+                let next = _palicanonCategoryCurrent.find(element => element.name == name);
+                if(typeof next !== "undefined"){
+                    if(next.children && next.children.length>0){
+                        //有子目录
+                        _palicanonCategoryCurrent = next.children.slice();
+                        _palicanonCategoryPath.push(_palicanonCategoryCurrent.slice());
+                    }else{
+                        //没有子目录
+                        tag_set(next.tag);
+                        $("#palicanon-category").hide();
+                        $("#chapter_shell").show();
+                    }
+                }
+            }else{
+
+            }
+            
+            break;
+    }
+    $('#palicanon-category').html(renderPalicanonCategoryList());
+
+}
+
+function renderPalicanonCategoryList(){
+    let html = "<ul class='chapter_list'>";
+    if(_palicanonCategoryPath.length>1){
+        html += "<li onclick=\"updatePalicanonCategoryList('__prev__')\">";
+        html += "上一级";
+        html += "</li>";
+    }
+
+    for (const item of _palicanonCategoryCurrent) {
+        html += "<li onclick=\"updatePalicanonCategoryList('"+item.name+"')\">";
+        html += "<div class='left_icon'>";
+        html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
+        html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#folder'>";
+        html += "</svg>" ;
+        html += "</div>";
+
+        html += "<div class='title'>";
+
+        html += '<div class="title_left" onclick="chapter_onclick(this)">';
+        html += '<div class="title_1">'+item.name+'</div>';
+        html += '<div class="title_2" lang="pali">'+item.name+'</div>';
+        html += "</div>";
+
+        html += '<div class="title_right">';
+        html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
+        html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#chevron-right'>";
+        html += "</svg>" ;
+        html += '</div>';
+
+        html += "</div>";
+
+        html += "</li>";
+    }
+    html += "</ul>";
+    return html;
+}
 
 function loadTagCategory(name="defualt"){
     $.getJSON("./category/"+name+".json",function(result){
-        console.log(tocGetTagCategory(result));
+
+        _palicanonCategory = result;
+        _palicanonCategoryCurrent = _palicanonCategory.slice();
+        _palicanonCategoryPath = new Array();
+        _palicanonCategoryPath.push(_palicanonCategoryCurrent.slice());
+        updatePalicanonCategoryList();
+        
         $("#tag-category").html("");
         $("#tag-category").fancytree({
             autoScroll: true,
             selectMode: 1, // 1:single, 2:multi, 3:multi-hier
             checkbox: false, // Show checkboxes.
-            source: tocGetTagCategory(result),
+            source: tocGetTagCategory(result.slice()),
             activate: function(e, data) {
-//				alert("activate " + );
-                //currSelectNode = data.node;
                 console.log('tree',data);
                 tag_set(arrTagCategory[data.node.key]);
             },
@@ -1066,13 +1220,26 @@ function TagCategoryIndexchange(obj){
 
 function RenderBreadCrumbs(){
     let html = "";
-    html += '<a onclick="chapter_back(1)">home</a>';
+	html += "<span>";
+    html += '<a onclick="chapter_back(1)" title="'+gLocal.gui.close+'">';
+	html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
+	html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#arrow-left-square'>";
+	html += "</svg>" ;	
+	html += '</a>';
+	html += "</span>";
     for (const iterator of gBreadCrumbs) {
         if(iterator.title1){
-            html += " > ";
+			html += "<span>";
+			html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
+			html += "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#chevron-right'>";
+			html += "</svg>" ;
+			html += "</span>";
+
+			html += "<span>";
             html += '<a onclick="chapter_back('+(iterator.level+1)+')">';
             html += iterator.title1;
             html += '</a>';
+			html += "</span>";
         }
     }
 
@@ -1090,7 +1257,11 @@ function select_channel(id,obj=null){
 function LoadAllChannel(){
     $.getJSON(
 		"/api/v2/progress?view=channel",
-		{},
+		{
+            lang:_lang,
+            channel_type: _channelType,
+            progress:_progress,
+        },
 		function (data, status) {
             let html = "";
             html += "<ul>"
@@ -1116,14 +1287,20 @@ function LoadAllLanguage(){
 		{},
 		function (data, status) {
             let html = "";
-            html += "<ul>"
+            html += "<option value='auto'>自动</option>";
+            html += "<option value=''>全部</option>";
             for (const iterator of data.data.rows) {
-                html += "<li>"
-                html += iterator.lang+"("+iterator.count+")";
-                html += "</li>"                    
+                if(iterator.lang!=''){
+                    html += "<option value='"+iterator.lang+"' ";
+                    if(_langsetting==iterator.lang){
+                        html +=" selected ";
+                    }
+                    html +=">";
+                    html += iterator.lang+"("+iterator.count+")";
+                    html += "</option>"                          
+                }
             }
-            html += "</ul>";
-            $("#filter-lang").html(html);
+            $("#setting_lang").html(html);
         }
     );
 }
@@ -1134,17 +1311,17 @@ function ReanderMainMenu(){
     if(_view=="community"){
         html += "class='select'";
     }
-    html +="><a href='index1.php?view=community'>社区</a></span>";
+    html +="><a href='index.php?view=community'>社区</a></span>";
     html += "<span ";
     if(_view=="category"){
         html += "class='select'";
     }
-    html +="><a href='index1.php?view=category' >分类</a></span>";
+    html +="><a href='index.php?view=category' >分类</a></span>";
     html += "<span ";
     if(_view=="my"){
         html += "class='select'";
     }
-    html +="><a href='index1.php?view=my' >我的</a></span>";
+    html +="><a href='index.php?view=my' >我的</a></span>";
     $("#main_menu").html(html);
 }
 
@@ -1192,4 +1369,5 @@ function loadContribution(){
     .fail(function() {
         console.log( "error" );
     });
-}
+}
+

+ 1 - 1
public/app/palicanon/router.js

@@ -19,7 +19,7 @@ Router.prototype.refresh = function() {
 };
 Router.prototype.init = function() {
     window.addEventListener('load', this.refresh.bind(this), false);
-    window.addEventListener('hashchange', this.refresh.bind(this), false);
+    //window.addEventListener('hashchange', this.refresh.bind(this), false);
     window.onpopstate = function(event) {
         console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
         _view = event.state.view;

+ 283 - 1
public/app/palicanon/style.css

@@ -39,6 +39,7 @@ tag {
 	padding: 2px 12px;
 	border-radius: 5px;
     cursor: pointer;
+    display: inline-block;
 }
 tag:hover{
     background-color: var(--border-line-color);
@@ -119,7 +120,7 @@ tag:hover{
 }
 
 #select_bar>div {
-    display:inline-block;
+    display:inline;
 }
 
 .chapter_list {
@@ -323,8 +324,289 @@ li.level_1.selected {
 .bangdan li{
     list-style-type:unset;
     white-space: nowrap;
+    overflow: auto;
 }
 .bangdan ol{
     padding-left: 1.5em;
     width: 200px;
+}
+
+.chapter_list ul {
+    margin-left: 0;
+}
+.head_bar{
+    display: flex;
+    flex-direction: column;
+}
+#left-bar{
+    flex: 2;
+	width: 300px;
+    background-color: var(--box-bg-color2);
+	position: fixed;
+}
+
+.chapter_list ul li .main{
+    display:flex;
+}
+.book_view  ul li{
+    display:block;
+}
+.book_view .level_1{
+    background:unset;
+}
+
+.book_view ul li{
+    border:unset;
+    width: 30%;
+    height:90px;
+}
+.chapter_list .list {
+    display: none;
+}
+.chapter_list .show {
+    display: block;
+    width: 100%;
+}
+.chapter_list .grid {
+    width: 100%;
+}
+.chapter_list > div {
+    max-height: unset;
+    overflow-y: unset; 
+}
+
+.chapter_list .more_info{
+    display:flex;
+    font-size:80%;
+    color: var(--main-color1);
+    justify-content: space-between;
+}
+
+.more_info>.palicanon_chapter_info>.item{
+    margin-right:1em;
+}
+.left_item>.item{
+    margin-right:1em;
+}
+.filter>.inner {
+    /*max-height: 200px;*/
+    /*overflow-y: auto;*/
+    background-color: var(--input-bg-color);
+}
+
+.main_menu {
+    font-size: 100%;
+    text-align: center;
+    margin: 0 1em;
+    transition: all 600ms ease;
+    text-transform: capitalize;
+}
+.main_menu>span {
+    margin: 2px;
+    padding: 2px 12px;
+    font-weight: 500;
+    transition-duration: 0.2s;
+    cursor: pointer;
+    font-size: 120%;
+    border: unset;
+    border-radius: 0;
+    border-bottom: 2px solid var(--nocolor);
+    display: inline-block;
+}
+.main_menu>.select {
+    border-bottom: 2px solid var(--link-color);
+}
+.main_menu>span>a {
+    color:unset;
+}
+.main_menu span:hover {
+    background-color: unset;
+    color: unset;
+    border-color: var(--link-hover-color);
+}
+.submenu select>option {
+    background-color: gray;
+}
+button.active {
+    background-color: gray;
+}
+
+.chapter_list ul li>.main>.left{
+    width: 100px;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+.chapter_list ul li>.main>.right{
+    width:100%;
+}
+.chapter_tag {
+    width: 475px;
+    padding: 5px 0;
+    overflow-y: visible;
+    overflow-x: auto;
+    display: flex;
+    flex-wrap: wrap;
+}
+.left_item {
+    margin: 4px 0;
+}
+.left_item>.item>.small_icon{
+    width:16px;
+    height:16px;
+}
+.left_item>.item>.text{
+    padding:5px;
+}
+
+div#tag_list {
+    background-color: var(--btn-color);
+    padding: 5px;
+    display: none;
+}
+
+#more_chapter {
+    text-align: center;
+}
+#more_chapter_line {
+    border-bottom: 1px solid var(--border-line-color);
+    height: 1em;
+}
+#btn_more_chapter{
+        position: absolute;
+    margin-top: -1.1em;
+    background-color: var(--link-color);
+    color: var(--bg-color);
+    border: none;
+    padding: 2px 40px;
+    margin-left: -5em;
+}
+#filter-author li.active{
+    background-color:gray;
+}
+
+#filter_bar {
+    display: flex;
+    justify-content: space-between;
+}
+div#filter_bar {
+    font-size: 120%;
+}
+
+span.channel:hover {
+    background-color: wheat;
+}
+span.channel {
+    cursor: pointer;
+}
+
+.settting-item {
+    display: flex;
+    justify-content: space-between;
+    padding: 2px;
+}
+
+#main_view{
+    display:flex;
+}
+
+#tag_list_inner {
+    display: flex;
+    flex-direction: row;
+}
+
+#tag_list_tag_div {
+    flex: 7;
+    padding: 10px;
+}
+
+#tag_list_setting_div {
+    flex: 3;
+    padding: 10px;
+}
+
+#palicanon-category{
+    display:none;
+}
+#select_bar_home{
+    display:none;
+}
+
+#left-bar-inner {
+    height: calc(100vh - 50px);
+    overflow-y: scroll;
+}
+#palicanon-category{
+    display:block;
+}
+
+.community #palicanon-category{
+    display:none;
+}
+
+#palicanon-category>.chapter_list {
+    flex-direction: column;
+}
+
+#palicanon-category li{
+    display: flex;
+    padding: 5px 0;
+    border-bottom: 1px solid var(--border-line-color);
+}
+
+#palicanon-category .chapter_list .title .title_1 {
+    width: unset;
+}
+#palicanon-category .chapter_list .title{
+    width: -webkit-fill-available;
+    padding-left: 12px;
+}
+
+#course_head_bar{
+	flex:6;
+	padding:0 10px 10px 315px;
+}
+
+#bread-crumbs{
+	display: none;
+}
+.popup {
+    color: var(--tool-bt-color);
+}
+.popup #bread-crumbs{
+	display: block;
+}
+.popup #file_background {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100vw;
+    height: 100vh;
+    background-color: rgba(0,0,0,0.85);
+	z-index: 200;
+}
+.popup #file_list_div {
+    position: fixed;
+    top: 4em;
+	z-index: 210;
+}
+.popup #index_inner {
+    height: calc(100vh - 4em);
+    overflow-y: auto;
+}
+.popup  .index_inner {
+    height: calc(100vh - 5em);
+    overflow-y: auto;
+}
+header {
+	z-index: 100;
+}
+
+#bread-crumbs>span{
+	padding: 0 4px;
+}
+
+
+.category #btn_more_chapter{
+	display:none;
 }

+ 64 - 0
public/app/palicanon/style_mobile.css

@@ -14,3 +14,67 @@
 .chapter_head_tool_bar .chapter_close_button {
 	display: none;
 }
+#main_view{
+    display:flex;
+    flex-direction: column;
+}
+
+#left-bar {
+    flex: 2;
+    background-color: var(--box-bg-color2);
+    display: none;
+}
+
+.chapter_list .more_info {
+    display: flex;
+    font-size: 80%;
+    color: var(--main-color1);
+    flex-direction: column;
+}
+
+.chapter_list ul li .main {
+    display: flex;
+    flex-direction: column;
+}
+
+.left_items {
+    display: flex;
+    flex-direction: row;
+}
+
+#tag_list_inner {
+    display: flex;
+    flex-direction: column-reverse;
+}
+
+#tag_list_tag_div {
+    padding: 6px;
+}
+
+#tag_list_setting_div {
+    padding: 6px;
+}
+#palicanon-category{
+    display:block;
+}
+
+#palicanon-category>.chapter_list {
+    flex-direction: column;
+}
+
+#palicanon-category li{
+    display: flex;
+    padding: 5px 0;
+    border-bottom: 1px solid var(--border-line-color);
+}
+
+#palicanon-category .chapter_list .title .title_1 {
+    width: unset;
+}
+#palicanon-category .chapter_list .title{
+    width: -webkit-fill-available;
+    padding-left: 12px;
+}
+#course_head_bar{
+	padding:0 10px 10px 15px;
+}

+ 2 - 2
public/app/pcdl/css/style.css

@@ -101,8 +101,8 @@ h3 {
 }
 
 ::-webkit-scrollbar {
-	width: 8px;
-	height: 8px;
+	/*width: 8px;*/
+	/*height: 8px;*/
 	/*display: none;*/
 }
 

+ 5 - 0
public/app/term/term.css

@@ -751,6 +751,11 @@ pw {
     left:6.2em;
     margin-top: calc(-2.1em - 8px);
 }
+
+.translation>.sent_tran_inner:hover>.tool_bar > .right {
+    display: block;
+}
+
 .sent_tran.commentary>.sent_tran_inner{
     padding-top: 2.2em;
 }

+ 1 - 1
public/app/usent/get.php

@@ -85,7 +85,7 @@ if (isset($_GET["sentences"])) {
 					sent.strlen,
 					sent.modify_time,
                     channel.type
-					FROM "._TABLE_SENTENCE_. " as sent LEFT JOIN "._TABLE_CHANNEL_." as channel ON sent.channel_uid=channel.uid  WHERE (channel.type= ? AND sent.book_id = ?  AND sent.paragraph = ? AND sent.word_start = ? AND sent.word_end = ? and sent.strlen >0 and (sent.status = 30 {$channel_query} ) ) order by sent.modify_time DESC  ";
+					FROM "._TABLE_SENTENCE_. " as sent LEFT JOIN "._TABLE_CHANNEL_." as channel ON uuid(sent.channel_uid)=channel.uid  WHERE (channel.type= ? AND sent.book_id = ?  AND sent.paragraph = ? AND sent.word_start = ? AND sent.word_end = ? and sent.strlen >0 and (sent.status = 30 {$channel_query} ) ) order by sent.modify_time DESC  ";
     $stmt = $dbh->prepare($query);
     $parm = array($type,$book, $para, $begin, $end);
     $parm = array_merge_recursive($parm, $channal_list);

+ 0 - 0
public/app/widget/submenu.css


+ 31 - 0
public/app/widget/submenu.js

@@ -0,0 +1,31 @@
+function submenu_init(obj,param){
+    let html = "";
+    <div class="submenu" >
+		<p class="submenu_title" onclick="submenu_show_detail(this)">
+			样式
+            <svg class="icon" style="transform: rotate(0deg);">
+				<use xlink:href="../studio/svg/icon.svg#ic_add"></use>
+			</svg>
+		</p>
+		<div class="submenu_details hidden" style="max-height: 0px; padding: 0px; opacity: 0;">
+
+		</div>
+	</div>
+}
+
+function submenu_show_detail(obj) {
+	eParent = obj.parentNode;
+	var x = eParent.getElementsByTagName("div");
+	var o = obj.getElementsByTagName("svg");
+	if (x[0].style.maxHeight == "200em") {
+		x[0].style.maxHeight = "0px";
+		x[0].style.padding = "0px";
+		x[0].style.opacity = "0";
+		o[0].style.transform = "rotate(0deg)";
+	} else {
+		x[0].style.maxHeight = "200em";
+		x[0].style.padding = "10px";
+		x[0].style.opacity = "1";
+		o[0].style.transform = "rotate(45deg)";
+	}
+}

+ 4 - 3
public/app/wiki/wiki.js

@@ -105,9 +105,10 @@ function term_render_word_to_div(strWord,eDiv) {
 									"</button>";
 							}
 
-							html += "<button class='icon_btn'><a href='#'>" + gLocal.gui.like + "</a></button>";
-							html +=
-								"<button class='icon_btn'><a href='#'>" + gLocal.gui.favorite + "</a></button></span>";
+							html += "<button class='icon_btn'><a href='../article/index.php?view=term&id="+iterator.guid+"&display=sent&mode=edit' target='_blank'>" + gLocal.gui.translate + "</a></button>";
+							//TODO 增加点赞按钮
+                            //html += "<button class='icon_btn'><a href='#'>" + gLocal.gui.like + "</a></button>";
+                            html += "</span>";
 							html += "</div>";
 
 							html += "</div>";

+ 4 - 0
public/app/wiki/wiki.php

@@ -284,6 +284,10 @@ else{
 		.wiki_search_list li:hover {
 			background-color: beige;
 		}
+
+    .note_shell{
+        display:none;
+    }
 	</style>
 
 <style media="screen and (max-width:800px)">

+ 85 - 12
public/documents/模版设计.md

@@ -1,15 +1,88 @@
-{{sent|10|2|56|89}}
+# 文章内模版设计方案
 
-function:sent
-param:book=1,para=2,start=3,end=4
-{
-    <note book="{{book}}" para='{{meaning}}' start='{{meaning2}}' end='{{end}}'></note>
-}
+## 需求
 
-{{term|dhamma}}
+在用户编辑的markdown文档内嵌入自定义模版。支持术语显示,注释,文章引用,声明等可重用内容。
 
-function:term
-param:word
-{
-    <term word="{{word}}" ></term>
-}
+markdown 文档内容:
+```
+# 标题
+
+{{term|citta}}
+{{term|word=citta}}
+
+```
+
+## 解决方案
+
+使用 https://mustache.github.io/ 。由于mustache不支持自定义函数。所以绕道,用mustache 的 helper 拿到用户输入的参数后再次用mustache进行渲染。
+
+https://github.com/bobthecow/mustache.php/wiki#helpers
+
+# 第一步
+
+用户输入的markdown 文本。
+用正则替换
+```
+搜索
+\{\{(.+?)\}\}
+替换为
+\n{{#function}}\n$1\n{{/function}}\n
+```
+```
+{{term|citta}}
+就变成
+{{#function}}
+term|citta
+{{/function}}
+```
+
+# 第二步 准备模版文件
+这个其实是放数据库里的
+
+term.tpl
+```
+<term word='{{word}}'>
+<span class='word'>{{word}}</span>
+(<span class='meaning'>{{meaning}}</span>)
+</term>
+```
+
+# 第三步 解析{{#function}} 
+
+用helper 解析{{#function}} 里面的内容。拿到模版名称和参数。并再次用Mustache 和对应的**模版文件**以及**参数**渲染html字符串
+需要预处理,得到这个文章里面用的模版名称(函数名)列表。
+
+```
+$tpl-list=["term"=>"term.tpl的内容"];
+$m = new Mustache_Engine(array('entity_flags' => ENT_QUOTES));
+$m->render($tpl, array(
+  'function' => function($text) use($m,$tpl-list) {
+    1: 使用url函数解析path
+    $param = explode("|",$text);
+    3: 处理业务逻辑
+    switch([param[0]){
+        case 'term':
+            //获取实际的参数
+            $tplParam = Term::where("word",param[1])->first();
+        case 'article':
+            $tplParam = Article::where("uid",param[1])->first();
+        default:
+            $tplParam['p1'] = param[1];
+        break;
+    }
+    4: 返回拼好的字符串
+    $html = $m->render($tpl-list[param[0]], $tplParam)
+    return $html;
+  }
+)); 
+```
+
+## 模版
+
+{{inlinenote|note content}}
+
+{{q|sn.a. 2|3|2}}
+{{q|137|45}}
+
+{{article|122342234324}}