diff --git a/.maestro/enrichedMarkdownText/screenshots/android/mixed_nested_list_display.png b/.maestro/enrichedMarkdownText/screenshots/android/mixed_nested_list_display.png index f361ea8b..906e1b31 100644 Binary files a/.maestro/enrichedMarkdownText/screenshots/android/mixed_nested_list_display.png and b/.maestro/enrichedMarkdownText/screenshots/android/mixed_nested_list_display.png differ diff --git a/.maestro/enrichedMarkdownText/screenshots/android/nested_unordered_list_display.png b/.maestro/enrichedMarkdownText/screenshots/android/nested_unordered_list_display.png index 5ad507c5..1ba4e26f 100644 Binary files a/.maestro/enrichedMarkdownText/screenshots/android/nested_unordered_list_display.png and b/.maestro/enrichedMarkdownText/screenshots/android/nested_unordered_list_display.png differ diff --git a/.maestro/enrichedMarkdownText/screenshots/ios/mixed_nested_list_display.png b/.maestro/enrichedMarkdownText/screenshots/ios/mixed_nested_list_display.png index 92acab09..f52249b5 100644 Binary files a/.maestro/enrichedMarkdownText/screenshots/ios/mixed_nested_list_display.png and b/.maestro/enrichedMarkdownText/screenshots/ios/mixed_nested_list_display.png differ diff --git a/.maestro/enrichedMarkdownText/screenshots/ios/nested_unordered_list_display.png b/.maestro/enrichedMarkdownText/screenshots/ios/nested_unordered_list_display.png index 3e9a633c..287ba88d 100644 Binary files a/.maestro/enrichedMarkdownText/screenshots/ios/nested_unordered_list_display.png and b/.maestro/enrichedMarkdownText/screenshots/ios/nested_unordered_list_display.png differ diff --git a/.maestro/scripts/setup-ios-simulator.sh b/.maestro/scripts/setup-ios-simulator.sh index e7761d63..6a9b9578 100755 --- a/.maestro/scripts/setup-ios-simulator.sh +++ b/.maestro/scripts/setup-ios-simulator.sh @@ -31,8 +31,13 @@ if [ "$STATE" != "(Booted)" ]; then xcrun simctl boot "$UDID" # `bootstatus -b` exits before the app registry is ready on some runtimes. # Polling listapps for a built-in app is better signal that SpringBoard is up. - echo "Waiting for simulator to finish booting..." + echo "Waiting for simulator to finish booting (max 20s)..." + SECONDS=0 until xcrun simctl listapps "$UDID" 2>/dev/null | grep -q "com.apple.Preferences"; do + if (( SECONDS >= 20 )); then + echo "Timed out waiting for SpringBoard; continuing to build step to unstick the simulator." + break + fi sleep 2 done fi diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt index 6fc33c86..2b3465aa 100644 --- a/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt @@ -35,11 +35,14 @@ class UnorderedListSpan( } private val radius: Float = listStyle.bulletSize / 2f + private val ringStrokeWidth: Float = radius * 0.3f private val markerColumnWidth: Float = listStyle.effectiveMarkerWidth(radius) private fun configureBulletPaint(): Paint = sharedBulletPaint.apply { color = listStyle.bulletColor + style = Paint.Style.FILL + strokeWidth = 0f } override fun getMarkerWidth(): Float = markerColumnWidth @@ -64,6 +67,26 @@ class UnorderedListSpan( val fontMetrics = paint.fontMetrics val bulletY = baseline + (fontMetrics.ascent + fontMetrics.descent) / 2f - canvas.drawCircle(bulletX, bulletY, radius, bulletPaint) + when (depth) { + 0 -> { + canvas.drawCircle(bulletX, bulletY, radius, bulletPaint) + } + + 1 -> { + bulletPaint.style = Paint.Style.STROKE + bulletPaint.strokeWidth = ringStrokeWidth + canvas.drawCircle(bulletX, bulletY, radius - ringStrokeWidth / 2f, bulletPaint) + } + + else -> { + canvas.drawRect( + bulletX - radius, + bulletY - radius, + bulletX + radius, + bulletY + radius, + bulletPaint, + ) + } + } } } diff --git a/ios/styles/StyleConfig.h b/ios/styles/StyleConfig.h index 8b63e9dc..397b2f04 100644 --- a/ios/styles/StyleConfig.h +++ b/ios/styles/StyleConfig.h @@ -15,8 +15,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong, nullable) RCTUIColor *backgroundColor; @end -NS_ASSUME_NONNULL_END - @interface StyleConfig : NSObject - (instancetype)init; - (CGFloat)fontScaleMultiplier; @@ -400,3 +398,5 @@ NS_ASSUME_NONNULL_END - (void)setSubscriptBaselineOffsetScale:(CGFloat)newValue; @end + +NS_ASSUME_NONNULL_END diff --git a/ios/utils/ListMarkerDrawer.m b/ios/utils/ListMarkerDrawer.m index e2dafdd3..94095589 100644 --- a/ios/utils/ListMarkerDrawer.m +++ b/ios/utils/ListMarkerDrawer.m @@ -80,8 +80,10 @@ - (void)drawMarkersForGlyphRange:(NSRange)glyphsToShow checked:checked]; } else if ([attrs[ListTypeAttribute] integerValue] == ListTypeUnordered) { UIFont *font = attrs[NSFontAttributeName] ?: [self defaultFont]; + NSInteger depth = [attrs[ListDepthAttribute] integerValue]; [self drawBulletAtX:markerX - centerY:baselineY - (font.xHeight + font.capHeight) / 4.0]; + centerY:baselineY - (font.xHeight + font.capHeight) / 4.0 + depth:depth]; } else { [self drawOrderedMarkerAtX:markerX attrs:attrs baselineY:baselineY isRTL:isRTL]; } @@ -138,13 +140,29 @@ - (void)drawCheckmarkInsideRect:(CGRect)rect size:(CGFloat)size [checkmark stroke]; } -- (void)drawBulletAtX:(CGFloat)x centerY:(CGFloat)y +- (void)drawBulletAtX:(CGFloat)x centerY:(CGFloat)y depth:(NSInteger)depth { + CGFloat size = [_config listStyleBulletSize]; + CGRect rect = CGRectMake(x - size / 2.0, y - size / 2.0, size, size); [self executeDrawing:^(CGContextRef ctx) { - [[_config listStyleBulletColor] setFill]; - CGFloat size = [_config listStyleBulletSize]; - CGContextFillEllipseInRect(ctx, CGRectMake(x - size / 2.0, y - size / 2.0, size, size)); + switch (depth) { + case 0: + [[_config listStyleBulletColor] setFill]; + CGContextFillEllipseInRect(ctx, rect); + break; + case 1: { + CGFloat lineWidth = MAX(1.0, size * 0.15); + [[_config listStyleBulletColor] setStroke]; + CGContextSetLineWidth(ctx, lineWidth); + CGContextStrokeEllipseInRect(ctx, CGRectInset(rect, lineWidth / 2.0, lineWidth / 2.0)); + break; + } + default: + [[_config listStyleBulletColor] setFill]; + CGContextFillRect(ctx, rect); + break; + } } atX:x y:y]; @@ -192,4 +210,4 @@ - (BOOL)isValidX:(CGFloat)x y:(CGFloat)y return !isnan(x) && !isinf(x) && !isnan(y) && !isinf(y); } -@end \ No newline at end of file +@end