Skip to content

Commit

Permalink
Merge branch 'MacPaw:main' into new-content-format
Browse files Browse the repository at this point in the history
  • Loading branch information
rawnly authored Nov 19, 2023
2 parents 9a7f1d1 + ac5892f commit b2b9358
Show file tree
Hide file tree
Showing 20 changed files with 605 additions and 20 deletions.
30 changes: 30 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Contribution Guidelines
Make your Pull Requests clear and obvious to anyone viewing them.
Set `main` as your target branch.

#### Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) principles in naming PRs and branches:

- `Feat: ...` for new features and new functionality implementations.
- `Bug: ...` for bug fixes.
- `Fix: ...` for minor issues fixing, like typos or inaccuracies in code.
- `Chore: ...` for boring stuff like code polishing, refactoring, deprecation fixing etc.

PR naming example: `Feat: Add Threads API handling` or `Bug: Fix message result duplication`

Branch naming example: `feat/add-threads-API-handling` or `bug/fix-message-result-duplication`

#### Write description to pull requests in following format:
- What

...
- Why

...
- Affected Areas

...
- More Info

...

We'll appreciate you including tests to your code if it is needed and possible. ❤️
8 changes: 8 additions & 0 deletions Demo/App/APIProvidedView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SwiftUI
struct APIProvidedView: View {
@Binding var apiKey: String
@StateObject var chatStore: ChatStore
@StateObject var imageStore: ImageStore
@StateObject var miscStore: MiscStore
@State var isShowingAPIConfigModal: Bool = true

Expand All @@ -29,6 +30,11 @@ struct APIProvidedView: View {
idProvider: idProvider
)
)
self._imageStore = StateObject(
wrappedValue: ImageStore(
openAIClient: OpenAI(apiToken: apiKey.wrappedValue)
)
)
self._miscStore = StateObject(
wrappedValue: MiscStore(
openAIClient: OpenAI(apiToken: apiKey.wrappedValue)
Expand All @@ -39,11 +45,13 @@ struct APIProvidedView: View {
var body: some View {
ContentView(
chatStore: chatStore,
imageStore: imageStore,
miscStore: miscStore
)
.onChange(of: apiKey) { newApiKey in
let client = OpenAI(apiToken: newApiKey)
chatStore.openAIClient = client
imageStore.openAIClient = client
miscStore.openAIClient = client
}
}
Expand Down
9 changes: 2 additions & 7 deletions Demo/App/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import SwiftUI

struct ContentView: View {
@ObservedObject var chatStore: ChatStore
@ObservedObject var imageStore: ImageStore
@ObservedObject var miscStore: MiscStore
@State private var selectedTab = 0
@Environment(\.idProviderValue) var idProvider
Expand All @@ -33,6 +34,7 @@ struct ContentView: View {
.tag(1)

ImageView(
store: imageStore
)
.tabItem {
Label("Image", systemImage: "photo")
Expand Down Expand Up @@ -63,10 +65,3 @@ struct TranscribeView: View {
.font(.largeTitle)
}
}

struct ImageView: View {
var body: some View {
Text("Image: TBD")
.font(.largeTitle)
}
}
33 changes: 33 additions & 0 deletions Demo/DemoChat/Sources/ImageStore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// ImageStore.swift
// DemoChat
//
// Created by Aled Samuel on 24/04/2023.
//

import Foundation
import OpenAI

public final class ImageStore: ObservableObject {
public var openAIClient: OpenAIProtocol

@Published var images: [ImagesResult.URLResult] = []

public init(
openAIClient: OpenAIProtocol
) {
self.openAIClient = openAIClient
}

@MainActor
func images(query: ImagesQuery) async {
images.removeAll()
do {
let response = try await openAIClient.images(query: query)
images = response.data
} catch {
// TODO: Better error handling
print(error.localizedDescription)
}
}
}
8 changes: 7 additions & 1 deletion Demo/DemoChat/Sources/UI/DetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,20 @@ struct DetailView: View {
.frame(width: 24, height: 24)
.padding(.trailing)
}
.disabled(inputText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
}
.padding(.bottom)
}

private func tapSendMessage(
scrollViewProxy: ScrollViewProxy
) {
sendMessage(inputText, selectedChatModel)
let message = inputText.trimmingCharacters(in: .whitespacesAndNewlines)
if message.isEmpty {
return
}

sendMessage(message, selectedChatModel)
inputText = ""

// if let lastMessage = conversation.messages.last {
Expand Down
75 changes: 75 additions & 0 deletions Demo/DemoChat/Sources/UI/Images/ImageCreationView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// ImageCreationView.swift
// DemoChat
//
// Created by Aled Samuel on 24/04/2023.
//

import SwiftUI
import OpenAI

public struct ImageCreationView: View {
@ObservedObject var store: ImageStore

@State private var prompt: String = ""
@State private var n: Int = 1
@State private var size: String

private var sizes = ["256x256", "512x512", "1024x1024"]

public init(store: ImageStore) {
self.store = store
size = sizes[0]
}

public var body: some View {
List {
Section {
HStack {
Text("Prompt")
Spacer()
TextEditor(text: $prompt)
.multilineTextAlignment(.trailing)
}
HStack {
Stepper("Amount: \(n)", value: $n, in: 1...10)
}
HStack {
Picker("Size", selection: $size) {
ForEach(sizes, id: \.self) {
Text($0)
}
}
}
}
Section {
HStack {
Button("Create Image" + (n == 1 ? "" : "s")) {
Task {
let query = ImagesQuery(prompt: prompt, n: n, size: size)
await store.images(query: query)
}
}
.foregroundColor(.accentColor)
Spacer()
}
}
if !$store.images.isEmpty {
Section("Images") {
ForEach($store.images, id: \.self) { image in
let urlString = image.wrappedValue.url ?? ""
if let imageURL = URL(string: urlString), UIApplication.shared.canOpenURL(imageURL) {
LinkPreview(previewURL: imageURL)
.aspectRatio(contentMode: .fit)
} else {
Text(urlString)
.foregroundStyle(.secondary)
}
}
}
}
}
.listStyle(.insetGrouped)
.navigationTitle("Create Image")
}
}
63 changes: 63 additions & 0 deletions Demo/DemoChat/Sources/UI/Images/ImageView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// ImageView.swift
// DemoChat
//
// Created by Aled Samuel on 24/04/2023.
//

import SwiftUI

public struct ImageView: View {
@ObservedObject var store: ImageStore

public init(store: ImageStore) {
self.store = store
}

public var body: some View {
NavigationStack {
List {
NavigationLink("Create Image", destination: ImageCreationView(store: store))
NavigationLink("Create Image Edit", destination: ImageEditView(store: store))
.disabled(true)
NavigationLink("Create Image Variation", destination: ImageVariationView(store: store))
.disabled(true)

}
.listStyle(.insetGrouped)
.navigationTitle("Image")
}
}
}

public struct ImageEditView: View {
@ObservedObject var store: ImageStore

public init(store: ImageStore) {
self.store = store
}

public var body: some View {
List {

}
.listStyle(.insetGrouped)
.navigationTitle("Create Image Edit")
}
}

public struct ImageVariationView: View {
@ObservedObject var store: ImageStore

public init(store: ImageStore) {
self.store = store
}

public var body: some View {
List {

}
.listStyle(.insetGrouped)
.navigationTitle("Create Image Variation")
}
}
33 changes: 33 additions & 0 deletions Demo/DemoChat/Sources/UI/Images/LinkPreview.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// LinkPreview.swift
// DemoChat
//
// Created by Aled Samuel on 25/04/2023.
//

import SwiftUI
import LinkPresentation

struct LinkPreview: UIViewRepresentable {
typealias UIViewType = LPLinkView

var previewURL: URL

func makeUIView(context: Context) -> LPLinkView {
LPLinkView(url: previewURL)
}

func updateUIView(_ uiView: UIViewType, context: Context) {
LPMetadataProvider().startFetchingMetadata(for: previewURL) { metadata, error in
if let error = error {
print(error.localizedDescription)
return
}
guard let metadata = metadata else {
print("Metadata missing for \(previewURL.absoluteString)")
return
}
uiView.metadata = metadata
}
}
}
Loading

0 comments on commit b2b9358

Please sign in to comment.