Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # app/appearance/langs/en_US.json # app/appearance/langs/es_ES.json # app/appearance/langs/fr_FR.json # app/appearance/langs/zh_CHT.json # app/appearance/langs/zh_CN.json
This commit is contained in:
commit
cdae86d50b
21 changed files with 144 additions and 58 deletions
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"cardShowAnswer": "Show Answer",
|
||||
"cardRatingAgain": "Again",
|
||||
"cardRatingHard": "Hard",
|
||||
"cardRatingGood": "Good",
|
||||
"cardRatingEasy": "Easy",
|
||||
"pdfIsLoading": "PDF is loading, please try again later",
|
||||
"addToDeck": "Add to Deck...",
|
||||
"quickMakeCard": "Quick make card",
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
{
|
||||
"pdfIsLoading": "El PDF se está cargando, inténtalo de nuevo más tarde",
|
||||
"cardShowAnswer": "Afficher la réponse",
|
||||
"cardRatingAgain": "Otra vez",
|
||||
"cardRatingHard": "Difícil",
|
||||
"cardRatingGood": "Bueno",
|
||||
"cardRatingEasy": "Fácil",
|
||||
"addToDeck": "Agregar a la plataforma...",
|
||||
"quickMakeCard": "Tarjeta de creación rápida",
|
||||
"allAttrs": "Todos los nombres de atributos y valores de atributos",
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"cardShowAnswer": "Afficher la réponse",
|
||||
"cardRatingAgain": "Encore",
|
||||
"cardRatingHard": "Difficile",
|
||||
"cardRatingGood": "Bien",
|
||||
"cardRatingEasy": "Facile",
|
||||
"pdfIsLoading": "Le PDF est en cours de chargement, veuillez réessayer plus tard",
|
||||
"addToDeck": "Ajouter au deck...",
|
||||
"quickMakeCard": "Carte de création rapide",
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
{
|
||||
"pdfIsLoading": "PDF 正在加載中,請稍後再試",
|
||||
"cardShowAnswer": "顯示答案",
|
||||
"cardRatingAgain": "重來",
|
||||
"cardRatingHard": "困難",
|
||||
"cardRatingGood": "一般",
|
||||
"cardRatingEasy": "輕鬆",
|
||||
"addToDeck": "添加到卡包...",
|
||||
"quickMakeCard": "快速制卡",
|
||||
"allAttrs": "所有屬性名和屬性值",
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
{
|
||||
"pdfIsLoading": "PDF 正在加载中,请稍后再试",
|
||||
"cardShowAnswer": "显示答案",
|
||||
"cardRatingAgain": "重来",
|
||||
"cardRatingHard": "困难",
|
||||
"cardRatingGood": "一般",
|
||||
"cardRatingEasy": "轻松",
|
||||
"addToDeck": "添加到卡包...",
|
||||
"quickMakeCard": "快速制卡",
|
||||
"allAttrs": "所有属性名和属性值",
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
width: 90%;
|
||||
|
||||
& > div {
|
||||
font-size: 46px;
|
||||
font-size: 32px;
|
||||
display: block;
|
||||
line-height: 46px;
|
||||
margin-bottom: 4px;
|
||||
|
|
|
@ -54,35 +54,35 @@ export const openCardByData = (cardsData: ICard[], html = "") => {
|
|||
${window.siyuan.languages.noDueCard}
|
||||
</div>
|
||||
<div class="fn__flex card__action${blocks.length === 0 ? " fn__none" : ""}">
|
||||
<button data-type="-1" class="b3-button fn__flex-1">Show (S)</button>
|
||||
<button data-type="-1" class="b3-button fn__flex-1">${window.siyuan.languages.cardShowAnswer} (S)</button>
|
||||
</div>
|
||||
<div class="fn__flex card__action fn__none">
|
||||
<div>
|
||||
<span></span>
|
||||
<button data-type="0" aria-label="1 / j" class="b3-button b3-button--error b3-tooltips__s b3-tooltips">
|
||||
<div>❌</div>
|
||||
Again
|
||||
${window.siyuan.languages.cardRatingAgain} (1)
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<span></span>
|
||||
<button data-type="1" aria-label="2 / k" class="b3-button b3-button--warning b3-tooltips__s b3-tooltips">
|
||||
<div>😬</div>
|
||||
Hard
|
||||
${window.siyuan.languages.cardRatingHard} (2)
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<span></span>
|
||||
<button data-type="2" aria-label="3 / l" class="b3-button b3-button--info b3-tooltips__s b3-tooltips">
|
||||
<div>😊</div>
|
||||
Good
|
||||
${window.siyuan.languages.cardRatingGood} (3)
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<span></span>
|
||||
<button data-type="3" aria-label="4 / ;" class="b3-button b3-button--success b3-tooltips__s b3-tooltips">
|
||||
<div>🌈</div>
|
||||
Easy
|
||||
${window.siyuan.languages.cardRatingEasy} (4)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -128,7 +128,7 @@ export const initFramework = () => {
|
|||
closePanel();
|
||||
});
|
||||
initEditorName();
|
||||
if (window.siyuan.config.newbie) {
|
||||
if (window.siyuan.config.openHelp) {
|
||||
mountHelp();
|
||||
}
|
||||
const transactionTipElement = document.getElementById("transactionTip");
|
||||
|
|
2
app/src/types/index.d.ts
vendored
2
app/src/types/index.d.ts
vendored
|
@ -413,7 +413,7 @@ declare interface IConfig {
|
|||
api: {
|
||||
token: string
|
||||
}
|
||||
newbie: boolean
|
||||
openHelp: boolean
|
||||
system: {
|
||||
networkProxy: {
|
||||
host: string
|
||||
|
|
|
@ -176,7 +176,7 @@ export const onGetConfig = (isStart: boolean) => {
|
|||
resizeDrag();
|
||||
}, 200);
|
||||
});
|
||||
if (window.siyuan.config.newbie) {
|
||||
if (window.siyuan.config.openHelp) {
|
||||
mountHelp();
|
||||
}
|
||||
addGA();
|
||||
|
|
|
@ -30,6 +30,7 @@ import (
|
|||
"github.com/88250/lute"
|
||||
"github.com/88250/lute/ast"
|
||||
"github.com/88250/lute/parse"
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/siyuan-note/filelock"
|
||||
"github.com/siyuan-note/logging"
|
||||
|
@ -80,7 +81,7 @@ func extensionCopy(c *gin.Context) {
|
|||
continue
|
||||
}
|
||||
fName := path.Base(u.Path)
|
||||
fName = util.FilterUploadFileName(fName)
|
||||
|
||||
f, err := file[0].Open()
|
||||
if nil != err {
|
||||
ret.Code = -1
|
||||
|
@ -96,10 +97,19 @@ func extensionCopy(c *gin.Context) {
|
|||
}
|
||||
|
||||
ext := path.Ext(fName)
|
||||
fName = fName[0 : len(fName)-len(ext)]
|
||||
originalExt := ext
|
||||
if "" == ext || strings.Contains(ext, "!") {
|
||||
// 改进浏览器剪藏扩展转换本地图片后缀 https://github.com/siyuan-note/siyuan/issues/7467
|
||||
if mtype := mimetype.Detect(data); nil != mtype {
|
||||
ext = mtype.Extension()
|
||||
}
|
||||
}
|
||||
if "" == ext && bytes.HasPrefix(data, []byte("<svg ")) && bytes.HasSuffix(data, []byte("</svg>")) {
|
||||
ext = ".svg"
|
||||
}
|
||||
|
||||
fName = fName[0 : len(fName)-len(originalExt)]
|
||||
fName = util.FilterUploadFileName(fName)
|
||||
fName = fName + "-" + ast.NewNodeID() + ext
|
||||
writePath := filepath.Join(assets, fName)
|
||||
if err = filelock.WriteFile(writePath, data); nil != err {
|
||||
|
|
|
@ -35,7 +35,11 @@ func netImg2LocalAssets(c *gin.Context) {
|
|||
}
|
||||
|
||||
id := arg["id"].(string)
|
||||
err := model.NetImg2LocalAssets(id)
|
||||
var url string
|
||||
if urlArg := arg["url"]; nil != urlArg {
|
||||
url = urlArg.(string)
|
||||
}
|
||||
err := model.NetImg2LocalAssets(id, url)
|
||||
if nil != err {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
|
|
|
@ -47,7 +47,7 @@ require (
|
|||
github.com/siyuan-note/filelock v0.0.0-20230223100551-200cbe1cf84e
|
||||
github.com/siyuan-note/httpclient v0.0.0-20230223101139-409ed0b4c5ff
|
||||
github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb
|
||||
github.com/siyuan-note/riff v0.0.0-20221228031102-17d458a1217b
|
||||
github.com/siyuan-note/riff v0.0.0-20230224070227-4514ccc3e496
|
||||
github.com/steambap/captcha v1.4.1
|
||||
github.com/studio-b12/gowebdav v0.0.0-20230203202212-3282f94193f2
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5
|
||||
|
|
|
@ -10,8 +10,6 @@ github.com/88250/gulu v1.2.3-0.20230223100136-26e5f16ac3c0 h1:hZn2F/kNKcxoK41Jhf
|
|||
github.com/88250/gulu v1.2.3-0.20230223100136-26e5f16ac3c0/go.mod h1:pTWnjt+6qUqNnP9xltswsJxgCBVu3C7eW09u48LWX0k=
|
||||
github.com/88250/lute v1.7.6-0.20230223100349-d4c62da413ce h1:PGos/Sz/SRVDPzToUgn/SBttEsAO5livLUWzoI+/bZ4=
|
||||
github.com/88250/lute v1.7.6-0.20230223100349-d4c62da413ce/go.mod h1:+wUqx/1kdFDbWtxn9LYJlaCOAeol2pjSO6w+WJTVQsg=
|
||||
github.com/88250/pdfcpu v0.3.14-0.20230223050947-68dec81c7661 h1:s8YOfk7TpajM8SBivP0ReIHmNfMQu20hWgEBc98D14w=
|
||||
github.com/88250/pdfcpu v0.3.14-0.20230223050947-68dec81c7661/go.mod h1:S5YT38L/GCjVjmB4PB84PymA1qfopjEhfhTNQilLpv4=
|
||||
github.com/88250/pdfcpu v0.3.14-0.20230224021324-e51076eb6390 h1:q2AR33VoQ87WYtvZ4pEvwj5gZkv22HK/yMlPWwF1oyc=
|
||||
github.com/88250/pdfcpu v0.3.14-0.20230224021324-e51076eb6390/go.mod h1:S5YT38L/GCjVjmB4PB84PymA1qfopjEhfhTNQilLpv4=
|
||||
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY=
|
||||
|
@ -288,8 +286,8 @@ github.com/siyuan-note/httpclient v0.0.0-20230223101139-409ed0b4c5ff h1:3G48J/tG
|
|||
github.com/siyuan-note/httpclient v0.0.0-20230223101139-409ed0b4c5ff/go.mod h1:/fjYEiYPN2ZNR2zVTopobwzo3rOychV2qbsutxiV0jI=
|
||||
github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb h1:qzz7ZQw7/tHJd1IST+8UymXFF8RacokMLD7VZgyS+ww=
|
||||
github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb/go.mod h1:6mRFtAAvYPn3cDzqvyv+t8BVPGqpONDMMb5ywOhY1D4=
|
||||
github.com/siyuan-note/riff v0.0.0-20221228031102-17d458a1217b h1:JDpKOdiyocNsgKFfrF3mB7UoBJz4qcHBUKBig78kVjc=
|
||||
github.com/siyuan-note/riff v0.0.0-20221228031102-17d458a1217b/go.mod h1:WnNt0JPjfXp2fjAgbF9rS5W7JC2W0YVcaVmLXIeYF8A=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224070227-4514ccc3e496 h1:6u9vlE4EhRja4abccUPGNmG+aMBm/D+5lVomkoYuSmo=
|
||||
github.com/siyuan-note/riff v0.0.0-20230224070227-4514ccc3e496/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.7 h1:I6tZjLXD2Q1kjvNbIzB1wvQBsXmKXiVrhpRE8ZjP5jY=
|
||||
|
|
|
@ -70,7 +70,7 @@ func DocImageAssets(rootID string) (ret []string, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func NetImg2LocalAssets(rootID string) (err error) {
|
||||
func NetImg2LocalAssets(rootID, originalURL string) (err error) {
|
||||
tree, err := loadTreeByBlockID(rootID)
|
||||
if nil != err {
|
||||
return
|
||||
|
@ -138,6 +138,7 @@ func NetImg2LocalAssets(rootID string) (err error) {
|
|||
}
|
||||
util.PushUpdateMsg(msgId, fmt.Sprintf(Conf.Language(119), u), 15000)
|
||||
request := httpclient.NewBrowserRequest()
|
||||
request.SetHeader("Referer", originalURL) // 改进浏览器剪藏扩展转换本地图片成功率 https://github.com/siyuan-note/siyuan/issues/7464
|
||||
resp, reqErr := request.Get(u)
|
||||
if nil != reqErr {
|
||||
logging.LogErrorf("download net img [%s] failed: %s", u, reqErr)
|
||||
|
|
|
@ -70,7 +70,7 @@ type AppConf struct {
|
|||
Stat *conf.Stat `json:"stat"` // 统计
|
||||
Api *conf.API `json:"api"` // API
|
||||
Repo *conf.Repo `json:"repo"` // 数据仓库
|
||||
Newbie bool `json:"newbie"` // 是否是安装后第一次启动
|
||||
OpenHelp bool `json:"openHelp"` // 启动后是否需要打开用户指南
|
||||
}
|
||||
|
||||
func InitConf() {
|
||||
|
@ -211,7 +211,9 @@ func InitConf() {
|
|||
}
|
||||
if nil == Conf.System {
|
||||
Conf.System = conf.NewSystem()
|
||||
Conf.OpenHelp = true
|
||||
} else {
|
||||
Conf.OpenHelp = Conf.System.KernelVersion != util.Ver
|
||||
Conf.System.KernelVersion = util.Ver
|
||||
Conf.System.IsInsider = util.IsInsider
|
||||
}
|
||||
|
@ -237,7 +239,6 @@ func InitConf() {
|
|||
}
|
||||
Conf.System.OS = runtime.GOOS
|
||||
Conf.System.OSPlatform, _ = util.GetOSPlatform()
|
||||
Conf.Newbie = util.IsNewbie
|
||||
|
||||
if "" != Conf.UserData {
|
||||
Conf.User = loadUserFromConf()
|
||||
|
|
|
@ -19,7 +19,6 @@ package model
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
@ -93,35 +92,10 @@ func (box *Box) docFromFileInfo(fileInfo *FileInfo, ial map[string]string) (ret
|
|||
}
|
||||
|
||||
ret.Mtime = mTime.Unix()
|
||||
ret.HMtime = HumanizeTime(mTime)
|
||||
ret.HMtime = util.HumanizeTime(mTime, Conf.Lang)
|
||||
return
|
||||
}
|
||||
|
||||
func HumanizeTime(then time.Time) string {
|
||||
labels := util.TimeLangs[Conf.Lang]
|
||||
|
||||
defaultMagnitudes := []humanize.RelTimeMagnitude{
|
||||
{time.Second, labels["now"].(string), time.Second},
|
||||
{2 * time.Second, labels["1s"].(string), 1},
|
||||
{time.Minute, labels["xs"].(string), time.Second},
|
||||
{2 * time.Minute, labels["1m"].(string), 1},
|
||||
{time.Hour, labels["xm"].(string), time.Minute},
|
||||
{2 * time.Hour, labels["1h"].(string), 1},
|
||||
{humanize.Day, labels["xh"].(string), time.Hour},
|
||||
{2 * humanize.Day, labels["1d"].(string), 1},
|
||||
{humanize.Week, labels["xd"].(string), humanize.Day},
|
||||
{2 * humanize.Week, labels["1w"].(string), 1},
|
||||
{humanize.Month, labels["xw"].(string), humanize.Week},
|
||||
{2 * humanize.Month, labels["1M"].(string), 1},
|
||||
{humanize.Year, labels["xM"].(string), humanize.Month},
|
||||
{18 * humanize.Month, labels["1y"].(string), 1},
|
||||
{2 * humanize.Year, labels["2y"].(string), 1},
|
||||
{humanize.LongTime, labels["xy"].(string), humanize.Year},
|
||||
{math.MaxInt64, labels["max"].(string), 1},
|
||||
}
|
||||
return humanize.CustomRelTime(then, time.Now(), labels["albl"].(string), labels["blbl"].(string), defaultMagnitudes)
|
||||
}
|
||||
|
||||
func (box *Box) docIAL(p string) (ret map[string]string) {
|
||||
name := strings.ToLower(filepath.Base(p))
|
||||
if !strings.HasSuffix(name, ".sy") {
|
||||
|
|
|
@ -29,7 +29,6 @@ import (
|
|||
"github.com/88250/gulu"
|
||||
"github.com/88250/lute/ast"
|
||||
"github.com/88250/lute/parse"
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/riff"
|
||||
"github.com/siyuan-note/siyuan/kernel/cache"
|
||||
|
@ -156,6 +155,9 @@ func GetFlashcards(deckID string, page int) (blocks []*Block, total, pageCount i
|
|||
return
|
||||
}
|
||||
|
||||
// reviewCardCache <cardID, card> 用于复习时缓存卡片,以便支持撤销。
|
||||
var reviewCardCache = map[string]riff.Card{}
|
||||
|
||||
func ReviewFlashcard(deckID string, blockID string, rating riff.Rating) (err error) {
|
||||
deckLock.Lock()
|
||||
defer deckLock.Unlock()
|
||||
|
@ -166,17 +168,39 @@ func ReviewFlashcard(deckID string, blockID string, rating riff.Rating) (err err
|
|||
}
|
||||
|
||||
deck := Decks[deckID]
|
||||
card := deck.GetCard(blockID)
|
||||
if nil == card {
|
||||
logging.LogErrorf("card not found [%s]", blockID)
|
||||
return
|
||||
}
|
||||
|
||||
if cachedCard := reviewCardCache[card.ID()]; nil != cachedCard {
|
||||
// 命中缓存说明这张卡片已经复习过了,这次调用复习是撤销后再次复习
|
||||
// 将缓存的卡片重新覆盖回卡包中,以恢复最开始复习前的状态
|
||||
deck.SetCard(cachedCard)
|
||||
} else {
|
||||
// 首次复习该卡片,将卡片缓存以便后续支持撤销后再次复习
|
||||
reviewCardCache[card.ID()] = card
|
||||
}
|
||||
|
||||
deck.Review(blockID, rating)
|
||||
err = deck.Save()
|
||||
if nil != err {
|
||||
logging.LogErrorf("save deck [%s] failed: %s", deckID, err)
|
||||
return
|
||||
}
|
||||
|
||||
dueCards := getDueFlashcards(deckID)
|
||||
if 1 > len(dueCards) {
|
||||
// 该卡包中没有待复习的卡片了,说明最后一张卡片已经复习完了,清空撤销缓存
|
||||
reviewCardCache = map[string]riff.Card{}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type Flashcard struct {
|
||||
DeckID string `json:"deckID"`
|
||||
CardID string `json:"cardID"`
|
||||
BlockID string `json:"blockID"`
|
||||
NextDues map[riff.Rating]string `json:"nextDues"`
|
||||
}
|
||||
|
@ -207,11 +231,12 @@ func GetTreeDueFlashcards(rootID string) (ret []*Flashcard, err error) {
|
|||
|
||||
nextDues := map[riff.Rating]string{}
|
||||
for rating, due := range card.NextDues() {
|
||||
nextDues[rating] = strings.TrimSpace(humanize.RelTime(due, now, "", ""))
|
||||
nextDues[rating] = strings.TrimSpace(util.HumanizeRelTime(due, now, Conf.Lang))
|
||||
}
|
||||
|
||||
ret = append(ret, &Flashcard{
|
||||
DeckID: builtinDeckID,
|
||||
CardID: card.ID(),
|
||||
BlockID: blockID,
|
||||
NextDues: nextDues,
|
||||
})
|
||||
|
@ -270,10 +295,21 @@ func GetDueFlashcards(deckID string) (ret []*Flashcard, err error) {
|
|||
}
|
||||
|
||||
if "" == deckID {
|
||||
return getAllDueFlashcards()
|
||||
ret = getAllDueFlashcards()
|
||||
return
|
||||
}
|
||||
|
||||
ret = getDueFlashcards(deckID)
|
||||
return
|
||||
}
|
||||
|
||||
func getDueFlashcards(deckID string) (ret []*Flashcard) {
|
||||
deck := Decks[deckID]
|
||||
if nil == deck {
|
||||
logging.LogWarnf("deck not found [%s]", deckID)
|
||||
return
|
||||
}
|
||||
|
||||
cards := deck.Dues()
|
||||
now := time.Now()
|
||||
for _, card := range cards {
|
||||
|
@ -285,11 +321,12 @@ func GetDueFlashcards(deckID string) (ret []*Flashcard, err error) {
|
|||
|
||||
nextDues := map[riff.Rating]string{}
|
||||
for rating, due := range card.NextDues() {
|
||||
nextDues[rating] = strings.TrimSpace(humanize.RelTime(due, now, "", ""))
|
||||
nextDues[rating] = strings.TrimSpace(util.HumanizeRelTime(due, now, Conf.Lang))
|
||||
}
|
||||
|
||||
ret = append(ret, &Flashcard{
|
||||
DeckID: deckID,
|
||||
CardID: card.ID(),
|
||||
BlockID: blockID,
|
||||
NextDues: nextDues,
|
||||
})
|
||||
|
@ -300,7 +337,7 @@ func GetDueFlashcards(deckID string) (ret []*Flashcard, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func getAllDueFlashcards() (ret []*Flashcard, err error) {
|
||||
func getAllDueFlashcards() (ret []*Flashcard) {
|
||||
blockIDs := map[string]bool{}
|
||||
now := time.Now()
|
||||
for _, deck := range Decks {
|
||||
|
@ -317,11 +354,12 @@ func getAllDueFlashcards() (ret []*Flashcard, err error) {
|
|||
|
||||
nextDues := map[riff.Rating]string{}
|
||||
for rating, due := range card.NextDues() {
|
||||
nextDues[rating] = strings.TrimSpace(humanize.RelTime(due, now, "", ""))
|
||||
nextDues[rating] = strings.TrimSpace(util.HumanizeRelTime(due, now, Conf.Lang))
|
||||
}
|
||||
|
||||
ret = append(ret, &Flashcard{
|
||||
DeckID: deck.ID,
|
||||
CardID: card.ID(),
|
||||
BlockID: blockID,
|
||||
NextDues: nextDues,
|
||||
})
|
||||
|
|
|
@ -162,8 +162,8 @@ func Mount(boxID string) (alreadyMount bool, err error) {
|
|||
box.SaveConf(boxConf)
|
||||
}
|
||||
|
||||
if Conf.Newbie {
|
||||
Conf.Newbie = false
|
||||
if Conf.OpenHelp {
|
||||
Conf.OpenHelp = false
|
||||
Conf.Save()
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
)
|
||||
|
||||
func Millisecond2Time(t int64) time.Time {
|
||||
|
@ -33,3 +37,37 @@ func CurrentTimeMillis() int64 {
|
|||
func CurrentTimeSecondsStr() string {
|
||||
return time.Now().Format("20060102150405")
|
||||
}
|
||||
|
||||
func HumanizeRelTime(a time.Time, b time.Time, lang string) string {
|
||||
_, magnitudes := humanizeTimeMagnitudes(lang)
|
||||
return strings.TrimSpace(humanize.CustomRelTime(a, b, "", "", magnitudes))
|
||||
}
|
||||
|
||||
func HumanizeTime(then time.Time, lang string) string {
|
||||
labels, magnitudes := humanizeTimeMagnitudes(lang)
|
||||
return strings.TrimSpace(humanize.CustomRelTime(then, time.Now(), labels["albl"].(string), labels["blbl"].(string), magnitudes))
|
||||
}
|
||||
|
||||
func humanizeTimeMagnitudes(lang string) (labels map[string]interface{}, magnitudes []humanize.RelTimeMagnitude) {
|
||||
labels = TimeLangs[lang]
|
||||
magnitudes = []humanize.RelTimeMagnitude{
|
||||
{time.Second, labels["now"].(string), time.Second},
|
||||
{2 * time.Second, labels["1s"].(string), 1},
|
||||
{time.Minute, labels["xs"].(string), time.Second},
|
||||
{2 * time.Minute, labels["1m"].(string), 1},
|
||||
{time.Hour, labels["xm"].(string), time.Minute},
|
||||
{2 * time.Hour, labels["1h"].(string), 1},
|
||||
{humanize.Day, labels["xh"].(string), time.Hour},
|
||||
{2 * humanize.Day, labels["1d"].(string), 1},
|
||||
{humanize.Week, labels["xd"].(string), humanize.Day},
|
||||
{2 * humanize.Week, labels["1w"].(string), 1},
|
||||
{humanize.Month, labels["xw"].(string), humanize.Week},
|
||||
{2 * humanize.Month, labels["1M"].(string), 1},
|
||||
{humanize.Year, labels["xM"].(string), humanize.Month},
|
||||
{18 * humanize.Month, labels["1y"].(string), 1},
|
||||
{2 * humanize.Year, labels["2y"].(string), 1},
|
||||
{humanize.LongTime, labels["xy"].(string), humanize.Year},
|
||||
{math.MaxInt64, labels["max"].(string), 1},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -180,15 +180,12 @@ var (
|
|||
SnippetsPath string // 数据目录下的 snippets/ 路径
|
||||
|
||||
UIProcessIDs = sync.Map{} // UI 进程 ID
|
||||
|
||||
IsNewbie bool // 是否是第一次安装
|
||||
)
|
||||
|
||||
func initWorkspaceDir(workspaceArg string) {
|
||||
userHomeConfDir := filepath.Join(HomeDir, ".config", "siyuan")
|
||||
workspaceConf := filepath.Join(userHomeConfDir, "workspace.json")
|
||||
if !gulu.File.IsExist(workspaceConf) {
|
||||
IsNewbie = ContainerStd == Container // 只有桌面端需要设置新手标识,前端自动挂载帮助文档
|
||||
if err := os.MkdirAll(userHomeConfDir, 0755); nil != err && !os.IsExist(err) {
|
||||
log.Printf("create user home conf folder [%s] failed: %s", userHomeConfDir, err)
|
||||
os.Exit(ExitCodeCreateConfDirErr)
|
||||
|
|
Loading…
Add table
Reference in a new issue