Skip to content

Commit

Permalink
Merge pull request #75 from buzsh/feat-update-manager
Browse files Browse the repository at this point in the history
feat: UpdateManager, checkForUpdates
  • Loading branch information
buzsh authored Mar 4, 2024
2 parents 940e0f7 + 807c9ba commit 87b2893
Show file tree
Hide file tree
Showing 27 changed files with 871 additions and 229 deletions.
34 changes: 23 additions & 11 deletions SwiftDiffusion.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,15 @@
29C06C282B93CC8F00F950C4 /* URLParserUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C06C272B93CC8F00F950C4 /* URLParserUtility.swift */; };
29C06C2B2B93DD0F00F950C4 /* BetaOnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C06C2A2B93DD0F00F950C4 /* BetaOnboardingView.swift */; };
29C06C2D2B940D8200F950C4 /* BlueButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C06C2C2B940D8200F950C4 /* BlueButton.swift */; };
29C06C2F2B94C55900F950C4 /* UpdateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C06C2E2B94C55900F950C4 /* UpdateManager.swift */; };
29C06C312B95003600F950C4 /* GitHubReleaseFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C06C302B95003600F950C4 /* GitHubReleaseFetcher.swift */; };
29C06C332B95196200F950C4 /* UpdateViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C06C322B95196200F950C4 /* UpdateViewState.swift */; };
29C0F35F2B79BDA80017DD6B /* NotificationUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F35E2B79BDA80017DD6B /* NotificationUtility.swift */; };
29C0F3632B79C8020017DD6B /* FullscreenImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F3622B79C8020017DD6B /* FullscreenImageView.swift */; };
29C0F3652B79C81F0017DD6B /* ImageWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F3642B79C81F0017DD6B /* ImageWindowManager.swift */; };
29C0F36B2B79D2CA0017DD6B /* FileNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F36A2B79D2CA0017DD6B /* FileNode.swift */; };
29C0F36D2B79D2F80017DD6B /* FileHierarchy+Control.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F36C2B79D2F80017DD6B /* FileHierarchy+Control.swift */; };
29C0F36F2B7A5C3D0017DD6B /* UpdatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F36E2B7A5C3D0017DD6B /* UpdatesView.swift */; };
29C0F36F2B7A5C3D0017DD6B /* UpdateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F36E2B7A5C3D0017DD6B /* UpdateView.swift */; };
29C0F3712B7A62180017DD6B /* WindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F3702B7A62180017DD6B /* WindowManager.swift */; };
29C0F3752B7A75960017DD6B /* CopyPasteUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F3742B7A75960017DD6B /* CopyPasteUtility.swift */; };
29C0F3772B7AA6310017DD6B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C0F3762B7AA6310017DD6B /* AppDelegate.swift */; };
Expand Down Expand Up @@ -248,12 +251,15 @@
29C06C272B93CC8F00F950C4 /* URLParserUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLParserUtility.swift; sourceTree = "<group>"; };
29C06C2A2B93DD0F00F950C4 /* BetaOnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetaOnboardingView.swift; sourceTree = "<group>"; };
29C06C2C2B940D8200F950C4 /* BlueButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlueButton.swift; sourceTree = "<group>"; };
29C06C2E2B94C55900F950C4 /* UpdateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateManager.swift; sourceTree = "<group>"; };
29C06C302B95003600F950C4 /* GitHubReleaseFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubReleaseFetcher.swift; sourceTree = "<group>"; };
29C06C322B95196200F950C4 /* UpdateViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateViewState.swift; sourceTree = "<group>"; };
29C0F35E2B79BDA80017DD6B /* NotificationUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationUtility.swift; sourceTree = "<group>"; };
29C0F3622B79C8020017DD6B /* FullscreenImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullscreenImageView.swift; sourceTree = "<group>"; };
29C0F3642B79C81F0017DD6B /* ImageWindowManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageWindowManager.swift; sourceTree = "<group>"; };
29C0F36A2B79D2CA0017DD6B /* FileNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileNode.swift; sourceTree = "<group>"; };
29C0F36C2B79D2F80017DD6B /* FileHierarchy+Control.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileHierarchy+Control.swift"; sourceTree = "<group>"; };
29C0F36E2B7A5C3D0017DD6B /* UpdatesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdatesView.swift; sourceTree = "<group>"; };
29C0F36E2B7A5C3D0017DD6B /* UpdateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateView.swift; sourceTree = "<group>"; };
29C0F3702B7A62180017DD6B /* WindowManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowManager.swift; sourceTree = "<group>"; };
29C0F3742B7A75960017DD6B /* CopyPasteUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyPasteUtility.swift; sourceTree = "<group>"; };
29C0F3762B7AA6310017DD6B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -478,7 +484,7 @@
isa = PBXGroup;
children = (
29C06C292B93DCEF00F950C4 /* BetaOnboardingView */,
29C0F37B2B7AB37E0017DD6B /* UpdatesView */,
29C0F37B2B7AB37E0017DD6B /* UpdateView */,
29D3623A2B72ED3B006C57B3 /* CheckpointManagerView */,
2916F3322B7278D4001D14B9 /* SettingsView */,
);
Expand Down Expand Up @@ -912,12 +918,15 @@
path = ContentView;
sourceTree = "<group>";
};
29C0F37B2B7AB37E0017DD6B /* UpdatesView */ = {
29C0F37B2B7AB37E0017DD6B /* UpdateView */ = {
isa = PBXGroup;
children = (
29C0F36E2B7A5C3D0017DD6B /* UpdatesView.swift */,
29C06C322B95196200F950C4 /* UpdateViewState.swift */,
29C0F36E2B7A5C3D0017DD6B /* UpdateView.swift */,
29C06C2E2B94C55900F950C4 /* UpdateManager.swift */,
29C06C302B95003600F950C4 /* GitHubReleaseFetcher.swift */,
);
path = UpdatesView;
path = UpdateView;
sourceTree = "<group>";
};
29C0F37E2B7ABED50017DD6B /* SettingsSections */ = {
Expand Down Expand Up @@ -1063,7 +1072,7 @@
29169D0E2B8EAD740099A9C5 /* ImageInfo.swift in Sources */,
29C0F36B2B79D2CA0017DD6B /* FileNode.swift in Sources */,
29145E7D2B78111200BFA64B /* ToolbarButton.swift in Sources */,
29C0F36F2B7A5C3D0017DD6B /* UpdatesView.swift in Sources */,
29C0F36F2B7A5C3D0017DD6B /* UpdateView.swift in Sources */,
29708F942B803350004A95AD /* PasteGenerationDataStatusBar.swift in Sources */,
290A34B02B7C616A00963C6E /* MapModelData.swift in Sources */,
29F91D332B8D42390047B3C9 /* NSImage+Extensions.swift in Sources */,
Expand All @@ -1090,6 +1099,7 @@
29A1A38A2B919E7100CC3D1B /* Sidebar+Preload.swift in Sources */,
297196652B719C32000F7960 /* ScriptManager+ServiceAvailability.swift in Sources */,
292CE8282B82430000116D60 /* SoundUtility.swift in Sources */,
29C06C332B95196200F950C4 /* UpdateViewState.swift in Sources */,
2916F3342B7278FD001D14B9 /* SettingsView.swift in Sources */,
29F0D3032B76C9DD00BF56CE /* ModelLoadState.swift in Sources */,
29169D252B8FCB780099A9C5 /* Sidebar.swift in Sources */,
Expand Down Expand Up @@ -1117,6 +1127,7 @@
29145E6C2B77CD1600BFA64B /* StateDebugInfo.swift in Sources */,
29FB923F2B8DAA660023C7C5 /* ShareButton.swift in Sources */,
2916F3372B72859D001D14B9 /* DetailView.swift in Sources */,
29C06C2F2B94C55900F950C4 /* UpdateManager.swift in Sources */,
29C0F3822B7ABF210017DD6B /* FilesSection.swift in Sources */,
29169D102B8EADDF0099A9C5 /* SidebarFolder.swift in Sources */,
29145E6F2B77D82A00BFA64B /* DebugPromptStatusView.swift in Sources */,
Expand All @@ -1142,6 +1153,7 @@
2916F33D2B72867C001D14B9 /* FileRowView.swift in Sources */,
2952BAD72B71AEFA002FC885 /* PromptView.swift in Sources */,
29B64A482B8D480D00B0012D /* CachedPreviewImageView.swift in Sources */,
29C06C312B95003600F950C4 /* GitHubReleaseFetcher.swift in Sources */,
290A34B42B7D283600963C6E /* SidebarMockDataController.swift in Sources */,
292A30DD2B9017F700344DA8 /* WorkspaceItemView.swift in Sources */,
29A7BDE12B8A40F200F9144B /* ApiCheckpointRow.swift in Sources */,
Expand Down Expand Up @@ -1311,7 +1323,7 @@
CODE_SIGN_ENTITLEMENTS = SwiftDiffusion/SwiftDiffusion.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 100;
CURRENT_PROJECT_VERSION = 1000;
DEVELOPMENT_ASSET_PATHS = "\"SwiftDiffusion/Preview Content\"";
DEVELOPMENT_TEAM = 85N3S3DG8M;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -1323,7 +1335,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 0.0.1;
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.buzsh.SwiftDiffusion;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand All @@ -1339,7 +1351,7 @@
CODE_SIGN_ENTITLEMENTS = SwiftDiffusion/SwiftDiffusion.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 100;
CURRENT_PROJECT_VERSION = 1000;
DEVELOPMENT_ASSET_PATHS = "\"SwiftDiffusion/Preview Content\"";
DEVELOPMENT_TEAM = 85N3S3DG8M;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -1351,7 +1363,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 0.0.1;
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.buzsh.SwiftDiffusion;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ class CheckpointsManager: ObservableObject {

func stopObservingDirectory() {
directoryObserver?.stopObserving()

updateFlagForHasLoadedInitialCheckpointDataFromApi(to: false)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,6 @@ struct DebugApiView: View {
}
}





#Preview {
let scriptManagerPreview: ScriptManager = .preview(withState: .active)
let promptModelPreview = PromptModel()
Expand Down
2 changes: 1 addition & 1 deletion SwiftDiffusion/Models/SidebarModels/SidebarFolder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SidebarFolder: Identifiable {

extension SidebarFolder: Equatable {
static func == (lhs: SidebarFolder, rhs: SidebarFolder) -> Bool {
lhs.name == rhs.name
lhs.id == rhs.id
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ class ScriptManager: ObservableObject {
var shouldTrimOutput: Bool = false

@Published var genStatus: GenerationStatus = .idle
@Published var genProgress: Double = 0
@Published var genProgress: Double = 0.0

@Published var genIterationPerSecond: String = ""
@Published var genCurrentStepOutOfTotalSteps: String = ""

@Published var modelLoadState: ModelLoadState = .idle
@Published var modelLoadTime: Double = 0
@Published var modelLoadTime: Double = 0.0
@Published var modelLoadStateShouldExpire: Bool = false
@Published var modelLoadTypeErrorThrown: Bool = false

Expand Down
4 changes: 3 additions & 1 deletion SwiftDiffusion/SwiftDiffusionApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct SwiftDiffusionApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var modelContainer: ModelContainer
var scriptManager = ScriptManager.shared
let updateManager = UpdateManager()
let sidebarModel = SidebarModel()
let checkpointsManager = CheckpointsManager()
let currentPrompt = PromptModel()
Expand Down Expand Up @@ -48,6 +49,7 @@ struct SwiftDiffusionApp: App {
.frame(minWidth: 720, idealWidth: 900, maxWidth: .infinity,
minHeight: 500, idealHeight: 800, maxHeight: .infinity)
.environmentObject(scriptManager)
.environmentObject(updateManager)
.environmentObject(sidebarModel)
.environmentObject(checkpointsManager)
.environmentObject(currentPrompt)
Expand All @@ -61,7 +63,7 @@ struct SwiftDiffusionApp: App {
Divider()

Button("Check for Updates...") {
WindowManager.shared.showUpdatesWindow()
WindowManager.shared.showUpdatesWindow(updateManager: updateManager)
}
.keyboardShortcut("U", modifiers: [.command])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ extension PromptView {
}
}
/// Asynchronously checks the system pasteboard for generation data and updates a flag accordingly. Intended to be used on the main actor to ensure UI updates are handled correctly.
@MainActor
func checkPasteboardAndUpdateFlag() async {
if let pasteboardContent = getPasteboardString() {
let hasData = userHasGenerationDataInPasteboard(from: pasteboardContent)
generationDataInPasteboard = hasData
await MainActor.run {
withAnimation {
generationDataInPasteboard = hasData
}
}
}
}
/// Determines if the pasteboard content contains generation data by looking for specific keywords.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extension Constants {
enum PayloadKey: String {
case prompt
case negativePrompt = "negative_prompt"
case samplingMethod = "sampler_index"
case width
case height
case cfgScale = "cfg_scale"
Expand All @@ -49,9 +50,17 @@ enum PayloadKey: String {

extension ContentView {
func prepareImageGenerationPayloadFromPrompt() -> [String: Any] {
let sanitizedPositivePrompt = currentPrompt.positivePrompt
.replacingOccurrences(of: "\n", with: " ")
.replacingOccurrences(of: "\"", with: "'")
let sanitizedNegativePrompt = currentPrompt.negativePrompt
.replacingOccurrences(of: "\n", with: " ")
.replacingOccurrences(of: "\"", with: "'")

var payload: [String: Any] = [
PayloadKey.prompt.rawValue: currentPrompt.positivePrompt,
PayloadKey.negativePrompt.rawValue: currentPrompt.negativePrompt,
PayloadKey.prompt.rawValue: sanitizedPositivePrompt,
PayloadKey.negativePrompt.rawValue: sanitizedNegativePrompt,
PayloadKey.samplingMethod.rawValue: currentPrompt.samplingMethod ?? "DPM++ SDE Karras",
PayloadKey.width.rawValue: Int(currentPrompt.width),
PayloadKey.height.rawValue: Int(currentPrompt.height),
PayloadKey.cfgScale.rawValue: Int(currentPrompt.cfgScale),
Expand Down
26 changes: 22 additions & 4 deletions SwiftDiffusion/Views/MainViews/ContentView/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extension ViewManager: Hashable, Identifiable {

struct ContentView: View {
@Environment(\.modelContext) var modelContext
@EnvironmentObject var updateManager: UpdateManager
@EnvironmentObject var sidebarModel: SidebarModel
@EnvironmentObject var checkpointsManager: CheckpointsManager
@EnvironmentObject var currentPrompt: PromptModel
Expand All @@ -41,7 +42,7 @@ struct ContentView: View {

@State private var scriptManagerObserver: ScriptManagerObserver?

@AppStorage("hasLaunchedBeforeTest4") var hasLaunchedBefore: Bool = false
@AppStorage("hasLaunchedBeforeTest") var hasLaunchedBefore: Bool = false
@State private var showingBetaOnboardingSheetView: Bool = false

// RequiredInputPaths
Expand All @@ -58,12 +59,10 @@ struct ContentView: View {
@State var selectedImage: NSImage? = nil
@AppStorage("lastSelectedImagePath") var lastSelectedImagePath: String = ""
@State var lastSavedImageUrls: [URL] = []

@State var imageCountToGenerate: Int = 0

@State private var columnVisibility = NavigationSplitViewVisibility.all // .doubleColumn (hide by default)


var body: some View {
NavigationSplitView(columnVisibility: $columnVisibility) {
Sidebar(selectedImage: $selectedImage, lastSavedImageUrls: $lastSavedImageUrls)
Expand All @@ -89,6 +88,10 @@ struct ContentView: View {
.background(VisualEffectBlurView(material: .headerView, blendingMode: .behindWindow))
.navigationSplitViewStyle(.automatic)
.onAppear {
if hasLaunchedBefore {
checkForUpdatesIfAutomaticUpdatesAreEnabled()
}

scriptManagerObserver = ScriptManagerObserver(scriptManager: scriptManager, userSettings: userSettings, checkpointsManager: checkpointsManager, loraModelsManager: loraModelsManager, vaeModelsManager: vaeModelsManager)

if let directoryPath = userSettings.outputDirectoryUrl?.path {
Expand Down Expand Up @@ -256,9 +259,13 @@ struct ContentView: View {
handleScriptOnLaunch()
}
.onChange(of: scriptManager.genStatus) {
if scriptManager.genStatus == .preparingToGenerate {
sidebarModel.currentlyGeneratingSidebarItem = sidebarModel.selectedSidebarItem
}

if scriptManager.genStatus == .generating {
imageCountToGenerate = Int(currentPrompt.batchSize * currentPrompt.batchCount)
sidebarModel.currentlyGeneratingSidebarItem = sidebarModel.selectedSidebarItem
//sidebarModel.currentlyGeneratingSidebarItem = sidebarModel.selectedSidebarItem

} else if scriptManager.genStatus == .done {
imagesDidGenerateSuccessfully()
Expand All @@ -278,6 +285,7 @@ struct ContentView: View {

if let storableSidebarItem = sidebarModel.currentlyGeneratingSidebarItem {
sidebarModel.addToStorableSidebarItems(sidebarItem: storableSidebarItem, withImageUrls: lastSavedImageUrls)
sidebarModel.currentlyGeneratingSidebarItem = nil
}

Task {
Expand All @@ -297,6 +305,16 @@ struct ContentView: View {
}
}

func checkForUpdatesIfAutomaticUpdatesAreEnabled() {
Task {
await updateManager.checkForUpdatesIfNeeded()
if let currentBuildIsLatestVersion = updateManager.currentBuildIsLatestVersion,
currentBuildIsLatestVersion == false {
WindowManager.shared.showUpdatesWindow(updateManager: updateManager)
}
}
}

}

#Preview {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct BlueBackgroundButtonStyle: ButtonStyle {
.overlay(
RoundedRectangle(cornerRadius: 6)
.stroke(self.borderColor(for: configuration.isPressed), lineWidth: 1)
.opacity(self.borderOpacity(for: configuration.isPressed)) // Adjust border opacity
.opacity(self.borderOpacity(for: configuration.isPressed))
)
}

Expand Down Expand Up @@ -122,3 +122,50 @@ struct BorderBackgroundButtonStyle: ButtonStyle {
#Preview {
CommonPreviews.contentView
}


struct BlueBackgroundSmallButtonStyle: ButtonStyle {
@Environment(\.isEnabled) var isEnabled: Bool

func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding(.vertical, 4).padding(.horizontal, 8)
.background(self.backgroundColor(for: configuration.isPressed))
.foregroundColor(.white)
.opacity(self.textOpacity(for: configuration.isPressed))
.clipShape(RoundedRectangle(cornerRadius: 6))
.overlay(
RoundedRectangle(cornerRadius: 6)
.stroke(self.borderColor(for: configuration.isPressed), lineWidth: 1)
.opacity(self.borderOpacity(for: configuration.isPressed))
)
}

private func backgroundColor(for isPressed: Bool) -> Color {
if !isEnabled {
return StateColors.disabledGray
} else {
return isPressed ? StateColors.pressedBlue : StateColors.normalBlue
}
}

private func borderColor(for isPressed: Bool) -> Color {
return isEnabled ? StateColors.normalBlue : StateColors.disabledGray
}

private func textOpacity(for isPressed: Bool) -> Double {
if !isEnabled {
return StateColors.disabledTextOpacity
} else {
return isPressed ? StateColors.pressedTextOpacity : StateColors.normalTextOpacity
}
}

private func borderOpacity(for isPressed: Bool) -> Double {
if !isEnabled {
return StateColors.disabledBorderOpacity
} else {
return isPressed ? StateColors.pressedBorderOpacity : StateColors.normalBorderOpacity
}
}
}
Loading

0 comments on commit 87b2893

Please sign in to comment.