mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-03 10:31:10 +08:00
✨ 数据仓库支持云端备份 https://github.com/siyuan-note/siyuan/issues/5336
This commit is contained in:
parent
ebdb5b2a36
commit
e41d411c2d
@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"snapshotName": "Snapshot Name",
|
||||||
|
"snapshotNameTip": "Do not include symbols \\ / : * ? " ' < > |",
|
||||||
"syncDataRepo": "⚗️ Use data repo sync mechanism",
|
"syncDataRepo": "⚗️ Use data repo sync mechanism",
|
||||||
"syncDataRepoTip": "The data repo sync mechanism can better handle data conflicts, and the sync performance is also better",
|
"syncDataRepoTip": "The data repo sync mechanism can better handle data conflicts, and the sync performance is also better",
|
||||||
"dataRepo": "Data repo",
|
"dataRepo": "Data repo",
|
||||||
@ -910,8 +912,9 @@
|
|||||||
"145": "Data repository reset completed",
|
"145": "Data repository reset completed",
|
||||||
"146": "Failed to reset data repository: %s",
|
"146": "Failed to reset data repository: %s",
|
||||||
"147": "Created a new data snapshot, took %.2fs",
|
"147": "Created a new data snapshot, took %.2fs",
|
||||||
"148": "Checked the data snapshot and found no changes",
|
"148": "Checked the data snapshot and found no changes, took %.2fs",
|
||||||
"149": "Data snapshot has been synchronized, took %.2fs",
|
"149": "Data snapshot has been synchronized, took %.2fs",
|
||||||
"150": "Uploaded/Downloaded files %d/%d\nUploaded/Downloaded chunks %d/%d\nSent/Received bytes %s/%s"
|
"150": "Uploaded/Downloaded files %d/%d\nUploaded/Downloaded chunks %d/%d\nSent/Received bytes %s/%s",
|
||||||
|
"151": "Do not include symbols \\ / : * ? " ' < > |"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"snapshotName": "Nombre de la instantánea",
|
||||||
|
"snapshotNameTip": "No incluir símbolos \\ / : * ? " ' < > |",
|
||||||
"syncDataRepo": "⚗️ Usar mecanismo de sincronización de repositorio de datos",
|
"syncDataRepo": "⚗️ Usar mecanismo de sincronización de repositorio de datos",
|
||||||
"syncDataRepoTip": "El mecanismo de sincronización del repositorio de datos puede manejar mejor los conflictos de datos y el rendimiento de la sincronización también es mejor",
|
"syncDataRepoTip": "El mecanismo de sincronización del repositorio de datos puede manejar mejor los conflictos de datos y el rendimiento de la sincronización también es mejor",
|
||||||
"dataRepo": "Repositorio de datos",
|
"dataRepo": "Repositorio de datos",
|
||||||
@ -910,8 +912,9 @@
|
|||||||
"145": "Restablecimiento del repositorio de datos completado",
|
"145": "Restablecimiento del repositorio de datos completado",
|
||||||
"146": "Fallo en el restablecimiento del repositorio de datos: %s",
|
"146": "Fallo en el restablecimiento del repositorio de datos: %s",
|
||||||
"147": "Creó una nueva instantánea de datos, tomó %.2fs",
|
"147": "Creó una nueva instantánea de datos, tomó %.2fs",
|
||||||
"148": "Se ha comprobado la instantánea de los datos y no se encontro ningún cambio",
|
"148": "Se ha comprobado la instantánea de los datos y no se encontro ningún cambio, tomó %.2fs",
|
||||||
"149": "La instantánea de datos ha sido sincronizada, ha tomado %.2fs",
|
"149": "La instantánea de datos ha sido sincronizada, ha tomado %.2fs",
|
||||||
"150": "Archivos cargados/descargados %d/%d\nFragmentos cargados/descargados %d/%d\nBytes enviados/recibidos %s/%s"
|
"150": "Archivos cargados/descargados %d/%d\nFragmentos cargados/descargados %d/%d\nBytes enviados/recibidos %s/%s",
|
||||||
|
"151": "No incluir símbolos \\ / : * ? " ' < > |"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"snapshotName": "Nom de l'instantané",
|
||||||
|
"snapshotNameTip": "Ne pas inclure les symboles \\ / : * ? " ' < > |",
|
||||||
"syncDataRepo": "⚗️ Utiliser le mécanisme de synchronisation du référentiel de données",
|
"syncDataRepo": "⚗️ Utiliser le mécanisme de synchronisation du référentiel de données",
|
||||||
"syncDataRepoTip": "Le mécanisme de synchronisation du référentiel de données peut mieux gérer les conflits de données, et les performances de synchronisation sont également meilleures",
|
"syncDataRepoTip": "Le mécanisme de synchronisation du référentiel de données peut mieux gérer les conflits de données, et les performances de synchronisation sont également meilleures",
|
||||||
"dataRepo": "Dépôt de données",
|
"dataRepo": "Dépôt de données",
|
||||||
@ -910,8 +912,9 @@
|
|||||||
"145": "Réinitialisation du référentiel de données terminée",
|
"145": "Réinitialisation du référentiel de données terminée",
|
||||||
"146": "Échec de la réinitialisation du référentiel de données : %s",
|
"146": "Échec de la réinitialisation du référentiel de données : %s",
|
||||||
"147": "Créé un nouvel instantané de données, a pris %.2fs",
|
"147": "Créé un nouvel instantané de données, a pris %.2fs",
|
||||||
"148": "Vérifié l'instantané des données et n'a trouvé aucun changement",
|
"148": "Vérifié l'instantané des données et n'a trouvé aucun changement, a pris %.2fs",
|
||||||
"149": "L'instantané des données a été synchronisé, a pris %.2fs",
|
"149": "L'instantané des données a été synchronisé, a pris %.2fs",
|
||||||
"150": "Fichiers chargés/téléchargés %d/%d\nMorceaux chargés/téléchargés %d/%d\nOctets envoyés/reçus %s/%s"
|
"150": "Fichiers chargés/téléchargés %d/%d\nMorceaux chargés/téléchargés %d/%d\nOctets envoyés/reçus %s/%s",
|
||||||
|
"151": "Ne pas inclure les symboles \\ / : * ? " ' < > |"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"snapshotName": "快照名稱",
|
||||||
|
"snapshotNameTip": "請勿包含符號 \\ / : * ? " ' < > |",
|
||||||
"syncDataRepo": "⚗️ 使用數據倉庫同步機制",
|
"syncDataRepo": "⚗️ 使用數據倉庫同步機制",
|
||||||
"syncDataRepoTip": "數據倉庫同步機制能夠更好地處理數據衝突,同步性能也更好",
|
"syncDataRepoTip": "數據倉庫同步機制能夠更好地處理數據衝突,同步性能也更好",
|
||||||
"dataRepo": "數據倉庫",
|
"dataRepo": "數據倉庫",
|
||||||
@ -909,8 +911,9 @@
|
|||||||
"145": "數據倉庫重置完畢",
|
"145": "數據倉庫重置完畢",
|
||||||
"146": "重置數據倉庫失敗:%s",
|
"146": "重置數據倉庫失敗:%s",
|
||||||
"147": "創建了一個新的數據快照,耗時 %.2fs",
|
"147": "創建了一個新的數據快照,耗時 %.2fs",
|
||||||
"148": "檢查數據快照,沒有發現任何變化",
|
"148": "檢查數據快照,沒有發現任何變化,耗時 %.2fs",
|
||||||
"149": "已經同步數據快照,耗時 %.2fs",
|
"149": "已經同步數據快照,耗時 %.2fs",
|
||||||
"150": "上傳/下載文件數 %d/%d\n上傳/下載分塊數 %d/%d\n發送/接受字節數 %s/%s"
|
"150": "上傳/下載文件數 %d/%d\n上傳/下載分塊數 %d/%d\n發送/接受字節數 %s/%s",
|
||||||
|
"151": "請勿包含符號 \\ / : * ? " ' < > |"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"snapshotName": "快照名称",
|
||||||
|
"snapshotNameTip": "请勿包含符号 \\ / : * ? " ' < > |",
|
||||||
"syncDataRepo": "⚗️ 使用数据仓库同步机制(该特性正处于公测阶段)",
|
"syncDataRepo": "⚗️ 使用数据仓库同步机制(该特性正处于公测阶段)",
|
||||||
"syncDataRepoTip": "数据仓库同步机制能够更好地处理数据冲突,同步性能也更好",
|
"syncDataRepoTip": "数据仓库同步机制能够更好地处理数据冲突,同步性能也更好",
|
||||||
"dataRepo": "数据仓库",
|
"dataRepo": "数据仓库",
|
||||||
@ -911,8 +913,9 @@
|
|||||||
"145": "数据仓库重置完毕",
|
"145": "数据仓库重置完毕",
|
||||||
"146": "重置数据仓库失败:%s",
|
"146": "重置数据仓库失败:%s",
|
||||||
"147": "创建了一个新的数据快照,耗时 %.2fs",
|
"147": "创建了一个新的数据快照,耗时 %.2fs",
|
||||||
"148": "检查数据快照,没有发现任何变化",
|
"148": "检查数据快照,没有发现任何变化,耗时 %.2fs",
|
||||||
"149": "已经同步数据快照,耗时 %.2fs",
|
"149": "已经同步数据快照,耗时 %.2fs",
|
||||||
"150": "上传/下载文件数 %d/%d\n上传/下载分块数 %d/%d\n发送/接受字节数 %s/%s"
|
"150": "上传/下载文件数 %d/%d\n上传/下载分块数 %d/%d\n发送/接受字节数 %s/%s",
|
||||||
|
"151": "请勿包含符号 \\ / : * ? " ' < > |"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,9 +379,9 @@ export const openHistory = () => {
|
|||||||
break;
|
break;
|
||||||
} else if (type === "genRepo") {
|
} else if (type === "genRepo") {
|
||||||
const genRepoDialog = new Dialog({
|
const genRepoDialog = new Dialog({
|
||||||
title: window.siyuan.languages.memo,
|
title: window.siyuan.languages.snapshotName,
|
||||||
content: `<div class="b3-dialog__content">
|
content: `<div class="b3-dialog__content">
|
||||||
<textarea class="b3-text-field fn__block"></textarea>
|
<input class="b3-text-field fn__block" placeholder="${window.siyuan.languages.snapshotNameTip}"></input>
|
||||||
</div>
|
</div>
|
||||||
<div class="b3-dialog__action">
|
<div class="b3-dialog__action">
|
||||||
<button class="b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button><div class="fn__space"></div>
|
<button class="b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button><div class="fn__space"></div>
|
||||||
@ -389,14 +389,14 @@ export const openHistory = () => {
|
|||||||
</div>`,
|
</div>`,
|
||||||
width: isMobile() ? "80vw" : "520px",
|
width: isMobile() ? "80vw" : "520px",
|
||||||
});
|
});
|
||||||
const textAreaElement = genRepoDialog.element.querySelector("textarea");
|
const inputElement = genRepoDialog.element.querySelector("input");
|
||||||
textAreaElement.focus();
|
inputElement.focus();
|
||||||
const btnsElement = genRepoDialog.element.querySelectorAll(".b3-button");
|
const btnsElement = genRepoDialog.element.querySelectorAll(".b3-button");
|
||||||
btnsElement[0].addEventListener("click", () => {
|
btnsElement[0].addEventListener("click", () => {
|
||||||
genRepoDialog.destroy();
|
genRepoDialog.destroy();
|
||||||
});
|
});
|
||||||
btnsElement[1].addEventListener("click", () => {
|
btnsElement[1].addEventListener("click", () => {
|
||||||
fetchPost("/api/repo/indexRepo", {message: textAreaElement.value}, () => {
|
fetchPost("/api/repo/createSnapshot", {name: inputElement.value}, () => {
|
||||||
renderRepo(repoElement, 1);
|
renderRepo(repoElement, 1);
|
||||||
});
|
});
|
||||||
genRepoDialog.destroy();
|
genRepoDialog.destroy();
|
||||||
|
@ -66,7 +66,7 @@ func getRepoIndexLogs(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func indexRepo(c *gin.Context) {
|
func createSnapshot(c *gin.Context) {
|
||||||
ret := gulu.Ret.NewResult()
|
ret := gulu.Ret.NewResult()
|
||||||
defer c.JSON(http.StatusOK, ret)
|
defer c.JSON(http.StatusOK, ret)
|
||||||
|
|
||||||
@ -75,8 +75,8 @@ func indexRepo(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
message := arg["message"].(string)
|
name := arg["name"].(string)
|
||||||
if err := model.IndexRepo(message); nil != err {
|
if err := model.CreateSnapshot(name); nil != err {
|
||||||
ret.Code = -1
|
ret.Code = -1
|
||||||
ret.Msg = fmt.Sprintf(model.Conf.Language(140), err)
|
ret.Msg = fmt.Sprintf(model.Conf.Language(140), err)
|
||||||
ret.Data = map[string]interface{}{"closeTimeout": 5000}
|
ret.Data = map[string]interface{}{"closeTimeout": 5000}
|
||||||
|
@ -254,7 +254,7 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||||||
ginServer.Handle("POST", "/api/repo/initRepoKey", model.CheckAuth, initRepoKey)
|
ginServer.Handle("POST", "/api/repo/initRepoKey", model.CheckAuth, initRepoKey)
|
||||||
ginServer.Handle("POST", "/api/repo/resetRepo", model.CheckAuth, resetRepo)
|
ginServer.Handle("POST", "/api/repo/resetRepo", model.CheckAuth, resetRepo)
|
||||||
ginServer.Handle("POST", "/api/repo/importRepoKey", model.CheckAuth, importRepoKey)
|
ginServer.Handle("POST", "/api/repo/importRepoKey", model.CheckAuth, importRepoKey)
|
||||||
ginServer.Handle("POST", "/api/repo/indexRepo", model.CheckAuth, indexRepo)
|
ginServer.Handle("POST", "/api/repo/createSnapshot", model.CheckAuth, createSnapshot)
|
||||||
ginServer.Handle("POST", "/api/repo/checkoutRepo", model.CheckAuth, checkoutRepo)
|
ginServer.Handle("POST", "/api/repo/checkoutRepo", model.CheckAuth, checkoutRepo)
|
||||||
ginServer.Handle("POST", "/api/repo/getRepoIndexLogs", model.CheckAuth, getRepoIndexLogs)
|
ginServer.Handle("POST", "/api/repo/getRepoIndexLogs", model.CheckAuth, getRepoIndexLogs)
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ func ImportRepoKey(base64Key string) (err error) {
|
|||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
util.PushUpdateMsg(msgId, Conf.Language(138), 3000)
|
util.PushUpdateMsg(msgId, Conf.Language(138), 3000)
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
if initErr := IndexRepo("Init data repo"); nil != initErr {
|
if initErr := indexRepo("[Auto] Init data repo"); nil != initErr {
|
||||||
util.PushUpdateMsg(msgId, fmt.Sprintf(Conf.Language(140), initErr), 7000)
|
util.PushUpdateMsg(msgId, fmt.Sprintf(Conf.Language(140), initErr), 7000)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -145,7 +145,7 @@ func InitRepoKey() (err error) {
|
|||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
util.PushUpdateMsg(msgId, Conf.Language(138), 3000)
|
util.PushUpdateMsg(msgId, Conf.Language(138), 3000)
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
if initErr := IndexRepo("Init data repo"); nil != initErr {
|
if initErr := indexRepo("[Auto] Init data repo"); nil != initErr {
|
||||||
util.PushUpdateMsg(msgId, fmt.Sprintf(Conf.Language(140), initErr), 7000)
|
util.PushUpdateMsg(msgId, fmt.Sprintf(Conf.Language(140), initErr), 7000)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -194,7 +194,59 @@ func CheckoutRepo(id string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func IndexRepo(memo string) (err error) {
|
func CreateSnapshot(name string) (err error) {
|
||||||
|
if 1 > len(Conf.Repo.Key) {
|
||||||
|
err = errors.New(Conf.Language(26))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name = gulu.Str.RemoveInvisible(name)
|
||||||
|
if "" == name {
|
||||||
|
err = errors.New(Conf.Language(142))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !gulu.File.IsValidFilename(name) {
|
||||||
|
err = errors.New(Conf.Language(151))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := newRepository()
|
||||||
|
if nil != err {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
util.PushEndlessProgress(Conf.Language(143))
|
||||||
|
writingDataLock.Lock()
|
||||||
|
defer writingDataLock.Unlock()
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
latest, _ := repo.Latest()
|
||||||
|
WaitForWritingFiles()
|
||||||
|
filelock.ReleaseAllFileLocks()
|
||||||
|
index, err := repo.Index("[Snapshot] "+name, map[string]interface{}{
|
||||||
|
CtxPushMsg: CtxPushMsgToStatusBarAndProgress,
|
||||||
|
})
|
||||||
|
if nil != err {
|
||||||
|
util.PushStatusBar("Create data snapshot failed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
elapsed := time.Since(start)
|
||||||
|
|
||||||
|
if nil == latest || latest.ID != index.ID {
|
||||||
|
msg := fmt.Sprintf(Conf.Language(147), elapsed.Seconds())
|
||||||
|
util.PushStatusBar(msg)
|
||||||
|
util.PushMsg(msg, 5000)
|
||||||
|
} else {
|
||||||
|
msg := fmt.Sprintf(Conf.Language(148), elapsed.Seconds())
|
||||||
|
util.PushStatusBar(msg)
|
||||||
|
util.PushMsg(msg, 5000)
|
||||||
|
}
|
||||||
|
util.PushClearProgress()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexRepo(memo string) (err error) {
|
||||||
if 1 > len(Conf.Repo.Key) {
|
if 1 > len(Conf.Repo.Key) {
|
||||||
err = errors.New(Conf.Language(26))
|
err = errors.New(Conf.Language(26))
|
||||||
return
|
return
|
||||||
@ -223,7 +275,7 @@ func IndexRepo(memo string) (err error) {
|
|||||||
CtxPushMsg: CtxPushMsgToStatusBarAndProgress,
|
CtxPushMsg: CtxPushMsgToStatusBarAndProgress,
|
||||||
})
|
})
|
||||||
if nil != err {
|
if nil != err {
|
||||||
util.PushStatusBar("Create data snapshot failed")
|
util.PushStatusBar("Index data repo failed: " + err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
@ -233,7 +285,7 @@ func IndexRepo(memo string) (err error) {
|
|||||||
util.PushStatusBar(msg)
|
util.PushStatusBar(msg)
|
||||||
util.PushMsg(msg, 5000)
|
util.PushMsg(msg, 5000)
|
||||||
} else {
|
} else {
|
||||||
msg := Conf.Language(148)
|
msg := fmt.Sprintf(Conf.Language(148), elapsed.Seconds())
|
||||||
util.PushStatusBar(msg)
|
util.PushStatusBar(msg)
|
||||||
util.PushMsg(msg, 5000)
|
util.PushMsg(msg, 5000)
|
||||||
}
|
}
|
||||||
@ -354,23 +406,20 @@ func indexRepoBeforeCloudSync(repo *dejavu.Repo) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
if nil != latest {
|
|
||||||
if latest.ID != index.ID {
|
if nil == latest || latest.ID != index.ID {
|
||||||
// 对新创建的快照需要更新备注,加入耗时统计
|
// 对新创建的快照需要更新备注,加入耗时统计
|
||||||
index.Memo = fmt.Sprintf("[Auto] Cloud sync, completed in %.2fs", elapsed.Seconds())
|
index.Memo = fmt.Sprintf("[Auto] Cloud sync, completed in %.2fs", elapsed.Seconds())
|
||||||
err = repo.PutIndex(index)
|
if err = repo.PutIndex(index); nil != err {
|
||||||
if nil != err {
|
util.PushStatusBar("Save data snapshot for cloud sync failed")
|
||||||
util.PushStatusBar("Save data snapshot for cloud sync failed")
|
util.LogErrorf("put index into data repo before cloud sync failed: %s", err)
|
||||||
util.LogErrorf("put index into data repo before cloud sync failed: %s", err)
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
util.PushStatusBar(fmt.Sprintf(Conf.Language(147), elapsed.Seconds()))
|
|
||||||
} else {
|
|
||||||
util.PushStatusBar(Conf.Language(148))
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
util.PushStatusBar(fmt.Sprintf(Conf.Language(147), elapsed.Seconds()))
|
util.PushStatusBar(fmt.Sprintf(Conf.Language(147), elapsed.Seconds()))
|
||||||
|
} else {
|
||||||
|
util.PushStatusBar(fmt.Sprintf(Conf.Language(148), elapsed.Seconds()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if 7000 < elapsed.Milliseconds() {
|
if 7000 < elapsed.Milliseconds() {
|
||||||
util.LogWarnf("index data repo before cloud sync elapsed [%dms]", elapsed.Milliseconds())
|
util.LogWarnf("index data repo before cloud sync elapsed [%dms]", elapsed.Milliseconds())
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/88250/gulu"
|
"github.com/88250/gulu"
|
||||||
|
"github.com/88250/lute/html"
|
||||||
"github.com/88250/melody"
|
"github.com/88250/melody"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -125,28 +126,33 @@ func ReloadUI() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func PushTxErr(msg string, code int, data interface{}) {
|
func PushTxErr(msg string, code int, data interface{}) {
|
||||||
|
msg = html.EscapeHTMLStr(msg)
|
||||||
BroadcastByType("main", "txerr", code, msg, data)
|
BroadcastByType("main", "txerr", code, msg, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PushUpdateMsg(msgId string, msg string, timeout int) {
|
func PushUpdateMsg(msgId string, msg string, timeout int) {
|
||||||
|
msg = html.EscapeHTMLStr(msg)
|
||||||
BroadcastByType("main", "msg", 0, msg, map[string]interface{}{"id": msgId, "closeTimeout": timeout})
|
BroadcastByType("main", "msg", 0, msg, map[string]interface{}{"id": msgId, "closeTimeout": timeout})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func PushMsg(msg string, timeout int) (msgId string) {
|
func PushMsg(msg string, timeout int) (msgId string) {
|
||||||
msgId = gulu.Rand.String(7)
|
msgId = gulu.Rand.String(7)
|
||||||
|
msg = html.EscapeHTMLStr(msg)
|
||||||
BroadcastByType("main", "msg", 0, msg, map[string]interface{}{"id": msgId, "closeTimeout": timeout})
|
BroadcastByType("main", "msg", 0, msg, map[string]interface{}{"id": msgId, "closeTimeout": timeout})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func PushErrMsg(msg string, timeout int) (msgId string) {
|
func PushErrMsg(msg string, timeout int) (msgId string) {
|
||||||
msgId = gulu.Rand.String(7)
|
msgId = gulu.Rand.String(7)
|
||||||
|
msg = html.EscapeHTMLStr(msg)
|
||||||
BroadcastByType("main", "msg", -1, msg, map[string]interface{}{"id": msgId, "closeTimeout": timeout})
|
BroadcastByType("main", "msg", -1, msg, map[string]interface{}{"id": msgId, "closeTimeout": timeout})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func PushStatusBar(msg string) {
|
func PushStatusBar(msg string) {
|
||||||
msg += " (" + time.Now().Format("2006-01-02 15:04:05") + ")"
|
msg += " (" + time.Now().Format("2006-01-02 15:04:05") + ")"
|
||||||
|
msg = html.EscapeHTMLStr(msg)
|
||||||
BroadcastByType("main", "statusbar", 0, msg, nil)
|
BroadcastByType("main", "statusbar", 0, msg, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user