diff --git a/Diffusion-macOS/ContentView.swift b/Diffusion-macOS/ContentView.swift index a3bc5bc..a2f6a0a 100644 --- a/Diffusion-macOS/ContentView.swift +++ b/Diffusion-macOS/ContentView.swift @@ -80,6 +80,8 @@ struct ContentView: View { NavigationSplitView { ControlsView() .navigationSplitViewColumnWidth(min: 250, ideal: 300) + Divider() + HistoryView() } detail: { GeneratedImageView() .aspectRatio(contentMode: .fit) diff --git a/Diffusion-macOS/HistoryView.swift b/Diffusion-macOS/HistoryView.swift new file mode 100644 index 0000000..8c1eb55 --- /dev/null +++ b/Diffusion-macOS/HistoryView.swift @@ -0,0 +1,54 @@ +// +// HistoryView.swift +// Diffusion-macOS +// +// Created by Daniel Colish on 2/28/23. +// + + +import SwiftUI + +struct HistoryView: View { + @ObservedObject var context = GenerationContext() + @State private var disclosedHistory = true + func computeUnitsToString(units: ComputeUnits) -> String{ + switch(units) { + case ComputeUnits.cpuAndGPU: + return "CPU and GPU" + case ComputeUnits.cpuAndNeuralEngine: + return "CPU and ANE" + case ComputeUnits.cpuOnly: + return "CPU" + default: + return "ALL" + } + } + + var body: some View { + VStack (alignment: .leading) { + Label("Generation History", systemImage: "fossil.shell.fill") + .font(.headline) + .fontWeight(.bold) + VStack { + List(context.dataStore.historyItems) { item in + VStack(alignment: .leading) { + Text("Prompt: " + item.prompt) + .font(.body) + if (!item.negativePrompt.isEmpty) { + Text("Negative Prompt: " + item.negativePrompt) + .font(.body) + } + Text("Seed: " + item.seed.formatted()).font(.body) + Text("Steps: " + item.steps.formatted()).font(.body) + Text("Guidance: " + item.guidance.formatted()).font(.body) + Text("Compute: " + self.computeUnitsToString(units: ComputeUnits(rawValue: item.computeUnits) ?? ComputeUnits.all)).font(.body) + Text("Timing: " + item.timing.formatted()).font(.body) + } + } + .textSelection(.enabled) + } + .navigationTitle("Generation History") + } + .padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)) + } +} diff --git a/Diffusion-macOS/StatusView.swift b/Diffusion-macOS/StatusView.swift index ac02f42..5aa3fa2 100644 --- a/Diffusion-macOS/StatusView.swift +++ b/Diffusion-macOS/StatusView.swift @@ -20,6 +20,7 @@ struct StatusView: View { generation.state = .running(nil) do { let result = try await generation.generate() + generation.storeGenerationInputs(result: result) if result.userCanceled { generation.state = .userCanceled } else { diff --git a/Diffusion.xcodeproj/project.pbxproj b/Diffusion.xcodeproj/project.pbxproj index 68fe22d..b75c732 100644 --- a/Diffusion.xcodeproj/project.pbxproj +++ b/Diffusion.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 9B80C0A729AEF6260062BBDE /* HistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B80C0A629AEF6260062BBDE /* HistoryView.swift */; }; EB067F872992E561004D1AD9 /* HelpContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB067F862992E561004D1AD9 /* HelpContent.swift */; }; EB33A51D2954D89F00B16357 /* StableDiffusion in Frameworks */ = {isa = PBXBuildFile; productRef = EB33A51C2954D89F00B16357 /* StableDiffusion */; }; EB560F0429A3C20800C0F8B8 /* Capabilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB560F0329A3C20800C0F8B8 /* Capabilities.swift */; }; @@ -63,6 +64,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 9B80C0A629AEF6260062BBDE /* HistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = ""; }; EB067F862992E561004D1AD9 /* HelpContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpContent.swift; sourceTree = ""; }; EB33A51E2954E1BC00B16357 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; EB560F0329A3C20800C0F8B8 /* Capabilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Capabilities.swift; sourceTree = ""; }; @@ -251,6 +253,7 @@ F1552030297109C300DC009B /* ControlsView.swift */, F155203329710B3600DC009B /* StatusView.swift */, EB067F862992E561004D1AD9 /* HelpContent.swift */, + 9B80C0A629AEF6260062BBDE /* HistoryView.swift */, EB560F0329A3C20800C0F8B8 /* Capabilities.swift */, F155202C2971093400DC009B /* Diffusion_macOS.entitlements */, F15520292971093400DC009B /* Preview Content */, @@ -505,6 +508,7 @@ EB067F872992E561004D1AD9 /* HelpContent.swift in Sources */, EBDD7DB42973200200C1C4B2 /* Utils.swift in Sources */, F1552031297109C300DC009B /* ControlsView.swift in Sources */, + 9B80C0A729AEF6260062BBDE /* HistoryView.swift in Sources */, EBDD7DB62973206600C1C4B2 /* Downloader.swift in Sources */, F155203429710B3600DC009B /* StatusView.swift in Sources */, EB560F0429A3C20800C0F8B8 /* Capabilities.swift in Sources */, @@ -818,7 +822,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_ASSET_PATHS = "\"Diffusion-macOS/Preview Content\""; - DEVELOPMENT_TEAM = 2EADP68M95; + DEVELOPMENT_TEAM = 6YK8ZZH9G7; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "Diffusion-macOS/Info.plist"; @@ -846,7 +850,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_ASSET_PATHS = "\"Diffusion-macOS/Preview Content\""; - DEVELOPMENT_TEAM = 2EADP68M95; + DEVELOPMENT_TEAM = 6YK8ZZH9G7; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "Diffusion-macOS/Info.plist"; diff --git a/Diffusion/ModelInfo.swift b/Diffusion/ModelInfo.swift index 843a853..3f679f7 100644 --- a/Diffusion/ModelInfo.swift +++ b/Diffusion/ModelInfo.swift @@ -101,6 +101,11 @@ extension ModelInfo { modelVersion: "stabilityai/stable-diffusion-2-1-base", supportsEncoder: true ) + + static let ojV2Base = ModelInfo( + modelId: "dcolish/coreml-openjourney-v2", + modelVersion: "prompthero/openjourney-v2" + ) static let ofaSmall = ModelInfo( modelId: "pcuenq/coreml-small-stable-diffusion-v0", @@ -112,7 +117,8 @@ extension ModelInfo { ModelInfo.v15Base, ModelInfo.v2Base, ModelInfo.v21Base, - ModelInfo.ofaSmall + ModelInfo.ofaSmall, + ModelInfo.ojV2Base ] static func from(modelVersion: String) -> ModelInfo? { diff --git a/Diffusion/State.swift b/Diffusion/State.swift index c9b2dfd..7f1474f 100644 --- a/Diffusion/State.swift +++ b/Diffusion/State.swift @@ -53,6 +53,8 @@ class GenerationContext: ObservableObject { @Published var disableSafety = false @Published var computeUnits: ComputeUnits = Settings.shared.userSelectedComputeUnits ?? ModelInfo.defaultComputeUnits + + @Published var dataStore = HistoryStore() private var progressSubscriber: Cancellable? @@ -73,6 +75,18 @@ class GenerationContext: ObservableObject { func cancelGeneration() { pipeline?.setCancelled() } + + func storeGenerationInputs(result: GenerationResult) { + self.dataStore.historyItems.append( + HistoryItem( + prompt: positivePrompt, + negativePrompt: negativePrompt, + guidance: Float(guidanceScale), + steps: Float(steps), + seed: Float(result.lastSeed), + computeUnits: self.computeUnits.rawValue, + timing: Float(result.interval ?? -1.0 ))) + } } class Settings { @@ -127,3 +141,45 @@ class Settings { } } } + + +struct HistoryItem: Identifiable, Codable { + var id = UUID() + let prompt: String + let negativePrompt: String + let guidance: Float + let steps: Float + let seed: Float + let computeUnits: Int + let timing: Float +} + +class HistoryStore: ObservableObject { + @Published var historyItems: [HistoryItem] { + didSet { + saveItems() + } + } + + init() { + self.historyItems = HistoryStore.loadItems() + } + + private static let key = "historyItems" + + private func saveItems() { + print(historyItems) + if let encoded = try? JSONEncoder().encode(historyItems) { + UserDefaults.standard.set(encoded, forKey: Self.key) + } + } + + private static func loadItems() -> [HistoryItem] { + guard let encodedItems = UserDefaults.standard.data(forKey: Self.key), + let items = try? JSONDecoder().decode([HistoryItem].self, from: encodedItems) + else { + return [] + } + return items + } +} diff --git a/config/common.xcconfig b/config/common.xcconfig index 8c20eb6..fb5add3 100644 --- a/config/common.xcconfig +++ b/config/common.xcconfig @@ -10,9 +10,9 @@ // https://help.apple.com/xcode/#/dev745c5c974 PRODUCT_NAME = Diffusers -CURRENT_PROJECT_VERSION = 1.1.0 +CURRENT_PROJECT_VERSION = 20230301.104716 MARKETING_VERSION = 1.1 // Update if you fork this repo -DEVELOPMENT_TEAM = 2EADP68M95 +DEVELOPMENT_TEAM = 6YK8ZZH9G7 PRODUCT_BUNDLE_IDENTIFIER = com.huggingface.Diffusers