diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 76d7a2b3d..add470848 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -173,6 +173,10 @@ "setEmojiTip": "请在 [设置 - 外观] 中添加自定义表情", "openSyncTip1": "启用云端同步", "openSyncTip2": "从禁用改为启用时建议手动点击同步按钮触发一次同步", + "syncMode": "云端同步模式", + "syncModeTip": "启用云端同步后可进一步选择同步模式", + "syncMode1": "自动同步(数据不再变动后 30 秒进行一次同步)", + "syncMode2": "手动同步(仅启动和关闭软件时自动同步一次,其他时候需要手动触发同步)", "cloudSync": "云端同步", "cloudSyncDir": "云端同步目录", "emptyCloudSyncList": "云端同步列表为空", diff --git a/app/src/config/repos.ts b/app/src/config/repos.ts index e15bed6fd..ba7f211cd 100644 --- a/app/src/config/repos.ts +++ b/app/src/config/repos.ts @@ -325,6 +325,17 @@ ${passwordHTML} +
${window.siyuan.languages.cloudSync}
@@ -362,6 +373,17 @@ ${passwordHTML} } }); }); + const syncModeElement = repos.element.querySelector("#syncMode") as HTMLSelectElement; + syncModeElement.addEventListener("change", () => { + fetchPost("/api/sync/setSyncMode", {mode: parseInt(syncModeElement.value, 10)}, (response) => { + if (response.code === 1) { + showMessage(response.msg); + syncModeElement.value = "1"; + } else { + window.siyuan.config.sync.mode = parseInt(syncModeElement.value, 10); + } + }); + }); const loadingElement = repos.element.querySelector("#reposLoading") as HTMLElement; loadingElement.style.width = repos.element.clientWidth + "px"; loadingElement.style.height = repos.element.clientHeight + "px"; diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index bccb0c32c..672ce2f47 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -242,6 +242,7 @@ declare interface IConfig { e2eePasswdMode: number sync: { enabled: boolean + mode: number synced: number stat: string interval: number diff --git a/kernel/api/router.go b/kernel/api/router.go index cb7af192d..04cf706e4 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -163,6 +163,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/backup/removeCloudBackup", model.CheckAuth, model.CheckReadonly, removeCloudBackup) ginServer.Handle("POST", "/api/sync/setSyncEnable", model.CheckAuth, setSyncEnable) + ginServer.Handle("POST", "/api/sync/setSyncMode", model.CheckAuth, setSyncMode) ginServer.Handle("POST", "/api/sync/setCloudSyncDir", model.CheckAuth, setCloudSyncDir) ginServer.Handle("POST", "/api/sync/createCloudSyncDir", model.CheckAuth, model.CheckReadonly, createCloudSyncDir) ginServer.Handle("POST", "/api/sync/removeCloudSyncDir", model.CheckAuth, model.CheckReadonly, removeCloudSyncDir) diff --git a/kernel/api/sync.go b/kernel/api/sync.go index 3315b6d44..78e882e5f 100644 --- a/kernel/api/sync.go +++ b/kernel/api/sync.go @@ -140,6 +140,25 @@ func setSyncEnable(c *gin.Context) { } } +func setSyncMode(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + mode := int(arg["mode"].(float64)) + err := model.SetSyncMode(mode) + if nil != err { + ret.Code = 1 + ret.Msg = err.Error() + ret.Data = map[string]interface{}{"closeTimeout": 5000} + return + } +} + func setCloudSyncDir(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/conf/sync.go b/kernel/conf/sync.go index d98ef46c1..506622258 100644 --- a/kernel/conf/sync.go +++ b/kernel/conf/sync.go @@ -25,6 +25,7 @@ import ( type Sync struct { CloudName string `json:"cloudName"` // 云端同步目录名称 Enabled bool `json:"enabled"` // 是否开启同步 + Mode int `json:"mode"` // 同步模式,0:未设置(为兼容已有配置,initConf 函数中会转换为 1),1:自动,2:手动 https://github.com/siyuan-note/siyuan/issues/5089 Uploaded int64 `json:"uploaded"` // 最近上传时间 Downloaded int64 `json:"downloaded"` // 最近下载时间 Synced int64 `json:"synced"` // 最近同步时间 @@ -35,6 +36,7 @@ func NewSync() *Sync { return &Sync{ CloudName: "main", Enabled: true, + Mode: 1, } } diff --git a/kernel/model/conf.go b/kernel/model/conf.go index 445854665..987af968c 100644 --- a/kernel/model/conf.go +++ b/kernel/model/conf.go @@ -214,6 +214,9 @@ func InitConf() { util.LogErrorf("create sync dir [%s] failed: %s", Conf.Sync.GetSaveDir(), err) } } + if 0 == Conf.Sync.Mode { + Conf.Sync.Mode = 1 + } if nil == Conf.Api { Conf.Api = conf.NewAPI() diff --git a/kernel/model/sync.go b/kernel/model/sync.go index 15339f2b0..fbe493455 100644 --- a/kernel/model/sync.go +++ b/kernel/model/sync.go @@ -513,6 +513,15 @@ func SetSyncEnable(b bool) (err error) { return } +func SetSyncMode(mode int) (err error) { + syncLock.Lock() + defer syncLock.Unlock() + + Conf.Sync.Mode = mode + Conf.Save() + return +} + var syncLock = sync.Mutex{} func syncDirUpsertWorkspaceData(downloadedFiles []string) (err error) {