Add insights screenshot export and improve promo video phone frames
- Add ExportableInsightsViews with sample AI insights data - Add InsightsExporter service for light/dark mode screenshots - Add export insights button to Settings debug section - Update ConceptB promo to use insights_light.png in privacy scene - Fix phone frame clipping with overflow hidden and borderRadius 64 - Add timeline voting widget images for promo video Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
103
Shared/Services/InsightsExporter.swift
Normal file
103
Shared/Services/InsightsExporter.swift
Normal file
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// InsightsExporter.swift
|
||||
// Feels
|
||||
//
|
||||
// Debug utility to export insights view screenshots with sample AI data.
|
||||
//
|
||||
|
||||
#if DEBUG
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
|
||||
/// Exports insights view screenshots for App Store marketing
|
||||
@MainActor
|
||||
class InsightsExporter {
|
||||
|
||||
// MARK: - Screen Sizes (iPhone 15 Pro Max @ 3x)
|
||||
|
||||
/// Full screen size for insights export
|
||||
static let screenSize = CGSize(width: 430, height: 932)
|
||||
|
||||
// MARK: - Export All Insights Screenshots
|
||||
|
||||
/// Exports insights screenshots in light and dark mode
|
||||
/// - Returns: URL to the export directory, or nil if failed
|
||||
static func exportInsightsScreenshots() async -> URL? {
|
||||
let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||
let exportPath = documentsPath.appendingPathComponent("InsightsExports", isDirectory: true)
|
||||
|
||||
// Clean and create export directory
|
||||
try? FileManager.default.removeItem(at: exportPath)
|
||||
try? FileManager.default.createDirectory(at: exportPath, withIntermediateDirectories: true)
|
||||
|
||||
var totalExported = 0
|
||||
|
||||
// Export with default tint and emoji pack
|
||||
let moodTint: MoodTints = .Default
|
||||
let imagePack: MoodImages = .Emoji
|
||||
|
||||
// Export light mode
|
||||
await exportInsightsView(
|
||||
colorScheme: .light,
|
||||
moodTint: moodTint,
|
||||
imagePack: imagePack,
|
||||
to: exportPath,
|
||||
name: "insights_light"
|
||||
)
|
||||
totalExported += 1
|
||||
|
||||
// Export dark mode
|
||||
await exportInsightsView(
|
||||
colorScheme: .dark,
|
||||
moodTint: moodTint,
|
||||
imagePack: imagePack,
|
||||
to: exportPath,
|
||||
name: "insights_dark"
|
||||
)
|
||||
totalExported += 1
|
||||
|
||||
print("✨ Total \(totalExported) insights screenshots exported to: \(exportPath.path)")
|
||||
return exportPath
|
||||
}
|
||||
|
||||
// MARK: - Export Single Screenshot
|
||||
|
||||
private static func exportInsightsView(
|
||||
colorScheme: ColorScheme,
|
||||
moodTint: MoodTints,
|
||||
imagePack: MoodImages,
|
||||
to folder: URL,
|
||||
name: String
|
||||
) async {
|
||||
let content = ExportableInsightsView(
|
||||
colorScheme: colorScheme,
|
||||
moodTint: moodTint,
|
||||
imagePack: imagePack
|
||||
)
|
||||
|
||||
let view = ExportableInsightsContainer(
|
||||
width: screenSize.width,
|
||||
height: screenSize.height,
|
||||
colorScheme: colorScheme
|
||||
) {
|
||||
content
|
||||
}
|
||||
|
||||
await renderAndSave(view: view, to: folder, name: name)
|
||||
}
|
||||
|
||||
// MARK: - Render and Save
|
||||
|
||||
private static func renderAndSave<V: View>(view: V, to folder: URL, name: String) async {
|
||||
let renderer = ImageRenderer(content: view.frame(width: screenSize.width, height: screenSize.height))
|
||||
renderer.scale = 3.0 // 3x for high res
|
||||
|
||||
if let image = renderer.uiImage {
|
||||
let url = folder.appendingPathComponent("\(name).png")
|
||||
if let data = image.pngData() {
|
||||
try? data.write(to: url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user