Add 4 new mood icon styles and improve widget layouts
New mood icon styles: - Weather (☀️ → ⛈️) - Garden (🌸 → 🥀) - Hearts (💖 → 💔) - Cosmic (⭐ → 🕳️) Widget improvements: - Small vote widget: 3-over-2 grid layout - Medium vote widget: single horizontal row - Redesigned voted stats view with checkmark badge - Fixed text truncation on non-subscriber view - Added comprehensive previews for all widget types Bug fix: - Voting header now updates when mood image style changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -726,52 +726,117 @@ struct FeelsGraphicWidget: Widget {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Preview Helpers
|
||||
|
||||
private extension FeelsWidget_Previews {
|
||||
static func sampleTimelineViews(count: Int) -> [WatchTimelineView] {
|
||||
let moods: [Mood] = [.great, .good, .average, .bad, .horrible]
|
||||
return (0..<count).map { index in
|
||||
let mood = moods[index % moods.count]
|
||||
return WatchTimelineView(
|
||||
image: EmojiMoodImages.icon(forMood: mood),
|
||||
graphic: EmojiMoodImages.icon(forMood: mood),
|
||||
date: Calendar.current.date(byAdding: .day, value: -index, to: Date())!,
|
||||
color: MoodTints.Default.color(forMood: mood),
|
||||
secondaryColor: MoodTints.Default.secondary(forMood: mood)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
static func sampleEntry(timelineCount: Int = 5) -> SimpleEntry {
|
||||
SimpleEntry(
|
||||
date: Date(),
|
||||
configuration: ConfigurationIntent(),
|
||||
timeLineViews: sampleTimelineViews(count: timelineCount),
|
||||
hasSubscription: true,
|
||||
hasVotedToday: true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct FeelsWidget_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group {
|
||||
FeelsGraphicWidgetEntryView(entry: SimpleEntry(date: Date(),
|
||||
configuration: ConfigurationIntent(),
|
||||
timeLineViews: [WatchTimelineView(image: HandEmojiMoodImages.icon(forMood: .great),
|
||||
graphic: HandEmojiMoodImages.icon(forMood: .great),
|
||||
date: Date(),
|
||||
color: MoodTints.Neon.color(forMood: .great),
|
||||
|
||||
secondaryColor: .white),
|
||||
WatchTimelineView(image: HandEmojiMoodImages.icon(forMood: .great),
|
||||
graphic: HandEmojiMoodImages.icon(forMood: .great),
|
||||
date: Date(),
|
||||
color: MoodTints.Neon.color(forMood: .great),
|
||||
|
||||
secondaryColor: .white)]))
|
||||
// MARK: - FeelsWidget (Timeline)
|
||||
FeelsWidgetEntryView(entry: sampleEntry(timelineCount: 1))
|
||||
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
||||
|
||||
FeelsGraphicWidgetEntryView(entry: SimpleEntry(date: Date(),
|
||||
configuration: ConfigurationIntent(),
|
||||
timeLineViews: [WatchTimelineView(image: HandEmojiMoodImages.icon(forMood: .horrible),
|
||||
graphic: HandEmojiMoodImages.icon(forMood: .horrible),
|
||||
date: Date(),
|
||||
color: MoodTints.Neon.color(forMood: .horrible),
|
||||
|
||||
secondaryColor: .white),
|
||||
WatchTimelineView(image: HandEmojiMoodImages.icon(forMood: .horrible),
|
||||
graphic: HandEmojiMoodImages.icon(forMood: .horrible),
|
||||
date: Date(),
|
||||
color: MoodTints.Neon.color(forMood: .horrible),
|
||||
|
||||
secondaryColor: .white)]))
|
||||
.previewDisplayName("Timeline - Small")
|
||||
|
||||
FeelsWidgetEntryView(entry: sampleEntry(timelineCount: 5))
|
||||
.previewContext(WidgetPreviewContext(family: .systemMedium))
|
||||
.previewDisplayName("Timeline - Medium")
|
||||
|
||||
FeelsWidgetEntryView(entry: sampleEntry(timelineCount: 10))
|
||||
.previewContext(WidgetPreviewContext(family: .systemLarge))
|
||||
.previewDisplayName("Timeline - Large")
|
||||
|
||||
// MARK: - FeelsGraphicWidget (Mood Graphic)
|
||||
FeelsGraphicWidgetEntryView(entry: sampleEntry(timelineCount: 2))
|
||||
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
||||
|
||||
// FeelsWidgetEntryView(entry: SimpleEntry(date: Date(),
|
||||
// configuration: ConfigurationIntent(),
|
||||
// timeLineViews: FeelsWidget_Previews.data))
|
||||
// .previewContext(WidgetPreviewContext(family: .systemMedium))
|
||||
// .environment(\.sizeCategory, .medium)
|
||||
//
|
||||
// FeelsWidgetEntryView(entry: SimpleEntry(date: Date(),
|
||||
// configuration: ConfigurationIntent(),
|
||||
// timeLineViews: FeelsWidget_Previews.data))
|
||||
// .previewContext(WidgetPreviewContext(family: .systemLarge))
|
||||
// .environment(\.sizeCategory, .large)
|
||||
.previewDisplayName("Mood Graphic - Small")
|
||||
|
||||
// MARK: - FeelsIconWidget (Custom Icon)
|
||||
FeelsIconWidgetEntryView(entry: sampleEntry())
|
||||
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
||||
.previewDisplayName("Custom Icon - Small")
|
||||
|
||||
// MARK: - FeelsVoteWidget (Vote - Not Voted)
|
||||
FeelsVoteWidgetEntryView(entry: VoteWidgetEntry(
|
||||
date: Date(),
|
||||
hasSubscription: true,
|
||||
hasVotedToday: false,
|
||||
todaysMood: nil,
|
||||
stats: nil,
|
||||
promptText: "How are you feeling?"
|
||||
))
|
||||
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
||||
.previewDisplayName("Vote - Small (Not Voted)")
|
||||
|
||||
FeelsVoteWidgetEntryView(entry: VoteWidgetEntry(
|
||||
date: Date(),
|
||||
hasSubscription: true,
|
||||
hasVotedToday: false,
|
||||
todaysMood: nil,
|
||||
stats: nil,
|
||||
promptText: "How are you feeling?"
|
||||
))
|
||||
.previewContext(WidgetPreviewContext(family: .systemMedium))
|
||||
.previewDisplayName("Vote - Medium (Not Voted)")
|
||||
|
||||
// MARK: - FeelsVoteWidget (Vote - Already Voted)
|
||||
FeelsVoteWidgetEntryView(entry: VoteWidgetEntry(
|
||||
date: Date(),
|
||||
hasSubscription: true,
|
||||
hasVotedToday: true,
|
||||
todaysMood: .great,
|
||||
stats: MoodStats(totalEntries: 30, moodCounts: [.great: 10, .good: 12, .average: 5, .bad: 2, .horrible: 1]),
|
||||
promptText: ""
|
||||
))
|
||||
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
||||
.previewDisplayName("Vote - Small (Voted)")
|
||||
|
||||
FeelsVoteWidgetEntryView(entry: VoteWidgetEntry(
|
||||
date: Date(),
|
||||
hasSubscription: true,
|
||||
hasVotedToday: true,
|
||||
todaysMood: .good,
|
||||
stats: MoodStats(totalEntries: 45, moodCounts: [.great: 15, .good: 18, .average: 8, .bad: 3, .horrible: 1]),
|
||||
promptText: ""
|
||||
))
|
||||
.previewContext(WidgetPreviewContext(family: .systemMedium))
|
||||
.previewDisplayName("Vote - Medium (Voted)")
|
||||
|
||||
// MARK: - FeelsVoteWidget (Non-Subscriber)
|
||||
FeelsVoteWidgetEntryView(entry: VoteWidgetEntry(
|
||||
date: Date(),
|
||||
hasSubscription: false,
|
||||
hasVotedToday: false,
|
||||
todaysMood: nil,
|
||||
stats: nil,
|
||||
promptText: ""
|
||||
))
|
||||
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
||||
.previewDisplayName("Vote - Small (Non-Subscriber)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user