mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-10-31 14:53:49 +00:00
fix(servers): separate detail actions into two rows
This commit is contained in:
@@ -32,7 +32,6 @@ struct CatalogNodeDetailView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.disabled(!(eligibility?.canActivate ?? false) || activation.isPending)
|
||||
if let subscription = subscriptionSummary(for: node) {
|
||||
Button(
|
||||
@@ -44,6 +43,7 @@ struct CatalogNodeDetailView: View {
|
||||
}
|
||||
.disabled(workflow.refreshingSubscriptionIDs.contains(subscription.id))
|
||||
}
|
||||
} secondaryActions: {
|
||||
if let module = workflow.connectivity {
|
||||
ConnectivityTestButton(module: module, node: node)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import SwiftUI
|
||||
|
||||
/// 只接受展示值与外部动作;不查询节点类型、工作流或凭据。
|
||||
struct NodeDetailView<Actions: View, Feedback: View, Supplement: View>: View {
|
||||
struct NodeDetailView<
|
||||
PrimaryActions: View, SecondaryActions: View, Feedback: View, Supplement: View
|
||||
>: View {
|
||||
let detail: NodeDetailPresentation
|
||||
@ViewBuilder let actions: Actions
|
||||
@ViewBuilder let primaryActions: PrimaryActions
|
||||
@ViewBuilder let secondaryActions: SecondaryActions
|
||||
@ViewBuilder let feedback: Feedback
|
||||
@ViewBuilder let supplement: Supplement
|
||||
|
||||
@@ -26,7 +29,19 @@ struct NodeDetailView<Actions: View, Feedback: View, Supplement: View>: View {
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
}
|
||||
HStack(spacing: 12) { actions }
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
HStack(spacing: 12) { primaryActions }
|
||||
.buttonStyle(.borderedProminent)
|
||||
HStack(spacing: 12) { secondaryActions }
|
||||
.buttonStyle(.bordered)
|
||||
}
|
||||
.fixedSize(horizontal: true, vertical: true)
|
||||
.background {
|
||||
GeometryReader { geometry in
|
||||
Color.clear.preference(
|
||||
key: NodeDetailMinimumWidth.self, value: geometry.size.width + 32)
|
||||
}
|
||||
}
|
||||
feedback
|
||||
}
|
||||
Divider()
|
||||
@@ -58,3 +73,12 @@ struct NodeDetailView<Actions: View, Feedback: View, Supplement: View>: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 操作区按完整文字测量;包含详情的左右内边距,供外层分栏限制拖动宽度。
|
||||
struct NodeDetailMinimumWidth: PreferenceKey {
|
||||
static let defaultValue: CGFloat = 320
|
||||
|
||||
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
|
||||
value = max(value, nextValue())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ struct ServersView: View {
|
||||
@State private var subscriptionEditTarget: SubscriptionSummary?
|
||||
@State private var deleteTarget: DeleteTarget?
|
||||
@State private var dropState = ServerTableDropState()
|
||||
@State private var detailMinimumWidth: CGFloat = NodeDetailMinimumWidth.defaultValue
|
||||
@FocusState private var isServerTableFocused: Bool
|
||||
// 分享 popover 打开时冻结载荷、顶部资料与建议文件名。
|
||||
@State var shareContext: ShareContext?
|
||||
@@ -57,7 +58,10 @@ struct ServersView: View {
|
||||
ZStack(alignment: .topLeading) {
|
||||
serverDetailPane
|
||||
}
|
||||
.frame(minWidth: 320, maxWidth: .infinity, maxHeight: .infinity)
|
||||
.frame(minWidth: detailMinimumWidth, maxWidth: .infinity, maxHeight: .infinity)
|
||||
.onPreferenceChange(NodeDetailMinimumWidth.self) {
|
||||
detailMinimumWidth = max(NodeDetailMinimumWidth.defaultValue, $0)
|
||||
}
|
||||
}
|
||||
.frame(minHeight: 420)
|
||||
.sheet(
|
||||
|
||||
Reference in New Issue
Block a user