mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-04-26 14:57:37 +00:00
Merge pull request #33 from RobotsAndPencils/selection-performance-fix
Move Xcode selection state into window, improve performance
This commit is contained in:
commit
cc9afeda97
5 changed files with 20 additions and 25 deletions
|
|
@ -32,10 +32,6 @@ class AppState: ObservableObject {
|
||||||
@Published var presentingSignInAlert = false
|
@Published var presentingSignInAlert = false
|
||||||
@Published var isProcessingAuthRequest = false
|
@Published var isProcessingAuthRequest = false
|
||||||
@Published var secondFactorData: SecondFactorData?
|
@Published var secondFactorData: SecondFactorData?
|
||||||
// Selected in the Xcode list, not in the xcode-select sense
|
|
||||||
// This probably belongs as private @State in XcodeListView,
|
|
||||||
// but we need it here instead so that it can be a focusedValue at the top level in XcodesApp instead of in a list row. The latter seems more like how the focusedValue API is supposed to work, but currently doesn't.
|
|
||||||
@Published var selectedXcodeID: Xcode.ID?
|
|
||||||
@Published var xcodeBeingConfirmedForUninstallation: Xcode?
|
@Published var xcodeBeingConfirmedForUninstallation: Xcode?
|
||||||
@Published var helperInstallState: HelperInstallState = .notInstalled
|
@Published var helperInstallState: HelperInstallState = .notInstalled
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import SwiftUI
|
||||||
|
|
||||||
struct MainWindow: View {
|
struct MainWindow: View {
|
||||||
@EnvironmentObject var appState: AppState
|
@EnvironmentObject var appState: AppState
|
||||||
@State private var selection: Xcode.ID?
|
@State private var selectedXcodeID: Xcode.ID?
|
||||||
@State private var searchText: String = ""
|
@State private var searchText: String = ""
|
||||||
@AppStorage("lastUpdated") private var lastUpdated: Double?
|
@AppStorage("lastUpdated") private var lastUpdated: Double?
|
||||||
@SceneStorage("isShowingInfoPane") private var isShowingInfoPane = false
|
@SceneStorage("isShowingInfoPane") private var isShowingInfoPane = false
|
||||||
|
|
@ -10,11 +10,11 @@ struct MainWindow: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HSplitView {
|
HSplitView {
|
||||||
XcodeListView(searchText: searchText, category: category)
|
XcodeListView(selectedXcodeID: $selectedXcodeID, searchText: searchText, category: category)
|
||||||
.frame(minWidth: 300)
|
.frame(minWidth: 300)
|
||||||
.layoutPriority(1)
|
.layoutPriority(1)
|
||||||
|
|
||||||
InspectorPane()
|
InspectorPane(selectedXcodeID: selectedXcodeID)
|
||||||
.frame(minWidth: 300, maxWidth: .infinity)
|
.frame(minWidth: 300, maxWidth: .infinity)
|
||||||
.frame(width: isShowingInfoPane ? nil : 0)
|
.frame(width: isShowingInfoPane ? nil : 0)
|
||||||
.isHidden(!isShowingInfoPane)
|
.isHidden(!isShowingInfoPane)
|
||||||
|
|
@ -44,6 +44,9 @@ struct MainWindow: View {
|
||||||
secondFactorView(appState.secondFactorData!)
|
secondFactorView(appState.secondFactorData!)
|
||||||
.environmentObject(appState)
|
.environmentObject(appState)
|
||||||
}
|
}
|
||||||
|
// I'm expecting to be able to use this modifier on a List row, but using it at the top level here is the only way that has made XcodeCommands work so far.
|
||||||
|
// FB8954571 focusedValue(_:_:) on List row doesn't propagate value to @FocusedValue
|
||||||
|
.focusedValue(\.selectedXcode, SelectedXcode(appState.allXcodes.first { $0.id == selectedXcodeID }))
|
||||||
}
|
}
|
||||||
|
|
||||||
private var subtitleText: Text {
|
private var subtitleText: Text {
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,12 @@ import struct XCModel.Compilers
|
||||||
|
|
||||||
struct InspectorPane: View {
|
struct InspectorPane: View {
|
||||||
@EnvironmentObject var appState: AppState
|
@EnvironmentObject var appState: AppState
|
||||||
|
let selectedXcodeID: Xcode.ID?
|
||||||
@SwiftUI.Environment(\.openURL) var openURL: OpenURLAction
|
@SwiftUI.Environment(\.openURL) var openURL: OpenURLAction
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
Group {
|
||||||
if let xcode = appState.allXcodes.first(where: { $0.id == appState.selectedXcodeID }) {
|
if let xcode = appState.allXcodes.first(where: { $0.id == selectedXcodeID }) {
|
||||||
VStack(spacing: 16) {
|
VStack(spacing: 16) {
|
||||||
icon(for: xcode)
|
icon(for: xcode)
|
||||||
|
|
||||||
|
|
@ -169,7 +170,7 @@ struct InspectorPane: View {
|
||||||
struct InspectorPane_Previews: PreviewProvider {
|
struct InspectorPane_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
Group {
|
Group {
|
||||||
InspectorPane()
|
InspectorPane(selectedXcodeID: Version(major: 12, minor: 3, patch: 0))
|
||||||
.environmentObject(configure(AppState()) {
|
.environmentObject(configure(AppState()) {
|
||||||
$0.allXcodes = [
|
$0.allXcodes = [
|
||||||
.init(
|
.init(
|
||||||
|
|
@ -194,11 +195,10 @@ struct InspectorPane_Previews: PreviewProvider {
|
||||||
swift: .init(number: "5.3.2")
|
swift: .init(number: "5.3.2")
|
||||||
))
|
))
|
||||||
]
|
]
|
||||||
$0.selectedXcodeID = Version(major: 12, minor: 3, patch: 0)
|
|
||||||
})
|
})
|
||||||
.previewDisplayName("Populated, Installed, Selected")
|
.previewDisplayName("Populated, Installed, Selected")
|
||||||
|
|
||||||
InspectorPane()
|
InspectorPane(selectedXcodeID: Version(major: 12, minor: 3, patch: 0))
|
||||||
.environmentObject(configure(AppState()) {
|
.environmentObject(configure(AppState()) {
|
||||||
$0.allXcodes = [
|
$0.allXcodes = [
|
||||||
.init(
|
.init(
|
||||||
|
|
@ -221,11 +221,10 @@ struct InspectorPane_Previews: PreviewProvider {
|
||||||
swift: .init(number: "5.3.2")
|
swift: .init(number: "5.3.2")
|
||||||
))
|
))
|
||||||
]
|
]
|
||||||
$0.selectedXcodeID = Version(major: 12, minor: 3, patch: 0)
|
|
||||||
})
|
})
|
||||||
.previewDisplayName("Populated, Installed, Unselected")
|
.previewDisplayName("Populated, Installed, Unselected")
|
||||||
|
|
||||||
InspectorPane()
|
InspectorPane(selectedXcodeID: Version(major: 12, minor: 3, patch: 0))
|
||||||
.environmentObject(configure(AppState()) {
|
.environmentObject(configure(AppState()) {
|
||||||
$0.allXcodes = [
|
$0.allXcodes = [
|
||||||
.init(
|
.init(
|
||||||
|
|
@ -248,15 +247,13 @@ struct InspectorPane_Previews: PreviewProvider {
|
||||||
swift: .init(number: "5.3.2")
|
swift: .init(number: "5.3.2")
|
||||||
))
|
))
|
||||||
]
|
]
|
||||||
$0.selectedXcodeID = Version(major: 12, minor: 3, patch: 0)
|
|
||||||
})
|
})
|
||||||
.previewDisplayName("Populated, Uninstalled")
|
.previewDisplayName("Populated, Uninstalled")
|
||||||
|
|
||||||
InspectorPane()
|
InspectorPane(selectedXcodeID: nil)
|
||||||
.environmentObject(configure(AppState()) {
|
.environmentObject(configure(AppState()) {
|
||||||
$0.allXcodes = [
|
$0.allXcodes = [
|
||||||
]
|
]
|
||||||
$0.selectedXcodeID = nil
|
|
||||||
})
|
})
|
||||||
.previewDisplayName("Empty")
|
.previewDisplayName("Empty")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@ import PromiseKit
|
||||||
|
|
||||||
struct XcodeListView: View {
|
struct XcodeListView: View {
|
||||||
@EnvironmentObject var appState: AppState
|
@EnvironmentObject var appState: AppState
|
||||||
|
@Binding var selectedXcodeID: Xcode.ID?
|
||||||
private let searchText: String
|
private let searchText: String
|
||||||
private let category: XcodeListCategory
|
private let category: XcodeListCategory
|
||||||
|
|
||||||
init(searchText: String, category: XcodeListCategory) {
|
init(selectedXcodeID: Binding<Xcode.ID?>, searchText: String, category: XcodeListCategory) {
|
||||||
|
self._selectedXcodeID = selectedXcodeID
|
||||||
self.searchText = searchText
|
self.searchText = searchText
|
||||||
self.category = category
|
self.category = category
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +31,7 @@ struct XcodeListView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List(visibleXcodes, selection: $appState.selectedXcodeID) { xcode in
|
List(visibleXcodes, selection: $selectedXcodeID) { xcode in
|
||||||
HStack {
|
HStack {
|
||||||
appIconView(for: xcode)
|
appIconView(for: xcode)
|
||||||
|
|
||||||
|
|
@ -39,7 +41,7 @@ struct XcodeListView: View {
|
||||||
|
|
||||||
Text(verbatim: xcode.path ?? "")
|
Text(verbatim: xcode.path ?? "")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(appState.selectedXcodeID == xcode.id ? Color(NSColor.selectedMenuItemTextColor) : Color(NSColor.secondaryLabelColor))
|
.foregroundColor(selectedXcodeID == xcode.id ? Color(NSColor.selectedMenuItemTextColor) : Color(NSColor.secondaryLabelColor))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -54,8 +56,8 @@ struct XcodeListView: View {
|
||||||
print("Installing...")
|
print("Installing...")
|
||||||
}
|
}
|
||||||
.buttonStyle(AppStoreButtonStyle(installed: xcode.installed,
|
.buttonStyle(AppStoreButtonStyle(installed: xcode.installed,
|
||||||
highlighted: appState.selectedXcodeID == xcode.id))
|
highlighted: selectedXcodeID == xcode.id))
|
||||||
.disabled(xcode.installed)
|
.disabled(xcode.installed)
|
||||||
}
|
}
|
||||||
.contextMenu {
|
.contextMenu {
|
||||||
InstallButton(xcode: xcode)
|
InstallButton(xcode: xcode)
|
||||||
|
|
@ -87,7 +89,7 @@ struct XcodeListView: View {
|
||||||
struct XcodeListView_Previews: PreviewProvider {
|
struct XcodeListView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
Group {
|
Group {
|
||||||
XcodeListView(searchText: "", category: .all)
|
XcodeListView(selectedXcodeID: .constant(nil), searchText: "", category: .all)
|
||||||
.environmentObject({ () -> AppState in
|
.environmentObject({ () -> AppState in
|
||||||
let a = AppState()
|
let a = AppState()
|
||||||
a.allXcodes = [
|
a.allXcodes = [
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,6 @@ struct XcodesApp: App {
|
||||||
appState.updateIfNeeded()
|
appState.updateIfNeeded()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// I'm expecting to be able to use this modifier on a List row, but using it at the top level here is the only way that has made XcodeCommands work so far.
|
|
||||||
// FB8954571 focusedValue(_:_:) on List row doesn't propagate value to @FocusedValue
|
|
||||||
.focusedValue(\.selectedXcode, SelectedXcode(appState.allXcodes.first { $0.id == appState.selectedXcodeID }))
|
|
||||||
}
|
}
|
||||||
.commands {
|
.commands {
|
||||||
CommandGroup(replacing: .appInfo) {
|
CommandGroup(replacing: .appInfo) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue