go-common/app/interface/main/app-card/model/card/double.go
2019-04-22 18:49:16 +08:00

1131 lines
37 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package card
import (
"strconv"
"go-common/app/interface/main/app-card/model"
"go-common/app/interface/main/app-card/model/bplus"
"go-common/app/interface/main/app-card/model/card/ai"
"go-common/app/interface/main/app-card/model/card/audio"
"go-common/app/interface/main/app-card/model/card/bangumi"
"go-common/app/interface/main/app-card/model/card/cm"
"go-common/app/interface/main/app-card/model/card/live"
"go-common/app/interface/main/app-card/model/card/operate"
"go-common/app/interface/main/app-card/model/card/show"
tag "go-common/app/interface/main/tag/model"
article "go-common/app/interface/openplatform/article/model"
account "go-common/app/service/main/account/model"
"go-common/app/service/main/archive/model/archive"
relation "go-common/app/service/main/relation/model"
episodegrpc "go-common/app/service/openplatform/pgc-season/api/grpc/episode/v1"
season "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
"go-common/library/log"
)
func doubleHandle(cardGoto model.CardGt, cardType model.CardType, rcmd *ai.Item, tagm map[int64]*tag.Tag, isAttenm map[int64]int8, statm map[int64]*relation.Stat, cardm map[int64]*account.Card) (hander Handler) {
base := &Base{CardType: cardType, CardGoto: cardGoto, Rcmd: rcmd, Tagm: tagm, IsAttenm: isAttenm, Statm: statm, Cardm: cardm, Columnm: model.ColumnSvrDouble}
switch cardType {
case model.ThreePicV2:
base.CardLen = 1
hander = &ThreePicV2{Base: base}
case model.SmallCoverV2:
base.CardLen = 1
hander = &SmallCoverV2{Base: base}
case model.OptionsV2:
hander = &Option{Base: base}
case model.OnePicV2:
base.CardLen = 1
hander = &OnePicV2{Base: base}
case model.Select:
hander = &Select{Base: base}
default:
switch cardGoto {
case model.CardGotoAv, model.CardGotoLive, model.CardGotoArticleS, model.CardGotoSpecialS, model.CardGotoShoppingS, model.CardGotoAudio, model.CardGotoGameDownloadS, model.CardGotoBangumi, model.CardGotoMoe, model.CardGotoPGC:
base.CardType = model.SmallCoverV2
base.CardLen = 1
hander = &SmallCoverV2{Base: base}
case model.CardGotoAdAv:
base.CardType = model.CmV2
base.CardLen = 1
hander = &SmallCoverV2{Base: base}
case model.CardGotoChannelRcmd, model.CardGotoUpRcmdAv:
base.CardType = model.SmallCoverV3
base.CardLen = 1
hander = &SmallCoverV3{Base: base}
case model.CardGotoSpecial:
base.CardType = model.MiddleCoverV2
hander = &MiddleCover{Base: base}
case model.CardGotoPlayer, model.CardGotoPlayerLive:
base.CardType = model.LargeCoverV2
hander = &LargeCoverV2{Base: base}
case model.CardGotoSubscribe, model.CardGotoSearchSubscribe:
base.CardType = model.ThreeItemHV2
hander = &ThreeItemH{Base: base}
case model.CardGotoLiveUpRcmd:
base.CardType = model.TwoItemV2
return &TwoItemV2{Base: base}
case model.CardGotoConverge, model.CardGotoRank:
base.CardType = model.ThreeItemV2
hander = &ThreeItemV2{Base: base}
case model.CardGotoBangumiRcmd:
base.CardType = model.SmallCoverV4
hander = &SmallCoverV4{Base: base}
case model.CardGotoLogin:
base.CardType = model.CoverOnlyV2
base.CardLen = 1
return &CoverOnly{Base: base}
case model.CardGotoBanner:
base.CardType = model.BannerV2
return &Banner{Base: base}
case model.CardGotoAdWebS:
base.CardType = model.CmV2
base.CardLen = 1
hander = &SmallCoverV2{Base: base}
case model.CardGotoAdWeb:
base.CardType = model.CmV2
hander = &MiddleCover{Base: base}
case model.CardGotoNews:
base.CardType = model.News
hander = &Text{Base: base}
case model.CardGotoEntrance:
base.CardType = model.MultiItemH
hander = &MultiItem{Base: base}
case model.CardGotoTagRcmd, model.CardGotoContentRcmd:
base.CardType = model.MultiItem
hander = &MultiItem{Base: base}
}
}
return
}
type SmallCoverV2 struct {
*Base
CoverBlur model.BlurStatus `json:"cover_blur,omitempty"`
CoverLeftText1 string `json:"cover_left_text_1,omitempty"`
CoverLeftIcon1 model.Icon `json:"cover_left_icon_1,omitempty"`
CoverLeftText2 string `json:"cover_left_text_2,omitempty"`
CoverLeftIcon2 model.Icon `json:"cover_left_icon_2,omitempty"`
CoverRightText string `json:"cover_right_text,omitempty"`
CoverRightIcon model.Icon `json:"cover_right_icon,omitempty"`
CoverRightBackgroundColor string `json:"cover_right_background_color,omitempty"`
Subtitle string `json:"subtitle,omitempty"`
Badge string `json:"badge,omitempty"`
RcmdReason string `json:"rcmd_reason,omitempty"`
DescButton *Button `json:"desc_button,omitempty"`
Desc string `json:"desc,omitempty"`
Avatar *Avatar `json:"avatar,omitempty"`
OfficialIcon model.Icon `json:"official_icon,omitempty"`
CanPlay int32 `json:"can_play,omitempty"`
RcmdReasonStyle *ReasonStyle `json:"rcmd_reason_style,omitempty"`
}
func (c *SmallCoverV2) From(main interface{}, op *operate.Card) {
if op == nil {
return
}
var (
upID int64
button interface{}
avatar *AvatarStatus
)
switch main.(type) {
case map[int64]*archive.ArchiveWithPlayer:
am := main.(map[int64]*archive.ArchiveWithPlayer)
a, ok := am[op.ID]
if !ok {
return
}
switch op.CardGoto {
case model.CardGotoAdAv:
if !model.AdAvIsNormal(a) {
return
}
c.AdInfo = op.AdInfo
default:
if !model.AvIsNormal(a) {
return
}
}
c.Base.from(op.Param, a.Pic, a.Title, model.GotoAv, strconv.FormatInt(a.Aid, 10), model.AvPlayHandler(a.Archive3, a.PlayerInfo, op.TrackID))
// c.CoverLeftText1 = model.RecommendString(a.Stat.Like, a.Stat.DisLike)
c.CoverLeftText1 = model.StatString(a.Stat.View, "")
c.CoverLeftIcon1 = model.IconPlay
c.CoverLeftText2 = model.StatString(a.Stat.Danmaku, "")
c.CoverLeftIcon2 = model.IconDanmaku
if op.SwitchLike == model.SwitchFeedIndexLike {
c.CoverLeftText1 = model.StatString(a.Stat.Like, "")
c.CoverLeftIcon1 = model.IconLike
c.CoverLeftText2 = model.StatString(a.Stat.View, "")
c.CoverLeftIcon2 = model.IconPlay
}
c.CoverRightText = model.DurationString(a.Duration)
if c.Rcmd != nil {
c.RcmdReason, c.Desc = rcmdReason(c.Rcmd.RcmdReason, a.Author.Name, c.IsAttenm[a.Author.Mid], c.Cardm)
c.RcmdReasonStyle = topReasonStyleFrom(c.Rcmd, c.RcmdReason, c.Base.Goto)
}
if c.RcmdReason == "" {
if t, ok := c.Tagm[op.Tid]; ok {
tag := &tag.Tag{}
*tag = *t
tag.Name = a.TypeName + " · " + tag.Name
button = tag
} else {
button = &ButtonStatus{Text: a.TypeName}
}
}
c.Base.PlayerArgs = playerArgsFrom(a.Archive3)
c.Args.fromArchive(a.Archive3, c.Tagm[op.Tid])
c.CanPlay = a.Rights.Autoplay
upID = a.Author.Mid
switch op.CardGoto {
case model.CardGotoAdAv:
c.AdInfo = op.AdInfo
}
case map[int64]*bangumi.Season:
sm := main.(map[int64]*bangumi.Season)
s, ok := sm[op.ID]
if !ok {
return
}
c.Base.from(s.EpisodeID, s.Cover, s.Title, model.GotoBangumi, s.EpisodeID, nil)
c.CoverLeftText1 = model.StatString(s.PlayCount, "")
c.CoverLeftIcon1 = model.IconPlay
c.CoverLeftText2 = model.StatString(s.Favorites, "")
c.CoverLeftIcon2 = model.BangumiIcon(s.SeasonType)
c.Badge = s.TypeBadge
c.Subtitle = s.UpdateDesc
case map[int32]*season.CardInfoProto:
sm := main.(map[int32]*season.CardInfoProto)
s, ok := sm[int32(op.ID)]
if !ok {
return
}
c.Base.from(op.Param, s.Cover, s.Title, model.GotoPGC, op.URI, nil)
c.CoverLeftText1 = model.StatString(int32(s.Stat.View), "")
c.CoverLeftIcon1 = model.IconPlay
if s.Stat != nil {
c.CoverLeftText2 = model.StatString(int32(s.Stat.Follow), "")
}
c.CoverLeftIcon2 = model.BangumiIcon(int8(s.SeasonType))
c.Badge = s.SeasonTypeName
if s.NewEp != nil {
c.Subtitle = s.NewEp.IndexShow
}
case map[int32]*episodegrpc.EpisodeCardsProto:
sm := main.(map[int32]*episodegrpc.EpisodeCardsProto)
s, ok := sm[int32(op.ID)]
if !ok {
return
}
title := s.Season.Title + "" + s.ShowTitle
c.Base.from(op.Param, s.Cover, title, model.GotoBangumi, op.URI, nil)
c.Goto = model.GotoPGC
c.CoverLeftText1 = model.StatString(int32(s.Season.Stat.View), "")
c.CoverLeftIcon1 = model.IconPlay
if s.Season.Stat != nil {
c.CoverLeftText2 = model.StatString(int32(s.Season.Stat.Follow), "")
}
c.CoverLeftIcon2 = model.BangumiIcon(int8(s.Season.SeasonType))
c.Badge = s.Season.SeasonTypeName
if s.Season != nil {
c.Subtitle = s.Season.NewEpShow
}
case map[int64]*live.Room:
rm := main.(map[int64]*live.Room)
r, ok := rm[op.ID]
if !ok || r.LiveStatus != 1 {
return
}
c.Base.from(op.Param, r.Cover, r.Title, model.GotoLive, strconv.FormatInt(r.RoomID, 10), model.LiveRoomHandler(r))
c.CoverLeftText1 = model.StatString(r.Online, "")
c.CoverLeftIcon1 = model.IconOnline
c.CoverRightText = r.Uname
c.Badge = "直播"
c.Base.PlayerArgs = playerArgsFrom(r)
c.Args.fromLiveRoom(r)
if c.Rcmd != nil && (c.Rcmd.RcmdReason != nil || c.IsAttenm[r.UID] == 1) {
c.RcmdReason, c.Desc = rcmdReason(c.Rcmd.RcmdReason, "", c.IsAttenm[r.UID], c.Cardm)
c.RcmdReasonStyle = topReasonStyleFrom(c.Rcmd, c.RcmdReason, c.Base.Goto)
} else {
button = r
}
upID = r.UID
c.CanPlay = 1
case map[int64]*show.Shopping:
sm := main.(map[int64]*show.Shopping)
s, ok := sm[op.ID]
if !ok {
return
}
c.Base.from(op.Param, model.ShoppingCover(s.PerformanceImage), s.Name, model.GotoWeb, s.URL, nil)
if s.Type == 1 {
c.CoverLeftText1 = model.ShoppingDuration(s.STime, s.ETime)
c.CoverRightText = s.CityName
c.CoverRightIcon = model.IconLocation
if len(s.Tags) != 0 {
c.Desc = s.Tags[0].TagName
}
} else if s.Type == 2 {
c.CoverLeftText1 = s.Want
c.Desc = s.Subname
}
c.Badge = "会员购"
c.Args.fromShopping(s)
case map[int64]*audio.Audio:
am := main.(map[int64]*audio.Audio)
a, ok := am[op.ID]
if !ok {
return
}
c.Base.from(op.Param, a.CoverURL, a.Title, model.GotoAudio, strconv.FormatInt(a.MenuID, 10), nil)
c.CoverBlur = model.BlurYes
c.CoverLeftText1 = model.StatString(a.PlayNum, "")
c.CoverLeftIcon1 = model.IconHeadphone
c.CoverRightText = model.AudioTotalStirng(a.RecordNum)
c.Badge = model.AudioBadgeString(a.Type)
button = a.Ctgs
c.Args.fromAudio(a)
case map[int64]*article.Meta:
mm := main.(map[int64]*article.Meta)
m, ok := mm[op.ID]
if !ok {
return
}
if len(m.ImageURLs) == 0 {
return
}
c.Base.from(op.Param, m.ImageURLs[0], m.Title, model.GotoArticle, strconv.FormatInt(m.ID, 10), nil)
if m.Stats != nil {
c.CoverLeftText1 = model.StatString(int32(m.Stats.View), "")
c.CoverLeftIcon1 = model.IconRead
c.CoverLeftText2 = model.StatString(int32(m.Stats.Reply), "")
c.CoverLeftIcon2 = model.IconComment
}
button = m.Categories
c.Badge = "文章"
c.Args.fromArticle(m)
case map[int64]*bplus.Picture:
pm := main.(map[int64]*bplus.Picture)
p, ok := pm[op.ID]
if !ok || len(p.Imgs) == 0 || p.ViewCount == 0 {
return
}
c.Base.from(op.Param, p.Imgs[0], p.DynamicText, model.GotoPicture, strconv.FormatInt(p.DynamicID, 10), nil)
c.CoverLeftText1 = model.StatString(int32(p.ViewCount), "")
c.CoverLeftIcon1 = model.IconRead
if p.ImgCount > 1 {
c.CoverRightText = model.PictureCountString(p.ImgCount)
c.CoverRightBackgroundColor = "#66666666"
}
if c.Rcmd != nil && c.Rcmd.RcmdReason != nil {
c.RcmdReason, _ = rcmdReason(c.Rcmd.RcmdReason, p.NickName, c.IsAttenm[p.Mid], c.Cardm)
c.RcmdReasonStyle = topReasonStyleFrom(c.Rcmd, c.RcmdReason, c.Base.Goto)
} else {
button = p
c.Badge = "动态"
}
case *cm.AdInfo:
ad := main.(*cm.AdInfo)
c.AdInfo = ad
case *bangumi.Moe:
m := main.(*bangumi.Moe)
if m == nil {
return
}
c.Base.from(strconv.FormatInt(m.ID, 10), m.Square, m.Title, model.GotoWeb, m.Link, nil)
c.Desc = m.Desc
c.Badge = m.Badge
case nil:
if op == nil {
return
}
c.Base.from(op.Param, op.Coverm[c.Columnm], op.Title, op.Goto, op.URI, nil)
switch op.CardGoto {
case model.CardGotoDownload:
c.CoverLeftText1 = model.DownloadString(op.Download)
avatar = &AvatarStatus{Cover: op.Avatar, Goto: op.Goto, Param: op.URI, Type: model.AvatarSquare}
c.Desc = op.Desc
case model.CardGotoSpecial:
c.Desc = op.Desc
c.Badge = op.Badge
default:
log.Warn("SmallCoverV2 From: unexpected card_goto %s", op.CardGoto)
return
}
default:
log.Warn("SmallCoverV2 From: unexpected type %T", main)
return
}
c.OfficialIcon = model.OfficialIcon(c.Cardm[upID])
c.Avatar = avatarFrom(avatar)
c.DescButton = buttonFrom(button, op.Plat)
c.Right = true
}
func (c *SmallCoverV2) Get() *Base {
return c.Base
}
type SmallCoverV3 struct {
*Base
Avatar *Avatar `json:"avatar,omitempty"`
CoverLeftText string `json:"cover_left_text,omitempty"`
CoverRightButton *Button `json:"cover_right_button,omitempty"`
RcmdReason string `json:"rcmd_reason,omitempty"`
Desc string `json:"desc,omitempty"`
DescButton *Button `json:"desc_button,omitempty"`
OfficialIcon model.Icon `json:"official_icon,omitempty"`
CanPlay int32 `json:"can_play,omitempty"`
RcmdReasonStyle *ReasonStyle `json:"rcmd_reason_style,omitempty"`
}
func (c *SmallCoverV3) From(main interface{}, op *operate.Card) {
if op == nil {
return
}
var (
button interface{}
descButton interface{}
)
switch main.(type) {
case map[int64]*archive.ArchiveWithPlayer:
am := main.(map[int64]*archive.ArchiveWithPlayer)
a, ok := am[op.ID]
if !ok || !model.AvIsNormal(a) {
return
}
c.Base.from(op.Param, a.Pic, a.Title, model.GotoAv, op.URI, model.AvPlayHandler(a.Archive3, a.PlayerInfo, op.TrackID))
switch op.CardGoto {
case model.CardGotoUpRcmdAv:
c.Avatar = avatarFrom(&AvatarStatus{Cover: a.Author.Face, Goto: model.GotoMid, Param: strconv.FormatInt(a.Author.Mid, 10), Type: model.AvatarRound})
c.CoverLeftText = a.Author.Name
if c.Rcmd != nil && c.Rcmd.RcmdReason != nil {
c.RcmdReason, _ = rcmdReason(c.Rcmd.RcmdReason, "", c.IsAttenm[a.Author.Mid], c.Cardm)
c.RcmdReasonStyle = topReasonStyleFrom(c.Rcmd, c.RcmdReason, c.Base.Goto)
} else {
descButton = c.Tagm[op.Tid]
}
button = &ButtonStatus{Goto: model.GotoMid, Param: strconv.FormatInt(a.Author.Mid, 10), IsAtten: c.IsAttenm[a.Author.Mid]}
c.Base.PlayerArgs = playerArgsFrom(a.Archive3)
c.Args.fromArchive(a.Archive3, c.Tagm[op.Tid])
case model.CardGotoChannelRcmd:
t, ok := c.Tagm[op.Tid]
if !ok {
return
}
c.Avatar = avatarFrom(&AvatarStatus{Cover: t.Cover, Goto: model.GotoTag, Param: strconv.FormatInt(t.ID, 10), Type: model.AvatarSquare})
c.CoverLeftText = t.Name
c.Desc = model.SubscribeString(int32(t.Count.Atten))
button = &ButtonStatus{Goto: model.GotoTag, Param: strconv.FormatInt(t.ID, 10), IsAtten: t.IsAtten}
c.Base.PlayerArgs = playerArgsFrom(a.Archive3)
c.Args.fromArchive(a.Archive3, c.Tagm[op.Tid])
default:
log.Warn("SmallCoverV3 From: unexpected card_goto %s", op.CardGoto)
return
}
c.CanPlay = a.Rights.Autoplay
default:
log.Warn("SmallCoverV3 From: unexpected type %T", main)
return
}
c.CoverRightButton = buttonFrom(button, op.Plat)
c.DescButton = buttonFrom(descButton, op.Plat)
c.Right = true
}
func (c *SmallCoverV3) Get() *Base {
return c.Base
}
type MiddleCoverV2 struct {
*Base
Ratio int `json:"ratio,omitempty"`
Desc string `json:"desc,omitempty"`
Badge string `json:"badge,omitempty"`
}
func (c *MiddleCoverV2) Get() *Base {
return c.Base
}
type LargeCoverV2 struct {
*Base
Avatar *Avatar `json:"avatar,omitempty"`
Badge string `json:"badge,omitempty"`
CoverRightButton *Button `json:"cover_right_button,omitempty"`
CoverLeftText1 string `json:"cover_left_text_1,omitempty"`
CoverLeftIcon1 model.Icon `json:"cover_left_icon_1,omitempty"`
CoverLeftText2 string `json:"cover_left_text_2,omitempty"`
CoverLeftIcon2 model.Icon `json:"cover_left_icon_2,omitempty"`
RcmdReason string `json:"rcmd_reason,omitempty"`
DescButton *Button `json:"desc_button,omitempty"`
OfficialIcon model.Icon `json:"official_icon,omitempty"`
CanPlay int32 `json:"can_play,omitempty"`
RcmdReasonStyle *ReasonStyle `json:"rcmd_reason_style,omitempty"`
}
func (c *LargeCoverV2) From(main interface{}, op *operate.Card) {
if op == nil {
return
}
var (
button interface{}
coverButton interface{}
upID int64
)
switch main.(type) {
case map[int64]*archive.ArchiveWithPlayer:
am := main.(map[int64]*archive.ArchiveWithPlayer)
a, ok := am[op.ID]
if !ok || !model.AvIsNormal(a) {
return
}
c.Base.from(op.Param, a.Pic, a.Title, model.GotoAv, op.URI, model.AvPlayHandler(a.Archive3, a.PlayerInfo, op.TrackID))
c.Avatar = avatarFrom(&AvatarStatus{Cover: a.Author.Face, Text: a.Author.Name, Goto: model.GotoMid, Param: strconv.FormatInt(a.Author.Mid, 10), Type: model.AvatarRound})
c.CoverLeftText1 = model.StatString(a.Stat.View, "")
c.CoverLeftIcon1 = model.IconPlay
c.CoverLeftText2 = model.StatString(a.Stat.Danmaku, "")
c.CoverLeftIcon2 = model.IconDanmaku
if op.SwitchLike == model.SwitchFeedIndexLike {
c.CoverLeftText1 = model.StatString(a.Stat.Like, "")
c.CoverLeftIcon1 = model.IconLike
c.CoverLeftText2 = model.StatString(a.Stat.View, "")
c.CoverLeftIcon2 = model.IconPlay
}
coverButton = &ButtonStatus{Goto: model.GotoMid, Param: strconv.FormatInt(a.Author.Mid, 10), IsAtten: c.IsAttenm[a.Author.Mid]}
if c.Rcmd != nil && c.Rcmd.RcmdReason != nil {
c.RcmdReason, _ = rcmdReason(c.Rcmd.RcmdReason, "", c.IsAttenm[a.Author.Mid], c.Cardm)
c.RcmdReasonStyle = topReasonStyleFrom(c.Rcmd, c.RcmdReason, c.Base.Goto)
} else if t, ok := c.Tagm[op.Tid]; ok {
tag := &tag.Tag{}
*tag = *t
tag.Name = a.TypeName + " · " + tag.Name
button = tag
} else {
button = &ButtonStatus{Text: a.TypeName}
}
c.CanPlay = a.Rights.Autoplay
c.Base.PlayerArgs = playerArgsFrom(a.Archive3)
if op.CardGoto == model.CardGotoPlayer && c.Base.PlayerArgs == nil {
log.Warn("player card aid(%d) can't auto player", a.Aid)
return
}
c.Args.fromArchive(a.Archive3, c.Tagm[op.Tid])
upID = a.Author.Mid
case map[int64]*live.Room:
rm := main.(map[int64]*live.Room)
r, ok := rm[op.ID]
if !ok || r.LiveStatus != 1 {
return
}
c.Base.from(op.Param, r.Cover, r.Title, model.GotoLive, op.URI, model.LiveRoomHandler(r))
c.Avatar = avatarFrom(&AvatarStatus{Cover: r.Face, Text: r.Uname, Goto: model.GotoMid, Param: strconv.FormatInt(r.UID, 10), Type: model.AvatarRound})
c.CoverLeftText1 = model.StatString(r.Online, "")
c.CoverLeftIcon1 = model.IconOnline
coverButton = &ButtonStatus{Goto: model.GotoMid, Param: strconv.FormatInt(r.UID, 10), IsAtten: c.IsAttenm[r.UID]}
if c.Rcmd != nil && (c.Rcmd.RcmdReason != nil || c.IsAttenm[r.UID] == 1) {
c.RcmdReason, _ = rcmdReason(c.Rcmd.RcmdReason, r.Uname, c.IsAttenm[r.UID], c.Cardm)
c.RcmdReasonStyle = topReasonStyleFrom(c.Rcmd, c.RcmdReason, c.Base.Goto)
} else {
button = r
}
c.Badge = "直播"
c.CanPlay = 1
c.Base.PlayerArgs = playerArgsFrom(r)
c.Args.fromLiveRoom(r)
upID = r.UID
default:
log.Warn("MiddleCoverV2 From: unexpected type %T", main)
return
}
c.DescButton = buttonFrom(button, op.Plat)
c.CoverRightButton = buttonFrom(coverButton, op.Plat)
c.OfficialIcon = model.OfficialIcon(c.Cardm[upID])
c.Right = true
}
func (c *LargeCoverV2) Get() *Base {
return c.Base
}
type ThreeItemV2 struct {
*Base
TitleIcon model.Icon `json:"title_icon,omitempty"`
MoreURI string `json:"more_uri,omitempty"`
MoreText string `json:"more_text,omitempty"`
Items []*ThreeItemV2Item `json:"items,omitempty"`
}
type ThreeItemV2Item struct {
Base
CoverLeftIcon model.Icon `json:"cover_left_icon,omitempty"`
DescText1 string `json:"desc_text_1,omitempty"`
DescIcon1 model.Icon `json:"desc_icon_1,omitempty"`
DescText2 string `json:"desc_text_2,omitempty"`
DescIcon2 model.Icon `json:"desc_icon_2,omitempty"`
Badge string `json:"badge,omitempty"`
}
func (c *ThreeItemV2) From(main interface{}, op *operate.Card) {
switch main.(type) {
case map[model.Gt]interface{}:
intfcm := main.(map[model.Gt]interface{})
if op == nil {
return
}
switch op.CardGoto {
case model.CardGotoRank:
const (
_title = "全站排行榜"
_limit = 3
)
c.Base.from("0", "", _title, "", "", nil)
c.TitleIcon = model.IconRank
c.MoreURI = model.FillURI(op.Goto, op.URI, nil)
c.MoreText = "查看更多"
c.Items = make([]*ThreeItemV2Item, 0, _limit)
for _, v := range op.Items {
if v == nil {
continue
}
intfc, ok := intfcm[v.Goto]
if !ok {
continue
}
var item *ThreeItemV2Item
switch intfc.(type) {
case map[int64]*archive.ArchiveWithPlayer:
am := intfc.(map[int64]*archive.ArchiveWithPlayer)
a, ok := am[v.ID]
if !ok || !model.AvIsNormal(a) {
continue
}
item = &ThreeItemV2Item{
DescText1: model.ScoreString(v.Score),
}
item.Base.from(v.Param, a.Pic, a.Title, model.GotoAv, v.URI, model.AvPlayHandler(a.Archive3, a.PlayerInfo, op.TrackID))
item.Args.fromArchive(a.Archive3, nil)
default:
log.Warn("ThreeItemV2 From: unexpected type %T", intfc)
continue
}
c.Items = append(c.Items, item)
if len(c.Items) == _limit {
break
}
}
if len(c.Items) < _limit {
return
}
c.Items[0].CoverLeftIcon = model.IconGoldMedal
c.Items[1].CoverLeftIcon = model.IconSilverMedal
c.Items[2].CoverLeftIcon = model.IconBronzeMedal
case model.CardGotoConverge:
limit := 3
if op.Coverm[c.Columnm] != "" {
limit = 2
}
c.Base.from(op.Param, op.Coverm[c.Columnm], op.Title, op.Goto, op.URI, nil)
c.MoreURI = model.FillURI(model.GotoConverge, op.Param, nil)
c.MoreText = "查看更多"
c.Items = make([]*ThreeItemV2Item, 0, len(op.Items))
for _, v := range op.Items {
if v == nil {
continue
}
intfc, ok := intfcm[v.Goto]
if !ok {
continue
}
var item *ThreeItemV2Item
switch intfc.(type) {
case map[int64]*archive.ArchiveWithPlayer:
am := intfc.(map[int64]*archive.ArchiveWithPlayer)
a, ok := am[v.ID]
if !ok || !model.AvIsNormal(a) {
continue
}
item = &ThreeItemV2Item{
DescText1: model.StatString(a.Stat.View, ""),
DescIcon1: model.IconPlay,
DescText2: model.StatString(a.Stat.Danmaku, ""),
DescIcon2: model.IconDanmaku,
}
if op.SwitchLike == model.SwitchFeedIndexLike {
item.DescText1 = model.StatString(a.Stat.Like, "")
item.DescIcon1 = model.IconLike
item.DescText2 = model.StatString(a.Stat.View, "")
item.DescIcon2 = model.IconPlay
}
item.Base.from(v.Param, a.Pic, a.Title, model.GotoAv, v.URI, model.AvPlayHandler(a.Archive3, a.PlayerInfo, op.TrackID))
item.Args.fromArchive(a.Archive3, nil)
case map[int64]*live.Room:
rm := intfc.(map[int64]*live.Room)
r, ok := rm[v.ID]
if !ok || r.LiveStatus != 1 {
continue
}
item = &ThreeItemV2Item{
DescText1: model.StatString(r.Online, ""),
DescIcon1: model.IconOnline,
Badge: "直播",
}
item.Base.from(v.Param, r.Cover, r.Title, model.GotoLive, v.URI, model.LiveRoomHandler(r))
item.Args.fromLiveRoom(r)
case map[int64]*article.Meta:
mm := intfc.(map[int64]*article.Meta)
m, ok := mm[v.ID]
if !ok {
continue
}
if len(m.ImageURLs) == 0 {
continue
}
item = &ThreeItemV2Item{
Badge: "文章",
}
item.Base.from(v.Param, m.ImageURLs[0], m.Title, model.GotoArticle, v.URI, nil)
if m.Stats != nil {
item.DescText1 = model.StatString(int32(m.Stats.View), "")
item.DescIcon1 = model.IconRead
item.DescText2 = model.StatString(int32(m.Stats.Reply), "")
item.DescIcon2 = model.IconComment
}
item.Args.fromArticle(m)
default:
log.Warn("ThreeItemV2 From: unexpected type %T", intfc)
continue
}
c.Items = append(c.Items, item)
if len(c.Items) == limit {
break
}
}
if len(c.Items) < limit {
return
}
default:
log.Warn("ThreeItemV2 From: unexpected card_goto %s", op.CardGoto)
return
}
default:
log.Warn("ThreeItemV2 From: unexpected type %T", main)
return
}
c.Right = true
}
func (c *ThreeItemV2) Get() *Base {
return c.Base
}
type SmallCoverV4 struct {
*Base
CoverBadge string `json:"cover_badge,omitempty"`
Desc string `json:"desc,omitempty"`
TitleRightText string `json:"title_right_text,omitempty"`
TitleRightPic model.Icon `json:"title_right_pic,omitempty"`
}
func (c *SmallCoverV4) From(main interface{}, op *operate.Card) {
switch main.(type) {
case *bangumi.Update:
title := "你的追番更新啦"
const (
_updates = 99
)
u := main.(*bangumi.Update)
if u == nil || u.Updates == 0 {
return
}
emojim := map[string]struct{}{
"(´∀`*)ウフフ": struct{}{},
"ヾ( ・∀・)ノ": struct{}{},
"(`・ω・´)ゞ": struct{}{},
"(・∀・)イイ!!": struct{}{},
}
for emoji := range emojim {
title = title + emoji
break
}
c.Base.from("", u.SquareCover, title, "", "", nil)
updates := u.Updates
if updates > _updates {
updates = _updates
c.TitleRightPic = model.IconBomb
} else {
c.TitleRightPic = model.IconTV
}
c.Desc = u.Title
c.TitleRightText = strconv.Itoa(updates)
default:
log.Warn("SmallCoverV4 From: unexpected type %T", main)
return
}
c.Right = true
}
func (c *SmallCoverV4) Get() *Base {
return c.Base
}
type TwoItemV2 struct {
*Base
Items []*TwoItemV2Item `json:"items,omitempty"`
}
type TwoItemV2Item struct {
Base
Badge string `json:"badge,omitempty"`
CoverLeftText1 string `json:"cover_left_text_1,omitempty"`
CoverLeftIcon1 model.Icon `json:"cover_left_icon_1,omitempty"`
DescButton *Button `json:"desc_button,omitempty"`
}
func (c *TwoItemV2) From(main interface{}, op *operate.Card) {
if op == nil {
return
}
switch main.(type) {
case map[int64][]*live.Card:
const _limit = 2
csm := main.(map[int64][]*live.Card)
cs, ok := csm[op.ID]
if !ok {
return
}
c.Base.from(op.Param, "", "", "", "", nil)
c.Items = make([]*TwoItemV2Item, 0, _limit)
for _, card := range cs {
if card == nil || card.LiveStatus != 1 {
continue
}
item := &TwoItemV2Item{
Badge: "直播",
CoverLeftText1: model.StatString(card.Online, ""),
CoverLeftIcon1: model.IconOnline,
}
item.DescButton = buttonFrom(card, op.Plat)
item.Base.from(strconv.FormatInt(card.RoomID, 10), card.ShowCover, card.Title, model.GotoLive, strconv.FormatInt(card.RoomID, 10), model.LiveUpHandler(card))
item.Args.fromLiveUp(card)
c.Items = append(c.Items, item)
if len(c.Items) == _limit {
break
}
}
}
c.Right = true
}
func (c *TwoItemV2) Get() *Base {
return c.Base
}
type MultiItem struct {
*Base
MoreURI string `json:"more_uri,omitempty"`
MoreText string `json:"more_text,omitempty"`
Items []Handler `json:"items,omitempty"`
}
func (c *MultiItem) From(main interface{}, op *operate.Card) {
if op == nil {
return
}
switch main.(type) {
case map[model.Gt]interface{}:
intfcm := main.(map[model.Gt]interface{})
switch op.CardGoto {
case model.CardGotoTagRcmd, model.CardGotoContentRcmd:
items := make([]Handler, 0, len(op.Items))
for _, v := range op.Items {
if v == nil {
continue
}
intfc, ok := intfcm[v.Goto]
if !ok {
continue
}
var hander Handler
switch intfc.(type) {
case map[int64]*archive.ArchiveWithPlayer:
am := intfc.(map[int64]*archive.ArchiveWithPlayer)
a, ok := am[v.ID]
if !ok || !model.AvIsNormal(a) {
continue
}
item := &SmallCoverV2{
CoverLeftText1: model.StatString(a.Stat.View, ""),
CoverLeftIcon1: model.IconPlay,
CoverLeftText2: model.StatString(a.Stat.Danmaku, ""),
CoverLeftIcon2: model.IconDanmaku,
CoverRightText: model.DurationString(a.Duration),
Base: &Base{CardType: model.SmallCoverV2},
}
if op.SwitchLike == model.SwitchFeedIndexLike {
item.CoverLeftText1 = model.StatString(a.Stat.Like, "")
item.CoverLeftIcon1 = model.IconLike
item.CoverLeftText2 = model.StatString(a.Stat.View, "")
item.CoverLeftIcon2 = model.IconPlay
}
item.Base.from(v.Param, a.Pic, a.Title, model.GotoAv, strconv.FormatInt(a.Aid, 10), model.AvPlayHandler(a.Archive3, a.PlayerInfo, op.TrackID))
item.Args.fromArchive(a.Archive3, nil)
if op.Switch == model.SwitchFeedIndexTabThreePoint {
item.TabThreePointWatchLater()
}
item.DescButton = buttonFrom(&ButtonStatus{Text: a.TypeName}, op.Plat)
hander = item
case map[int64]*live.Room:
rm := intfc.(map[int64]*live.Room)
r, ok := rm[v.ID]
if !ok || r.LiveStatus != 1 {
continue
}
item := &SmallCoverV2{
CoverLeftText1: model.StatString(r.Online, ""),
CoverLeftIcon1: model.IconOnline,
Badge: "直播",
Base: &Base{CardType: model.SmallCoverV2},
}
item.Base.from(v.Param, r.Cover, r.Title, model.GotoLive, strconv.FormatInt(r.RoomID, 10), model.LiveRoomHandler(r))
item.Args.fromLiveRoom(r)
item.DescButton = buttonFrom(r, op.Plat)
hander = item
case map[int64]*article.Meta:
mm := intfc.(map[int64]*article.Meta)
m, ok := mm[v.ID]
if !ok {
continue
}
if len(m.ImageURLs) == 0 {
continue
}
item := &SmallCoverV2{
Badge: "文章",
Base: &Base{CardType: model.SmallCoverV2},
}
item.Base.from(v.Param, m.ImageURLs[0], m.Title, model.GotoArticle, strconv.FormatInt(m.ID, 10), nil)
if m.Stats != nil {
item.CoverLeftText1 = model.StatString(int32(m.Stats.View), "")
item.CoverLeftIcon1 = model.IconRead
item.CoverLeftText2 = model.StatString(int32(m.Stats.Reply), "")
item.CoverLeftIcon2 = model.IconComment
}
item.Args.fromArticle(m)
item.DescButton = buttonFrom(m.Categories, op.Plat)
hander = item
case map[int64]*operate.Card:
dm := intfc.(map[int64]*operate.Card)
d, ok := dm[v.ID]
if !ok {
continue
}
item := &SmallCoverV2{
CoverLeftText1: model.DownloadString(d.Download),
Base: &Base{CardType: model.SmallCoverV2},
}
item.Base.from(v.Param, d.Coverm[c.Columnm], d.Title, d.Goto, d.URI, nil)
hander = item
case map[int64]*bangumi.Season:
sm := intfc.(map[int64]*bangumi.Season)
s, ok := sm[v.ID]
if !ok {
continue
}
item := &SmallCoverV2{
CoverLeftText1: model.StatString(s.PlayCount, ""),
CoverLeftIcon1: model.IconPlay,
CoverLeftText2: model.StatString(s.Favorites, ""),
CoverLeftIcon2: model.BangumiIcon(s.SeasonType),
Badge: s.TypeBadge,
Desc: s.UpdateDesc,
Base: &Base{CardType: model.SmallCoverV2},
}
item.Base.from(s.EpisodeID, s.Cover, s.Title, model.GotoBangumi, s.EpisodeID, nil)
hander = item
case map[int64]*bplus.Picture:
pm := intfc.(map[int64]*bplus.Picture)
p, ok := pm[v.ID]
if !ok {
continue
}
if len(p.Imgs) < 3 {
hander = &OnePicV2{Base: &Base{CardType: model.OnePicV2}}
} else {
hander = &ThreePicV2{Base: &Base{CardType: model.ThreePicV2}}
}
hander.From(pm, v)
if !hander.Get().Right {
continue
}
default:
log.Warn("MultiItem From: unexpected type %T", intfc)
continue
}
if hander != nil {
items = append(items, hander)
}
}
if len(items) < 2 {
return
}
if len(items)%2 != 0 {
c.Items = items[:len(items)-1]
} else {
c.Items = items
}
var title string
switch op.Goto {
case model.GotoTag:
if t, ok := c.Tagm[op.ID]; ok {
title = t.Name
}
default:
title = op.Title
}
c.Base.from(op.Param, "", title, "", "", nil)
c.MoreURI = model.FillURI(op.Goto, op.URI, nil)
c.MoreText = op.Subtitle
default:
log.Warn("MultiItem From: unexpected card_goto %s", op.CardGoto)
return
}
case nil:
switch op.CardGoto {
case model.CardGotoEntrance:
c.Items = make([]Handler, 0, len(op.Items))
for _, v := range op.Items {
item := &SmallCoverV2{Base: &Base{CardType: model.SmallCoverV2}}
item.Base.from(v.Param, v.Cover, v.Title, v.Goto, v.URI, nil)
c.Items = append(c.Items, item)
}
}
default:
log.Warn("MultiItem From: unexpected type %T", main)
return
}
c.Right = true
}
func (c *MultiItem) Get() *Base {
return c.Base
}
type ThreePicV2 struct {
*Base
LeftCover string `json:"left_cover,omitempty"`
RightCover1 string `json:"right_cover_1,omitempty"`
RightCover2 string `json:"right_cover_2,omitempty"`
CoverLeftText1 string `json:"cover_left_text_1,omitempty"`
CoverLeftIcon1 model.Icon `json:"cover_left_icon_1,omitempty"`
CoverLeftText2 string `json:"cover_left_text_2,omitempty"`
CoverLeftIcon2 model.Icon `json:"cover_left_icon_2,omitempty"`
CoverRightText string `json:"cover_right_text,omitempty"`
CoverRightIcon model.Icon `json:"cover_right_icon,omitempty"`
CoverRightBackgroundColor string `json:"cover_right_background_color,omitempty"`
Badge string `json:"badge,omitempty"`
RcmdReason string `json:"rcmd_reason,omitempty"`
DescButton *Button `json:"desc_button,omitempty"`
Desc string `json:"desc,omitempty"`
Avatar *Avatar `json:"avatar,omitempty"`
RcmdReasonStyle *ReasonStyle `json:"rcmd_reason_style,omitempty"`
}
func (c *ThreePicV2) From(main interface{}, op *operate.Card) {
var (
button interface{}
)
if op == nil {
return
}
switch main.(type) {
case map[int64]*bplus.Picture:
pm := main.(map[int64]*bplus.Picture)
p, ok := pm[op.ID]
if !ok || len(p.Imgs) < 3 || p.ViewCount == 0 {
return
}
c.Base.from(op.Param, "", p.DynamicText, model.GotoPicture, strconv.FormatInt(p.DynamicID, 10), nil)
c.LeftCover = p.Imgs[0]
c.RightCover1 = p.Imgs[1]
c.RightCover2 = p.Imgs[2]
c.CoverLeftText1 = model.StatString(int32(p.ViewCount), "")
c.CoverLeftIcon1 = model.IconRead
if p.ImgCount > 3 {
c.CoverRightText = model.PictureCountString(p.ImgCount)
c.CoverRightBackgroundColor = "#66666666"
}
if c.Rcmd != nil && c.Rcmd.RcmdReason != nil {
c.RcmdReason, c.Desc = rcmdReason(c.Rcmd.RcmdReason, p.NickName, c.IsAttenm[p.Mid], c.Cardm)
c.RcmdReasonStyle = topReasonStyleFrom(c.Rcmd, c.RcmdReason, c.Base.Goto)
} else {
button = p
c.Badge = "动态"
}
c.Avatar = avatarFrom(&AvatarStatus{Cover: p.FaceImg, Text: p.NickName, Goto: model.GotoDynamicMid, Param: strconv.FormatInt(p.Mid, 10), Type: model.AvatarRound})
default:
log.Warn("ThreePicV2 From: unexpected type %T", main)
return
}
c.DescButton = buttonFrom(button, op.Plat)
c.Right = true
}
func (c *ThreePicV2) Get() *Base {
return c.Base
}
type OnePicV2 struct {
*Base
CoverLeftText1 string `json:"cover_left_text_1,omitempty"`
CoverLeftIcon1 model.Icon `json:"cover_left_icon_1,omitempty"`
CoverRightText string `json:"cover_right_text,omitempty"`
CoverRightIcon model.Icon `json:"cover_right_icon,omitempty"`
CoverRightBackgroundColor string `json:"cover_right_background_color,omitempty"`
Badge string `json:"badge,omitempty"`
RcmdReason string `json:"rcmd_reason,omitempty"`
Avatar *Avatar `json:"avatar,omitempty"`
RcmdReasonStyle *ReasonStyle `json:"rcmd_reason_style,omitempty"`
}
func (c *OnePicV2) From(main interface{}, op *operate.Card) {
var (
button interface{}
)
if op == nil {
return
}
switch main.(type) {
case map[int64]*bplus.Picture:
pm := main.(map[int64]*bplus.Picture)
p, ok := pm[op.ID]
if !ok || len(p.Imgs) == 0 || p.ViewCount == 0 {
return
}
c.Base.from(op.Param, p.Imgs[0], p.DynamicText, model.GotoPicture, strconv.FormatInt(p.DynamicID, 10), nil)
c.CoverLeftText1 = model.StatString(int32(p.ViewCount), "")
c.CoverLeftIcon1 = model.IconRead
if p.ImgCount > 1 {
c.CoverRightText = model.PictureCountString(p.ImgCount)
c.CoverRightBackgroundColor = "#66666666"
}
if c.Rcmd != nil && c.Rcmd.RcmdReason != nil {
c.RcmdReason, _ = rcmdReason(c.Rcmd.RcmdReason, p.NickName, c.IsAttenm[p.Mid], c.Cardm)
c.RcmdReasonStyle = topReasonStyleFrom(c.Rcmd, c.RcmdReason, c.Base.Goto)
} else {
button = p
c.Badge = "动态"
}
c.Avatar = avatarFrom(&AvatarStatus{Cover: p.FaceImg, Text: p.NickName, Goto: model.GotoDynamicMid, Param: strconv.FormatInt(p.Mid, 10), Type: model.AvatarRound})
default:
log.Warn("OnePicV2 From: unexpected type %T", main)
return
}
c.DescButton = buttonFrom(button, op.Plat)
c.Right = true
}
func (c *OnePicV2) Get() *Base {
return c.Base
}