Add links for email, phone and domain

This commit is contained in:
Christoph Hagen 2023-11-10 11:22:49 +01:00
parent 43a1789332
commit b0f2bdf430
6 changed files with 82 additions and 15 deletions

View File

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
880A8C212AFE3B0C000ABBFA /* PhoneNumberKit in Frameworks */ = {isa = PBXBuildFile; productRef = 880A8C202AFE3B0C000ABBFA /* PhoneNumberKit */; };
886AD6452AB9CD9100B1A00D /* ColorScheme+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 886AD6442AB9CD9100B1A00D /* ColorScheme+Extensions.swift */; }; 886AD6452AB9CD9100B1A00D /* ColorScheme+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 886AD6442AB9CD9100B1A00D /* ColorScheme+Extensions.swift */; };
E267D1742A8E0DE80069112B /* ResumeBuilderApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E267D1732A8E0DE80069112B /* ResumeBuilderApp.swift */; }; E267D1742A8E0DE80069112B /* ResumeBuilderApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E267D1732A8E0DE80069112B /* ResumeBuilderApp.swift */; };
E267D1762A8E0DE80069112B /* CV.swift in Sources */ = {isa = PBXBuildFile; fileRef = E267D1752A8E0DE80069112B /* CV.swift */; }; E267D1762A8E0DE80069112B /* CV.swift in Sources */ = {isa = PBXBuildFile; fileRef = E267D1752A8E0DE80069112B /* CV.swift */; };
@ -84,6 +85,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
E267D1882A8E12D60069112B /* SFSafeSymbols in Frameworks */, E267D1882A8E12D60069112B /* SFSafeSymbols in Frameworks */,
880A8C212AFE3B0C000ABBFA /* PhoneNumberKit in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -220,6 +222,7 @@
name = ResumeBuilder; name = ResumeBuilder;
packageProductDependencies = ( packageProductDependencies = (
E267D1872A8E12D60069112B /* SFSafeSymbols */, E267D1872A8E12D60069112B /* SFSafeSymbols */,
880A8C202AFE3B0C000ABBFA /* PhoneNumberKit */,
); );
productName = ResumeBuilder; productName = ResumeBuilder;
productReference = E267D1702A8E0DE80069112B /* ResumeBuilder.app */; productReference = E267D1702A8E0DE80069112B /* ResumeBuilder.app */;
@ -251,6 +254,7 @@
mainGroup = E267D1672A8E0DE80069112B; mainGroup = E267D1672A8E0DE80069112B;
packageReferences = ( packageReferences = (
E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */, E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
880A8C1F2AFE3B0C000ABBFA /* XCRemoteSwiftPackageReference "PhoneNumberKit" */,
); );
productRefGroup = E267D1712A8E0DE80069112B /* Products */; productRefGroup = E267D1712A8E0DE80069112B /* Products */;
projectDirPath = ""; projectDirPath = "";
@ -516,6 +520,14 @@
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */ /* Begin XCRemoteSwiftPackageReference section */
880A8C1F2AFE3B0C000ABBFA /* XCRemoteSwiftPackageReference "PhoneNumberKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/marmelroy/PhoneNumberKit";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 3.7.4;
};
};
E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */ = { E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */ = {
isa = XCRemoteSwiftPackageReference; isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SFSafeSymbols/SFSafeSymbols"; repositoryURL = "https://github.com/SFSafeSymbols/SFSafeSymbols";
@ -527,6 +539,11 @@
/* End XCRemoteSwiftPackageReference section */ /* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */ /* Begin XCSwiftPackageProductDependency section */
880A8C202AFE3B0C000ABBFA /* PhoneNumberKit */ = {
isa = XCSwiftPackageProductDependency;
package = 880A8C1F2AFE3B0C000ABBFA /* XCRemoteSwiftPackageReference "PhoneNumberKit" */;
productName = PhoneNumberKit;
};
E267D1872A8E12D60069112B /* SFSafeSymbols */ = { E267D1872A8E12D60069112B /* SFSafeSymbols */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
package = E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */; package = E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */;

View File

@ -1,5 +1,14 @@
{ {
"pins" : [ "pins" : [
{
"identity" : "phonenumberkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/marmelroy/PhoneNumberKit",
"state" : {
"revision" : "b456f2f9be10c1d183158220b831afd22697dd68",
"version" : "3.7.4"
}
},
{ {
"identity" : "sfsafesymbols", "identity" : "sfsafesymbols",
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>ResumeBuilder.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>

View File

@ -1,20 +1,20 @@
import SwiftUI import SwiftUI
import SFSafeSymbols import SFSafeSymbols
struct LeftImageLabel: View { struct LeftImageLabel<Content>: View where Content: View {
let text: String
let systemSymbol: SFSymbol let systemSymbol: SFSymbol
init(_ text: String, systemSymbol: SFSymbol) { let content: Content
self.text = text
init(systemSymbol: SFSymbol, @ViewBuilder content: () -> Content) {
self.systemSymbol = systemSymbol self.systemSymbol = systemSymbol
self.content = content()
} }
var body: some View { var body: some View {
HStack(alignment: .firstTextBaseline, spacing: 0) { HStack(alignment: .center, spacing: 0) {
Text(text) content
Image(systemSymbol: systemSymbol) Image(systemSymbol: systemSymbol)
.frame(width: 20) .frame(width: 20)
} }
@ -23,6 +23,6 @@ struct LeftImageLabel: View {
struct LeftImageLabel_Previews: PreviewProvider { struct LeftImageLabel_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
LeftImageLabel("Home address", systemSymbol: .house) LeftImageLabel(systemSymbol: .house) { Text("Home address") }
} }
} }

View File

@ -1,5 +1,8 @@
import SwiftUI import SwiftUI
import SFSafeSymbols import SFSafeSymbols
import PhoneNumberKit
private let emailPattern = #"^\S+@\S+\.\S+$"#
struct TopView: View { struct TopView: View {
@ -9,6 +12,21 @@ struct TopView: View {
let accent: Color let accent: Color
private let phoneNumberKit = PhoneNumberKit()
var isValidEmail: Bool {
info.email.range(of: emailPattern, options: .regularExpression) != nil
}
var isValidPhoneNumber: Bool {
do {
_ = try phoneNumberKit.parse(info.phone)
return true
} catch {
return false
}
}
var body: some View { var body: some View {
GeometryReader { geo in GeometryReader { geo in
let sideWidth = max(0, (geo.size.width - geo.size.height) / 2) let sideWidth = max(0, (geo.size.width - geo.size.height) / 2)
@ -34,18 +52,26 @@ struct TopView: View {
shadow: style.imageShadowSize, shadow: style.imageShadowSize,
lineWidth: style.imageBorderWidth) lineWidth: style.imageBorderWidth)
VStack(alignment: .trailing) { VStack(alignment: .trailing) {
LeftImageLabel(info.web, systemSymbol: .globe) LeftImageLabel(systemSymbol: .globe) {
.frame(maxHeight: style.iconHeight) Link(info.web, destination: URL(string: "https://" + info.web)!)
}
.frame(maxHeight: style.iconHeight)
Spacer() Spacer()
LeftImageLabel(info.email, systemSymbol: .envelope) LeftImageLabel(systemSymbol: .envelope) {
.frame(maxHeight: style.iconHeight) Link(info.email, destination: URL(string: "mailto:" + info.email)!)
.disabled(!isValidEmail)
}
.frame(maxHeight: style.iconHeight)
Spacer() Spacer()
LeftImageLabel(info.phone, systemSymbol: .phone) LeftImageLabel(systemSymbol: .phone) {
.frame(maxHeight: style.iconHeight) Link(info.phone, destination: URL(string: "tel:" + info.phone)!)
.disabled(!isValidPhoneNumber)
}
.frame(maxHeight: style.iconHeight)
Spacer() Spacer()
HStack(spacing: 0) { HStack(spacing: 0) {
Spacer() Spacer()
Text(info.github) Link(info.github, destination: URL(string: "https://" + info.github)!)
Image("Github") Image("Github")
.resizable() .resizable()
.aspectRatio(1.0, contentMode: .fit) .aspectRatio(1.0, contentMode: .fit)
@ -55,6 +81,7 @@ struct TopView: View {
} }
.font(.subheadline) .font(.subheadline)
.frame(width: sideWidth) .frame(width: sideWidth)
.foregroundStyle(.primary)
} }
} }
} }