package handler
import (
"strconv"
"strings"
"time"
)
// 内联 SVG:path 对齐 lucide-react@1.18(由 scripts/extract-lucide-paths.mjs 抽取)
func ssrSVG(size int, paths ...string) string {
return ssrSVGWithClass(size, "", paths...)
}
func ssrSVGWithClass(size int, className string, paths ...string) string {
var b strings.Builder
b.WriteString(``)
return b.String()
}
func ssrIconSearch() string {
return ssrSVGWithClass(16, "header-search-icon",
``,
``,
)
}
func ssrIconSliders() string {
return ssrSVG(15,
``,
``,
``,
``,
``,
``,
``,
``,
``,
)
}
func ssrIconPlus() string {
return ssrSVG(16,
``,
``,
)
}
func ssrIconMoon() string {
return ssrSVG(18,
``,
)
}
func ssrIconSun() string {
return ssrSVG(18,
``,
``,
``,
``,
``,
``,
``,
``,
``,
)
}
func ssrIconMail() string {
return ssrSVG(18,
``,
``,
)
}
func ssrIconHome() string {
return ssrSVG(18,
``,
``,
)
}
func ssrIconStar() string {
return ssrSVG(18,
``,
)
}
func ssrIconFolderGit() string {
return ssrSVG(18,
``,
``,
``,
``,
)
}
func ssrIconLink2() string {
return ssrSVG(18,
``,
``,
``,
)
}
func ssrWidgetIconLink2() string {
return ssrSVGWithClass(15, "widget-card-icon widget-card-icon--links",
``,
``,
``,
)
}
func ssrIconEarth() string {
return ssrSVG(18,
``,
``,
``,
``,
)
}
func ssrWidgetIconEarth() string {
return ssrSVGWithClass(15, "widget-card-icon widget-card-icon--showcase",
``,
``,
``,
``,
)
}
func ssrIconFileText() string {
return ssrSVG(18,
``,
``,
``,
``,
``,
)
}
func ssrIconLayoutDashboard() string {
return ssrSVG(18,
``,
``,
``,
``,
)
}
func ssrIconMessageCircle() string {
return ssrSVG(16,
``,
)
}
func ssrWidgetIconMessageCircle() string {
return ssrSVGWithClass(15, "widget-card-icon widget-card-icon--notice",
``,
)
}
func ssrIconClock() string {
return ssrSVG(16,
``,
``,
)
}
func ssrIconBadgeCheck() string {
return ssrSVG(16,
``,
``,
)
}
func ssrIconTags() string {
return ssrSVG(16,
``,
``,
``,
)
}
func ssrWidgetIconTags() string {
return ssrSVGWithClass(15, "widget-card-icon widget-card-icon--tags",
``,
``,
``,
)
}
func ssrIconUserPlus() string {
return ssrSVG(16,
``,
``,
``,
``,
)
}
func ssrWidgetIconUserPlus() string {
return ssrSVGWithClass(15, "widget-card-icon widget-card-icon--users",
``,
``,
``,
``,
)
}
func ssrIconCalendarCheck() string {
return ssrSVG(18,
``,
``,
``,
``,
``,
)
}
func ssrIconCheck() string {
return ssrSVG(18,
``,
)
}
func ssrIconGift() string {
return ssrSVG(15,
``,
``,
``,
``,
)
}
func ssrIconPanelRight() string {
return ssrSVG(18,
``,
``,
)
}
// 板块图标 path(key 对齐 BOARD_ICON_OPTIONS / AllowedBoardIcons)
var ssrBoardIconInner = map[string]string{
"code-2": ``,
"coffee": ``,
"help-circle": ``,
"message-square": ``,
"lightbulb": ``,
"book-open": ``,
"gamepad-2": ``,
"palette": ``,
"music": ``,
"camera": ``,
"heart": ``,
"zap": ``,
"globe": ``,
"users": ``,
"briefcase": ``,
"graduation-cap": ``,
"shopping-bag": ``,
"map-pin": ``,
"megaphone": ``,
"flame": ``,
"star": ``,
"folder": ``,
"wrench": ``,
"cpu": ``,
}
// 与前端 DEFAULT_ICONS 顺序一致(按 themeIndex 回退)
var ssrBoardDefaultIcons = []string{
"code-2",
"coffee",
"help-circle",
"message-square",
"lightbulb",
"book-open",
"gamepad-2",
"palette",
}
// ssrBoardIconSVG 输出板块 Lucide 图标;class 打在 svg 上(与 React BoardIconDisplay 一致)
func ssrBoardIconSVG(icon string, themeIndex int, className string) string {
key := strings.TrimSpace(strings.ToLower(icon))
inner, ok := ssrBoardIconInner[key]
if !ok || inner == "" {
if themeIndex < 0 {
themeIndex = 0
}
key = ssrBoardDefaultIcons[themeIndex%len(ssrBoardDefaultIcons)]
inner = ssrBoardIconInner[key]
}
return ssrSVGWithClass(18, className, inner)
}
// formatSSRRelativeTime 与前端 formatTime 同规则
func formatSSRRelativeTime(t time.Time) string {
if t.IsZero() {
return ""
}
now := time.Now()
diffSec := now.Sub(t).Seconds()
if diffSec < 0 {
diffSec = 0
}
if diffSec < 60 {
return "刚刚"
}
if diffSec < 3600 {
return strconv.Itoa(int(diffSec/60)) + "分钟前"
}
if diffSec < 86400 {
return strconv.Itoa(int(diffSec/3600)) + "小时前"
}
diffDay := int(diffSec / 86400)
if diffDay < 30 {
return strconv.Itoa(diffDay) + "天前"
}
if t.Year() == now.Year() {
return strconv.Itoa(int(t.Month())) + "月" + strconv.Itoa(t.Day()) + "日"
}
return strconv.Itoa(t.Year()) + "年" + strconv.Itoa(int(t.Month())) + "月" + strconv.Itoa(t.Day()) + "日"
}
// formatSSRShortDateTime 与前端 formatShortDateTime 同规则(MM-DD HH:mm)
func formatSSRShortDateTime(t time.Time) string {
if t.IsZero() {
return ""
}
local := t.Local()
pad := func(n int) string {
if n < 10 {
return "0" + strconv.Itoa(n)
}
return strconv.Itoa(n)
}
return pad(int(local.Month())) + "-" + pad(local.Day()) + " " + pad(local.Hour()) + ":" + pad(local.Minute())
}