refactor preview code

This commit is contained in:
Duong Thai 2023-11-24 00:15:41 +07:00
parent 2fdc06031c
commit a596e5ff6c
15 changed files with 154 additions and 363 deletions

View file

@ -9,7 +9,7 @@
/* Begin PBXBuildFile section */
36741BFD291E4FDB00A85AAE /* DownloadPreferencePane.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36741BFC291E4FDB00A85AAE /* DownloadPreferencePane.swift */; };
36741BFF291E50F500A85AAE /* FileError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36741BFE291E50F500A85AAE /* FileError.swift */; };
536CFDD2263C94DE00026CE0 /* SignedInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536CFDD1263C94DE00026CE0 /* SignedInView.swift */; };
536CFDD2263C94DE00026CE0 /* SignedInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536CFDD1263C94DE00026CE0 /* SignedInView.swift */; };
536CFDD4263C9A8000026CE0 /* XcodesSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536CFDD3263C9A8000026CE0 /* XcodesSheet.swift */; };
53CBAB2C263DCC9100410495 /* XcodesAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CBAB2B263DCC9100410495 /* XcodesAlert.swift */; };
63EAA4EB259944450046AB8F /* ProgressButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63EAA4EA259944450046AB8F /* ProgressButton.swift */; };

View file

@ -25,32 +25,7 @@ struct CompatibilityView: View {
}
}
struct CompatibilityView_Preview: PreviewProvider {
static var previews: some View {
WrapperView()
}
}
private struct WrapperView: View {
@State var isNil = false
var requiredMacOSVersion: String? {
isNil
? nil
: "10.15.4"
}
var body: some View {
VStack {
HStack {
CompatibilityView(requiredMacOSVersion: requiredMacOSVersion)
.border(.red)
}
Spacer()
Toggle(isOn: $isNil) {
Text("Is Nil?")
}
}
.frame(width: 200, height: 100)
.padding()
}
#Preview {
CompatibilityView(requiredMacOSVersion: "10.15.4")
.padding()
}

View file

@ -44,36 +44,15 @@ struct CompilersView: View {
}
}
struct CompilersView_Preview: PreviewProvider {
static var previews: some View {
WrapperView()
}
#Preview {
let compilers = Compilers(
gcc: .init(number: "4"),
llvm_gcc: .init(number: "213"),
llvm: .init(number: "2.3"),
clang: .init(number: "7.3"),
swift: .init(number: "5.3.2")
)
return CompilersView(compilers: compilers)
.padding()
}
private struct WrapperView: View {
@State var isNil = false
var compilers: Compilers? {
isNil
? nil
: Compilers(
gcc: .init(number: "4"),
llvm_gcc: .init(number: "213"),
llvm: .init(number: "2.3"),
clang: .init(number: "7.3"),
swift: .init(number: "5.3.2"))
}
var body: some View {
VStack {
CompilersView(compilers: compilers)
.border(.red)
Spacer()
Toggle(isOn: $isNil) {
Text("Is Nil?")
}
}
.frame(width: 200, height: 100)
.padding()
}
}

View file

@ -24,38 +24,14 @@ struct IconView: View {
}
}
//#Preview {
// Group {
// IconView(path: "/Applications/Xcode.app")
// IconView()
// }
// .padding()
//}
struct IconView_Preview: PreviewProvider {
static var previews: some View {
WrapperView()
}
#Preview("Installed") {
IconView(installState: XcodeInstallState.installed(Path("/Applications/Xcode.app")!))
.frame(width: 300, height: 100)
.padding()
}
private struct WrapperView: View {
@State var isIcon = false
var state: XcodeInstallState {
isIcon
? XcodeInstallState.installed(Path("/Applications/Xcode.app")!)
: XcodeInstallState.notInstalled
}
var body: some View {
VStack {
IconView(installState: state)
.border(.red)
Spacer()
Toggle(isOn: $isIcon) {
Text("Icon?")
}
}
.frame(width: 300, height: 100)
.padding()
}
#Preview("Not Installed") {
IconView(installState: XcodeInstallState.notInstalled)
.frame(width: 300, height: 100)
.padding()
}

View file

@ -49,31 +49,14 @@ struct IdenticalBuildsView: View {
}
}
struct IdenticalBuildsView_Preview: PreviewProvider {
static var previews: some View {
WrapperView()
}
let builds: [Version] = [.init(xcodeVersion: "15.0")!, .init(xcodeVersion: "15.1")!]
#Preview("Has Some Builds") {
IdenticalBuildsView(builds: builds)
.padding()
}
private struct WrapperView: View {
@State var isEmpty = false
var builds: [Version] {
isEmpty
? []
: [.init(xcodeVersion: "15.0")!,
.init(xcodeVersion: "15.1")!]
}
var body: some View {
VStack {
IdenticalBuildsView(builds: builds)
.border(.red)
Spacer()
Toggle(isOn: $isEmpty) {
Text("No Builds?")
}
}
.frame(width: 300, height: 100)
.padding()
}
#Preview("No Build") {
IdenticalBuildsView(builds: [])
.padding()
}

View file

@ -36,36 +36,21 @@ struct InfoPane: View {
}
}
struct InfoPane_Previews: PreviewProvider {
static var previews: some View {
WrapperView()
}
}
#Preview(PreviewName.allCases[0].rawValue) { makePreviewContent(for: 0) }
#Preview(PreviewName.allCases[1].rawValue) { makePreviewContent(for: 1) }
#Preview(PreviewName.allCases[2].rawValue) { makePreviewContent(for: 2) }
#Preview(PreviewName.allCases[3].rawValue) { makePreviewContent(for: 3) }
#Preview(PreviewName.allCases[4].rawValue) { makePreviewContent(for: 4) }
private struct WrapperView: View {
@State var name: PreviewName = .Populated_Installed_Selected
private func makePreviewContent(for index: Int) -> some View {
let name = PreviewName.allCases[index]
var body: some View {
VStack {
InfoPane(xcode: xcode)
.environmentObject(configure(AppState()) {
$0.allXcodes = [xcode]
})
.border(.red)
.frame(width: 300, height: 400)
Spacer()
Picker("Preview Name", selection: $name) {
ForEach(PreviewName.allCases) {
Text($0.rawValue).tag($0)
}
}
.pickerStyle(.inline)
}
.frame(maxWidth: .infinity)
.padding()
}
var xcode: Xcode { xcodeDict[name]! }
return InfoPane(xcode: xcodeDict[name]!)
.environmentObject(configure(AppState()) {
$0.allXcodes = [xcodeDict[name]!]
})
.frame(width: 300, height: 400)
.padding()
}
enum PreviewName: String, CaseIterable, Identifiable {

View file

@ -28,35 +28,19 @@ struct InfoPaneControls: View {
}
}
struct InfoPaneControls_Previews: PreviewProvider {
static var previews: some View {
WrapperView()
}
}
private struct WrapperView: View {
@State var name: PreviewName = .Populated_Installed_Selected
var body: some View {
VStack {
InfoPaneControls(xcode: xcode)
.environmentObject(configure(AppState()) {
$0.allXcodes = [xcode]
})
.border(.red)
.frame(width: 300, height: 400)
Spacer()
Picker("Preview Name", selection: $name) {
ForEach(PreviewName.allCases) {
Text($0.rawValue).tag($0)
}
}
.pickerStyle(.inline)
}
.frame(maxWidth: .infinity)
.padding()
}
var xcode: Xcode { xcodeDict[name]! }
#Preview(PreviewName.allCases[0].rawValue) { makePreviewContent(for: 0) }
#Preview(PreviewName.allCases[1].rawValue) { makePreviewContent(for: 1) }
#Preview(PreviewName.allCases[2].rawValue) { makePreviewContent(for: 2) }
#Preview(PreviewName.allCases[3].rawValue) { makePreviewContent(for: 3) }
#Preview(PreviewName.allCases[4].rawValue) { makePreviewContent(for: 4) }
private func makePreviewContent(for index: Int) -> some View {
let name = PreviewName.allCases[index]
return InfoPaneControls(xcode: xcodeDict[name]!)
.environmentObject(configure(AppState()) {
$0.allXcodes = [xcodeDict[name]!]
})
.frame(width: 300)
.padding()
}

View file

@ -24,26 +24,25 @@ struct InstallationStepDetailView: View {
}
}
struct InstallDetailView_Previews: PreviewProvider {
static var previews: some View {
Group {
InstallationStepDetailView(
installationStep: .downloading(
progress: configure(Progress()) {
$0.kind = .file
$0.fileOperationKind = .downloading
$0.estimatedTimeRemaining = 123
$0.totalUnitCount = 11944848484
$0.completedUnitCount = 848444920
$0.throughput = 9211681
}
)
)
InstallationStepDetailView(
installationStep: .unarchiving
)
}
.padding()
}
#Preview("Downloading") {
InstallationStepDetailView(
installationStep: .downloading(
progress: configure(Progress()) {
$0.kind = .file
$0.fileOperationKind = .downloading
$0.estimatedTimeRemaining = 123
$0.totalUnitCount = 11944848484
$0.completedUnitCount = 848444920
$0.throughput = 9211681
}
)
)
.padding()
}
#Preview("Unarchiving") {
InstallationStepDetailView(
installationStep: .unarchiving
)
.padding()
}

View file

@ -42,38 +42,35 @@ struct InstalledStateButtons: View {
}
}
struct InstalledStateButtons_Preview: PreviewProvider {
static var previews: some View {
InstalledStateButtons(xcode: Self.xcode)
.environmentObject(configure(AppState()) {
$0.allXcodes = [Self.xcode]
})
.padding()
.frame(width: 300)
}
static private let xcode = Xcode(
version: Version(major: 12, minor: 3, patch: 0),
installState: .installed(Path("/Applications/Xcode-12.3.0.app")!),
selected: true,
icon: NSWorkspace.shared.icon(forFile: "/Applications/Xcode-12.3.0.app"),
requiredMacOSVersion: "10.15.4",
releaseNotesURL: URL(string: "https://developer.apple.com/documentation/xcode-release-notes/xcode-12_3-release-notes/")!,
releaseDate: Date(),
sdks: SDKs(
macOS: .init(number: "11.1"),
iOS: .init(number: "14.3"),
watchOS: .init(number: "7.3"),
tvOS: .init(number: "14.3")
),
compilers: Compilers(
gcc: .init(number: "4"),
llvm_gcc: .init(number: "213"),
llvm: .init(number: "2.3"),
clang: .init(number: "7.3"),
swift: .init(number: "5.3.2")
),
downloadFileSize: 242342424
)
#Preview {
InstalledStateButtons(xcode: xcode)
.environmentObject(configure(AppState()) {
$0.allXcodes = [xcode]
})
.padding()
.frame(width: 300)
}
private let xcode = Xcode(
version: Version(major: 12, minor: 3, patch: 0),
installState: .installed(Path("/Applications/Xcode-12.3.0.app")!),
selected: true,
icon: NSWorkspace.shared.icon(forFile: "/Applications/Xcode-12.3.0.app"),
requiredMacOSVersion: "10.15.4",
releaseNotesURL: URL(string: "https://developer.apple.com/documentation/xcode-release-notes/xcode-12_3-release-notes/")!,
releaseDate: Date(),
sdks: SDKs(
macOS: .init(number: "11.1"),
iOS: .init(number: "14.3"),
watchOS: .init(number: "7.3"),
tvOS: .init(number: "14.3")
),
compilers: Compilers(
gcc: .init(number: "4"),
llvm_gcc: .init(number: "213"),
llvm: .init(number: "2.3"),
clang: .init(number: "7.3"),
swift: .init(number: "5.3.2")
),
downloadFileSize: 242342424
)

View file

@ -35,34 +35,10 @@ struct NotInstalledStateButtons: View {
}
}
struct NotInstalledStateButtons_Preview: PreviewProvider {
static var previews: some View {
WrapperView()
}
}
private struct WrapperView: View {
@State var isSizeNil = false
var downloadFileSizeString: String? {
isSizeNil
? nil
: "1,19 GB"
}
var body: some View {
VStack {
NotInstalledStateButtons(
downloadFileSizeString: downloadFileSizeString,
id: Version(major: 12, minor: 3, patch: 0)
)
.border(.red)
Spacer()
Toggle(isOn: $isSizeNil) {
Text("Is Size Nil?")
}
}
.frame(width: 200, height: 100)
.padding()
}
#Preview {
NotInstalledStateButtons(
downloadFileSizeString: "1,19 GB",
id: Version(major: 12, minor: 3, patch: 0)
)
.padding()
}

View file

@ -29,26 +29,7 @@ struct ReleaseDateView: View {
}
}
struct ReleaseDateView_Preview: PreviewProvider {
static var previews: some View {
WrapperView()
}
}
private struct WrapperView: View {
@State var isNil = false
var date: Date? { isNil ? nil : Date() }
var body: some View {
VStack {
ReleaseDateView(date: date)
.border(.red)
Spacer()
Toggle(isOn: $isNil) {
Text("Is Nil?")
}
}
.frame(width: 300, height: 100)
.padding()
}
#Preview {
ReleaseDateView(date: Date())
.padding()
}

View file

@ -30,29 +30,9 @@ struct ReleaseNotesView: View {
}
}
struct ReleaseNotesView_Preview: PreviewProvider {
static var previews: some View {
WrapperView()
}
}
#Preview {
let url = URL(string: "https://developer.apple.com/documentation/xcode-release-notes/xcode-12_3-release-notes/")!
private struct WrapperView: View {
@State var hasURL = false
var url: URL? {
hasURL
? nil
: URL(string: "https://developer.apple.com/documentation/xcode-release-notes/xcode-12_3-release-notes/")!
}
var body: some View {
VStack {
ReleaseNotesView(url: url).border(.red)
Spacer()
Toggle(isOn: $hasURL) {
Text("Has URL?")
}
}
.frame(width: 300, height: 100)
.padding()
}
return ReleaseNotesView(url: url)
.padding()
}

View file

