mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-18 07:30:12 +01:00
🎨 Database gallery view https://github.com/siyuan-note/siyuan/issues/10414
This commit is contained in:
parent
6ba4058a13
commit
0d2e753c5e
2 changed files with 82 additions and 18 deletions
|
|
@ -22,12 +22,21 @@ import "sort"
|
||||||
type LayoutGallery struct {
|
type LayoutGallery struct {
|
||||||
*BaseLayout
|
*BaseLayout
|
||||||
|
|
||||||
CoverFrom int `json:"coverFrom"` // 封面来源,0:无,1:内容图,2:资源字段
|
CoverFrom CoverFrom `json:"coverFrom"` // 封面来源,0:无,1:内容图,2:资源字段
|
||||||
CoverFromAssetKeyID string `json:"coverFromAssetKeyId,omitempty"` // 资源字段 ID,CoverFrom 为 2 时有效
|
CoverFromAssetKeyID string `json:"coverFromAssetKeyId,omitempty"` // 资源字段 ID,CoverFrom 为 2 时有效
|
||||||
CardFields []*ViewGalleryCardField `json:"fields"` // 画廊卡片字段
|
CardFields []*ViewGalleryCardField `json:"fields"` // 画廊卡片字段
|
||||||
CardIDs []string `json:"cardIds"` // 卡片 ID,用于自定义排序
|
CardIDs []string `json:"cardIds"` // 卡片 ID,用于自定义排序
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CoverFrom 描述了画廊中的卡片封面来源的枚举类型。
|
||||||
|
type CoverFrom int
|
||||||
|
|
||||||
|
const (
|
||||||
|
CoverFromNone CoverFrom = iota // 无封面
|
||||||
|
CoverFromContentImage // 内容图
|
||||||
|
CoverFromAssetField // 资源字段
|
||||||
|
)
|
||||||
|
|
||||||
// ViewGalleryCardField 描述了画廊卡片字段的结构。
|
// ViewGalleryCardField 描述了画廊卡片字段的结构。
|
||||||
type ViewGalleryCardField struct {
|
type ViewGalleryCardField struct {
|
||||||
ID string `json:"id"` // 字段 ID
|
ID string `json:"id"` // 字段 ID
|
||||||
|
|
|
||||||
|
|
@ -55,23 +55,23 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成卡片
|
// 生成卡片
|
||||||
cards := map[string][]*av.KeyValues{}
|
cardsValues := map[string][]*av.KeyValues{}
|
||||||
for _, keyValues := range attrView.KeyValues {
|
for _, keyValues := range attrView.KeyValues {
|
||||||
for _, val := range keyValues.Values {
|
for _, val := range keyValues.Values {
|
||||||
values := cards[val.BlockID]
|
values := cardsValues[val.BlockID]
|
||||||
if nil == values {
|
if nil == values {
|
||||||
values = []*av.KeyValues{{Key: keyValues.Key, Values: []*av.Value{val}}}
|
values = []*av.KeyValues{{Key: keyValues.Key, Values: []*av.Value{val}}}
|
||||||
} else {
|
} else {
|
||||||
values = append(values, &av.KeyValues{Key: keyValues.Key, Values: []*av.Value{val}})
|
values = append(values, &av.KeyValues{Key: keyValues.Key, Values: []*av.Value{val}})
|
||||||
}
|
}
|
||||||
cards[val.BlockID] = values
|
cardsValues[val.BlockID] = values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 过滤掉不存在的卡片
|
// 过滤掉不存在的卡片
|
||||||
var notFound []string
|
var notFound []string
|
||||||
var toCheckBlockIDs []string
|
var toCheckBlockIDs []string
|
||||||
for blockID, keyValues := range cards {
|
for blockID, keyValues := range cardsValues {
|
||||||
blockValue := getBlockValue(keyValues)
|
blockValue := getBlockValue(keyValues)
|
||||||
if nil == blockValue {
|
if nil == blockValue {
|
||||||
notFound = append(notFound, blockID)
|
notFound = append(notFound, blockID)
|
||||||
|
|
@ -96,15 +96,15 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, blockID := range notFound {
|
for _, blockID := range notFound {
|
||||||
delete(cards, blockID)
|
delete(cardsValues, blockID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成卡片字段值
|
// 生成卡片字段值
|
||||||
for cardID, card := range cards {
|
for cardID, cardValues := range cardsValues {
|
||||||
var galleryCard av.GalleryCard
|
var galleryCard av.GalleryCard
|
||||||
for _, field := range ret.Fields {
|
for _, field := range ret.Fields {
|
||||||
var fieldValue *av.GalleryFieldValue
|
var fieldValue *av.GalleryFieldValue
|
||||||
for _, keyValues := range card {
|
for _, keyValues := range cardValues {
|
||||||
if keyValues.Key.ID == field.ID {
|
if keyValues.Key.ID == field.ID {
|
||||||
fieldValue = &av.GalleryFieldValue{
|
fieldValue = &av.GalleryFieldValue{
|
||||||
BaseValue: &av.BaseValue{
|
BaseValue: &av.BaseValue{
|
||||||
|
|
@ -152,6 +152,8 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
|
|
||||||
galleryCard.Values = append(galleryCard.Values, fieldValue)
|
galleryCard.Values = append(galleryCard.Values, fieldValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fillGalleryCardCover(attrView, view, cardValues, galleryCard, cardID)
|
||||||
ret.Cards = append(ret.Cards, &galleryCard)
|
ret.Cards = append(ret.Cards, &galleryCard)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,10 +234,10 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
|
|
||||||
value.Value.Rollup.RenderContents(rollupKey.Rollup.Calc, destKey)
|
value.Value.Rollup.RenderContents(rollupKey.Rollup.Calc, destKey)
|
||||||
|
|
||||||
// 将汇总字段的值保存到 cards 中,后续渲染模板字段的时候会用到,下同
|
// 将汇总字段的值保存到 cardsValues 中,后续渲染模板字段的时候会用到,下同
|
||||||
keyValues := cards[card.ID]
|
keyValues := cardsValues[card.ID]
|
||||||
keyValues = append(keyValues, &av.KeyValues{Key: rollupKey, Values: []*av.Value{{ID: value.Value.ID, KeyID: rollupKey.ID, BlockID: card.ID, Type: av.KeyTypeRollup, Rollup: value.Value.Rollup}}})
|
keyValues = append(keyValues, &av.KeyValues{Key: rollupKey, Values: []*av.Value{{ID: value.Value.ID, KeyID: rollupKey.ID, BlockID: card.ID, Type: av.KeyTypeRollup, Rollup: value.Value.Rollup}}})
|
||||||
cards[card.ID] = keyValues
|
cardsValues[card.ID] = keyValues
|
||||||
case av.KeyTypeRelation: // 渲染关联字段
|
case av.KeyTypeRelation: // 渲染关联字段
|
||||||
relKey, _ := attrView.GetKey(value.Value.KeyID)
|
relKey, _ := attrView.GetKey(value.Value.KeyID)
|
||||||
if nil != relKey && nil != relKey.Relation {
|
if nil != relKey && nil != relKey.Relation {
|
||||||
|
|
@ -262,9 +264,9 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keyValues := cards[card.ID]
|
keyValues := cardsValues[card.ID]
|
||||||
keyValues = append(keyValues, &av.KeyValues{Key: relKey, Values: []*av.Value{{ID: value.Value.ID, KeyID: relKey.ID, BlockID: card.ID, Type: av.KeyTypeRelation, Relation: value.Value.Relation}}})
|
keyValues = append(keyValues, &av.KeyValues{Key: relKey, Values: []*av.Value{{ID: value.Value.ID, KeyID: relKey.ID, BlockID: card.ID, Type: av.KeyTypeRelation, Relation: value.Value.Relation}}})
|
||||||
cards[card.ID] = keyValues
|
cardsValues[card.ID] = keyValues
|
||||||
case av.KeyTypeCreated: // 渲染创建时间
|
case av.KeyTypeCreated: // 渲染创建时间
|
||||||
createdStr := card.ID[:len("20060102150405")]
|
createdStr := card.ID[:len("20060102150405")]
|
||||||
created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
|
created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
|
||||||
|
|
@ -275,10 +277,10 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
value.Value.Created = av.NewFormattedValueCreated(time.Now().UnixMilli(), 0, av.CreatedFormatNone)
|
value.Value.Created = av.NewFormattedValueCreated(time.Now().UnixMilli(), 0, av.CreatedFormatNone)
|
||||||
}
|
}
|
||||||
|
|
||||||
keyValues := cards[card.ID]
|
keyValues := cardsValues[card.ID]
|
||||||
createdKey, _ := attrView.GetKey(value.Value.KeyID)
|
createdKey, _ := attrView.GetKey(value.Value.KeyID)
|
||||||
keyValues = append(keyValues, &av.KeyValues{Key: createdKey, Values: []*av.Value{{ID: value.Value.ID, KeyID: createdKey.ID, BlockID: card.ID, Type: av.KeyTypeCreated, Created: value.Value.Created}}})
|
keyValues = append(keyValues, &av.KeyValues{Key: createdKey, Values: []*av.Value{{ID: value.Value.ID, KeyID: createdKey.ID, BlockID: card.ID, Type: av.KeyTypeCreated, Created: value.Value.Created}}})
|
||||||
cards[card.ID] = keyValues
|
cardsValues[card.ID] = keyValues
|
||||||
case av.KeyTypeUpdated: // 渲染更新时间
|
case av.KeyTypeUpdated: // 渲染更新时间
|
||||||
ial := ials[card.ID]
|
ial := ials[card.ID]
|
||||||
if nil == ial {
|
if nil == ial {
|
||||||
|
|
@ -299,10 +301,10 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keyValues := cards[card.ID]
|
keyValues := cardsValues[card.ID]
|
||||||
updatedKey, _ := attrView.GetKey(value.Value.KeyID)
|
updatedKey, _ := attrView.GetKey(value.Value.KeyID)
|
||||||
keyValues = append(keyValues, &av.KeyValues{Key: updatedKey, Values: []*av.Value{{ID: value.Value.ID, KeyID: updatedKey.ID, BlockID: card.ID, Type: av.KeyTypeUpdated, Updated: value.Value.Updated}}})
|
keyValues = append(keyValues, &av.KeyValues{Key: updatedKey, Values: []*av.Value{{ID: value.Value.ID, KeyID: updatedKey.ID, BlockID: card.ID, Type: av.KeyTypeUpdated, Updated: value.Value.Updated}}})
|
||||||
cards[card.ID] = keyValues
|
cardsValues[card.ID] = keyValues
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -314,7 +316,7 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
for _, value := range card.Values {
|
for _, value := range card.Values {
|
||||||
switch value.ValueType {
|
switch value.ValueType {
|
||||||
case av.KeyTypeTemplate: // 渲染模板字段
|
case av.KeyTypeTemplate: // 渲染模板字段
|
||||||
keyValues := cards[card.ID]
|
keyValues := cardsValues[card.ID]
|
||||||
ial := ials[card.ID]
|
ial := ials[card.ID]
|
||||||
if nil == ial {
|
if nil == ial {
|
||||||
ial = map[string]string{}
|
ial = map[string]string{}
|
||||||
|
|
@ -388,3 +390,56 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fillGalleryCardCover(attrView *av.AttributeView, view *av.View, cardValues []*av.KeyValues, galleryCard av.GalleryCard, cardID string) {
|
||||||
|
switch view.Gallery.CoverFrom {
|
||||||
|
case av.CoverFromNone:
|
||||||
|
case av.CoverFromContentImage:
|
||||||
|
blockValue := getBlockValue(cardValues)
|
||||||
|
if !blockValue.IsDetached {
|
||||||
|
tree := loadTreeByBlockID(blockValue.BlockID)
|
||||||
|
if nil == tree {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
node := treenode.GetNodeInTree(tree, blockValue.BlockID)
|
||||||
|
if nil == node {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if ast.NodeDocument == node.Type {
|
||||||
|
if titleImg := node.IALAttr("title-img"); "" != titleImg {
|
||||||
|
galleryCard.CoverURL = titleImg
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||||
|
if !entering {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ast.NodeImage != n.Type {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
dest := n.ChildByType(ast.NodeLinkDest)
|
||||||
|
if nil == dest {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
galleryCard.CoverURL = dest.TokensStr()
|
||||||
|
return ast.WalkStop
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case av.CoverFromAssetField:
|
||||||
|
if "" == view.Gallery.CoverFromAssetKeyID {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
assetValue := attrView.GetValue(view.Gallery.CoverFromAssetKeyID, cardID)
|
||||||
|
if nil == assetValue || 1 > len(assetValue.MAsset) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
galleryCard.CoverURL = assetValue.MAsset[0].Content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue