Initial commit
This commit is contained in:
parent
392ca9a68d
commit
2ee44fac78
|
@ -7,22 +7,33 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
F8341F90295C636C009C8EE6 /* UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8341F8F295C636C009C8EE6 /* UIImage.swift */; };
|
||||||
|
F8341F92295C63BB009C8EE6 /* ImageStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8341F91295C63BB009C8EE6 /* ImageStatus.swift */; };
|
||||||
F88C246C295C37B80006098B /* VernissageApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C246B295C37B80006098B /* VernissageApp.swift */; };
|
F88C246C295C37B80006098B /* VernissageApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C246B295C37B80006098B /* VernissageApp.swift */; };
|
||||||
F88C246E295C37B80006098B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C246D295C37B80006098B /* ContentView.swift */; };
|
F88C246E295C37B80006098B /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C246D295C37B80006098B /* MainView.swift */; };
|
||||||
F88C2470295C37BB0006098B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F88C246F295C37BB0006098B /* Assets.xcassets */; };
|
F88C2470295C37BB0006098B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F88C246F295C37BB0006098B /* Assets.xcassets */; };
|
||||||
F88C2473295C37BB0006098B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F88C2472295C37BB0006098B /* Preview Assets.xcassets */; };
|
F88C2473295C37BB0006098B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F88C2472295C37BB0006098B /* Preview Assets.xcassets */; };
|
||||||
F88C2475295C37BB0006098B /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C2474295C37BB0006098B /* Persistence.swift */; };
|
F88C2475295C37BB0006098B /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C2474295C37BB0006098B /* Persistence.swift */; };
|
||||||
F88C2478295C37BB0006098B /* Vernissage.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */; };
|
F88C2478295C37BB0006098B /* Vernissage.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */; };
|
||||||
|
F88C2480295C38400006098B /* MastodonSwift in Frameworks */ = {isa = PBXBuildFile; productRef = F88C247F295C38400006098B /* MastodonSwift */; };
|
||||||
|
F88C2482295C3A4F0006098B /* ImageDetailsModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C2481295C3A4F0006098B /* ImageDetailsModalView.swift */; };
|
||||||
|
F88C2484295C3A870006098B /* DismissButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C2483295C3A870006098B /* DismissButtonView.swift */; };
|
||||||
|
F88C2486295C48030006098B /* HTMLFotmattedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C2485295C48030006098B /* HTMLFotmattedText.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
F8341F8F295C636C009C8EE6 /* UIImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImage.swift; sourceTree = "<group>"; };
|
||||||
|
F8341F91295C63BB009C8EE6 /* ImageStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageStatus.swift; sourceTree = "<group>"; };
|
||||||
F88C2468295C37B80006098B /* Vernissage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Vernissage.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
F88C2468295C37B80006098B /* Vernissage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Vernissage.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
F88C246B295C37B80006098B /* VernissageApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VernissageApp.swift; sourceTree = "<group>"; };
|
F88C246B295C37B80006098B /* VernissageApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VernissageApp.swift; sourceTree = "<group>"; };
|
||||||
F88C246D295C37B80006098B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
F88C246D295C37B80006098B /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
|
||||||
F88C246F295C37BB0006098B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
F88C246F295C37BB0006098B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
F88C2472295C37BB0006098B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
F88C2472295C37BB0006098B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
F88C2474295C37BB0006098B /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
|
F88C2474295C37BB0006098B /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
|
||||||
F88C2477295C37BB0006098B /* Vernissage.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Vernissage.xcdatamodel; sourceTree = "<group>"; };
|
F88C2477295C37BB0006098B /* Vernissage.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Vernissage.xcdatamodel; sourceTree = "<group>"; };
|
||||||
|
F88C2481295C3A4F0006098B /* ImageDetailsModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDetailsModalView.swift; sourceTree = "<group>"; };
|
||||||
|
F88C2483295C3A870006098B /* DismissButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissButtonView.swift; sourceTree = "<group>"; };
|
||||||
|
F88C2485295C48030006098B /* HTMLFotmattedText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTMLFotmattedText.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -30,12 +41,55 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
F88C2480295C38400006098B /* MastodonSwift in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
F8341F93295C63E2009C8EE6 /* Views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F88C2483295C3A870006098B /* DismissButtonView.swift */,
|
||||||
|
F88C2481295C3A4F0006098B /* ImageDetailsModalView.swift */,
|
||||||
|
F88C246D295C37B80006098B /* MainView.swift */,
|
||||||
|
);
|
||||||
|
path = Views;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
F8341F94295C63FE009C8EE6 /* Extensions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F8341F8F295C636C009C8EE6 /* UIImage.swift */,
|
||||||
|
);
|
||||||
|
path = Extensions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
F8341F95295C640C009C8EE6 /* Models */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F8341F91295C63BB009C8EE6 /* ImageStatus.swift */,
|
||||||
|
);
|
||||||
|
path = Models;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
F8341F96295C6427009C8EE6 /* CoreData */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F88C2474295C37BB0006098B /* Persistence.swift */,
|
||||||
|
);
|
||||||
|
path = CoreData;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
F8341F97295C6434009C8EE6 /* Formatters */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F88C2485295C48030006098B /* HTMLFotmattedText.swift */,
|
||||||
|
);
|
||||||
|
path = Formatters;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
F88C245F295C37B80006098B = {
|
F88C245F295C37B80006098B = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -55,10 +109,13 @@
|
||||||
F88C246A295C37B80006098B /* Vernissage */ = {
|
F88C246A295C37B80006098B /* Vernissage */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
F8341F97295C6434009C8EE6 /* Formatters */,
|
||||||
|
F8341F96295C6427009C8EE6 /* CoreData */,
|
||||||
|
F8341F95295C640C009C8EE6 /* Models */,
|
||||||
|
F8341F94295C63FE009C8EE6 /* Extensions */,
|
||||||
|
F8341F93295C63E2009C8EE6 /* Views */,
|
||||||
F88C246B295C37B80006098B /* VernissageApp.swift */,
|
F88C246B295C37B80006098B /* VernissageApp.swift */,
|
||||||
F88C246D295C37B80006098B /* ContentView.swift */,
|
|
||||||
F88C246F295C37BB0006098B /* Assets.xcassets */,
|
F88C246F295C37BB0006098B /* Assets.xcassets */,
|
||||||
F88C2474295C37BB0006098B /* Persistence.swift */,
|
|
||||||
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */,
|
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */,
|
||||||
F88C2471295C37BB0006098B /* Preview Content */,
|
F88C2471295C37BB0006098B /* Preview Content */,
|
||||||
);
|
);
|
||||||
|
@ -89,6 +146,9 @@
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
name = Vernissage;
|
name = Vernissage;
|
||||||
|
packageProductDependencies = (
|
||||||
|
F88C247F295C38400006098B /* MastodonSwift */,
|
||||||
|
);
|
||||||
productName = Vernissage;
|
productName = Vernissage;
|
||||||
productReference = F88C2468295C37B80006098B /* Vernissage.app */;
|
productReference = F88C2468295C37B80006098B /* Vernissage.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
|
@ -117,6 +177,9 @@
|
||||||
Base,
|
Base,
|
||||||
);
|
);
|
||||||
mainGroup = F88C245F295C37B80006098B;
|
mainGroup = F88C245F295C37B80006098B;
|
||||||
|
packageReferences = (
|
||||||
|
F88C247E295C38400006098B /* XCRemoteSwiftPackageReference "Mastodon" */,
|
||||||
|
);
|
||||||
productRefGroup = F88C2469295C37B80006098B /* Products */;
|
productRefGroup = F88C2469295C37B80006098B /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
|
@ -144,8 +207,13 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
F88C2475295C37BB0006098B /* Persistence.swift in Sources */,
|
F88C2475295C37BB0006098B /* Persistence.swift in Sources */,
|
||||||
F88C246E295C37B80006098B /* ContentView.swift in Sources */,
|
F8341F92295C63BB009C8EE6 /* ImageStatus.swift in Sources */,
|
||||||
|
F8341F90295C636C009C8EE6 /* UIImage.swift in Sources */,
|
||||||
|
F88C2484295C3A870006098B /* DismissButtonView.swift in Sources */,
|
||||||
|
F88C246E295C37B80006098B /* MainView.swift in Sources */,
|
||||||
F88C2478295C37BB0006098B /* Vernissage.xcdatamodeld in Sources */,
|
F88C2478295C37BB0006098B /* Vernissage.xcdatamodeld in Sources */,
|
||||||
|
F88C2482295C3A4F0006098B /* ImageDetailsModalView.swift in Sources */,
|
||||||
|
F88C2486295C48030006098B /* HTMLFotmattedText.swift in Sources */,
|
||||||
F88C246C295C37B80006098B /* VernissageApp.swift in Sources */,
|
F88C246C295C37B80006098B /* VernissageApp.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -283,6 +351,7 @@
|
||||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -312,6 +381,7 @@
|
||||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -348,6 +418,25 @@
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
F88C247E295C38400006098B /* XCRemoteSwiftPackageReference "Mastodon" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/Swiftodon/Mastodon.swift";
|
||||||
|
requirement = {
|
||||||
|
branch = main;
|
||||||
|
kind = branch;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
F88C247F295C38400006098B /* MastodonSwift */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = F88C247E295C38400006098B /* XCRemoteSwiftPackageReference "Mastodon" */;
|
||||||
|
productName = MastodonSwift;
|
||||||
|
};
|
||||||
|
/* End XCSwiftPackageProductDependency section */
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
/* Begin XCVersionGroup section */
|
||||||
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */ = {
|
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */ = {
|
||||||
isa = XCVersionGroup;
|
isa = XCVersionGroup;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
|
"filename" : "icon.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.000",
|
||||||
|
"green" : "0.000",
|
||||||
|
"red" : "0.000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "1.000",
|
||||||
|
"green" : "1.000",
|
||||||
|
"red" : "1.000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "255",
|
||||||
|
"green" : "143",
|
||||||
|
"red" : "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "255",
|
||||||
|
"green" : "164",
|
||||||
|
"red" : "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0",
|
||||||
|
"green" : "0",
|
||||||
|
"red" : "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "255",
|
||||||
|
"green" : "255",
|
||||||
|
"red" : "255"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "160",
|
||||||
|
"green" : "160",
|
||||||
|
"red" : "160"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "160",
|
||||||
|
"green" : "160",
|
||||||
|
"red" : "160"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,88 +0,0 @@
|
||||||
//
|
|
||||||
// https://mczachurski.dev
|
|
||||||
// Copyright © 2022 Marcin Czachurski and the repository contributors.
|
|
||||||
// Licensed under the MIT License.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import CoreData
|
|
||||||
|
|
||||||
struct ContentView: View {
|
|
||||||
@Environment(\.managedObjectContext) private var viewContext
|
|
||||||
|
|
||||||
@FetchRequest(
|
|
||||||
sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
|
|
||||||
animation: .default)
|
|
||||||
private var items: FetchedResults<Item>
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
NavigationView {
|
|
||||||
List {
|
|
||||||
ForEach(items) { item in
|
|
||||||
NavigationLink {
|
|
||||||
Text("Item at \(item.timestamp!, formatter: itemFormatter)")
|
|
||||||
} label: {
|
|
||||||
Text(item.timestamp!, formatter: itemFormatter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onDelete(perform: deleteItems)
|
|
||||||
}
|
|
||||||
.toolbar {
|
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
|
||||||
EditButton()
|
|
||||||
}
|
|
||||||
ToolbarItem {
|
|
||||||
Button(action: addItem) {
|
|
||||||
Label("Add Item", systemImage: "plus")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Text("Select an item")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func addItem() {
|
|
||||||
withAnimation {
|
|
||||||
let newItem = Item(context: viewContext)
|
|
||||||
newItem.timestamp = Date()
|
|
||||||
|
|
||||||
do {
|
|
||||||
try viewContext.save()
|
|
||||||
} catch {
|
|
||||||
// Replace this implementation with code to handle the error appropriately.
|
|
||||||
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
|
||||||
let nsError = error as NSError
|
|
||||||
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func deleteItems(offsets: IndexSet) {
|
|
||||||
withAnimation {
|
|
||||||
offsets.map { items[$0] }.forEach(viewContext.delete)
|
|
||||||
|
|
||||||
do {
|
|
||||||
try viewContext.save()
|
|
||||||
} catch {
|
|
||||||
// Replace this implementation with code to handle the error appropriately.
|
|
||||||
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
|
||||||
let nsError = error as NSError
|
|
||||||
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private let itemFormatter: DateFormatter = {
|
|
||||||
let formatter = DateFormatter()
|
|
||||||
formatter.dateStyle = .short
|
|
||||||
formatter.timeStyle = .medium
|
|
||||||
return formatter
|
|
||||||
}()
|
|
||||||
|
|
||||||
struct ContentView_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
|
||||||
ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// https://mczachurski.dev
|
||||||
|
// Copyright © 2022 Marcin Czachurski and the repository contributors.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public extension UIImage {
|
||||||
|
func getExifData() -> CFDictionary? {
|
||||||
|
var exifData: CFDictionary? = nil
|
||||||
|
|
||||||
|
if let data = self.jpegData(compressionQuality: 1.0) {
|
||||||
|
data.withUnsafeBytes {
|
||||||
|
let bytes = $0.baseAddress?.assumingMemoryBound(to: UInt8.self)
|
||||||
|
if let cfData = CFDataCreate(kCFAllocatorDefault, bytes, data.count),
|
||||||
|
let source = CGImageSourceCreateWithData(cfData, nil) {
|
||||||
|
exifData = CGImageSourceCopyPropertiesAtIndex(source, 0, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exifData
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
//
|
||||||
|
// https://mczachurski.dev
|
||||||
|
// Copyright © 2022 Marcin Czachurski and the repository contributors.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct HTMLFormattedText: UIViewRepresentable {
|
||||||
|
|
||||||
|
let text: String
|
||||||
|
private let textView = UITextView()
|
||||||
|
|
||||||
|
init(_ content: String) {
|
||||||
|
self.text = content
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeUIView(context: UIViewRepresentableContext<Self>) -> UITextView {
|
||||||
|
textView.widthAnchor.constraint(equalToConstant:UIScreen.main.bounds.width - 16).isActive = true
|
||||||
|
textView.isSelectable = false
|
||||||
|
textView.isUserInteractionEnabled = false
|
||||||
|
textView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
textView.isScrollEnabled = false
|
||||||
|
|
||||||
|
return textView
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<Self>) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
if let attributeText = self.converHTML(text: text) {
|
||||||
|
textView.attributedText = attributeText
|
||||||
|
} else {
|
||||||
|
textView.text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func converHTML(text: String) -> NSAttributedString?{
|
||||||
|
guard let data = text.data(using: .utf8) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let largeAttributes = [
|
||||||
|
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16),
|
||||||
|
NSAttributedString.Key.foregroundColor: UIColor(Color("mainTextColor"))
|
||||||
|
]
|
||||||
|
|
||||||
|
let linkAttributes = [
|
||||||
|
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16),
|
||||||
|
NSAttributedString.Key.foregroundColor: UIColor(Color("linkColor"))
|
||||||
|
]
|
||||||
|
|
||||||
|
if let attributedString = try? NSMutableAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {
|
||||||
|
|
||||||
|
attributedString.enumerateAttributes(in: NSRange(0..<attributedString.length)) { value, range, stop in
|
||||||
|
attributedString.setAttributes(largeAttributes, range: range)
|
||||||
|
|
||||||
|
if value.keys.contains(NSAttributedString.Key.link) {
|
||||||
|
attributedString.setAttributes(linkAttributes, range: range)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributedString
|
||||||
|
} else{
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HTMLFotmattedText_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
HTMLFormattedText("<p>Danish-made 1st class kebab</p><p>Say yes thanks to 2kg. delicious kebab, which is confused and cooked.</p><p>Yes thanks for 149.95</p><p>Now you can make the most delicious sandwiches, kebab mix and much more at home</p>")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// https://mczachurski.dev
|
||||||
|
// Copyright © 2022 Marcin Czachurski and the repository contributors.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import MastodonSwift
|
||||||
|
|
||||||
|
public struct ImageStatus: Identifiable {
|
||||||
|
public let id: String
|
||||||
|
public let image: UIImage
|
||||||
|
public let status: Status
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ struct VernissageApp: App {
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
ContentView()
|
MainView()
|
||||||
.environment(\.managedObjectContext, persistenceController.container.viewContext)
|
.environment(\.managedObjectContext, persistenceController.container.viewContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
// https://mczachurski.dev
|
||||||
|
// Copyright © 2022 Marcin Czachurski and the repository contributors.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct DismissButtonView: View {
|
||||||
|
var action: () -> ()
|
||||||
|
|
||||||
|
public init(_ action: @escaping () -> ()) {
|
||||||
|
self.action = action
|
||||||
|
}
|
||||||
|
|
||||||
|
public var body: some View {
|
||||||
|
Button(action: action) {
|
||||||
|
RoundedRectangle(cornerRadius: 16)
|
||||||
|
.fill(Color.gray)
|
||||||
|
.frame(width: 50, height: 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DismissButtonView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
DismissButtonView { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
//
|
||||||
|
// https://mczachurski.dev
|
||||||
|
// Copyright © 2022 Marcin Czachurski and the repository contributors.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import MastodonSwift
|
||||||
|
|
||||||
|
struct ImageDetailsModalView: View {
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@State public var current: ImageStatus
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
DismissButtonView { dismiss() }
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
VStack (alignment: .leading) {
|
||||||
|
Image(uiImage: current.image)
|
||||||
|
.resizable().aspectRatio(contentMode: .fit)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.onTapGesture {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
HStack (alignment: .center) {
|
||||||
|
AsyncImage(url: current.status.account?.avatar) { image in
|
||||||
|
image
|
||||||
|
.resizable()
|
||||||
|
.clipShape(Circle())
|
||||||
|
.shadow(radius: 10)
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
} placeholder: {
|
||||||
|
Color.gray
|
||||||
|
}
|
||||||
|
.frame(height: 60)
|
||||||
|
.frame(width: 60)
|
||||||
|
|
||||||
|
VStack (alignment: .leading) {
|
||||||
|
Text(current.status.account?.displayName ?? current.status.account?.username ?? "")
|
||||||
|
.foregroundColor(Color("displayNameColor"))
|
||||||
|
Text("@\(current.status.account?.username ?? "unknown")")
|
||||||
|
.foregroundColor(Color("userNameColor"))
|
||||||
|
.font(.footnote)
|
||||||
|
}
|
||||||
|
.padding(.leading, 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
HTMLFormattedText(current.status.content)
|
||||||
|
|
||||||
|
HStack (alignment: .top) {
|
||||||
|
Image(systemName: current.status.favourited ? "heart.fill" : "heart")
|
||||||
|
Text("\(current.status.favouritesCount) likes")
|
||||||
|
|
||||||
|
Image(systemName: "arrow.2.squarepath")
|
||||||
|
.padding(.leading, 16)
|
||||||
|
Text("\(current.status.reblogsCount) boosts")
|
||||||
|
}
|
||||||
|
.font(.footnote)
|
||||||
|
.foregroundColor(Color("mainTextColor"))
|
||||||
|
}
|
||||||
|
.padding(8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.gesture(
|
||||||
|
DragGesture().onEnded { value in
|
||||||
|
if value.location.y - value.startLocation.y > 150 {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FullScreenModalView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
Text("")
|
||||||
|
// FullScreenModalView(current: ImageStatus(id: "123", image: UIImage(), status: Status(from: <#T##Decoder#>)))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
//
|
||||||
|
// https://mczachurski.dev
|
||||||
|
// Copyright © 2022 Marcin Czachurski and the repository contributors.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import UIKit
|
||||||
|
import CoreData
|
||||||
|
import MastodonSwift
|
||||||
|
|
||||||
|
struct MainView: View {
|
||||||
|
@Environment(\.managedObjectContext) private var viewContext
|
||||||
|
|
||||||
|
@FetchRequest(
|
||||||
|
sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
|
||||||
|
animation: .default)
|
||||||
|
private var items: FetchedResults<Item>
|
||||||
|
|
||||||
|
@State private var statuses: [Status] = []
|
||||||
|
@State private var images: [ImageStatus] = []
|
||||||
|
@State private var showDetails: Bool = false
|
||||||
|
@State private var current: ImageStatus? = nil
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView {
|
||||||
|
ForEach(images) { item in
|
||||||
|
Image(uiImage: item.image)
|
||||||
|
.resizable().aspectRatio(contentMode: .fit)
|
||||||
|
.onTapGesture {
|
||||||
|
current = item
|
||||||
|
showDetails.toggle()
|
||||||
|
}
|
||||||
|
.fullScreenCover(item: $current) { item in
|
||||||
|
ImageDetailsModalView(current: item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.foregroundColor(Color.black)
|
||||||
|
.background(Color.black)
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
.task {
|
||||||
|
do {
|
||||||
|
try await loadData()
|
||||||
|
} catch {
|
||||||
|
print("Error", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func loadData() async throws {
|
||||||
|
let accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI2MTQwOCIsImp0aSI6IjZjMDg4N2ZlZThjZjBmZjQ1N2RjZDQ5MTU2YjE2NzYyYmQ2MDQ1NDQ1MmEwYzEyMzVmNDA3YjY2YjFhYjU3ZjBjMTY2YjFmZmIyNjJlZDg2IiwiaWF0IjoxNjcyMDU5MDYwLjI3NDgyMSwibmJmIjoxNjcyMDU5MDYwLjI3NDgyNCwiZXhwIjoxNzAzNTk1MDYwLjI1MzM1Nywic3ViIjoiNjc4MjMiLCJzY29wZXMiOlsicmVhZCIsIndyaXRlIiwiZm9sbG93Il19.kGvg3lW8lF1X1mOTdgGgoXNyzwUIJz5hz5RJKK_WiSoBWDQNadhZDty7XMNF0IAPjxOSi6UaIx2av7_eH_65aNlKFw89bkm8bT_zFQW2V0KbADJ-NmE6X0B_NgU2CNoF5IPn6bhCFHCKMtV6MWAQ_db6DT-LXaGemMY3QimcJzCqQuXI_1ouiZ235T297uEPNTrLwtLq-x_UoO-wx254LStBalDIGDVHAa4by9IT-mvu-QXz7k8pH2NHKoX-9Ql_Y3G9RJJNqoOmWMU45Dyo2HaJKKEb1tkeJ9tA3LIYgbwnEbG2PJ7CE8CXxtakiCIflJZpzzOmq1jXLAsCJ1mHnc77o7NfMaB_hY-f8PEI6d2ttOdH8bNlreF2avznNAIVHg_bf-yv_4wKUCUe0QZMG_yWqOwOk6lyruvboSGKuI5RnYsJbXBoJTGMLON6jVmtiKPbHy-9jNcfFgShAc3D5kTO-8Avj9_RquqEh1TQF_S4ljmganxKzMihyMDLK1OVcXzCFO6FKlCw7YKvbfJk1Qrn9kPBrVDM5jzIyXAmqRd1ivcE9nAdYb2l7KnxW_pi31uT0IdJMpTkZrUQSDMyEnj0HgV6Yd5BDlLG6Cnk8GXATTcU-a1pgE13OtWsCpD2cZQm-tOsFHWBDvY-BA0RtTvQAyEUxRIP9NjHe8rSR90"
|
||||||
|
|
||||||
|
let client = MastodonClient(baseURL: URL(string: "https://pixelfed.social")!)
|
||||||
|
.getAuthenticated(token: accessToken)
|
||||||
|
|
||||||
|
self.statuses = try await client.getHomeTimeline()
|
||||||
|
|
||||||
|
var imagesCache: [ImageStatus] = []
|
||||||
|
for item in self.statuses {
|
||||||
|
let imageStatus = try await self.fetchImage(status: item, accessToken: accessToken)
|
||||||
|
|
||||||
|
if let imageStatus {
|
||||||
|
imagesCache.append(imageStatus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.images = imagesCache
|
||||||
|
}
|
||||||
|
|
||||||
|
public func fetchImage(status: Status, accessToken: String) async throws -> ImageStatus? {
|
||||||
|
guard let url = status.mediaAttachments.first?.url, let id = status.mediaAttachments.first?.id else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let urlRequest = URLRequest(url: url)
|
||||||
|
|
||||||
|
// Fetching data.
|
||||||
|
let (data, response) = try await URLSession.shared.data(for: urlRequest)
|
||||||
|
guard (response as? HTTPURLResponse)?.statusCode == 200 else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoding JSON.
|
||||||
|
let image = UIImage(data: data)
|
||||||
|
guard let image = image else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
var exif = image.getExifData()
|
||||||
|
if let dict = exif as? [String: AnyObject] {
|
||||||
|
dict.keys.map { key in
|
||||||
|
print(key)
|
||||||
|
print(dict[key])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return ImageStatus(id: id,image: image, status: status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct MainView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
MainView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue