|
@@ -130,18 +130,7 @@ struct WidgetsRootView: View {
|
|
|
.foregroundStyle(secondaryTextColor)
|
|
.foregroundStyle(secondaryTextColor)
|
|
|
.padding(.top, 4)
|
|
.padding(.top, 4)
|
|
|
|
|
|
|
|
- HStack(alignment: .top, spacing: 18) {
|
|
|
|
|
- ForEach(selectedVariants) { variant in
|
|
|
|
|
- WidgetPreviewAddCard(
|
|
|
|
|
- app: selectedApp,
|
|
|
|
|
- variant: variant,
|
|
|
|
|
- isAdded: isWidgetAdded(appID: selectedApp.id, variantID: variant.id),
|
|
|
|
|
- isPremiumUnlocked: premiumStore.isPremiumUnlocked,
|
|
|
|
|
- onToggle: { handleWidgetTap(app: selectedApp, variant: variant) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- Spacer(minLength: 0)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ widgetPreviewPickerRow(app: selectedApp, variants: selectedVariants)
|
|
|
} else {
|
|
} else {
|
|
|
emptyState
|
|
emptyState
|
|
|
}
|
|
}
|
|
@@ -160,6 +149,43 @@ struct WidgetsRootView: View {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @ViewBuilder
|
|
|
|
|
+ private func widgetPreviewPickerRow(app: LauncherApp, variants: [WidgetVariant]) -> some View {
|
|
|
|
|
+ if variants.isEmpty {
|
|
|
|
|
+ Color.clear.frame(height: 0)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ let rowHeightAtFullScale = variants.map(\.previewCardSize.height).max() ?? 220
|
|
|
|
|
+ GeometryReader { geo in
|
|
|
|
|
+ let spacing: CGFloat = 18
|
|
|
|
|
+ /// Space for floating + / − controls that sit slightly outside the card clip.
|
|
|
|
|
+ let horizontalChrome: CGFloat = 28
|
|
|
|
|
+ let count = variants.count
|
|
|
|
|
+ let sumWidths = variants.reduce(CGFloat(0)) { $0 + $1.previewCardSize.width }
|
|
|
|
|
+ let rawRowWidth = sumWidths + CGFloat(max(count - 1, 0)) * spacing
|
|
|
|
|
+ let available = max(geo.size.width - horizontalChrome, 50)
|
|
|
|
|
+ let unclampedScale = available / max(rawRowWidth, 1)
|
|
|
|
|
+ let minLayoutScale: CGFloat = 0.38
|
|
|
|
|
+ let scale = max(minLayoutScale, min(1, unclampedScale))
|
|
|
|
|
+
|
|
|
|
|
+ HStack(alignment: .top, spacing: spacing) {
|
|
|
|
|
+ ForEach(variants) { variant in
|
|
|
|
|
+ WidgetPreviewAddCard(
|
|
|
|
|
+ app: app,
|
|
|
|
|
+ variant: variant,
|
|
|
|
|
+ layoutScale: scale,
|
|
|
|
|
+ isAdded: isWidgetAdded(appID: app.id, variantID: variant.id),
|
|
|
|
|
+ isPremiumUnlocked: premiumStore.isPremiumUnlocked,
|
|
|
|
|
+ onToggle: { handleWidgetTap(app: app, variant: variant) }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ Spacer(minLength: 0)
|
|
|
|
|
+ }
|
|
|
|
|
+ .frame(width: geo.size.width, height: geo.size.height, alignment: .topLeading)
|
|
|
|
|
+ }
|
|
|
|
|
+ .frame(height: rowHeightAtFullScale)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private func header(for app: LauncherApp) -> some View {
|
|
private func header(for app: LauncherApp) -> some View {
|
|
|
HStack(spacing: 12) {
|
|
HStack(spacing: 12) {
|
|
|
AppIconView(app: app, size: 42, showAppBackground: false, iconPaddingFactor: 0.1)
|
|
AppIconView(app: app, size: 42, showAppBackground: false, iconPaddingFactor: 0.1)
|
|
@@ -345,6 +371,7 @@ private struct WidgetSidebarRow: View {
|
|
|
private struct WidgetPreviewAddCard: View {
|
|
private struct WidgetPreviewAddCard: View {
|
|
|
let app: LauncherApp
|
|
let app: LauncherApp
|
|
|
let variant: WidgetVariant
|
|
let variant: WidgetVariant
|
|
|
|
|
+ var layoutScale: CGFloat = 1
|
|
|
let isAdded: Bool
|
|
let isAdded: Bool
|
|
|
let isPremiumUnlocked: Bool
|
|
let isPremiumUnlocked: Bool
|
|
|
let onToggle: () -> Void
|
|
let onToggle: () -> Void
|
|
@@ -354,7 +381,7 @@ private struct WidgetPreviewAddCard: View {
|
|
|
var body: some View {
|
|
var body: some View {
|
|
|
ZStack(alignment: .topTrailing) {
|
|
ZStack(alignment: .topTrailing) {
|
|
|
Button(action: onToggle) {
|
|
Button(action: onToggle) {
|
|
|
- WidgetPreviewCard(app: app, variant: variant)
|
|
|
|
|
|
|
+ WidgetPreviewCard(app: app, variant: variant, layoutScale: layoutScale)
|
|
|
.contentShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
|
|
.contentShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
|
|
|
}
|
|
}
|
|
|
.buttonStyle(.plain)
|
|
.buttonStyle(.plain)
|
|
@@ -374,7 +401,7 @@ private struct WidgetPreviewAddCard: View {
|
|
|
.contentShape(Circle())
|
|
.contentShape(Circle())
|
|
|
}
|
|
}
|
|
|
.buttonStyle(.plain)
|
|
.buttonStyle(.plain)
|
|
|
- .offset(x: 10, y: -10)
|
|
|
|
|
|
|
+ .offset(x: 10 * layoutScale, y: -10 * layoutScale)
|
|
|
.opacity(isAdded ? 1 : (hovering ? 1 : 0))
|
|
.opacity(isAdded ? 1 : (hovering ? 1 : 0))
|
|
|
.animation(.easeOut(duration: 0.12), value: hovering)
|
|
.animation(.easeOut(duration: 0.12), value: hovering)
|
|
|
}
|
|
}
|