189 lines
5.2 KiB
Go
189 lines
5.2 KiB
Go
package gio
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"gioui.org/layout"
|
||
|
|
"gioui.org/unit"
|
||
|
|
"gioui.org/widget/material"
|
||
|
|
|
||
|
|
"softbox.local/core/application"
|
||
|
|
"softbox.local/core/domain"
|
||
|
|
)
|
||
|
|
|
||
|
|
func (shell *AppShell) layoutDetail(
|
||
|
|
gtx layout.Context,
|
||
|
|
theme *material.Theme,
|
||
|
|
item application.CatalogListItem,
|
||
|
|
) layout.Dimensions {
|
||
|
|
shell.detailRendered = true
|
||
|
|
return panel(
|
||
|
|
gtx,
|
||
|
|
shellColors.muted,
|
||
|
|
unit.Dp(10),
|
||
|
|
layout.UniformInset(unit.Dp(16)),
|
||
|
|
func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return layout.Flex{Axis: layout.Vertical}.Layout(
|
||
|
|
gtx,
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return layout.Flex{Alignment: layout.Middle}.Layout(
|
||
|
|
gtx,
|
||
|
|
layout.Rigid(material.H6(theme, "软件详情").Layout),
|
||
|
|
layout.Flexed(1, layout.Spacer{}.Layout),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return shell.layoutFilterButton(
|
||
|
|
gtx,
|
||
|
|
theme,
|
||
|
|
&shell.closeDetail,
|
||
|
|
"关闭",
|
||
|
|
false,
|
||
|
|
)
|
||
|
|
}),
|
||
|
|
)
|
||
|
|
}),
|
||
|
|
layout.Rigid(layout.Spacer{Height: unit.Dp(16)}.Layout),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return shell.layoutAppIcon(
|
||
|
|
gtx,
|
||
|
|
theme,
|
||
|
|
item.ID,
|
||
|
|
item.Name,
|
||
|
|
unit.Dp(72),
|
||
|
|
unit.Dp(12),
|
||
|
|
)
|
||
|
|
})
|
||
|
|
}),
|
||
|
|
layout.Rigid(layout.Spacer{Height: unit.Dp(12)}.Layout),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return layout.Center.Layout(gtx, material.H6(theme, item.Name).Layout)
|
||
|
|
}),
|
||
|
|
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
label := material.Body2(
|
||
|
|
theme,
|
||
|
|
fmt.Sprintf("%s · %s", item.ID, item.Version),
|
||
|
|
)
|
||
|
|
label.Color = shellColors.secondary
|
||
|
|
return layout.Center.Layout(gtx, label.Layout)
|
||
|
|
}),
|
||
|
|
layout.Rigid(layout.Spacer{Height: unit.Dp(16)}.Layout),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return detailField(gtx, theme, "状态", statusLabel(item.Status))
|
||
|
|
}),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return detailField(gtx, theme, "分类", fallbackText(item.Category, "未分类"))
|
||
|
|
}),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return detailField(
|
||
|
|
gtx,
|
||
|
|
theme,
|
||
|
|
"标签",
|
||
|
|
fallbackText(strings.Join(item.Tags, " · "), "无"),
|
||
|
|
)
|
||
|
|
}),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return detailField(
|
||
|
|
gtx,
|
||
|
|
theme,
|
||
|
|
"简介",
|
||
|
|
fallbackText(item.Description, "暂无简介"),
|
||
|
|
)
|
||
|
|
}),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
if item.Reason == "" {
|
||
|
|
return layout.Dimensions{}
|
||
|
|
}
|
||
|
|
return detailField(gtx, theme, "不可用原因", reasonLabel(item.Reason))
|
||
|
|
}),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
if item.Tutorial == "" {
|
||
|
|
return layout.Dimensions{}
|
||
|
|
}
|
||
|
|
return detailField(gtx, theme, "教程", item.Tutorial)
|
||
|
|
}),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
if item.Homepage == "" {
|
||
|
|
return layout.Dimensions{}
|
||
|
|
}
|
||
|
|
return detailField(gtx, theme, "主页", item.Homepage)
|
||
|
|
}),
|
||
|
|
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
label := material.Caption(theme, actionLabel(item)+";实际操作将在后续用例接入")
|
||
|
|
label.Color = shellColors.secondary
|
||
|
|
return label.Layout(gtx)
|
||
|
|
}),
|
||
|
|
)
|
||
|
|
},
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
func actionLabel(item application.CatalogListItem) string {
|
||
|
|
if item.Reason != "" || item.Status == domain.StatusIncompatible {
|
||
|
|
return "查看不可用原因"
|
||
|
|
}
|
||
|
|
switch item.Status {
|
||
|
|
case domain.StatusInstalled:
|
||
|
|
return "查看或启动"
|
||
|
|
case domain.StatusUpdateAvailable:
|
||
|
|
return "查看更新"
|
||
|
|
case domain.StatusRunning:
|
||
|
|
return "查看运行状态"
|
||
|
|
case domain.StatusQueued,
|
||
|
|
domain.StatusDownloading,
|
||
|
|
domain.StatusVerifying,
|
||
|
|
domain.StatusExtracting,
|
||
|
|
domain.StatusInstalling:
|
||
|
|
return "查看任务"
|
||
|
|
case domain.StatusFailed, domain.StatusRollbackPending:
|
||
|
|
return "查看恢复选项"
|
||
|
|
default:
|
||
|
|
if item.Installable {
|
||
|
|
return "查看并安装"
|
||
|
|
}
|
||
|
|
return "查看详情"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func detailField(
|
||
|
|
gtx layout.Context,
|
||
|
|
theme *material.Theme,
|
||
|
|
labelText string,
|
||
|
|
value string,
|
||
|
|
) layout.Dimensions {
|
||
|
|
return layout.Inset{Bottom: unit.Dp(12)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||
|
|
return layout.Flex{Axis: layout.Vertical}.Layout(
|
||
|
|
gtx,
|
||
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||
|
|
label := material.Caption(theme, labelText)
|
||
|
|
label.Color = shellColors.secondary
|
||
|
|
return label.Layout(gtx)
|
||
|
|
}),
|
||
|
|
layout.Rigid(layout.Spacer{Height: unit.Dp(3)}.Layout),
|
||
|
|
layout.Rigid(material.Body2(theme, value).Layout),
|
||
|
|
)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func fallbackText(value, fallback string) string {
|
||
|
|
if value == "" {
|
||
|
|
return fallback
|
||
|
|
}
|
||
|
|
return value
|
||
|
|
}
|
||
|
|
|
||
|
|
func reasonLabel(reason string) string {
|
||
|
|
switch reason {
|
||
|
|
case "deprecated":
|
||
|
|
return "软件已停止发布,不能新装或更新"
|
||
|
|
case "minimum_os":
|
||
|
|
return "当前 Windows 版本低于最低要求"
|
||
|
|
case "architecture":
|
||
|
|
return "没有适用于当前系统架构的软件包"
|
||
|
|
default:
|
||
|
|
return reason
|
||
|
|
}
|
||
|
|
}
|