Adds keychain support
This commit is contained in:
@@ -6,6 +6,10 @@
|
|||||||
objectVersion = 77;
|
objectVersion = 77;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
CD41F5D32E62431D00E0027B /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = CD41F5D22E62431D00E0027B /* KeychainAccess */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
CD41F5972E5B8E7300E0027B /* kordophone2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = kordophone2.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
CD41F5972E5B8E7300E0027B /* kordophone2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = kordophone2.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
@@ -23,6 +27,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
CD41F5D32E62431D00E0027B /* KeychainAccess in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -65,6 +70,7 @@
|
|||||||
);
|
);
|
||||||
name = kordophone2;
|
name = kordophone2;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
|
CD41F5D22E62431D00E0027B /* KeychainAccess */,
|
||||||
);
|
);
|
||||||
productName = kordophone2;
|
productName = kordophone2;
|
||||||
productReference = CD41F5972E5B8E7300E0027B /* kordophone2.app */;
|
productReference = CD41F5972E5B8E7300E0027B /* kordophone2.app */;
|
||||||
@@ -94,6 +100,9 @@
|
|||||||
);
|
);
|
||||||
mainGroup = CD41F58E2E5B8E7300E0027B;
|
mainGroup = CD41F58E2E5B8E7300E0027B;
|
||||||
minimizedProjectReferenceProxies = 1;
|
minimizedProjectReferenceProxies = 1;
|
||||||
|
packageReferences = (
|
||||||
|
CD41F5D12E62431D00E0027B /* XCRemoteSwiftPackageReference "KeychainAccess" */,
|
||||||
|
);
|
||||||
preferredProjectObjectVersion = 77;
|
preferredProjectObjectVersion = 77;
|
||||||
productRefGroup = CD41F5982E5B8E7300E0027B /* Products */;
|
productRefGroup = CD41F5982E5B8E7300E0027B /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@@ -321,6 +330,25 @@
|
|||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
CD41F5D12E62431D00E0027B /* XCRemoteSwiftPackageReference "KeychainAccess" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess.git";
|
||||||
|
requirement = {
|
||||||
|
branch = master;
|
||||||
|
kind = branch;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
CD41F5D22E62431D00E0027B /* KeychainAccess */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = CD41F5D12E62431D00E0027B /* XCRemoteSwiftPackageReference "KeychainAccess" */;
|
||||||
|
productName = KeychainAccess;
|
||||||
|
};
|
||||||
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = CD41F58F2E5B8E7300E0027B /* Project object */;
|
rootObject = CD41F58F2E5B8E7300E0027B /* Project object */;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
// Created by James Magahern on 8/24/25.
|
// Created by James Magahern on 8/24/25.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import KeychainAccess
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct PreferencesView: View
|
struct PreferencesView: View
|
||||||
@@ -56,6 +57,7 @@ struct AccountSettings: View
|
|||||||
var password: String
|
var password: String
|
||||||
|
|
||||||
private let xpc = XPCClient()
|
private let xpc = XPCClient()
|
||||||
|
private let keychain = Keychain(service: "net.buzzert.kordophonecd")
|
||||||
|
|
||||||
init(serverURL: String = "", username: String = "", password: String = "") {
|
init(serverURL: String = "", username: String = "", password: String = "") {
|
||||||
self.serverURL = serverURL
|
self.serverURL = serverURL
|
||||||
@@ -70,6 +72,7 @@ struct AccountSettings: View
|
|||||||
let settings = try await xpc.getSettings()
|
let settings = try await xpc.getSettings()
|
||||||
self.serverURL = settings.serverUrl
|
self.serverURL = settings.serverUrl
|
||||||
self.username = settings.username
|
self.username = settings.username
|
||||||
|
self.password = keychain[settings.username] ?? ""
|
||||||
} catch {
|
} catch {
|
||||||
print("Error getting settings: \(error)")
|
print("Error getting settings: \(error)")
|
||||||
}
|
}
|
||||||
@@ -93,6 +96,8 @@ struct AccountSettings: View
|
|||||||
username: username
|
username: username
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keychain[username] = password
|
||||||
} catch {
|
} catch {
|
||||||
print("Error saving settings: \(error)")
|
print("Error saving settings: \(error)")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,16 +71,51 @@ struct ImageItemView: View
|
|||||||
@State private var img: NSImage?
|
@State private var img: NSImage?
|
||||||
@Environment(\.xpcClient) var xpcClient
|
@Environment(\.xpcClient) var xpcClient
|
||||||
|
|
||||||
|
@State private var containerWidth: CGFloat? = nil
|
||||||
|
|
||||||
|
var aspectRatio: CGFloat {
|
||||||
|
if let size = attachment.size, size.height > 0 {
|
||||||
|
return size.width / size.height
|
||||||
|
} else {
|
||||||
|
return 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var preferredSize: CGSize {
|
||||||
|
return CGSize(
|
||||||
|
width: preferredWidth,
|
||||||
|
height: preferredWidth / aspectRatio
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var preferredWidth: CGFloat {
|
||||||
|
if let containerWidth, let attachmentWidth = attachment.size?.width {
|
||||||
|
return CGFloat.minimum(containerWidth, attachmentWidth)
|
||||||
|
} else if let containerWidth {
|
||||||
|
return containerWidth
|
||||||
|
} else {
|
||||||
|
return 200.0 // fallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BubbleView(isFromMe: isFromMe) {
|
BubbleView(isFromMe: isFromMe) {
|
||||||
if let img {
|
if let img {
|
||||||
Image(nsImage: img)
|
Image(nsImage: img)
|
||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
|
.frame(
|
||||||
|
maxWidth: containerWidth
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
ProgressView()
|
Rectangle()
|
||||||
|
.fill(.gray)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onGeometryChange(for: CGFloat.self,
|
||||||
|
of: { $0.size.width },
|
||||||
|
action: { containerWidth = $0 })
|
||||||
.task {
|
.task {
|
||||||
do {
|
do {
|
||||||
let handle = try await xpcClient.openAttachmentFileHandle(
|
let handle = try await xpcClient.openAttachmentFileHandle(
|
||||||
|
|||||||
Reference in New Issue
Block a user