Skip to content

Commit

Permalink
feat:更新 Markdwon 组件,显示更加完善
Browse files Browse the repository at this point in the history
  • Loading branch information
iHTCboy committed Dec 9, 2022
1 parent a186c73 commit af22457
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 50 deletions.
30 changes: 17 additions & 13 deletions iChatGPT.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
6DAA91802943448D004ACD01 /* MarkdownText in Frameworks */ = {isa = PBXBuildFile; productRef = 6DAA917F2943448D004ACD01 /* MarkdownText */; };
6DAA9182294346D8004ACD01 /* MarkdownStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAA9181294346D8004ACD01 /* MarkdownStyles.swift */; };
6DC88ADE2942C8AD00DA6C55 /* iChatGPTApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC88ADD2942C8AD00DA6C55 /* iChatGPTApp.swift */; };
6DC88AE02942C8AD00DA6C55 /* AIChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC88ADF2942C8AD00DA6C55 /* AIChatView.swift */; };
6DC88AE22942C8AE00DA6C55 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6DC88AE12942C8AE00DA6C55 /* Assets.xcassets */; };
Expand All @@ -20,7 +22,6 @@
6DC88B102942C8DC00DA6C55 /* AIChatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC88B0E2942C8DB00DA6C55 /* AIChatModel.swift */; };
6DC88B112942C8DC00DA6C55 /* ChatGPT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC88B0F2942C8DB00DA6C55 /* ChatGPT.swift */; };
6DC88B142942C8E000DA6C55 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC88B132942C8E000DA6C55 /* Strings.swift */; };
6DC88B172942C91000DA6C55 /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 6DC88B162942C91000DA6C55 /* MarkdownUI */; };
6DC88B192942D0B700DA6C55 /* Dates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC88B182942D0B700DA6C55 /* Dates.swift */; };
6DC88B1B2942E84A00DA6C55 /* MultilineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC88B1A2942E84A00DA6C55 /* MultilineTextField.swift */; };
/* End PBXBuildFile section */
Expand All @@ -43,6 +44,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
6DAA9181294346D8004ACD01 /* MarkdownStyles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownStyles.swift; sourceTree = "<group>"; };
6DC88ADA2942C8AD00DA6C55 /* iChatGPT.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iChatGPT.app; sourceTree = BUILT_PRODUCTS_DIR; };
6DC88ADD2942C8AD00DA6C55 /* iChatGPTApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iChatGPTApp.swift; sourceTree = "<group>"; };
6DC88ADF2942C8AD00DA6C55 /* AIChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIChatView.swift; sourceTree = "<group>"; };
Expand All @@ -68,7 +70,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6DC88B172942C91000DA6C55 /* MarkdownUI in Frameworks */,
6DAA91802943448D004ACD01 /* MarkdownText in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -162,6 +164,7 @@
6DC88B122942C8E000DA6C55 /* Extensions */ = {
isa = PBXGroup;
children = (
6DAA9181294346D8004ACD01 /* MarkdownStyles.swift */,
6DC88B132942C8E000DA6C55 /* Strings.swift */,
6DC88B182942D0B700DA6C55 /* Dates.swift */,
6DC88B1A2942E84A00DA6C55 /* MultilineTextField.swift */,
Expand All @@ -186,7 +189,7 @@
);
name = iChatGPT;
packageProductDependencies = (
6DC88B162942C91000DA6C55 /* MarkdownUI */,
6DAA917F2943448D004ACD01 /* MarkdownText */,
);
productName = iChatGPT;
productReference = 6DC88ADA2942C8AD00DA6C55 /* iChatGPT.app */;
Expand Down Expand Up @@ -262,7 +265,7 @@
);
mainGroup = 6DC88AD12942C8AD00DA6C55;
packageReferences = (
6DC88B152942C91000DA6C55 /* XCRemoteSwiftPackageReference "MarkdownUI" */,
6DAA917E2943448D004ACD01 /* XCRemoteSwiftPackageReference "MarkdownText" */,
);
productRefGroup = 6DC88ADB2942C8AD00DA6C55 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -306,6 +309,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6DAA9182294346D8004ACD01 /* MarkdownStyles.swift in Sources */,
6DC88B0C2942C8D200DA6C55 /* ChatContextMenu.swift in Sources */,
6DC88AE02942C8AD00DA6C55 /* AIChatView.swift in Sources */,
6DC88B142942C8E000DA6C55 /* Strings.swift in Sources */,
Expand Down Expand Up @@ -492,7 +496,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = com.37iOS.iChatGPT;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -531,7 +535,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = com.37iOS.iChatGPT;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -658,21 +662,21 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
6DC88B152942C91000DA6C55 /* XCRemoteSwiftPackageReference "MarkdownUI" */ = {
6DAA917E2943448D004ACD01 /* XCRemoteSwiftPackageReference "MarkdownText" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/gonzalezreal/MarkdownUI";
repositoryURL = "https://github.com/shaps80/MarkdownText.git";
requirement = {
branch = main;
kind = branch;
kind = upToNextMajorVersion;
minimumVersion = 1.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
6DC88B162942C91000DA6C55 /* MarkdownUI */ = {
6DAA917F2943448D004ACD01 /* MarkdownText */ = {
isa = XCSwiftPackageProductDependency;
package = 6DC88B152942C91000DA6C55 /* XCRemoteSwiftPackageReference "MarkdownUI" */;
productName = MarkdownUI;
package = 6DAA917E2943448D004ACD01 /* XCRemoteSwiftPackageReference "MarkdownText" */;
productName = MarkdownText;
};
/* End XCSwiftPackageProductDependency section */
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,39 @@
{
"pins" : [
{
"identity" : "attributedtext",
"identity" : "markdowntext",
"kind" : "remoteSourceControl",
"location" : "https://github.com/gonzalezreal/AttributedText",
"location" : "https://github.com/shaps80/MarkdownText.git",
"state" : {
"revision" : "0e811cb14de367bbd58a94d12259687e5ee08bea",
"revision" : "0dbef003e450a59283cefaed433bd267fff87e7f",
"version" : "1.0.1"
}
},
{
"identity" : "combine-schedulers",
"identity" : "swift-cmark",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/combine-schedulers",
"location" : "https://github.com/shaps80/swift-cmark.git",
"state" : {
"revision" : "882ac01eb7ef9e36d4467eb4b1151e74fcef85ab",
"version" : "0.9.1"
"revision" : "476f7b4fcf12eba381b4aaed8987006fd8fcec9c",
"version" : "0.2.0"
}
},
{
"identity" : "markdownui",
"identity" : "swift-markdown",
"kind" : "remoteSourceControl",
"location" : "https://github.com/gonzalezreal/MarkdownUI",
"location" : "https://github.com/shaps80/swift-markdown",
"state" : {
"branch" : "main",
"revision" : "3c80d50712dcecf38ceb8d327969e644d5c37de6"
"revision" : "83188dee2dbccfa70124c56055dd0b759d3e4ec3",
"version" : "0.3.0"
}
},
{
"identity" : "networkimage",
"identity" : "swiftuibackports",
"kind" : "remoteSourceControl",
"location" : "https://github.com/gonzalezreal/NetworkImage",
"location" : "https://github.com/shaps80/SwiftUIBackports",
"state" : {
"revision" : "c97f83e771c95186af80ef6118f158852a9e54be",
"version" : "4.0.1"
}
},
{
"identity" : "swiftcommonmark",
"kind" : "remoteSourceControl",
"location" : "https://github.com/gonzalezreal/SwiftCommonMark",
"state" : {
"revision" : "ed252beaddecce28ea6363f800c773d6169011b8",
"version" : "1.0.0"
}
},
{
"identity" : "xctest-dynamic-overlay",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
"state" : {
"revision" : "5a5457a744239896e9b0b03a8e1a5069c3e7b91f",
"version" : "0.6.0"
"revision" : "d9842f24656ff7c6116dc207b60f0b6d302a5a9a",
"version" : "1.9.0"
}
}
],
Expand Down
14 changes: 10 additions & 4 deletions iChatGPT/AIChatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

import SwiftUI
import MarkdownUI
import MarkdownText

struct AIChatView: View {

Expand All @@ -21,12 +21,12 @@ struct AIChatView: View {
List {
ForEach(chatModel.contents, id: \.datetime) { item in
Section(header: Text(item.datetime)) {
VStack {
Markdown(item.issue)
VStack(alignment: .leading) {
MarkdownText(item.issue)
Divider()
if item.isResponse {
// Text(.init(item.answer))
Markdown(item.answer ?? "")
MarkdownText(item.answer ?? "")
} else {
HStack {
ProgressView()
Expand All @@ -43,6 +43,12 @@ struct AIChatView: View {
Spacer()
ChatInputView(searchText: $searchText, chatModel: chatModel).padding([.leading, .trailing], 12)
}
.markdownHeadingStyle(.custom)
.markdownQuoteStyle(.custom)
.markdownCodeStyle(.custom)
.markdownInlineCodeStyle(.custom)
.markdownOrderedListBulletStyle(.custom)
.markdownImageStyle(.custom)
.navigationTitle("OpenAI ChatGPT")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
Expand Down
130 changes: 130 additions & 0 deletions iChatGPT/Extensions/MarkdownStyles.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import SwiftUI
import MarkdownText

struct CustomHeading: HeadingMarkdownStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundColor(.accentColor)
}
}

extension HeadingMarkdownStyle where Self == CustomHeading {
static var custom: Self { .init() }
}

struct Underline: StrikethroughMarkdownStyle {
func makeBody(configuration: Configuration) -> Text {
configuration.content.underline()
}
}

extension StrikethroughMarkdownStyle where Self == Underline {
static var custom: Self { .init() }
}

struct CustomInlineCode: InlineCodeMarkdownStyle {
func makeBody(configuration: Configuration) -> Text {
configuration.label
.foregroundColor(.pink)
}
}

extension InlineCodeMarkdownStyle where Self == CustomInlineCode {
static var custom: Self { .init() }
}

struct CustomQuote: QuoteMarkdownStyle {
struct Content: View {
@ScaledMetric(wrappedValue: 20) private var padding
@ScaledMetric(wrappedValue: 3) private var thickness
@Environment(\.markdownParagraphStyle) private var style

let paragraph: ParagraphMarkdownConfiguration

var body: some View {
style
.makeBody(configuration: paragraph)
.font(.system(.callout, design: .rounded))
.foregroundColor(.secondary)
.padding(.horizontal, padding)
.overlay(
RoundedRectangle(cornerRadius: thickness)
.frame(width: thickness)
#if os(iOS)
.foregroundColor(Color(.systemFill))
#endif
.offset(x: thickness),
alignment: .leading
)
}
}

func makeBody(configuration: Configuration) -> some View {
Content(paragraph: configuration.content)
}
}

extension QuoteMarkdownStyle where Self == CustomQuote {
static var custom: Self { .init() }
}

public struct CustomCode: CodeMarkdownStyle {
struct Label: View {
@ScaledMetric(wrappedValue: 15) private var padding

let configuration: Configuration

var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
configuration.label
.padding(padding)
}
#if os(iOS)
.background(Color(.quaternarySystemFill).cornerRadius(8))
#endif
.overlay(
configuration.language.flatMap { Text($0) }?
.padding(5)
.font(.footnote.weight(.semibold))
.foregroundColor(.secondary)
#if os(iOS)
.background(Color(.systemBackground))
#endif
.cornerRadius(6)
.padding(5),
alignment: .topTrailing
)
.environment(\.layoutDirection, .leftToRight)
}
}

public func makeBody(configuration: Configuration) -> some View {
Label(configuration: configuration)
}
}

extension CodeMarkdownStyle where Self == CustomCode {
static var custom: Self { .init() }
}

struct CustomOrderedBullet: OrderedListBulletMarkdownStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundColor(.secondary)
}
}

extension OrderedListBulletMarkdownStyle where Self == CustomOrderedBullet {
static var custom: Self { .init() }
}

struct CustomImage: ImageMarkdownStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.clipShape(RoundedRectangle(cornerRadius: 13, style: .continuous))
}
}

extension ImageMarkdownStyle where Self == CustomImage {
static var custom: Self { .init() }
}

0 comments on commit af22457

Please sign in to comment.