fixed missing period times in the ios widget ruler and unreadable tiles on tinted and clear home screens
A .systemLarge widget only gets ~27pt per period, below the 30pt threshold shared with Android, so iOS now shows the times from 24pt with a tighter cell. In non-full-color rendering modes the opaque tiles and the today circle flattened into solid slabs hiding their text; they are drawn translucent with an outline there and use the light-text palette. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -147,7 +147,8 @@ struct PeriodRuler: View {
|
||||
.font(.system(size: timeFont))
|
||||
.foregroundStyle(palette.textSecondary)
|
||||
.lineLimit(1)
|
||||
.padding(.vertical, 2)
|
||||
.minimumScaleFactor(0.8)
|
||||
.padding(.vertical, 1)
|
||||
}
|
||||
}
|
||||
.frame(width: RULER_WIDTH, height: height)
|
||||
@@ -304,6 +305,8 @@ private struct LessonTile: View {
|
||||
let metrics: TileMetrics
|
||||
let layout: TileTextLayout
|
||||
|
||||
@Environment(\.widgetRenderingMode) private var renderingMode
|
||||
|
||||
private static let cancelledRed =
|
||||
Color(red: 244 / 255, green: 67 / 255, blue: 54 / 255).opacity(200 / 255)
|
||||
|
||||
@@ -326,7 +329,7 @@ private struct LessonTile: View {
|
||||
.padding(.vertical, TILE_PADDING_V)
|
||||
.frame(maxWidth: .infinity, alignment: .topLeading)
|
||||
.frame(height: height, alignment: .topLeading)
|
||||
.background(lesson.tileColor)
|
||||
.background { tileBackground(shape) }
|
||||
.clipShape(shape)
|
||||
.overlay(alignment: .bottomTrailing) {
|
||||
if let count = lesson.siblingCount, count > 0 {
|
||||
@@ -357,6 +360,22 @@ private struct LessonTile: View {
|
||||
.padding(.horizontal, TILE_MARGIN_H)
|
||||
}
|
||||
|
||||
/// Tinted / clear home screens flatten an opaque colour block into a
|
||||
/// solid slab the white text disappears on; a translucent fill with an
|
||||
/// outline keeps tile and text apart in every rendering mode.
|
||||
@ViewBuilder
|
||||
private func tileBackground(_ shape: RoundedRectangle) -> some View {
|
||||
if renderingMode == .fullColor {
|
||||
lesson.tileColor
|
||||
} else {
|
||||
ZStack {
|
||||
shape.fill(Color.white.opacity(0.18))
|
||||
shape.strokeBorder(Color.white.opacity(0.55), lineWidth: 1)
|
||||
}
|
||||
.widgetAccentable()
|
||||
}
|
||||
}
|
||||
|
||||
private var titleRow: some View {
|
||||
HStack(alignment: .center, spacing: 3) {
|
||||
Text(layout.title)
|
||||
|
||||
@@ -47,7 +47,10 @@ let TITLE_WRAP_BELOW_FONT: CGFloat = 8
|
||||
let BADGE_WIDTH: CGFloat = 16
|
||||
let BADGE_HEIGHT: CGFloat = 11
|
||||
|
||||
let RULER_TIMES_MIN_CELL: CGFloat = 30
|
||||
/// Lower than Android's 30dp: a .systemLarge widget only gets ~27pt per
|
||||
/// period, so iOS packs the ruler cell tighter (see PeriodRuler.cell)
|
||||
/// instead of dropping the times.
|
||||
let RULER_TIMES_MIN_CELL: CGFloat = 24
|
||||
let BREAK_ICON_MIN_HEIGHT: CGFloat = 12
|
||||
|
||||
/// Space the holiday column keeps free above and below the rotated name for
|
||||
|
||||
@@ -4,6 +4,7 @@ import WidgetKit
|
||||
struct TimetableWeekView: View {
|
||||
let entry: TimetableEntry
|
||||
@Environment(\.widgetPalette) private var palette
|
||||
@Environment(\.widgetRenderingMode) private var renderingMode
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
@@ -115,13 +116,23 @@ struct TimetableWeekView: View {
|
||||
.lineLimit(1)
|
||||
Text("\(Calendar.current.component(.day, from: day))")
|
||||
.font(.system(size: 11, weight: isToday ? .bold : .regular))
|
||||
.foregroundStyle(isToday ? palette.onAccent : palette.textPrimary)
|
||||
.foregroundStyle(isToday ? todayNumberColor : palette.textPrimary)
|
||||
.lineLimit(1)
|
||||
.frame(width: 18, height: 18)
|
||||
.background(Circle().fill(isToday ? palette.accent : Color.clear))
|
||||
.background(Circle().fill(isToday ? todayCircleColor : Color.clear))
|
||||
}
|
||||
}
|
||||
|
||||
// An opaque accent circle flattens to the same shade as its number on
|
||||
// tinted / clear home screens; keep the circle translucent there.
|
||||
private var todayCircleColor: Color {
|
||||
renderingMode == .fullColor ? palette.accent : Color.white.opacity(0.3)
|
||||
}
|
||||
|
||||
private var todayNumberColor: Color {
|
||||
renderingMode == .fullColor ? palette.onAccent : palette.textPrimary
|
||||
}
|
||||
|
||||
private func placeholder(_ message: String) -> some View {
|
||||
VStack(spacing: 4) {
|
||||
Text("Marianum Stundenplan")
|
||||
|
||||
@@ -201,12 +201,15 @@ private struct WidgetSurface<Content: View>: View {
|
||||
let entry: TimetableEntry
|
||||
@ViewBuilder let content: () -> Content
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
@Environment(\.widgetRenderingMode) private var renderingMode
|
||||
|
||||
var body: some View {
|
||||
let palette = WidgetPalette.resolve(
|
||||
themeMode: entry.themeMode,
|
||||
colorScheme: colorScheme
|
||||
)
|
||||
// Tinted / clear home screens map every colour to its luminance, so
|
||||
// the light palette's near-black text would vanish — use the dark
|
||||
// palette's light text there regardless of the theme setting.
|
||||
let palette = renderingMode == .fullColor
|
||||
? WidgetPalette.resolve(themeMode: entry.themeMode, colorScheme: colorScheme)
|
||||
: .dark
|
||||
return AnyView(
|
||||
background(content: content(), palette: palette)
|
||||
.environment(\.widgetPalette, palette)
|
||||
|
||||
Reference in New Issue
Block a user