Compare commits
11 Commits
7f5a9fbada
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bad3524cf | ||
|
|
7471f06c52 | ||
|
|
828162ee36 | ||
|
|
f1f770c859 | ||
|
|
abf61463fe | ||
|
|
b0f2bdf430 | ||
|
|
43a1789332 | ||
|
|
d25c8e1207 | ||
|
|
cbc1b51e78 | ||
|
|
f7987bd429 | ||
|
|
f38ca55e4c |
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
.DS_Store
|
||||||
@@ -14,3 +14,6 @@ Problems:
|
|||||||
- The `ImageRenderer` sometimes renders text in the wrong color (seems to be a bug).
|
- The `ImageRenderer` sometimes renders text in the wrong color (seems to be a bug).
|
||||||
- PDF exports are fairly large (> 2 MB) due to included fonts, which is a problem for some applications.
|
- PDF exports are fairly large (> 2 MB) due to included fonts, which is a problem for some applications.
|
||||||
|
|
||||||
|
Next steps:
|
||||||
|
- Create HTML export to use for my website
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
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 */; };
|
||||||
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 */; };
|
||||||
E267D1782A8E0DE90069112B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E267D1772A8E0DE90069112B /* Assets.xcassets */; };
|
E267D1782A8E0DE90069112B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E267D1772A8E0DE90069112B /* Assets.xcassets */; };
|
||||||
@@ -41,6 +43,7 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
886AD6442AB9CD9100B1A00D /* ColorScheme+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ColorScheme+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
E2329BB12A9651E200A1270E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
E2329BB12A9651E200A1270E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||||
E267D1702A8E0DE80069112B /* ResumeBuilder.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ResumeBuilder.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
E267D1702A8E0DE80069112B /* ResumeBuilder.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ResumeBuilder.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
E267D1732A8E0DE80069112B /* ResumeBuilderApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResumeBuilderApp.swift; sourceTree = "<group>"; };
|
E267D1732A8E0DE80069112B /* ResumeBuilderApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResumeBuilderApp.swift; sourceTree = "<group>"; };
|
||||||
@@ -82,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;
|
||||||
};
|
};
|
||||||
@@ -118,6 +122,7 @@
|
|||||||
E267D17C2A8E0DE90069112B /* ResumeBuilder.entitlements */,
|
E267D17C2A8E0DE90069112B /* ResumeBuilder.entitlements */,
|
||||||
E267D1792A8E0DE90069112B /* Preview Content */,
|
E267D1792A8E0DE90069112B /* Preview Content */,
|
||||||
E267D1822A8E0F320069112B /* Color+Extension.swift */,
|
E267D1822A8E0F320069112B /* Color+Extension.swift */,
|
||||||
|
886AD6442AB9CD9100B1A00D /* ColorScheme+Extensions.swift */,
|
||||||
E267D1932A8E38C60069112B /* Data.swift */,
|
E267D1932A8E38C60069112B /* Data.swift */,
|
||||||
E267D1A52A8EC34B0069112B /* Data */,
|
E267D1A52A8EC34B0069112B /* Data */,
|
||||||
E267D1BE2A90095D0069112B /* Language */,
|
E267D1BE2A90095D0069112B /* Language */,
|
||||||
@@ -217,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 */;
|
||||||
@@ -230,7 +236,7 @@
|
|||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = 1;
|
BuildIndependentTargetsInParallel = 1;
|
||||||
LastSwiftUpdateCheck = 1430;
|
LastSwiftUpdateCheck = 1430;
|
||||||
LastUpgradeCheck = 1430;
|
LastUpgradeCheck = 1500;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
E267D16F2A8E0DE80069112B = {
|
E267D16F2A8E0DE80069112B = {
|
||||||
CreatedOnToolsVersion = 14.3.1;
|
CreatedOnToolsVersion = 14.3.1;
|
||||||
@@ -248,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 = "";
|
||||||
@@ -295,6 +302,7 @@
|
|||||||
E267D18C2A8E1A890069112B /* TopViewImage.swift in Sources */,
|
E267D18C2A8E1A890069112B /* TopViewImage.swift in Sources */,
|
||||||
E267D19C2A8E45470069112B /* CareerStation.swift in Sources */,
|
E267D19C2A8E45470069112B /* CareerStation.swift in Sources */,
|
||||||
E267D1BA2A8F9D9C0069112B /* SkillStyle.swift in Sources */,
|
E267D1BA2A8F9D9C0069112B /* SkillStyle.swift in Sources */,
|
||||||
|
886AD6452AB9CD9100B1A00D /* ColorScheme+Extensions.swift in Sources */,
|
||||||
E267D1AD2A8F694A0069112B /* PublicationView.swift in Sources */,
|
E267D1AD2A8F694A0069112B /* PublicationView.swift in Sources */,
|
||||||
E267D1BC2A8FFF300069112B /* TagView.swift in Sources */,
|
E267D1BC2A8FFF300069112B /* TagView.swift in Sources */,
|
||||||
E267D1A02A8E45620069112B /* CVInfo.swift in Sources */,
|
E267D1A02A8E45620069112B /* CVInfo.swift in Sources */,
|
||||||
@@ -313,6 +321,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
@@ -342,9 +351,11 @@
|
|||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
@@ -373,6 +384,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
@@ -402,9 +414,11 @@
|
|||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
@@ -431,6 +445,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"ResumeBuilder/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"ResumeBuilder/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = H8WR4M6QQ4;
|
DEVELOPMENT_TEAM = H8WR4M6QQ4;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -460,6 +475,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"ResumeBuilder/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"ResumeBuilder/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = H8WR4M6QQ4;
|
DEVELOPMENT_TEAM = H8WR4M6QQ4;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -504,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";
|
||||||
@@ -515,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" */;
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
BIN
ResumeBuilder.xcodeproj/project.xcworkspace/xcuserdata/imac.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal 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>
|
||||||
@@ -1,61 +1,61 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "icon 9.jpg",
|
"filename" : "icon 9.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "16x16"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon 8.jpg",
|
"filename" : "icon 8.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "16x16"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon 7.jpg",
|
"filename" : "icon 7.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "32x32"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon 6.jpg",
|
"filename" : "icon 6.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "32x32"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon 5.jpg",
|
"filename" : "icon 5.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "128x128"
|
"size" : "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon 4.jpg",
|
"filename" : "icon 4.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "128x128"
|
"size" : "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon 3.jpg",
|
"filename" : "icon 3.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "256x256"
|
"size" : "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon 2.jpg",
|
"filename" : "icon 2.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "256x256"
|
"size" : "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon 1.jpg",
|
"filename" : "icon 1.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "512x512"
|
"size" : "512x512"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon.jpg",
|
"filename" : "icon.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "512x512"
|
"size" : "512x512"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 117 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 1.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 117 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 2.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 39 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 3.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 39 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 4.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 5.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 8.2 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 6.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 7.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 8.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon 9.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 377 KiB |
BIN
ResumeBuilder/Assets.xcassets/AppIcon.appiconset/icon.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
@@ -2,6 +2,9 @@ import SwiftUI
|
|||||||
|
|
||||||
struct CV: View {
|
struct CV: View {
|
||||||
|
|
||||||
|
@Environment(\.colorScheme)
|
||||||
|
var colorScheme: ColorScheme
|
||||||
|
|
||||||
let info: CVInfo
|
let info: CVInfo
|
||||||
|
|
||||||
let style: CVStyle
|
let style: CVStyle
|
||||||
@@ -61,7 +64,7 @@ struct CV: View {
|
|||||||
Spacer(minLength: 0)
|
Spacer(minLength: 0)
|
||||||
Text(info.footer)
|
Text(info.footer)
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(colorScheme.secondaryColor)
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
.aspectRatio(1 / sqrt(2), contentMode: .fit)
|
.aspectRatio(1 / sqrt(2), contentMode: .fit)
|
||||||
|
|||||||
@@ -13,4 +13,20 @@ extension Color {
|
|||||||
init(_ r: Double, _ g: Double, _ b: Double) {
|
init(_ r: Double, _ g: Double, _ b: Double) {
|
||||||
self.init(red: r, green: g, blue: b)
|
self.init(red: r, green: g, blue: b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var lightSchemePrimaryColor: Color {
|
||||||
|
.init(r: 1, g: 1, b: 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var darkSchemePrimaryColor: Color {
|
||||||
|
.init(r: 224, g: 224, b: 224)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var lightSchemeSecondaryColor: Color {
|
||||||
|
.init(r: 128, g: 128, b: 128)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var darkSchemeSecondaryColor: Color {
|
||||||
|
.init(r: 161, g: 161, b: 161)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
ResumeBuilder/ColorScheme+Extensions.swift
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
extension ColorScheme {
|
||||||
|
|
||||||
|
var primaryColor: Color {
|
||||||
|
self == .light ? .lightSchemePrimaryColor : .darkSchemePrimaryColor
|
||||||
|
}
|
||||||
|
|
||||||
|
var secondaryColor: Color {
|
||||||
|
self == .light ? .lightSchemeSecondaryColor : .darkSchemeSecondaryColor
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,6 +51,7 @@ struct ContentView: View {
|
|||||||
}) {
|
}) {
|
||||||
Label("Export", systemSymbol: .squareAndArrowDown)
|
Label("Export", systemSymbol: .squareAndArrowDown)
|
||||||
.padding(3)
|
.padding(3)
|
||||||
|
.frame(maxHeight: 20)
|
||||||
}.confirmationDialog(
|
}.confirmationDialog(
|
||||||
"Which format would you like?",
|
"Which format would you like?",
|
||||||
isPresented: $showExportFormatPicker
|
isPresented: $showExportFormatPicker
|
||||||
@@ -65,6 +66,7 @@ struct ContentView: View {
|
|||||||
Button(action: importData) {
|
Button(action: importData) {
|
||||||
Label("Import", systemSymbol: .docBadgePlus)
|
Label("Import", systemSymbol: .docBadgePlus)
|
||||||
.padding(8)
|
.padding(8)
|
||||||
|
.frame(maxHeight: 20)
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
Toggle("Dark mode", isOn: $darkModeEnabled)
|
Toggle("Dark mode", isOn: $darkModeEnabled)
|
||||||
@@ -205,7 +207,7 @@ struct ContentView: View {
|
|||||||
private var renderContent: some View {
|
private var renderContent: some View {
|
||||||
CV(info: info, style: style)
|
CV(info: info, style: style)
|
||||||
.frame(width: style.pageWidth, height: style.pageHeight)
|
.frame(width: style.pageWidth, height: style.pageHeight)
|
||||||
.preferredColorScheme(.dark)
|
.preferredColorScheme(colorStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
|||||||
@@ -32,13 +32,19 @@ let cvInfoEnglish = CVInfo(
|
|||||||
imageName: "Cover",
|
imageName: "Cover",
|
||||||
name: "Christoph Hagen",
|
name: "Christoph Hagen",
|
||||||
tagLine: "Problem solver and creative mind with a favour for interdisciplinary work.",
|
tagLine: "Problem solver and creative mind with a favour for interdisciplinary work.",
|
||||||
place: "Würzburg, Germany",
|
place: "Munich, Germany",
|
||||||
ageText: "Age 32",
|
ageText: "Age 33",
|
||||||
web: "christophhagen.de",
|
web: "christophhagen.de",
|
||||||
email: "jobs@christophhagen.de",
|
email: "jobs@christophhagen.de",
|
||||||
phone: "Upon Request",
|
phone: "Upon Request",
|
||||||
github: "github.com/christophhagen"),
|
github: "github.com/christophhagen"),
|
||||||
work: .init(title: "Work experience", items: [
|
work: .init(title: "Work experience", items: [
|
||||||
|
CareerStation(
|
||||||
|
time: "May 2024 - Present",
|
||||||
|
location: "Oberpfaffenhofen, Germany",
|
||||||
|
title: "German Aerospace Center",
|
||||||
|
subtitle: "Software Developer",
|
||||||
|
text: "Development of the mission control system of the LUNA moon simulator hall for robotic experiments and astronaut training."),
|
||||||
CareerStation(
|
CareerStation(
|
||||||
time: "Jul 2020 - Jul 2023",
|
time: "Jul 2020 - Jul 2023",
|
||||||
location: "Braunschweig, Germany",
|
location: "Braunschweig, Germany",
|
||||||
@@ -57,12 +63,6 @@ let cvInfoEnglish = CVInfo(
|
|||||||
title: "National Institute of Informatics",
|
title: "National Institute of Informatics",
|
||||||
subtitle: "Research Intern (Intelligent Robotics)",
|
subtitle: "Research Intern (Intelligent Robotics)",
|
||||||
text: "Topic: Concept Acquisition through interactions between Humans and Robots"),
|
text: "Topic: Concept Acquisition through interactions between Humans and Robots"),
|
||||||
CareerStation(
|
|
||||||
time: "Sep 2014 - Nov 2016",
|
|
||||||
location: "Würzburg, Germany",
|
|
||||||
title: "Julius-Maximilians-Universität",
|
|
||||||
subtitle: "Research & Teaching Assistant",
|
|
||||||
text: "Teaching exercises and robotics workshops, design of a modular robot arm connector.")
|
|
||||||
]),
|
]),
|
||||||
education: .init(title: "Education", items: [
|
education: .init(title: "Education", items: [
|
||||||
CareerStation(
|
CareerStation(
|
||||||
@@ -124,13 +124,19 @@ let cvInfoGerman = CVInfo(
|
|||||||
imageName: "Cover",
|
imageName: "Cover",
|
||||||
name: "Christoph Hagen",
|
name: "Christoph Hagen",
|
||||||
tagLine: "Problemlöser und kreativer Kopf mit einer Vorliebe für interdisziplinäre Arbeit.",
|
tagLine: "Problemlöser und kreativer Kopf mit einer Vorliebe für interdisziplinäre Arbeit.",
|
||||||
place: "Würzburg",
|
place: "München",
|
||||||
ageText: "32 Jahre",
|
ageText: "33 Jahre",
|
||||||
web: "christophhagen.de",
|
web: "christophhagen.de",
|
||||||
email: "jobs@christophhagen.de",
|
email: "jobs@christophhagen.de",
|
||||||
phone: "Auf Anfrage",
|
phone: "Auf Anfrage",
|
||||||
github: "github.com/christophhagen"),
|
github: "github.com/christophhagen"),
|
||||||
work: .init(title: "Berufserfahrung", items: [
|
work: .init(title: "Berufserfahrung", items: [
|
||||||
|
CareerStation(
|
||||||
|
time: "Mai 2024 - Heute",
|
||||||
|
location: "Oberpfaffenhofen",
|
||||||
|
title: "Deutsches Zentrum für Luft- und Raumfahrt",
|
||||||
|
subtitle: "Softwareentwickler",
|
||||||
|
text: "Entwicklung des Missionskontrollsystems der LUNA Mondsimulationshalle für robotische Experimente und Astronautentraining."),
|
||||||
CareerStation(
|
CareerStation(
|
||||||
time: "Jul 2020 - Jul 2023",
|
time: "Jul 2020 - Jul 2023",
|
||||||
location: "Braunschweig",
|
location: "Braunschweig",
|
||||||
@@ -147,14 +153,8 @@ let cvInfoGerman = CVInfo(
|
|||||||
time: "Jul 2017 - Okt 2017",
|
time: "Jul 2017 - Okt 2017",
|
||||||
location: "Tokio, Japan",
|
location: "Tokio, Japan",
|
||||||
title: "National Institute of Informatics",
|
title: "National Institute of Informatics",
|
||||||
subtitle: "Research Intern (Intelligent Robotics)",
|
subtitle: "Praktikant (Intelligente Robotik)",
|
||||||
text: "Thema: Concept Acquisition through interactions between Humans and Robots"),
|
text: "Thema: Concept Acquisition through interactions between Humans and Robots")
|
||||||
CareerStation(
|
|
||||||
time: "Sep 2014 - Nov 2016",
|
|
||||||
location: "Würzburg",
|
|
||||||
title: "Julius-Maximilians-Universität",
|
|
||||||
subtitle: "Research & Teaching Assistant",
|
|
||||||
text: "Leitung von Übungen und Robotikworkshops, Entwurf einer modularen Verbindung für einen Roboterarm.")
|
|
||||||
]),
|
]),
|
||||||
education: .init(title: "Bildung", items: [
|
education: .init(title: "Bildung", items: [
|
||||||
CareerStation(
|
CareerStation(
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import SFSafeSymbols
|
|||||||
|
|
||||||
struct CareerStationView: View {
|
struct CareerStationView: View {
|
||||||
|
|
||||||
|
@Environment(\.colorScheme)
|
||||||
|
var colorScheme: ColorScheme
|
||||||
|
|
||||||
let info: CareerStation
|
let info: CareerStation
|
||||||
|
|
||||||
let borderSpacing: CGFloat
|
let borderSpacing: CGFloat
|
||||||
@@ -20,7 +23,7 @@ struct CareerStationView: View {
|
|||||||
RightImageLabel(info.location, systemSymbol: .house)
|
RightImageLabel(info.location, systemSymbol: .house)
|
||||||
}
|
}
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(colorScheme.secondaryColor)
|
||||||
Text(info.title)
|
Text(info.title)
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.fontWeight(.regular)
|
.fontWeight(.regular)
|
||||||
@@ -32,7 +35,7 @@ struct CareerStationView: View {
|
|||||||
if let text = info.text {
|
if let text = info.text {
|
||||||
Text(text)
|
Text(text)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(colorScheme.secondaryColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import SwiftUI
|
|||||||
|
|
||||||
struct PublicationView: View {
|
struct PublicationView: View {
|
||||||
|
|
||||||
|
@Environment(\.colorScheme)
|
||||||
|
var colorScheme: ColorScheme
|
||||||
|
|
||||||
let info: Publication
|
let info: Publication
|
||||||
|
|
||||||
let borderSpacing: CGFloat
|
let borderSpacing: CGFloat
|
||||||
@@ -15,10 +18,11 @@ struct PublicationView: View {
|
|||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text(info.venue)
|
Text(info.venue)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(colorScheme.secondaryColor)
|
||||||
Text(info.title)
|
Text(info.title)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.fontWeight(.regular)
|
.fontWeight(.regular)
|
||||||
|
.foregroundColor(colorScheme.primaryColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,19 @@ import SwiftUI
|
|||||||
|
|
||||||
struct TitledTextSection: View {
|
struct TitledTextSection: View {
|
||||||
|
|
||||||
|
@Environment(\.colorScheme)
|
||||||
|
var colorScheme: ColorScheme
|
||||||
|
|
||||||
let content: Titled<String>
|
let content: Titled<String>
|
||||||
|
|
||||||
let titleSpacing: CGFloat
|
let titleSpacing: CGFloat
|
||||||
|
|
||||||
let paragraphSpacing: CGFloat
|
let paragraphSpacing: CGFloat
|
||||||
|
|
||||||
|
private var textColor: Color {
|
||||||
|
colorScheme == .light ? .lightSchemePrimaryColor : .darkSchemePrimaryColor
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
TitledSection(title: content.title, spacing: titleSpacing) {
|
TitledSection(title: content.title, spacing: titleSpacing) {
|
||||||
ForEach(content.items) { text in
|
ForEach(content.items) { text in
|
||||||
@@ -15,6 +22,7 @@ struct TitledTextSection: View {
|
|||||||
.font(.body)
|
.font(.body)
|
||||||
.fontWeight(.light)
|
.fontWeight(.light)
|
||||||
.padding(.bottom, paragraphSpacing)
|
.padding(.bottom, paragraphSpacing)
|
||||||
|
.foregroundColor(textColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,30 @@ 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) {
|
||||||
|
Text(info.web)
|
||||||
|
//Link(info.web, destination: URL(string: "https://" + info.web)!)
|
||||||
|
}
|
||||||
.frame(maxHeight: style.iconHeight)
|
.frame(maxHeight: style.iconHeight)
|
||||||
Spacer()
|
Spacer()
|
||||||
LeftImageLabel(info.email, systemSymbol: .envelope)
|
LeftImageLabel(systemSymbol: .envelope) {
|
||||||
|
Text(info.email)
|
||||||
|
//Link(info.email, destination: URL(string: "mailto:" + info.email)!)
|
||||||
|
//.disabled(!isValidEmail)
|
||||||
|
}
|
||||||
.frame(maxHeight: style.iconHeight)
|
.frame(maxHeight: style.iconHeight)
|
||||||
Spacer()
|
Spacer()
|
||||||
LeftImageLabel(info.phone, systemSymbol: .phone)
|
LeftImageLabel(systemSymbol: .phone) {
|
||||||
|
Text(info.phone)
|
||||||
|
//Link(info.phone, destination: URL(string: "tel:" + info.phone)!)
|
||||||
|
//.disabled(!isValidPhoneNumber)
|
||||||
|
}
|
||||||
.frame(maxHeight: style.iconHeight)
|
.frame(maxHeight: style.iconHeight)
|
||||||
Spacer()
|
Spacer()
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(info.github)
|
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 +85,7 @@ struct TopView: View {
|
|||||||
}
|
}
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.frame(width: sideWidth)
|
.frame(width: sideWidth)
|
||||||
|
.foregroundStyle(.primary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||