mirror of
https://github.com/X1a0He/Adobe-Downloader.git
synced 2025-11-25 19:27:35 +08:00
231 lines
6.5 KiB
Swift
231 lines
6.5 KiB
Swift
//
|
|
// Adobe Downloader
|
|
//
|
|
// Created by X1a0He.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
private enum AlertConstants {
|
|
static let iconSize: CGFloat = 64
|
|
static let warningIconSize: CGFloat = 24
|
|
static let warningIconOffset: CGFloat = 10
|
|
static let verticalSpacing: CGFloat = 20
|
|
static let buttonHeight: CGFloat = 24
|
|
static let buttonWidth: CGFloat = 260
|
|
static let buttonFontSize: CGFloat = 14
|
|
static let cornerRadius: CGFloat = 12
|
|
static let shadowRadius: CGFloat = 10
|
|
}
|
|
|
|
struct ExistingFileAlertView: View {
|
|
let path: URL
|
|
let onUseExisting: () -> Void
|
|
let onRedownload: () -> Void
|
|
let onCancel: () -> Void
|
|
let iconImage: NSImage?
|
|
|
|
var body: some View {
|
|
VStack(spacing: AlertConstants.verticalSpacing) {
|
|
IconSection(iconImage: iconImage)
|
|
|
|
Text("安装程序已存在")
|
|
.font(.headline)
|
|
|
|
PathSection(path: path)
|
|
ButtonSection(
|
|
onUseExisting: onUseExisting,
|
|
onRedownload: onRedownload,
|
|
onCancel: onCancel
|
|
)
|
|
}
|
|
.padding()
|
|
.background(BackgroundView())
|
|
}
|
|
}
|
|
|
|
private struct IconSection: View {
|
|
let iconImage: NSImage?
|
|
|
|
var body: some View {
|
|
ZStack(alignment: .bottomTrailing) {
|
|
AppIcon(iconImage: iconImage)
|
|
WarningIcon()
|
|
}
|
|
.padding(.bottom, 5)
|
|
}
|
|
}
|
|
|
|
private struct AppIcon: View {
|
|
let iconImage: NSImage?
|
|
|
|
var body: some View {
|
|
Group {
|
|
if let iconImage = iconImage {
|
|
Image(nsImage: iconImage)
|
|
.resizable()
|
|
.interpolation(.high)
|
|
.scaledToFit()
|
|
} else {
|
|
Image(systemName: "app.fill")
|
|
.resizable()
|
|
.scaledToFit()
|
|
.foregroundColor(.secondary)
|
|
}
|
|
}
|
|
.frame(width: AlertConstants.iconSize, height: AlertConstants.iconSize)
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 8)
|
|
.fill(Color.secondary.opacity(0.05))
|
|
.padding(-4)
|
|
)
|
|
.overlay(
|
|
RoundedRectangle(cornerRadius: 8)
|
|
.stroke(Color.secondary.opacity(0.1), lineWidth: 1)
|
|
.padding(-4)
|
|
)
|
|
}
|
|
}
|
|
|
|
private struct WarningIcon: View {
|
|
var body: some View {
|
|
Image(systemName: "exclamationmark.triangle.fill")
|
|
.font(.system(size: AlertConstants.warningIconSize))
|
|
.foregroundColor(.orange)
|
|
.offset(x: AlertConstants.warningIconOffset, y: 4)
|
|
}
|
|
}
|
|
|
|
private struct PathSection: View {
|
|
let path: URL
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
HStack {
|
|
Text(path.path)
|
|
.font(.system(size: 13))
|
|
.foregroundColor(.blue)
|
|
.padding(8)
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 6)
|
|
.fill(Color.blue.opacity(0.05))
|
|
)
|
|
.overlay(
|
|
RoundedRectangle(cornerRadius: 6)
|
|
.stroke(Color.blue.opacity(0.1), lineWidth: 0.5)
|
|
)
|
|
.onTapGesture {
|
|
openInFinder(path)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func openInFinder(_ path: URL) {
|
|
NSWorkspace.shared.activateFileViewerSelecting([path])
|
|
}
|
|
}
|
|
|
|
private struct ButtonSection: View {
|
|
let onUseExisting: () -> Void
|
|
let onRedownload: () -> Void
|
|
let onCancel: () -> Void
|
|
|
|
var body: some View {
|
|
VStack(spacing: 12) {
|
|
ActionButton(
|
|
title: String(localized: "使用现有程序"),
|
|
icon: "checkmark.circle",
|
|
color: .blue,
|
|
action: onUseExisting
|
|
)
|
|
|
|
ActionButton(
|
|
title: String(localized: "重新下载"),
|
|
icon: "arrow.down.circle",
|
|
color: .green,
|
|
action: onRedownload
|
|
)
|
|
|
|
ActionButton(
|
|
title: String(localized: "取消"),
|
|
icon: "xmark.circle",
|
|
color: .red,
|
|
action: onCancel,
|
|
isCancel: true
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct ActionButton: View {
|
|
let title: String
|
|
let icon: String
|
|
let color: Color
|
|
let action: () -> Void
|
|
var isCancel: Bool = false
|
|
|
|
var body: some View {
|
|
Button(action: action) {
|
|
Label(title, systemImage: icon)
|
|
.frame(minWidth: 0, maxWidth: AlertConstants.buttonWidth)
|
|
.frame(height: AlertConstants.buttonHeight)
|
|
.font(.system(size: AlertConstants.buttonFontSize))
|
|
.foregroundColor(.white)
|
|
}
|
|
.buttonStyle(BeautifulButtonStyle(baseColor: color))
|
|
.if(isCancel) { view in
|
|
view.keyboardShortcut(.cancelAction)
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct BackgroundView: View {
|
|
var body: some View {
|
|
Color(NSColor.windowBackgroundColor)
|
|
.cornerRadius(AlertConstants.cornerRadius)
|
|
.shadow(radius: AlertConstants.shadowRadius)
|
|
}
|
|
}
|
|
|
|
extension View {
|
|
@ViewBuilder
|
|
fileprivate func `if`<Transform: View>(
|
|
_ condition: Bool,
|
|
transform: (Self) -> Transform
|
|
) -> some View {
|
|
if condition {
|
|
transform(self)
|
|
} else {
|
|
self
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ExistingFileAlertView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
Group {
|
|
ExistingFileAlertView(
|
|
path: URL(fileURLWithPath: "/Users/username/Downloads/Adobe/Adobe Downloader PHSP_25.0-en_US-macuniversal"),
|
|
onUseExisting: {},
|
|
onRedownload: {},
|
|
onCancel: {},
|
|
iconImage: NSImage(named: "PHSP")
|
|
)
|
|
.background(Color.black.opacity(0.3))
|
|
.previewDisplayName("Light Mode")
|
|
|
|
ExistingFileAlertView(
|
|
path: URL(fileURLWithPath: "/Users/username/Downloads/Adobe/Adobe Downloader PHSP_25.0-en_US-macuniversal"),
|
|
onUseExisting: {},
|
|
onRedownload: {},
|
|
onCancel: {},
|
|
iconImage: NSImage(named: "PHSP")
|
|
)
|
|
.background(Color.black.opacity(0.3))
|
|
.preferredColorScheme(.dark)
|
|
.previewDisplayName("Dark Mode")
|
|
}
|
|
}
|
|
}
|