@ -56,32 +56,13 @@ struct SDKsView: View {
}
}
struct SDKsView_Preview: PreviewProvider {
static var previews: some View {
WrapperView()
}
}
#Preview {
let sdks = SDKs(
macOS: .init(number: "11.1"),
iOS: .init(number: "14.3"),
watchOS: .init(number: "7.3"),
tvOS: .init(number: "14.3"))
private struct WrapperView: View {
@State var isNil = false
var sdks: SDKs? {
isNil
? nil
: SDKs(macOS: .init(number: "11.1"),
iOS: .init(number: "14.3"),
watchOS: .init(number: "7.3"),
tvOS: .init(number: "14.3"))
}
var body: some View {
VStack {
SDKsView(sdks: sdks).border(.red)
Spacer()
Toggle(isOn: $isNil) {
Text("Empty Content?")
}
}
.frame(width: 200, height: 100)
.padding()
}
return SDKsView(sdks: sdks)
.padding()
}

View file

@ -20,9 +20,7 @@ struct UnselectedView: View {
}
}
struct UnselectedView_Preview: PreviewProvider {
static var previews: some View {
UnselectedView()
.padding()
}
#Preview {
UnselectedView()
.padding()
}

View file

@ -9,15 +9,15 @@ struct XcodesApp: App {
@SwiftUI.Environment(\.openURL) var openURL: OpenURLAction
@StateObject private var appState = AppState()
@StateObject private var updater = ObservableUpdater()
var body: some Scene {
WindowGroup("Xcodes") {
MainWindow()
.environmentObject(appState)
.environmentObject(updater)
// This is intentionally used on a View, and not on a WindowGroup,
// This is intentionally used on a View, and not on a WindowGroup,
// so that it's triggered when an individual window's phase changes instead of all window phases.
// When used on a View it's also invoked on launch, which doesn't occur with a WindowGroup.
// When used on a View it's also invoked on launch, which doesn't occur with a WindowGroup.
// FB8954581 ScenePhase read from App doesn't return a value on launch
.onChange(of: scenePhase) { newScenePhase in
guard !isTesting else { return }
@ -37,7 +37,7 @@ struct XcodesApp: App {
updater.checkForUpdates()
}
}
CommandGroup(after: CommandGroupPlacement.newItem) {
Button("Refresh") {
appState.update()
@ -47,33 +47,33 @@ struct XcodesApp: App {
}
XcodeCommands(appState: appState)
CommandGroup(replacing: CommandGroupPlacement.help) {
Button("Menu.GitHubRepo") {
let xcodesRepoURL = URL(string: "https://github.com/RobotsAndPencils/XcodesApp/")!
openURL(xcodesRepoURL)
}
Divider()
Button("Menu.ReportABug") {
let bugReportURL = URL(string: "https://github.com/RobotsAndPencils/XcodesApp/issues/new?assignees=&labels=bug&template=bug_report.md&title=")!
openURL(bugReportURL)
}
Button("Menu.RequestNewFeature") {
let featureRequestURL = URL(string: "https://github.com/RobotsAndPencils/XcodesApp/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=")!
openURL(featureRequestURL)
}
}
}
#if os(macOS)
Settings {
PreferencesView()
.environmentObject(appState)
.environmentObject(updater)
}
#endif
#if os(macOS)
Settings {
PreferencesView()
.environmentObject(appState)
.environmentObject(updater)
}
#endif
}
}
@ -88,7 +88,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
$0.contentView = NSHostingView(rootView: AboutView(showAcknowledgementsWindow: showAcknowledgementsWindow))
$0.isReleasedWhenClosed = false
}
private let acknowledgementsWindow = configure(NSWindow(
contentRect: .zero,
styleMask: [.closable, .resizable, .miniaturizable, .titled],
@ -103,21 +103,19 @@ class AppDelegate: NSObject, NSApplicationDelegate {
/// If we wanted to use only SwiftUI API to do this we could make a new WindowGroup and use openURL and handlesExternalEvents.
/// WindowGroup lets the user open more than one window right now, which is a little strange for an About window.
/// (It's also weird that the main Xcode list window can be opened more than once, there should only be one.)
/// To work around this, an AppDelegate holds onto a single instance of an NSWindow that is shown here.
/// To work around this, an AppDelegate holds onto a single instance of an NSWindow that is shown here.
/// FB8954588 Scene / WindowGroup is missing API to limit the number of windows that can be created
func showAboutWindow() {
aboutWindow.center()
aboutWindow.makeKeyAndOrderFront(nil)
}
func showAcknowledgementsWindow() {
acknowledgementsWindow.center()
acknowledgementsWindow.makeKeyAndOrderFront(nil)
}
func applicationDidFinishLaunching(_ notification: Notification) {
}
func applicationDidFinishLaunching(_: Notification) {}
}
func localizeString(_ key: String, comment: String = "") -> String {
@ -126,5 +124,4 @@ func localizeString(_ key: String, comment: String = "") -> String {
} else {
return NSLocalizedString(key, comment: comment)
}
}