Ablage und AirDrop teilen sich eine Kachel
Zwei eigene Kacheln waren zu viel des Guten: beide zeigen im Ruhezustand nichts als eine leere Fläche mit einem Satz darin, und zusammen nahmen sie ein Drittel des Panels. Jetzt übereinander in einer Kachel — oben die Ablegefläche fürs Senden, darunter die Ablage mit ihrer Liste. AirDrop steht dabei nebeneinander statt übereinander: in 52 Punkten Höhe ist für Symbol über Text kein Platz. Das eigenständige AirDrop-Widget entfällt. Gespeicherte Layouts, die es noch nennen, verlieren den Eintrag beim Laden — dafür ist der Filter da. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -229,8 +229,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
|
|
||||||
let shelfStore = ShelfStore()
|
let shelfStore = ShelfStore()
|
||||||
self.shelfStore = shelfStore
|
self.shelfStore = shelfStore
|
||||||
|
// AirDrop steckt in der Ablage-Kachel — zwei eigene Kacheln für je
|
||||||
|
// eine leere Ablegefläche waren ein Drittel des Panels.
|
||||||
WidgetRegistry.shared.register(ShelfWidget(store: shelfStore))
|
WidgetRegistry.shared.register(ShelfWidget(store: shelfStore))
|
||||||
WidgetRegistry.shared.register(AirDropWidget())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func applyContentSize() {
|
private func applyContentSize() {
|
||||||
|
|||||||
@@ -31,22 +31,48 @@ public enum AirDrop {
|
|||||||
|
|
||||||
/// Eine Fläche, auf die man Dateien fallen lässt, um sie zu verschicken.
|
/// Eine Fläche, auf die man Dateien fallen lässt, um sie zu verschicken.
|
||||||
public struct AirDropView: View {
|
public struct AirDropView: View {
|
||||||
|
/// Schmal, wenn sie sich die Kachel mit der Ablage teilt.
|
||||||
|
private let compact: Bool
|
||||||
@State private var isTargeted = false
|
@State private var isTargeted = false
|
||||||
@State private var failed = false
|
@State private var failed = false
|
||||||
|
|
||||||
public init() {}
|
public init(compact: Bool = false) {
|
||||||
|
self.compact = compact
|
||||||
|
}
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
|
Group {
|
||||||
|
if compact {
|
||||||
|
// Nebeneinander statt übereinander: in 52 Punkten Höhe ist für
|
||||||
|
// Symbol über Text kein Platz.
|
||||||
|
HStack(spacing: 8) {
|
||||||
|
Image(systemName: "shareplay")
|
||||||
|
.font(.system(size: 15, weight: .light))
|
||||||
|
.foregroundStyle(isTargeted ? Onyx.Color.accent
|
||||||
|
: Onyx.Color.textTertiary)
|
||||||
|
Text(failed ? "airdrop.unavailable" : "airdrop.hint", bundle: .module)
|
||||||
|
.font(Onyx.Font.caption)
|
||||||
|
.foregroundStyle(failed ? Onyx.Color.warning
|
||||||
|
: Onyx.Color.textSecondary)
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
Spacer(minLength: 0)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
} else {
|
||||||
VStack(spacing: 6) {
|
VStack(spacing: 6) {
|
||||||
Image(systemName: "shareplay")
|
Image(systemName: "shareplay")
|
||||||
.font(.system(size: 20, weight: .light))
|
.font(.system(size: 20, weight: .light))
|
||||||
.foregroundStyle(isTargeted ? Onyx.Color.accent : Onyx.Color.textTertiary)
|
.foregroundStyle(isTargeted ? Onyx.Color.accent
|
||||||
|
: Onyx.Color.textTertiary)
|
||||||
Text(failed ? "airdrop.unavailable" : "airdrop.hint", bundle: .module)
|
Text(failed ? "airdrop.unavailable" : "airdrop.hint", bundle: .module)
|
||||||
.font(Onyx.Font.caption)
|
.font(Onyx.Font.caption)
|
||||||
.foregroundStyle(failed ? Onyx.Color.warning : Onyx.Color.textSecondary)
|
.foregroundStyle(failed ? Onyx.Color.warning
|
||||||
|
: Onyx.Color.textSecondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
.background {
|
.background {
|
||||||
RoundedRectangle(cornerRadius: 10, style: .continuous)
|
RoundedRectangle(cornerRadius: 10, style: .continuous)
|
||||||
@@ -60,17 +86,3 @@ public struct AirDropView: View {
|
|||||||
.animation(Onyx.Motion.value, value: isTargeted)
|
.animation(Onyx.Motion.value, value: isTargeted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Widget
|
|
||||||
|
|
||||||
public struct AirDropWidget: OnyxWidget {
|
|
||||||
public let id = "airdrop"
|
|
||||||
public var displayName: String { String(localized: "airdrop.name", bundle: .module) }
|
|
||||||
public let symbolName = "shareplay"
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
|
|
||||||
public func makeView() -> AnyView {
|
|
||||||
AnyView(AirDropView())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
"de": {
|
"de": {
|
||||||
"stringUnit": {
|
"stringUnit": {
|
||||||
"state": "translated",
|
"state": "translated",
|
||||||
"value": "Dateien zum Senden ablegen"
|
"value": "Zum Senden ablegen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"stringUnit": {
|
"stringUnit": {
|
||||||
"state": "translated",
|
"state": "translated",
|
||||||
"value": "Drop files to send"
|
"value": "Drop to send"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,13 +118,13 @@
|
|||||||
"de": {
|
"de": {
|
||||||
"stringUnit": {
|
"stringUnit": {
|
||||||
"state": "translated",
|
"state": "translated",
|
||||||
"value": "Ablage"
|
"value": "Ablage & AirDrop"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"stringUnit": {
|
"stringUnit": {
|
||||||
"state": "translated",
|
"state": "translated",
|
||||||
"value": "Shelf"
|
"value": "Shelf & AirDrop"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,6 +187,12 @@ private struct ShelfRow: View {
|
|||||||
|
|
||||||
// MARK: - Widget
|
// MARK: - Widget
|
||||||
|
|
||||||
|
/// Ablage und AirDrop in **einer** Kachel.
|
||||||
|
///
|
||||||
|
/// Zwei eigene Kacheln waren zu viel des Guten: beide zeigen im Ruhezustand
|
||||||
|
/// nichts als eine leere Fläche mit einem Satz darin, und zusammen nahmen sie
|
||||||
|
/// ein Drittel des Panels. Übereinander in einer Kachel bleibt beides
|
||||||
|
/// erreichbar und kostet halb so viel Platz.
|
||||||
public struct ShelfWidget: OnyxWidget {
|
public struct ShelfWidget: OnyxWidget {
|
||||||
public let id = "shelf"
|
public let id = "shelf"
|
||||||
public var displayName: String { String(localized: "shelf.name", bundle: .module) }
|
public var displayName: String { String(localized: "shelf.name", bundle: .module) }
|
||||||
@@ -197,6 +203,17 @@ public struct ShelfWidget: OnyxWidget {
|
|||||||
public init(store: ShelfStore) { self.store = store }
|
public init(store: ShelfStore) { self.store = store }
|
||||||
|
|
||||||
public func makeView() -> AnyView {
|
public func makeView() -> AnyView {
|
||||||
AnyView(ShelfView(store: store))
|
AnyView(
|
||||||
|
VStack(spacing: 8) {
|
||||||
|
// AirDrop oben und schmal: es ist eine reine Ablegefläche ohne
|
||||||
|
// Zustand, die Ablage darunter braucht den Platz für ihre Liste.
|
||||||
|
AirDropView(compact: true)
|
||||||
|
.frame(height: 52)
|
||||||
|
|
||||||
|
Divider().overlay(Onyx.Color.hairline)
|
||||||
|
|
||||||
|
ShelfView(store: store)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user