Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 4 additions & 22 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/scinfu/SwiftSoup.git", from: "2.7.5"),
.package(url: "https://github.com/SVGKit/SVGKit", from: "3.0.0"),
.package(url: "https://github.com/exyte/SVGView.git", from: "1.0.6"),
],
targets: [
.target(
name: "GutenbergKit",
dependencies: ["SwiftSoup", "SVGKit"],
dependencies: ["SwiftSoup", "SVGView"],
path: "ios/Sources/GutenbergKit",
exclude: [],
resources: [.copy("Gutenberg")]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 8 additions & 12 deletions ios/Sources/GutenbergKit/Sources/Helpers/BlockIconCache.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Foundation
import SVGKit
import SVGView

@MainActor
final class BlockIconCache: ObservableObject {
var icons: [String: Result<SVGKImage, Error>] = [:]
var icons: [String: Result<SVGNode, Error>] = [:]

func getIcon(for block: BlockType) -> SVGKImage? {
func getIcon(for block: BlockType) -> SVGNode? {
if let result = icons[block.id] {
return try? result.get()
}
Expand All @@ -14,19 +14,15 @@ final class BlockIconCache: ObservableObject {
return try? result.get()
}

private func _getIcon(for block: BlockType) throws -> SVGKImage {
guard let svg = block.icon,
!svg.isEmpty,
let source = SVGKSourceString.source(fromContentsOf: svg),
let image = SVGKImage(source: source) else {
private func _getIcon(for block: BlockType) throws -> SVGNode {
guard let svg = block.icon, !svg.isEmpty else {
throw BlockIconCacheError.unknown
}
if let result = image.parseErrorsAndWarnings,
let error = result.errorsFatal.firstObject {
guard let image = SVGParser.parse(string: svg) else {
#if DEBUG
debugPrint("failed to parse SVG for block: \(block.name) with errors: \(String(describing: result.errorsFatal))\n\n\(svg)")
debugPrint("failed to parse SVG for block: \(block.name), svg: \(svg)")
#endif
throw (error as? Error) ?? BlockIconCacheError.unknown
throw BlockIconCacheError.unknown
}
return image
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SwiftUI
import SVGKit
import SVGView

struct BlockIconView: View {
let block: BlockType
Expand All @@ -14,10 +14,11 @@ struct BlockIconView: View {
.frame(width: size, height: size)
.shadow(color: Color.black.opacity(0.1), radius: 2, x: 0, y: 1)

if let image = cache.getIcon(for: block),
let view = SVGKFastImageView(svgkImage: image) {
SVGIconView(view: view)
.frame(width: size * 0.5, height: size * 0.5)
if let image = cache.getIcon(for: block) {
Color(.label).mask {
SVGView(svg: image)
}
.frame(width: size * 0.5, height: size * 0.5)
} else {
Image(systemName: "square")
.font(.system(size: size * 0.5))
Expand All @@ -27,43 +28,3 @@ struct BlockIconView: View {
}
}
}

private struct SVGIconView: UIViewRepresentable {
let view: SVGKFastImageView

@Environment(\.colorScheme) private var colorScheme

func makeUIView(context: Context) -> SVGKFastImageView {
view.contentMode = .scaleAspectFit
return view
}

func updateUIView(_ uiView: SVGKFastImageView, context: Context) {
view.image?.fillColor(color: UIColor.label)
view.setNeedsDisplay()
}
}

private extension SVGKImage {
/// SVGKit maintains two parallel representations of every SVG file: a
/// DOMTree following W3C SVG specifications and a CALayerTree for native
/// iOS rendering. The easiest and fastest way to change the colors of the
/// shapes it creates is by recursively traversing the layers.
private func fillColorForSubLayer(layer: CALayer, color: UIColor, opacity: Float) {
if let shapeLayer = layer as? CAShapeLayer {
shapeLayer.fillColor = color.cgColor
shapeLayer.opacity = opacity
}
if let sublayers = layer.sublayers {
for subLayer in sublayers {
fillColorForSubLayer(layer: subLayer, color: color, opacity: opacity)
}
}
}

func fillColor(color: UIColor, opacity: Float = 1.0) {
if let layer = caLayerTree {
fillColorForSubLayer(layer: layer, color: color, opacity: opacity)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import SwiftUI
import SVGKit

struct BlockInserterBlockView: View {
let block: BlockType
Expand Down