Browse Source

:art: 支持列出和切换最近打开的文档 https://github.com/siyuan-note/siyuan/issues/3293

Liang Ding 2 years ago
parent
commit
b3a147d60b
3 changed files with 130 additions and 0 deletions
  1. 2 0
      kernel/api/router.go
  2. 44 0
      kernel/api/storage.go
  3. 84 0
      kernel/model/storage.go

+ 2 - 0
kernel/api/router.go

@@ -61,6 +61,8 @@ func ServeAPI(ginServer *gin.Engine) {
 	ginServer.Handle("POST", "/api/storage/setCriterion", model.CheckAuth, setCriterion)
 	ginServer.Handle("POST", "/api/storage/getCriteria", model.CheckAuth, getCriteria)
 	ginServer.Handle("POST", "/api/storage/removeCriterion", model.CheckAuth, removeCriterion)
+	ginServer.Handle("POST", "/api/storage/setRecentDoc", model.CheckAuth, setRecentDoc)
+	ginServer.Handle("POST", "/api/storage/getRecentDocs", model.CheckAuth, getRecentDocs)
 
 	ginServer.Handle("POST", "/api/account/login", model.CheckAuth, login)
 	ginServer.Handle("POST", "/api/account/checkActivationcode", model.CheckAuth, checkActivationcode)

+ 44 - 0
kernel/api/storage.go

@@ -25,6 +25,50 @@ import (
 	"github.com/siyuan-note/siyuan/kernel/util"
 )
 
+func setRecentDoc(c *gin.Context) {
+	ret := gulu.Ret.NewResult()
+	defer c.JSON(http.StatusOK, ret)
+
+	arg, ok := util.JsonArg(c, ret)
+	if !ok {
+		return
+	}
+
+	param, err := gulu.JSON.MarshalJSON(arg["recentDoc"])
+	if nil != err {
+		ret.Code = -1
+		ret.Msg = err.Error()
+		return
+	}
+
+	recentDoc := &model.RecentDoc{}
+	if err = gulu.JSON.UnmarshalJSON(param, recentDoc); nil != err {
+		ret.Code = -1
+		ret.Msg = err.Error()
+		return
+	}
+
+	err = model.SetRecentDoc(recentDoc)
+	if nil != err {
+		ret.Code = -1
+		ret.Msg = err.Error()
+		return
+	}
+}
+
+func getRecentDocs(c *gin.Context) {
+	ret := gulu.Ret.NewResult()
+	defer c.JSON(http.StatusOK, ret)
+
+	data, err := model.GetRecentDocs()
+	if nil != err {
+		ret.Code = -1
+		ret.Msg = err.Error()
+		return
+	}
+	ret.Data = data
+}
+
 func removeCriterion(c *gin.Context) {
 	ret := gulu.Ret.NewResult()
 	defer c.JSON(http.StatusOK, ret)

+ 84 - 0
kernel/model/storage.go

@@ -27,6 +27,90 @@ import (
 	"github.com/siyuan-note/siyuan/kernel/util"
 )
 
+type RecentDoc struct {
+	RootID     string `json:"rootID"`
+	Icon       string `json:"icon"`
+	Title      string `json:"title"`
+	ScrollAttr string `json:"scrollAttr"`
+	Mode       string `json:"mode"`
+	Action     string `json:"action"`
+}
+
+var recentDocLock = sync.Mutex{}
+
+func SetRecentDoc(doc *RecentDoc) (err error) {
+	recentDocLock.Lock()
+	defer recentDocLock.Unlock()
+
+	recentDocs, err := getRecentDocs()
+	if nil != err {
+		return
+	}
+
+	update := false
+	for i, c := range recentDocs {
+		if c.RootID == doc.RootID {
+			recentDocs[i] = doc
+			update = true
+			break
+		}
+	}
+	if !update {
+		recentDocs = append(recentDocs, doc)
+	}
+
+	err = setRecentDocs(recentDocs)
+	return
+}
+
+func GetRecentDocs() (ret []*RecentDoc, err error) {
+	recentDocLock.Lock()
+	defer recentDocLock.Unlock()
+	return getRecentDocs()
+}
+
+func setRecentDocs(recentDocs []*RecentDoc) (err error) {
+	dirPath := filepath.Join(util.DataDir, "storage")
+	if err = os.MkdirAll(dirPath, 0755); nil != err {
+		logging.LogErrorf("create storage [recent-doc] dir failed: %s", err)
+		return
+	}
+
+	data, err := gulu.JSON.MarshalIndentJSON(recentDocs, "", "  ")
+	if nil != err {
+		logging.LogErrorf("marshal storage [recent-doc] failed: %s", err)
+		return
+	}
+
+	lsPath := filepath.Join(dirPath, "recent-doc.json")
+	err = filelock.WriteFile(lsPath, data)
+	if nil != err {
+		logging.LogErrorf("write storage [recent-doc] failed: %s", err)
+		return
+	}
+	return
+}
+
+func getRecentDocs() (ret []*RecentDoc, err error) {
+	ret = []*RecentDoc{}
+	dataPath := filepath.Join(util.DataDir, "storage/recent-doc.json")
+	if !gulu.File.IsExist(dataPath) {
+		return
+	}
+
+	data, err := filelock.ReadFile(dataPath)
+	if nil != err {
+		logging.LogErrorf("read storage [recent-doc] failed: %s", err)
+		return
+	}
+
+	if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err {
+		logging.LogErrorf("unmarshal storage [recent-doc] failed: %s", err)
+		return
+	}
+	return
+}
+
 type Criterion struct {
 	Name        string          `json:"name"`
 	Sort        int             `json:"sort"`       //  0:按块类型(默认),1:按创建时间升序,2:按创建时间降序,3:按更新时间升序,4:按更新时间降序,5:按内容顺序(仅在按文档分组时)