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
2 changes: 1 addition & 1 deletion ios/Sources/GutenbergKit/Sources/EditorJSMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ struct EditorJSMessage {
}

struct ShowBlockInserterBody: Decodable {
let blocks: [EditorBlock]
let sections: [BlockInserterSection]
}
}
20 changes: 15 additions & 5 deletions ios/Sources/GutenbergKit/Sources/EditorViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
try await webView.evaluateJavaScript("editor.getContent();") as! String
}

public struct EditorTitleAndContent: Decodable {
public let title: String
public let content: String
public let changed: Bool
}

/// Returns the current editor title and content.
public func getTitleAndContent() async throws -> EditorTitleAndContent {
let result = try await webView.evaluateJavaScript("editor.getTitleAndContent();")
Expand Down Expand Up @@ -245,16 +251,16 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro

// MARK: - Internal (Block Inserter)

private func showBlockInserter(blocks: [EditorBlock]) {
private func showBlockInserter(data: EditorJSMessage.ShowBlockInserterBody) {
let context = MediaPickerPresentationContext()

let host = UIHostingController(rootView: NavigationStack {
BlockInserterView(
blocks: blocks,
sections: data.sections,
mediaPicker: mediaPicker,
presentationContext: context,
onBlockSelected: {
print("insert blocks:", $0)
onBlockSelected: { [weak self] block in
self?.insertBlockFromInserter(block.id)
},
onMediaSelected: {
print("insert media:", $0)
Expand All @@ -267,6 +273,10 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
present(host, animated: true)
}

private func insertBlockFromInserter(_ blockID: String) {
evaluate("window.blockInserter.insertBlock('\(blockID)')")
}

private func openMediaLibrary(_ config: OpenMediaLibraryAction) {
delegate?.editor(self, didRequestMediaFromSiteMediaLibrary: config)
}
Expand Down Expand Up @@ -309,7 +319,7 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
delegate?.editor(self, didLogException: editorException)
case .showBlockInserter:
let body = try message.decode(EditorJSMessage.ShowBlockInserterBody.self)
showBlockInserter(blocks: body.blocks)
showBlockInserter(data: body)
case .openMediaLibrary:
let config = try message.decode(OpenMediaLibraryAction.self)
openMediaLibrary(config)
Expand Down
4 changes: 2 additions & 2 deletions ios/Sources/GutenbergKit/Sources/Helpers/BlockIconCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SVGKit
final class BlockIconCache: ObservableObject {
var icons: [String: Result<SVGKImage, Error>] = [:]

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

private func _getIcon(for block: EditorBlock) throws -> SVGKImage {
private func _getIcon(for block: BlockType) throws -> SVGKImage {
guard let svg = block.icon,
!svg.isEmpty,
let source = SVGKSourceString.source(fromContentsOf: svg),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import SwiftUI
import SVGKit

struct BlockIconView: View {
let block: EditorBlock
let block: BlockType
let size: CGFloat

@EnvironmentObject private var cache: BlockIconCache
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import SwiftUI
import SVGKit

struct BlockInserterBlockView: View {
let block: EditorBlock
let block: BlockType
let action: () -> Void

@State private var isPressed = false
Expand All @@ -29,6 +29,7 @@ struct BlockInserterBlockView: View {
.padding(.horizontal, 4)
}
.buttonStyle(.plain)
.disabled(block.isDisabled)
.frame(maxWidth: .infinity, alignment: .center)
.contextMenu {
Button {
Expand Down Expand Up @@ -57,7 +58,7 @@ struct BlockInserterBlockView: View {
}

private struct BlockDetailedView: View {
let block: EditorBlock
let block: BlockType

var body: some View {
HStack(spacing: 16) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,83 @@
import SwiftUI

struct BlockInserterSection: Identifiable {
struct BlockInserterSection: Identifiable, Decodable {
var id: String { category }
let category: String
let name: String
let blocks: [EditorBlock]
let name: String?
let blocks: [BlockType]
}

struct BlockInserterSectionView: View {
let section: BlockInserterSection
let onBlockSelected: (EditorBlock) -> Void
let onBlockSelected: (BlockType) -> Void

@ScaledMetric(relativeTo: .largeTitle) private var miniumSize = 80
@ScaledMetric(relativeTo: .largeTitle) private var padding = 20
@State private var isExpanded = false

private let initialDisplayCount = 16

private var displayedBlocks: [BlockType] {
if !isExpanded && section.blocks.count > initialDisplayCount {
return Array(section.blocks.prefix(initialDisplayCount))
}
return section.blocks
}

private var hasMoreBlocks: Bool {
section.blocks.count > initialDisplayCount
}

var body: some View {
VStack(alignment: .leading, spacing: 20) {
if section.category != "text" {
Text(section.name)
if let name = section.name {
Text(name)
.font(.headline)
.foregroundStyle(Color.secondary)
.padding(.leading, padding)
.frame(maxWidth: .infinity, alignment: .leading)
}
grid
if hasMoreBlocks {
toggleButton
}
}
.padding(.top, section.category != "text" ? 20 : 24)
.padding(.top, section.name != nil ? 20 : 24)
.padding(.bottom, 10)
.cardStyle()
}

private var grid: some View {
LazyVGrid(columns: [GridItem(.adaptive(minimum: miniumSize, maximum: miniumSize * 1.5), spacing: 0)]) {
ForEach(section.blocks) { block in
ForEach(displayedBlocks) { block in
BlockInserterBlockView(block: block) {
onBlockSelected(block)
}
}
}
.padding(.horizontal, 12)
}

private var toggleButton: some View {
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
HStack {
// TODO: CMM-874 add localization
Text(isExpanded ? "Show Less" : "Show More")
.font(.subheadline)
.fontWeight(.medium)
.foregroundStyle(Color.secondary)
Image(systemName: isExpanded ? "chevron.up" : "chevron.down")
.font(.caption)
.foregroundStyle(Color.primary)
}
.frame(maxWidth: .infinity)
.padding(.vertical, 8)
}
.buttonStyle(.plain)
.padding(.horizontal, 12)
}
}
Loading