Complete rename across all bundle IDs, App Groups, CloudKit containers, StoreKit product IDs, data store filenames, URL schemes, logger subsystems, Swift identifiers, user-facing strings (7 languages), file names, directory names, Xcode project, schemes, assets, and documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
210 lines
7.0 KiB
Swift
210 lines
7.0 KiB
Swift
//
|
|
// CurrentStreakVariations.swift
|
|
// Reflect
|
|
//
|
|
// 2 design variations for the Current Streak (Last 10 Days) sharing template.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
// MARK: - V2 "Gradient Cards" — 2x5 grid of colored cards
|
|
|
|
struct CurrentStreakV2: View {
|
|
let moodEntries: [MoodEntryModel]
|
|
|
|
@AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults)
|
|
private var moodTint: MoodTints = .Default
|
|
|
|
private let dayFormatter: DateFormatter = {
|
|
let f = DateFormatter()
|
|
f.dateFormat = "EEE"
|
|
return f
|
|
}()
|
|
|
|
private let numFormatter: DateFormatter = {
|
|
let f = DateFormatter()
|
|
f.dateFormat = "d"
|
|
return f
|
|
}()
|
|
|
|
var image: UIImage {
|
|
shareView.asImage(size: CGSize(width: 666, height: 1190))
|
|
}
|
|
|
|
let columns = [
|
|
GridItem(.flexible(), spacing: 16),
|
|
GridItem(.flexible(), spacing: 16)
|
|
]
|
|
|
|
var shareView: some View {
|
|
ZStack {
|
|
LinearGradient(
|
|
colors: [Color(hex: "FFF5EE"), Color(hex: "FFE8D6")],
|
|
startPoint: .top,
|
|
endPoint: .bottom
|
|
)
|
|
|
|
VStack(spacing: 0) {
|
|
Spacer().frame(height: 40)
|
|
|
|
Text("Last 10 Days")
|
|
.font(.system(size: 28, weight: .bold, design: .rounded))
|
|
.foregroundColor(Color(hex: "4A2810"))
|
|
|
|
Spacer().frame(height: 6)
|
|
|
|
Text("Your recent moods")
|
|
.font(.system(size: 16, weight: .medium, design: .rounded))
|
|
.foregroundColor(Color(hex: "8B5E3C").opacity(0.7))
|
|
|
|
Spacer().frame(height: 24)
|
|
|
|
LazyVGrid(columns: columns, spacing: 12) {
|
|
ForEach(moodEntries) { entry in
|
|
VStack(spacing: 8) {
|
|
entry.mood.icon
|
|
.resizable()
|
|
.aspectRatio(contentMode: .fit)
|
|
.frame(width: 36, height: 36)
|
|
.foregroundColor(.white)
|
|
|
|
Text(dayFormatter.string(from: entry.forDate ?? Date()))
|
|
.font(.system(size: 14, weight: .semibold, design: .rounded))
|
|
.foregroundColor(.white.opacity(0.9))
|
|
|
|
Text(numFormatter.string(from: entry.forDate ?? Date()))
|
|
.font(.system(size: 28, weight: .heavy, design: .rounded))
|
|
.foregroundColor(.white)
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.vertical, 16)
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 20)
|
|
.fill(moodTint.color(forMood: entry.mood))
|
|
.shadow(color: moodTint.color(forMood: entry.mood).opacity(0.3), radius: 10, y: 5)
|
|
)
|
|
}
|
|
}
|
|
.padding(.horizontal, 36)
|
|
|
|
Spacer()
|
|
|
|
VStack(spacing: 10) {
|
|
Image("ReflectAppIcon")
|
|
.resizable()
|
|
.aspectRatio(contentMode: .fit)
|
|
.frame(width: 96, height: 96)
|
|
.clipShape(RoundedRectangle(cornerRadius: 22))
|
|
|
|
Text("Reflect")
|
|
.font(.system(size: 28, weight: .semibold, design: .rounded))
|
|
.foregroundColor(Color(hex: "8B5E3C").opacity(0.4))
|
|
}
|
|
|
|
Spacer().frame(height: 50)
|
|
}
|
|
}
|
|
.frame(width: 666, height: 1190)
|
|
}
|
|
|
|
var body: some View { shareView }
|
|
}
|
|
|
|
// MARK: - V5 "Color Strips" — Full-width mood-colored horizontal strips
|
|
|
|
struct CurrentStreakV5: View {
|
|
let moodEntries: [MoodEntryModel]
|
|
|
|
@AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults)
|
|
private var moodTint: MoodTints = .Default
|
|
|
|
private let dayFormatter: DateFormatter = {
|
|
let f = DateFormatter()
|
|
f.dateFormat = "EEEE"
|
|
return f
|
|
}()
|
|
|
|
private let numFormatter: DateFormatter = {
|
|
let f = DateFormatter()
|
|
f.dateFormat = "d"
|
|
return f
|
|
}()
|
|
|
|
var image: UIImage {
|
|
shareView.asImage(size: CGSize(width: 666, height: 1190))
|
|
}
|
|
|
|
var shareView: some View {
|
|
ZStack {
|
|
Color(hex: "1C1C1E")
|
|
|
|
VStack(spacing: 0) {
|
|
// Header
|
|
VStack(spacing: 4) {
|
|
Text("10 DAYS")
|
|
.font(.system(size: 16, weight: .heavy, design: .rounded))
|
|
.foregroundColor(.white)
|
|
.tracking(4)
|
|
|
|
Text("of feeling")
|
|
.font(.system(size: 13, weight: .medium, design: .rounded))
|
|
.foregroundColor(.white.opacity(0.5))
|
|
}
|
|
.frame(height: 80)
|
|
|
|
// Color strips
|
|
ForEach(moodEntries) { entry in
|
|
ZStack {
|
|
moodTint.color(forMood: entry.mood)
|
|
|
|
HStack {
|
|
entry.mood.icon
|
|
.resizable()
|
|
.aspectRatio(contentMode: .fit)
|
|
.frame(width: 28, height: 28)
|
|
.foregroundColor(.white.opacity(0.9))
|
|
|
|
Text(entry.mood.strValue)
|
|
.font(.system(size: 18, weight: .bold, design: .rounded))
|
|
.foregroundColor(.white)
|
|
|
|
Spacer()
|
|
|
|
Text(dayFormatter.string(from: entry.forDate ?? Date()))
|
|
.font(.system(size: 14, weight: .medium, design: .rounded))
|
|
.foregroundColor(.white.opacity(0.7))
|
|
|
|
Text(numFormatter.string(from: entry.forDate ?? Date()))
|
|
.font(.system(size: 28, weight: .heavy, design: .rounded))
|
|
.foregroundColor(.white)
|
|
}
|
|
.padding(.horizontal, 32)
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.frame(height: 84)
|
|
}
|
|
|
|
Spacer()
|
|
|
|
// Footer
|
|
VStack(spacing: 10) {
|
|
Image("ReflectAppIcon")
|
|
.resizable()
|
|
.aspectRatio(contentMode: .fit)
|
|
.frame(width: 96, height: 96)
|
|
.clipShape(RoundedRectangle(cornerRadius: 22))
|
|
|
|
Text("Reflect")
|
|
.font(.system(size: 28, weight: .bold, design: .rounded))
|
|
.foregroundColor(.white.opacity(0.3))
|
|
}
|
|
|
|
Spacer().frame(height: 40)
|
|
}
|
|
}
|
|
.frame(width: 666, height: 1190)
|
|
}
|
|
|
|
var body: some View { shareView }
|
|
}
|