mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-20 16:40:13 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
446c81cf80
4 changed files with 120 additions and 48 deletions
|
|
@ -431,7 +431,12 @@ func exportMdContent(c *gin.Context) {
|
||||||
fillCSSVar = arg["fillCSSVar"].(bool)
|
fillCSSVar = arg["fillCSSVar"].(bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
hPath, content := model.ExportMarkdownContent(id, refMode, embedMode, yfm, fillCSSVar)
|
adjustHeadingLevel := false
|
||||||
|
if nil != arg["adjustHeadingLevel"] {
|
||||||
|
adjustHeadingLevel = arg["adjustHeadingLevel"].(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
hPath, content := model.ExportMarkdownContent(id, refMode, embedMode, yfm, fillCSSVar, adjustHeadingLevel)
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"hPath": hPath,
|
"hPath": hPath,
|
||||||
"content": content,
|
"content": content,
|
||||||
|
|
|
||||||
|
|
@ -1514,7 +1514,7 @@ func renderAttributeView(attrView *av.AttributeView, blockID, viewID, query stri
|
||||||
if isGroupByDate(view) {
|
if isGroupByDate(view) {
|
||||||
updatedDate := time.UnixMilli(view.GroupUpdated).Format("2006-01-02")
|
updatedDate := time.UnixMilli(view.GroupUpdated).Format("2006-01-02")
|
||||||
if time.Now().Format("2006-01-02") != updatedDate {
|
if time.Now().Format("2006-01-02") != updatedDate {
|
||||||
genAttrViewViewGroups(view, attrView)
|
regenAttrViewViewGroups(attrView, "force")
|
||||||
av.SaveAttributeView(attrView)
|
av.SaveAttributeView(attrView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1569,12 +1569,14 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) {
|
||||||
type GroupState struct {
|
type GroupState struct {
|
||||||
Folded bool
|
Folded bool
|
||||||
Hidden int
|
Hidden int
|
||||||
|
Sort int
|
||||||
}
|
}
|
||||||
groupStates := map[string]*GroupState{}
|
groupStates := map[string]*GroupState{}
|
||||||
for _, groupView := range view.Groups {
|
for i, groupView := range view.Groups {
|
||||||
groupStates[groupView.Name] = &GroupState{
|
groupStates[groupView.Name] = &GroupState{
|
||||||
Folded: groupView.GroupFolded,
|
Folded: groupView.GroupFolded,
|
||||||
Hidden: groupView.GroupHidden,
|
Hidden: groupView.GroupHidden,
|
||||||
|
Sort: i,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1730,7 +1732,7 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) {
|
||||||
|
|
||||||
view.GroupUpdated = time.Now().UnixMilli()
|
view.GroupUpdated = time.Now().UnixMilli()
|
||||||
|
|
||||||
// 则恢复分组视图状态
|
// 恢复分组视图状态
|
||||||
for _, groupView := range view.Groups {
|
for _, groupView := range view.Groups {
|
||||||
if state, ok := groupStates[groupView.Name]; ok {
|
if state, ok := groupStates[groupView.Name]; ok {
|
||||||
groupView.GroupFolded = state.Folded
|
groupView.GroupFolded = state.Folded
|
||||||
|
|
@ -1738,6 +1740,18 @@ func genAttrViewViewGroups(view *av.View, attrView *av.AttributeView) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 恢复分组视图的顺序
|
||||||
|
if len(groupStates) > 0 {
|
||||||
|
sort.SliceStable(view.Groups, func(i, j int) bool {
|
||||||
|
if stateI, ok := groupStates[view.Groups[i].Name]; ok {
|
||||||
|
if stateJ, ok := groupStates[view.Groups[j].Name]; ok {
|
||||||
|
return stateI.Sort < stateJ.Sort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if av.GroupOrderMan != view.Group.Order {
|
if av.GroupOrderMan != view.Group.Order {
|
||||||
sort.SliceStable(view.Groups, func(i, j int) bool {
|
sort.SliceStable(view.Groups, func(i, j int) bool {
|
||||||
iName, jName := view.Groups[i].Name, view.Groups[j].Name
|
iName, jName := view.Groups[i].Name, view.Groups[j].Name
|
||||||
|
|
@ -2936,24 +2950,8 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a
|
||||||
targetView = groupView
|
targetView = groupView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewable := sql.RenderGroupView(attrView, view, targetView)
|
|
||||||
av.Filter(viewable, attrView)
|
nearItem = getNearItem(attrView, view, targetView, previousBlockID)
|
||||||
av.Sort(viewable, attrView)
|
|
||||||
items := viewable.(av.Collection).GetItems()
|
|
||||||
if 0 < len(items) {
|
|
||||||
if "" != previousBlockID {
|
|
||||||
for _, row := range items {
|
|
||||||
if row.GetID() == previousBlockID {
|
|
||||||
nearItem = row
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if 0 < len(items) {
|
|
||||||
nearItem = items[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filterKeyIDs := map[string]bool{}
|
filterKeyIDs := map[string]bool{}
|
||||||
|
|
@ -3046,6 +3044,24 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a
|
||||||
} else {
|
} else {
|
||||||
v.ItemIDs = append([]string{addingBlockID}, v.ItemIDs...)
|
v.ItemIDs = append([]string{addingBlockID}, v.ItemIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, g := range v.Groups {
|
||||||
|
if "" != previousBlockID {
|
||||||
|
changed := false
|
||||||
|
for i, id := range g.GroupItemIDs {
|
||||||
|
if id == previousBlockID {
|
||||||
|
g.GroupItemIDs = append(g.GroupItemIDs[:i+1], append([]string{addingBlockID}, g.GroupItemIDs[i+1:]...)...)
|
||||||
|
changed = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !changed {
|
||||||
|
g.GroupItemIDs = append(g.GroupItemIDs, addingBlockID)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g.GroupItemIDs = append([]string{addingBlockID}, g.GroupItemIDs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果存在分组条件,则将分组条件应用到新添加的块上
|
// 如果存在分组条件,则将分组条件应用到新添加的块上
|
||||||
|
|
@ -3054,16 +3070,7 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a
|
||||||
if !filterKeyIDs[groupKey.ID] /* 过滤条件应用过的话就不重复处理了 */ && "" != groupID {
|
if !filterKeyIDs[groupKey.ID] /* 过滤条件应用过的话就不重复处理了 */ && "" != groupID {
|
||||||
if groupView := view.GetGroup(groupID); nil != groupView {
|
if groupView := view.GetGroup(groupID); nil != groupView {
|
||||||
if keyValues, _ := attrView.GetKeyValues(groupKey.ID); nil != keyValues {
|
if keyValues, _ := attrView.GetKeyValues(groupKey.ID); nil != keyValues {
|
||||||
var newValue, defaultVal *av.Value
|
newValue := getNewValueByNearItem(nearItem, groupKey, blockID)
|
||||||
if nil != nearItem {
|
|
||||||
defaultVal = nearItem.GetValue(groupKey.ID)
|
|
||||||
}
|
|
||||||
if nil != defaultVal {
|
|
||||||
newValue = defaultVal.Clone()
|
|
||||||
} else {
|
|
||||||
newValue = av.GetAttributeViewDefaultValue(ast.NewNodeID(), groupKey.ID, blockID, groupKey.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
if av.KeyTypeBlock == newValue.Type {
|
if av.KeyTypeBlock == newValue.Type {
|
||||||
// 如果是主键的话前面已经添加过了,这里仅修改内容
|
// 如果是主键的话前面已经添加过了,这里仅修改内容
|
||||||
blockValue.Block.Content = newValue.Block.Content
|
blockValue.Block.Content = newValue.Block.Content
|
||||||
|
|
@ -3096,6 +3103,40 @@ func addAttributeViewBlock(now int64, avID, blockID, groupID, previousBlockID, a
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getNewValueByNearItem(nearItem av.Item, key *av.Key, blockID string) (ret *av.Value) {
|
||||||
|
if nil != nearItem {
|
||||||
|
defaultVal := nearItem.GetValue(key.ID)
|
||||||
|
ret = defaultVal.Clone()
|
||||||
|
}
|
||||||
|
if nil == ret {
|
||||||
|
ret = av.GetAttributeViewDefaultValue(ast.NewNodeID(), key.ID, blockID, key.Type)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNearItem(attrView *av.AttributeView, view, groupView *av.View, previousItemID string) (ret av.Item) {
|
||||||
|
viewable := sql.RenderGroupView(attrView, view, groupView)
|
||||||
|
av.Filter(viewable, attrView)
|
||||||
|
av.Sort(viewable, attrView)
|
||||||
|
items := viewable.(av.Collection).GetItems()
|
||||||
|
if 0 < len(items) {
|
||||||
|
if "" != previousItemID {
|
||||||
|
for _, row := range items {
|
||||||
|
if row.GetID() == previousItemID {
|
||||||
|
ret = row
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if 0 < len(items) {
|
||||||
|
ret = items[0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *Transaction) doRemoveAttrViewBlock(operation *Operation) (ret *TxErr) {
|
func (tx *Transaction) doRemoveAttrViewBlock(operation *Operation) (ret *TxErr) {
|
||||||
err := removeAttributeViewBlock(operation.SrcIDs, operation.AvID, tx)
|
err := removeAttributeViewBlock(operation.SrcIDs, operation.AvID, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -3150,7 +3191,7 @@ func removeAttributeViewBlock(srcIDs []string, avID string, tx *Transaction) (er
|
||||||
|
|
||||||
for _, groupView := range view.Groups {
|
for _, groupView := range view.Groups {
|
||||||
for _, blockID := range srcIDs {
|
for _, blockID := range srcIDs {
|
||||||
groupView.ItemIDs = gulu.Str.RemoveElem(groupView.ItemIDs, blockID)
|
groupView.GroupItemIDs = gulu.Str.RemoveElem(groupView.GroupItemIDs, blockID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3560,11 +3601,15 @@ func sortAttributeViewRow(operation *Operation) (err error) {
|
||||||
}
|
}
|
||||||
groupView.GroupItemIDs = append(groupView.GroupItemIDs[:idx], groupView.GroupItemIDs[idx+1:]...)
|
groupView.GroupItemIDs = append(groupView.GroupItemIDs[:idx], groupView.GroupItemIDs[idx+1:]...)
|
||||||
|
|
||||||
targetGroupView := groupView
|
if operation.GroupID != operation.TargetGroupID { // 跨分组排序
|
||||||
if operation.GroupID != operation.TargetGroupID { // 跨分组拖拽
|
if targetGroupView := view.GetGroup(operation.TargetGroupID); nil != targetGroupView {
|
||||||
targetGroupView = view.GetGroup(operation.TargetGroupID)
|
groupKey := view.GetGroupKey(attrView)
|
||||||
}
|
nearItem := getNearItem(attrView, view, targetGroupView, operation.PreviousID)
|
||||||
if nil != targetGroupView {
|
newValue := getNewValueByNearItem(nearItem, groupKey, operation.ID)
|
||||||
|
val := attrView.GetValue(groupKey.ID, operation.ID)
|
||||||
|
newValueRaw := newValue.GetValByType(groupKey.Type)
|
||||||
|
val.SetValByType(groupKey.Type, newValueRaw)
|
||||||
|
|
||||||
for i, r := range targetGroupView.GroupItemIDs {
|
for i, r := range targetGroupView.GroupItemIDs {
|
||||||
if r == operation.PreviousID {
|
if r == operation.PreviousID {
|
||||||
previousIndex = i + 1
|
previousIndex = i + 1
|
||||||
|
|
@ -3573,6 +3618,15 @@ func sortAttributeViewRow(operation *Operation) (err error) {
|
||||||
}
|
}
|
||||||
targetGroupView.GroupItemIDs = util.InsertElem(targetGroupView.GroupItemIDs, previousIndex, itemID)
|
targetGroupView.GroupItemIDs = util.InsertElem(targetGroupView.GroupItemIDs, previousIndex, itemID)
|
||||||
}
|
}
|
||||||
|
} else { // 同分组内排序
|
||||||
|
for i, r := range groupView.GroupItemIDs {
|
||||||
|
if r == operation.PreviousID {
|
||||||
|
previousIndex = i + 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groupView.GroupItemIDs = util.InsertElem(groupView.GroupItemIDs, previousIndex, itemID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for i, id := range view.ItemIDs {
|
for i, id := range view.ItemIDs {
|
||||||
|
|
@ -4522,9 +4576,11 @@ func regenAttrViewViewGroups(attrView *av.AttributeView, keyID string) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if "force" != keyID {
|
||||||
if av.KeyTypeTemplate != groupKey.Type && view.Group.Field != keyID {
|
if av.KeyTypeTemplate != groupKey.Type && view.Group.Field != keyID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
genAttrViewViewGroups(view, attrView)
|
genAttrViewViewGroups(view, attrView)
|
||||||
|
|
||||||
|
|
@ -4894,8 +4950,11 @@ func setAttributeViewColumnOptionDesc(operation *Operation) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAttrViewViewByBlockID(attrView *av.AttributeView, blockID string) (ret *av.View, err error) {
|
func getAttrViewViewByBlockID(attrView *av.AttributeView, blockID string) (ret *av.View, err error) {
|
||||||
node, _, _ := getNodeByBlockID(nil, blockID)
|
|
||||||
var viewID string
|
var viewID string
|
||||||
|
var node *ast.Node
|
||||||
|
if "" != blockID {
|
||||||
|
node, _, _ = getNodeByBlockID(nil, blockID)
|
||||||
|
}
|
||||||
if nil != node {
|
if nil != node {
|
||||||
viewID = node.IALAttr(av.NodeAttrView)
|
viewID = node.IALAttr(av.NodeAttrView)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1458,12 +1458,13 @@ func processPDFLinkEmbedAssets(pdfCtx *model.Context, assetDests []string, remov
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExportStdMarkdown(id string, assetsDestSpace2Underscore, adjustHeadingLevel bool) string {
|
func ExportStdMarkdown(id string, assetsDestSpace2Underscore, adjustHeadingLevel bool) string {
|
||||||
tree, err := LoadTreeByBlockID(id)
|
bt := treenode.GetBlockTree(id)
|
||||||
if err != nil {
|
if nil == bt {
|
||||||
logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
|
logging.LogErrorf("block tree [%s] not found", id)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree := prepareExportTree(bt)
|
||||||
cloudAssetsBase := ""
|
cloudAssetsBase := ""
|
||||||
if IsSubscriber() {
|
if IsSubscriber() {
|
||||||
cloudAssetsBase = util.GetCloudAssetsServer() + Conf.GetUser().UserId + "/"
|
cloudAssetsBase = util.GetCloudAssetsServer() + Conf.GetUser().UserId + "/"
|
||||||
|
|
@ -1981,7 +1982,7 @@ func walkRelationAvs(avID string, exportAvIDs *hashset.Set) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExportMarkdownContent(id string, refMode, embedMode int, addYfm, fillCSSVar bool) (hPath, exportedMd string) {
|
func ExportMarkdownContent(id string, refMode, embedMode int, addYfm, fillCSSVar, adjustHeadingLv bool) (hPath, exportedMd string) {
|
||||||
bt := treenode.GetBlockTree(id)
|
bt := treenode.GetBlockTree(id)
|
||||||
if nil == bt {
|
if nil == bt {
|
||||||
return
|
return
|
||||||
|
|
@ -1989,7 +1990,7 @@ func ExportMarkdownContent(id string, refMode, embedMode int, addYfm, fillCSSVar
|
||||||
|
|
||||||
tree := prepareExportTree(bt)
|
tree := prepareExportTree(bt)
|
||||||
hPath = tree.HPath
|
hPath = tree.HPath
|
||||||
exportedMd = exportMarkdownContent0(id, tree, "", false, false,
|
exportedMd = exportMarkdownContent0(id, tree, "", false, adjustHeadingLv,
|
||||||
".md", refMode, embedMode, Conf.Export.FileAnnotationRefMode,
|
".md", refMode, embedMode, Conf.Export.FileAnnotationRefMode,
|
||||||
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
|
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
|
||||||
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
|
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
|
||||||
|
|
|
||||||
|
|
@ -1006,6 +1006,7 @@ func syncDelete2AttributeView(node *ast.Node) (changedAvIDs []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if changedAv {
|
if changedAv {
|
||||||
|
regenAttrViewViewGroups(attrView, "force")
|
||||||
av.SaveAttributeView(attrView)
|
av.SaveAttributeView(attrView)
|
||||||
changedAvIDs = append(changedAvIDs, avID)
|
changedAvIDs = append(changedAvIDs, avID)
|
||||||
}
|
}
|
||||||
|
|
@ -1539,6 +1540,12 @@ func upsertAvBlockRel(node *ast.Node) {
|
||||||
affectedAvIDs = append(affectedAvIDs, relatedAvIDs...)
|
affectedAvIDs = append(affectedAvIDs, relatedAvIDs...)
|
||||||
affectedAvIDs = gulu.Str.RemoveDuplicatedElem(affectedAvIDs)
|
affectedAvIDs = gulu.Str.RemoveDuplicatedElem(affectedAvIDs)
|
||||||
for _, avID := range affectedAvIDs {
|
for _, avID := range affectedAvIDs {
|
||||||
|
attrView, _ := av.ParseAttributeView(avID)
|
||||||
|
if nil != attrView {
|
||||||
|
regenAttrViewViewGroups(attrView, "force")
|
||||||
|
av.SaveAttributeView(attrView)
|
||||||
|
}
|
||||||
|
|
||||||
ReloadAttrView(avID)
|
ReloadAttrView(avID)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue