package gio import ( "fmt" "gioui.org/io/semantic" "gioui.org/layout" "gioui.org/unit" "gioui.org/widget/material" "softbox.local/core/application" ) func (shell *AppShell) layoutLicensePanel(gtx layout.Context, theme *material.Theme) layout.Dimensions { return layout.Flex{Axis: layout.Vertical}.Layout( gtx, layout.Rigid(material.H5(theme, "授权").Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return licenseText(gtx, theme, shell.licenseStatusText()) }), layout.Rigid(layout.Spacer{Height: unit.Dp(12)}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { if shell.authorization.MachineHash == "" { return licenseText(gtx, theme, "机器信息:授权配置完成后显示 machine_hash") } return licenseText(gtx, theme, "机器信息(machine_hash):"+shell.authorization.MachineHash) }), layout.Rigid(layout.Spacer{Height: unit.Dp(12)}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { if !shell.canImportLicense() { return licenseText(gtx, theme, "许可证导入:当前构建未配置可信授权来源") } return shell.layoutLicenseImportButton(gtx, theme) }), layout.Rigid(layout.Spacer{Height: unit.Dp(16)}.Layout), layout.Rigid(material.H6(theme, "已授权产品").Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout), layout.Flexed(1, func(gtx layout.Context) layout.Dimensions { if len(shell.authorization.Products) == 0 { return licenseText(gtx, theme, "暂无可用授权。试用功能需要服务端签发可验证的许可证,本机不会创建试用授权。") } return layout.Flex{Axis: layout.Vertical}.Layout(gtx, licenseProductWidgets(shell.authorization.Products, theme)...) }), ) } func (shell *AppShell) layoutLicenseImportButton(gtx layout.Context, theme *material.Theme) layout.Dimensions { gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(44)) button := material.Button(theme, &shell.importLicense, "导入许可证") button.Background = shellColors.primary button.Color = shellColors.onPrimary button.Inset = layout.Inset{Top: unit.Dp(10), Bottom: unit.Dp(10), Left: unit.Dp(14), Right: unit.Dp(14)} semantic.Button.Add(gtx.Ops) semantic.DescriptionOp("导入许可证文件,验证在后台完成").Add(gtx.Ops) return button.Layout(gtx) } func licenseProductWidgets(products []application.AuthorizedProduct, theme *material.Theme) []layout.FlexChild { widgets := make([]layout.FlexChild, 0, len(products)*3) for _, product := range products { product := product widgets = append(widgets, layout.Rigid(func(gtx layout.Context) layout.Dimensions { return licenseText(gtx, theme, fmt.Sprintf("%s · %s", product.ProductID, licenseKindText(product.Kind))) }), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return licenseText(gtx, theme, "换绑/申诉:"+product.RebindPolicy+";不会在本机修改绑定") }), layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout), ) } return widgets } func (shell *AppShell) canImportLicense() bool { return shell.authorizationLoaded && shell.authorization.State != application.AuthorizationStateUnconfigured } func (shell *AppShell) licenseStatusText() string { if !shell.authorizationLoaded { return "授权状态:正在加载" } switch shell.authorization.State { case application.AuthorizationStateReady: return "授权状态:撤销名单有效,当前授权可用" case application.AuthorizationStateGrace: return "授权状态:撤销名单已过期,处于 7 天离线宽限期" case application.AuthorizationStateNoLicense: return "授权状态:未找到当前机器的有效许可证" case application.AuthorizationStateRevoked: return "授权状态:许可证已撤销,不能启动受保护软件" case application.AuthorizationStateUnavailable: return "授权状态:撤销验证不可用,不能启动受保护软件" case application.AuthorizationStateImportFailed: return "授权状态:导入失败;原许可证与授权状态未被信任地替换" case application.AuthorizationStateUnconfigured: return "授权状态:可信授权来源尚未配置" default: return "授权状态:不可用" } } func licenseKindText(kind application.LicenseKind) string { if kind == application.LicenseKindPerpetual { return "正式许可证" } return "非永久许可证(License v1 未提供试用到期信息)" } func licenseText(gtx layout.Context, theme *material.Theme, value string) layout.Dimensions { label := material.Body2(theme, value) label.Color = shellColors.secondary return label.Layout(gtx) }