Mid Hack Demo

This commit is contained in:
Francisco Gindre 2020-06-26 12:45:19 -03:00
parent 3abd221b82
commit 2b49d85683
25 changed files with 695 additions and 133 deletions

View File

@ -14,16 +14,17 @@
0D11D3D4249D05D800223146 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3D3249D05D800223146 /* Wedge.swift */; }; 0D11D3D4249D05D800223146 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3D3249D05D800223146 /* Wedge.swift */; };
0D11D3D7249D2F0B00223146 /* ZircleProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3D6249D2F0B00223146 /* ZircleProgress.swift */; }; 0D11D3D7249D2F0B00223146 /* ZircleProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3D6249D2F0B00223146 /* ZircleProgress.swift */; };
0D11D3D9249D51FC00223146 /* ZircleTextField_Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3D8249D51FC00223146 /* ZircleTextField_Preview.swift */; }; 0D11D3D9249D51FC00223146 /* ZircleTextField_Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3D8249D51FC00223146 /* ZircleTextField_Preview.swift */; };
0D11D3DB249D5F1600223146 /* ProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3DA249D5F1600223146 /* ProgressBar.swift */; }; 0D11D3DB249D5F1600223146 /* NeumorphicProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3DA249D5F1600223146 /* NeumorphicProgressBar.swift */; };
0D11D3DD249D81B900223146 /* Pie.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3DC249D81B900223146 /* Pie.swift */; }; 0D11D3DD249D81B900223146 /* Pie.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3DC249D81B900223146 /* Pie.swift */; };
0D1366AC24991A6000F0EB54 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AB24991A6000F0EB54 /* AppDelegate.swift */; }; 0D1366AC24991A6000F0EB54 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AB24991A6000F0EB54 /* AppDelegate.swift */; };
0D1366AE24991A6000F0EB54 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AD24991A6000F0EB54 /* SceneDelegate.swift */; }; 0D1366AE24991A6000F0EB54 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AD24991A6000F0EB54 /* SceneDelegate.swift */; };
0D1366B024991A6000F0EB54 /* SplashScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AF24991A6000F0EB54 /* SplashScreen.swift */; }; 0D1366B024991A6000F0EB54 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AF24991A6000F0EB54 /* HomeScreen.swift */; };
0D1366B224991A6100F0EB54 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D1366B124991A6100F0EB54 /* Assets.xcassets */; }; 0D1366B224991A6100F0EB54 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D1366B124991A6100F0EB54 /* Assets.xcassets */; };
0D1366B524991A6100F0EB54 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D1366B424991A6100F0EB54 /* Preview Assets.xcassets */; }; 0D1366B524991A6100F0EB54 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D1366B424991A6100F0EB54 /* Preview Assets.xcassets */; };
0D1366B824991A6100F0EB54 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0D1366B624991A6100F0EB54 /* LaunchScreen.storyboard */; }; 0D1366B824991A6100F0EB54 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0D1366B624991A6100F0EB54 /* LaunchScreen.storyboard */; };
0D1366C324991A6200F0EB54 /* ZirclesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366C224991A6200F0EB54 /* ZirclesTests.swift */; }; 0D1366C324991A6200F0EB54 /* ZirclesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366C224991A6200F0EB54 /* ZirclesTests.swift */; };
0D1366CE24991A6200F0EB54 /* ZirclesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366CD24991A6200F0EB54 /* ZirclesUITests.swift */; }; 0D1366CE24991A6200F0EB54 /* ZirclesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366CD24991A6200F0EB54 /* ZirclesUITests.swift */; };
0D3FB6FE24A4CD4E0034A52A /* MockEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D3FB6FD24A4CD4E0034A52A /* MockEnvironment.swift */; };
0D5142C324A0F0B800F9AE2E /* Zboto.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0D5142C224A0F0B800F9AE2E /* Zboto.otf */; }; 0D5142C324A0F0B800F9AE2E /* Zboto.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0D5142C224A0F0B800F9AE2E /* Zboto.otf */; };
0D5142C624A14D0F00F9AE2E /* CreateNewZircleNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5142C524A14D0F00F9AE2E /* CreateNewZircleNameView.swift */; }; 0D5142C624A14D0F00F9AE2E /* CreateNewZircleNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5142C524A14D0F00F9AE2E /* CreateNewZircleNameView.swift */; };
0D5142C824A16F9600F9AE2E /* CreateNewTypeOfZircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5142C724A16F9600F9AE2E /* CreateNewTypeOfZircle.swift */; }; 0D5142C824A16F9600F9AE2E /* CreateNewTypeOfZircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5142C724A16F9600F9AE2E /* CreateNewTypeOfZircle.swift */; };
@ -48,6 +49,11 @@
0D6A22C7249AB36100B4E946 /* ZcashButtonBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */; }; 0D6A22C7249AB36100B4E946 /* ZcashButtonBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */; };
0D6A22C9249AB3CA00B4E946 /* ZcashButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22C8249AB3CA00B4E946 /* ZcashButton.swift */; }; 0D6A22C9249AB3CA00B4E946 /* ZcashButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22C8249AB3CA00B4E946 /* ZcashButton.swift */; };
0D6A22CB249AB61200B4E946 /* Glow_Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */; }; 0D6A22CB249AB61200B4E946 /* Glow_Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */; };
0DB5330F24A623AF0090D722 /* sapling-spend.params in Resources */ = {isa = PBXBuildFile; fileRef = 0DB5330D24A623AF0090D722 /* sapling-spend.params */; };
0DB5331024A623AF0090D722 /* sapling-output.params in Resources */ = {isa = PBXBuildFile; fileRef = 0DB5330E24A623AF0090D722 /* sapling-output.params */; };
0DB5331224A6413D0090D722 /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB5331124A6413D0090D722 /* LazyView.swift */; };
0DD7278924A5532300C36D27 /* AllZirclesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DD7278824A5532300C36D27 /* AllZirclesView.swift */; };
0DD7278B24A564AF00C36D27 /* ZircleListCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DD7278A24A564AF00C36D27 /* ZircleListCard.swift */; };
0DEE59A824A24B7300447C15 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DEE59A724A24B7300447C15 /* WelcomeView.swift */; }; 0DEE59A824A24B7300447C15 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DEE59A724A24B7300447C15 /* WelcomeView.swift */; };
0DEE59AA24A2B90F00447C15 /* CreateNewZircleDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DEE59A924A2B90F00447C15 /* CreateNewZircleDescription.swift */; }; 0DEE59AA24A2B90F00447C15 /* CreateNewZircleDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DEE59A924A2B90F00447C15 /* CreateNewZircleDescription.swift */; };
450B0C2B71526C48C265CB70 /* Pods_Zircles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 897CFDF9BD39874744EF71AB /* Pods_Zircles.framework */; }; 450B0C2B71526C48C265CB70 /* Pods_Zircles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 897CFDF9BD39874744EF71AB /* Pods_Zircles.framework */; };
@ -78,12 +84,12 @@
0D11D3D3249D05D800223146 /* Wedge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wedge.swift; sourceTree = "<group>"; }; 0D11D3D3249D05D800223146 /* Wedge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wedge.swift; sourceTree = "<group>"; };
0D11D3D6249D2F0B00223146 /* ZircleProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZircleProgress.swift; sourceTree = "<group>"; }; 0D11D3D6249D2F0B00223146 /* ZircleProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZircleProgress.swift; sourceTree = "<group>"; };
0D11D3D8249D51FC00223146 /* ZircleTextField_Preview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZircleTextField_Preview.swift; sourceTree = "<group>"; }; 0D11D3D8249D51FC00223146 /* ZircleTextField_Preview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZircleTextField_Preview.swift; sourceTree = "<group>"; };
0D11D3DA249D5F1600223146 /* ProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBar.swift; sourceTree = "<group>"; }; 0D11D3DA249D5F1600223146 /* NeumorphicProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicProgressBar.swift; sourceTree = "<group>"; };
0D11D3DC249D81B900223146 /* Pie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pie.swift; sourceTree = "<group>"; }; 0D11D3DC249D81B900223146 /* Pie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pie.swift; sourceTree = "<group>"; };
0D1366A824991A6000F0EB54 /* Zircles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Zircles.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0D1366A824991A6000F0EB54 /* Zircles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Zircles.app; sourceTree = BUILT_PRODUCTS_DIR; };
0D1366AB24991A6000F0EB54 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 0D1366AB24991A6000F0EB54 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
0D1366AD24991A6000F0EB54 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; }; 0D1366AD24991A6000F0EB54 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
0D1366AF24991A6000F0EB54 /* SplashScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreen.swift; sourceTree = "<group>"; }; 0D1366AF24991A6000F0EB54 /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = "<group>"; };
0D1366B124991A6100F0EB54 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 0D1366B124991A6100F0EB54 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0D1366B424991A6100F0EB54 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; }; 0D1366B424991A6100F0EB54 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
0D1366B724991A6100F0EB54 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 0D1366B724991A6100F0EB54 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
@ -94,6 +100,7 @@
0D1366C924991A6200F0EB54 /* ZirclesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ZirclesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 0D1366C924991A6200F0EB54 /* ZirclesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ZirclesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
0D1366CD24991A6200F0EB54 /* ZirclesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZirclesUITests.swift; sourceTree = "<group>"; }; 0D1366CD24991A6200F0EB54 /* ZirclesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZirclesUITests.swift; sourceTree = "<group>"; };
0D1366CF24991A6200F0EB54 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 0D1366CF24991A6200F0EB54 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0D3FB6FD24A4CD4E0034A52A /* MockEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockEnvironment.swift; sourceTree = "<group>"; };
0D5142C224A0F0B800F9AE2E /* Zboto.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Zboto.otf; sourceTree = "<group>"; }; 0D5142C224A0F0B800F9AE2E /* Zboto.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Zboto.otf; sourceTree = "<group>"; };
0D5142C524A14D0F00F9AE2E /* CreateNewZircleNameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateNewZircleNameView.swift; sourceTree = "<group>"; }; 0D5142C524A14D0F00F9AE2E /* CreateNewZircleNameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateNewZircleNameView.swift; sourceTree = "<group>"; };
0D5142C724A16F9600F9AE2E /* CreateNewTypeOfZircle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateNewTypeOfZircle.swift; sourceTree = "<group>"; }; 0D5142C724A16F9600F9AE2E /* CreateNewTypeOfZircle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateNewTypeOfZircle.swift; sourceTree = "<group>"; };
@ -118,6 +125,11 @@
0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZcashButtonBackground.swift; sourceTree = "<group>"; }; 0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZcashButtonBackground.swift; sourceTree = "<group>"; };
0D6A22C8249AB3CA00B4E946 /* ZcashButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZcashButton.swift; sourceTree = "<group>"; }; 0D6A22C8249AB3CA00B4E946 /* ZcashButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZcashButton.swift; sourceTree = "<group>"; };
0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Glow_Preview.swift; sourceTree = "<group>"; }; 0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Glow_Preview.swift; sourceTree = "<group>"; };
0DB5330D24A623AF0090D722 /* sapling-spend.params */ = {isa = PBXFileReference; lastKnownFileType = file; path = "sapling-spend.params"; sourceTree = "<group>"; };
0DB5330E24A623AF0090D722 /* sapling-output.params */ = {isa = PBXFileReference; lastKnownFileType = file; path = "sapling-output.params"; sourceTree = "<group>"; };
0DB5331124A6413D0090D722 /* LazyView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = "<group>"; };
0DD7278824A5532300C36D27 /* AllZirclesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllZirclesView.swift; sourceTree = "<group>"; };
0DD7278A24A564AF00C36D27 /* ZircleListCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZircleListCard.swift; sourceTree = "<group>"; };
0DEE59A724A24B7300447C15 /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = "<group>"; }; 0DEE59A724A24B7300447C15 /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = "<group>"; };
0DEE59A924A2B90F00447C15 /* CreateNewZircleDescription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateNewZircleDescription.swift; sourceTree = "<group>"; }; 0DEE59A924A2B90F00447C15 /* CreateNewZircleDescription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateNewZircleDescription.swift; sourceTree = "<group>"; };
5A3D0DB1D10FF551A7DE4766 /* Pods-Zircles-ZirclesUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Zircles-ZirclesUITests.release.xcconfig"; path = "Target Support Files/Pods-Zircles-ZirclesUITests/Pods-Zircles-ZirclesUITests.release.xcconfig"; sourceTree = "<group>"; }; 5A3D0DB1D10FF551A7DE4766 /* Pods-Zircles-ZirclesUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Zircles-ZirclesUITests.release.xcconfig"; path = "Target Support Files/Pods-Zircles-ZirclesUITests/Pods-Zircles-ZirclesUITests.release.xcconfig"; sourceTree = "<group>"; };
@ -172,6 +184,7 @@
0D11D3D5249D2E0400223146 /* Utils */ = { 0D11D3D5249D2E0400223146 /* Utils */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0DB5331124A6413D0090D722 /* LazyView.swift */,
0D64CEB224A3CDA90080AA4F /* BalanceUtils.swift */, 0D64CEB224A3CDA90080AA4F /* BalanceUtils.swift */,
0D64CEB124A3CDA90080AA4F /* CameraAccessHelper.swift */, 0D64CEB124A3CDA90080AA4F /* CameraAccessHelper.swift */,
0D64CEAE24A3CDA80080AA4F /* MnemonicSeedPhraseHandling.swift */, 0D64CEAE24A3CDA80080AA4F /* MnemonicSeedPhraseHandling.swift */,
@ -186,6 +199,7 @@
0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */, 0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */,
0D64CEC024A3F2580080AA4F /* FirstScreen.swift */, 0D64CEC024A3F2580080AA4F /* FirstScreen.swift */,
0D64CEC224A4137D0080AA4F /* ZircleData.swift */, 0D64CEC224A4137D0080AA4F /* ZircleData.swift */,
0D3FB6FD24A4CD4E0034A52A /* MockEnvironment.swift */,
); );
path = Utils; path = Utils;
sourceTree = "<group>"; sourceTree = "<group>";
@ -215,6 +229,8 @@
0D1366AA24991A6000F0EB54 /* Zircles */ = { 0D1366AA24991A6000F0EB54 /* Zircles */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0DB5330E24A623AF0090D722 /* sapling-output.params */,
0DB5330D24A623AF0090D722 /* sapling-spend.params */,
0D64CEBE24A3D3A30080AA4F /* CombineSynchronizer.swift */, 0D64CEBE24A3D3A30080AA4F /* CombineSynchronizer.swift */,
0D64CEA724A3CD040080AA4F /* Environment */, 0D64CEA724A3CD040080AA4F /* Environment */,
0D5142C424A1323900F9AE2E /* Views */, 0D5142C424A1323900F9AE2E /* Views */,
@ -262,12 +278,13 @@
0D5142C424A1323900F9AE2E /* Views */ = { 0D5142C424A1323900F9AE2E /* Views */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0D1366AF24991A6000F0EB54 /* SplashScreen.swift */, 0D1366AF24991A6000F0EB54 /* HomeScreen.swift */,
0D5142C524A14D0F00F9AE2E /* CreateNewZircleNameView.swift */, 0D5142C524A14D0F00F9AE2E /* CreateNewZircleNameView.swift */,
0D5142C724A16F9600F9AE2E /* CreateNewTypeOfZircle.swift */, 0D5142C724A16F9600F9AE2E /* CreateNewTypeOfZircle.swift */,
0DEE59A724A24B7300447C15 /* WelcomeView.swift */, 0DEE59A724A24B7300447C15 /* WelcomeView.swift */,
0DEE59A924A2B90F00447C15 /* CreateNewZircleDescription.swift */, 0DEE59A924A2B90F00447C15 /* CreateNewZircleDescription.swift */,
0D64CEC424A41AF30080AA4F /* AppDetails.swift */, 0D64CEC424A41AF30080AA4F /* AppDetails.swift */,
0DD7278824A5532300C36D27 /* AllZirclesView.swift */,
); );
path = Views; path = Views;
sourceTree = "<group>"; sourceTree = "<group>";
@ -288,6 +305,7 @@
0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */, 0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */,
0D6A22C4249AB1FC00B4E946 /* ZcashSymbol.swift */, 0D6A22C4249AB1FC00B4E946 /* ZcashSymbol.swift */,
0D64CEA524A3854C0080AA4F /* ZircleOptionSelector.swift */, 0D64CEA524A3854C0080AA4F /* ZircleOptionSelector.swift */,
0DD7278A24A564AF00C36D27 /* ZircleListCard.swift */,
); );
path = Components; path = Components;
sourceTree = "<group>"; sourceTree = "<group>";
@ -295,7 +313,7 @@
0D6A22CC249ACD6C00B4E946 /* Neumorphic */ = { 0D6A22CC249ACD6C00B4E946 /* Neumorphic */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0D11D3DA249D5F1600223146 /* ProgressBar.swift */, 0D11D3DA249D5F1600223146 /* NeumorphicProgressBar.swift */,
0D11D3CD249C294E00223146 /* NeumorphicButtons.swift */, 0D11D3CD249C294E00223146 /* NeumorphicButtons.swift */,
0D11D3CF249C3AE300223146 /* Card.swift */, 0D11D3CF249C3AE300223146 /* Card.swift */,
0D11D3D1249CE6C800223146 /* GlowEffect.swift */, 0D11D3D1249CE6C800223146 /* GlowEffect.swift */,
@ -430,7 +448,9 @@
0D1366B824991A6100F0EB54 /* LaunchScreen.storyboard in Resources */, 0D1366B824991A6100F0EB54 /* LaunchScreen.storyboard in Resources */,
0D1366B524991A6100F0EB54 /* Preview Assets.xcassets in Resources */, 0D1366B524991A6100F0EB54 /* Preview Assets.xcassets in Resources */,
0D5142C324A0F0B800F9AE2E /* Zboto.otf in Resources */, 0D5142C324A0F0B800F9AE2E /* Zboto.otf in Resources */,
0DB5331024A623AF0090D722 /* sapling-output.params in Resources */,
0D1366B224991A6100F0EB54 /* Assets.xcassets in Resources */, 0D1366B224991A6100F0EB54 /* Assets.xcassets in Resources */,
0DB5330F24A623AF0090D722 /* sapling-spend.params in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -574,16 +594,20 @@
0D11D3D0249C3AE400223146 /* Card.swift in Sources */, 0D11D3D0249C3AE400223146 /* Card.swift in Sources */,
0D64CEB724A3CDA90080AA4F /* QRCodeGenerator.swift in Sources */, 0D64CEB724A3CDA90080AA4F /* QRCodeGenerator.swift in Sources */,
0D64CEBF24A3D3A30080AA4F /* CombineSynchronizer.swift in Sources */, 0D64CEBF24A3D3A30080AA4F /* CombineSynchronizer.swift in Sources */,
0DD7278B24A564AF00C36D27 /* ZircleListCard.swift in Sources */,
0D6A22CB249AB61200B4E946 /* Glow_Preview.swift in Sources */, 0D6A22CB249AB61200B4E946 /* Glow_Preview.swift in Sources */,
0D5142C624A14D0F00F9AE2E /* CreateNewZircleNameView.swift in Sources */, 0D5142C624A14D0F00F9AE2E /* CreateNewZircleNameView.swift in Sources */,
0DEE59AA24A2B90F00447C15 /* CreateNewZircleDescription.swift in Sources */, 0DEE59AA24A2B90F00447C15 /* CreateNewZircleDescription.swift in Sources */,
0DD7278924A5532300C36D27 /* AllZirclesView.swift in Sources */,
0D3FB6FE24A4CD4E0034A52A /* MockEnvironment.swift in Sources */,
0D11D3D7249D2F0B00223146 /* ZircleProgress.swift in Sources */, 0D11D3D7249D2F0B00223146 /* ZircleProgress.swift in Sources */,
0D11D3D9249D51FC00223146 /* ZircleTextField_Preview.swift in Sources */, 0D11D3D9249D51FC00223146 /* ZircleTextField_Preview.swift in Sources */,
0D64CEC124A3F2580080AA4F /* FirstScreen.swift in Sources */, 0D64CEC124A3F2580080AA4F /* FirstScreen.swift in Sources */,
0D64CEBA24A3CDA90080AA4F /* zECC+SwiftUI.swift in Sources */, 0D64CEBA24A3CDA90080AA4F /* zECC+SwiftUI.swift in Sources */,
0D11D3D2249CE6C800223146 /* GlowEffect.swift in Sources */, 0D11D3D2249CE6C800223146 /* GlowEffect.swift in Sources */,
0D64CEB524A3CDA90080AA4F /* String+Zcash.swift in Sources */, 0D64CEB524A3CDA90080AA4F /* String+Zcash.swift in Sources */,
0D11D3DB249D5F1600223146 /* ProgressBar.swift in Sources */, 0DB5331224A6413D0090D722 /* LazyView.swift in Sources */,
0D11D3DB249D5F1600223146 /* NeumorphicProgressBar.swift in Sources */,
0D64CEBD24A3CDA90080AA4F /* SimpleLogger.swift in Sources */, 0D64CEBD24A3CDA90080AA4F /* SimpleLogger.swift in Sources */,
0D64CEBC24A3CDA90080AA4F /* BalanceUtils.swift in Sources */, 0D64CEBC24A3CDA90080AA4F /* BalanceUtils.swift in Sources */,
0D5142C824A16F9600F9AE2E /* CreateNewTypeOfZircle.swift in Sources */, 0D5142C824A16F9600F9AE2E /* CreateNewTypeOfZircle.swift in Sources */,
@ -591,7 +615,7 @@
0D64CEB424A3CDA90080AA4F /* SeedManagement.swift in Sources */, 0D64CEB424A3CDA90080AA4F /* SeedManagement.swift in Sources */,
0D64CEC324A4137D0080AA4F /* ZircleData.swift in Sources */, 0D64CEC324A4137D0080AA4F /* ZircleData.swift in Sources */,
0D64CEA924A3CD1B0080AA4F /* ZirclesEnvironment.swift in Sources */, 0D64CEA924A3CD1B0080AA4F /* ZirclesEnvironment.swift in Sources */,
0D1366B024991A6000F0EB54 /* SplashScreen.swift in Sources */, 0D1366B024991A6000F0EB54 /* HomeScreen.swift in Sources */,
0DEE59A824A24B7300447C15 /* WelcomeView.swift in Sources */, 0DEE59A824A24B7300447C15 /* WelcomeView.swift in Sources */,
0D64CEA624A3854C0080AA4F /* ZircleOptionSelector.swift in Sources */, 0D64CEA624A3854C0080AA4F /* ZircleOptionSelector.swift in Sources */,
); );

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "Invite.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "downchart.pdf",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "join.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "upchart.pdf",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

View File

@ -10,7 +10,7 @@ import Foundation
import SwiftUI import SwiftUI
extension Color { extension Color {
static let background = Color(#colorLiteral(red: 0.8931570649, green: 0.9219855666, blue: 0.9563117623, alpha: 1)) static let background = Color(#colorLiteral(red: 0.8941176471, green: 0.9411764706, blue: 0.9568627451, alpha: 1))
static let shadowBackground = Color(#colorLiteral(red: 0.8572473526, green: 0.8862729073, blue: 0.9295067191, alpha: 1)) static let shadowBackground = Color(#colorLiteral(red: 0.8572473526, green: 0.8862729073, blue: 0.9295067191, alpha: 1))
static let buttonBlue = Color(#colorLiteral(red: 0.2486506402, green: 0.3574069142, blue: 0.5763935447, alpha: 1)) static let buttonBlue = Color(#colorLiteral(red: 0.2486506402, green: 0.3574069142, blue: 0.5763935447, alpha: 1))
static let buttonGray = Color(#colorLiteral(red: 0.5530887246, green: 0.622399509, blue: 0.7596352696, alpha: 1)) static let buttonGray = Color(#colorLiteral(red: 0.5530887246, green: 0.622399509, blue: 0.7596352696, alpha: 1))

View File

@ -0,0 +1,56 @@
//
// ZircleListCard.swift
// Zircles
//
// Created by Francisco Gindre on 6/25/20.
// Copyright © 2020 Electric Coin Company. All rights reserved.
//
import SwiftUI
struct ZircleListCard: View {
var name: String
var progress: Double
@State var isPressed = false
var body: some View {
Toggle(isOn: $isPressed) {
HStack(spacing: 16) {
Toggle(isOn: $isPressed) {
if progress < 0.5 {
Image("downchart")
.renderingMode(.original)
} else {
Image("upchart")
.renderingMode(.original)
}
}.toggleStyle(SimpleToggleStyle(shape: RoundedRectangle(cornerRadius: 10, style: .continuous), padding: 16))
VStack {
HStack {
Text(name)
.foregroundColor(.zGray)
.shadow(radius: 1)
Text("\(Int(progress))%")
.foregroundColor(.zGray)
.shadow(radius: 1)
}
NeumorphicProgressBar(progress: .constant(CGFloat(progress)), fillStyle: progress < 0.5 ? Color.red : Color.green )
.frame(minWidth: 100, idealWidth: 100, maxWidth: .infinity, minHeight: 5, idealHeight: 5, maxHeight: 5, alignment: .center)
}
}
}
.toggleStyle(SimpleToggleStyle(shape: RoundedRectangle(cornerRadius: 10, style: .continuous),padding:16))
}
}
struct ZircleListCard_Previews: PreviewProvider {
static var previews: some View {
ZStack {
Color.background
Group {
ZircleListCard(name: "Hackathon Drinks", progress: 0.5)
ZircleListCard(name: "Long-term Circle", progress: 0.02)
}
}
}
}

View File

@ -18,7 +18,12 @@ enum WalletState {
} }
protocol AppEnvironment { protocol AppEnvironment {
func createNewWallet() throws
func nuke(abortApplication: Bool)
func getMainAddress() -> String
func getUsername() -> String
func getMainSeedPhrase() -> String
func getLatestHeight() -> Int64
} }
final class ZirclesEnvironment: ObservableObject { final class ZirclesEnvironment: ObservableObject {
@ -33,7 +38,7 @@ final class ZirclesEnvironment: ObservableObject {
static var shared: ZirclesEnvironment = try! ZirclesEnvironment() // app can't live without this existing. static var shared: ZirclesEnvironment = try! ZirclesEnvironment() // app can't live without this existing.
@Published var state: WalletState @Published var state: WalletState
var errorPublisher = PassthroughSubject<Error,Never>()
let endpoint = LightWalletEndpoint(address: ZcashSDK.isMainnet ? "lightwalletd.z.cash" : "lightwalletd.testnet.z.cash", port: 9067, secure: true) let endpoint = LightWalletEndpoint(address: ZcashSDK.isMainnet ? "lightwalletd.z.cash" : "lightwalletd.testnet.z.cash", port: 9067, secure: true)
var dataDbURL: URL var dataDbURL: URL
var cacheDbURL: URL var cacheDbURL: URL
@ -123,6 +128,27 @@ final class ZirclesEnvironment: ObservableObject {
self.synchronizer.start() self.synchronizer.start()
} }
static var appBuild: String? {
Bundle.main.infoDictionary?["CFBundleVersion"] as? String
}
static var appVersion: String? {
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
}
func isValidAddress(_ address: String) -> Bool {
self.initializer.isValidShieldedAddress(address) || self.initializer.isValidTransparentAddress(address)
}
func sufficientFundsToSend(amount: Double) -> Bool {
return sufficientFunds(availableBalance: self.initializer.getVerifiedBalance(), zatoshiToSend: amount.toZatoshi())
}
private func sufficientFunds(availableBalance: Int64, zatoshiToSend: Int64) -> Bool {
availableBalance - zatoshiToSend - Int64(ZcashSDK.MINERS_FEE_ZATOSHI) >= 0
}
static var minerFee: Double {
Int64(ZcashSDK.MINERS_FEE_ZATOSHI).asHumanReadableZecBalance()
}
/** /**
only for internal use only for internal use
*/ */
@ -152,6 +178,16 @@ final class ZirclesEnvironment: ObservableObject {
} }
} }
deinit {
cancellables.forEach {
c in
c.cancel()
}
}
}
extension Error {
static func mapError(error: Error) -> ZirclesEnvironment.WalletError { static func mapError(error: Error) -> ZirclesEnvironment.WalletError {
if let rustError = error as? RustWeldingError { if let rustError = error as? RustWeldingError {
@ -167,55 +203,50 @@ final class ZirclesEnvironment: ObservableObject {
case .malformedStringInput: case .malformedStringInput:
return ZirclesEnvironment.WalletError.genericError(message: "Malformed address or key detected") return ZirclesEnvironment.WalletError.genericError(message: "Malformed address or key detected")
default: default:
return WalletError.genericError(message: "\(rustError)") return ZirclesEnvironment.WalletError.genericError(message: "\(rustError)")
} }
} else if let synchronizerError = error as? SynchronizerError { } else if let synchronizerError = error as? SynchronizerError {
switch synchronizerError { switch synchronizerError {
case .generalError(let message): case .generalError(let message):
return ZirclesEnvironment.WalletError.genericError(message: message) return ZirclesEnvironment.WalletError.genericError(message: message)
case .initFailed(let message): case .initFailed(let message):
return WalletError.initializationFailed(message: "Synchronizer failed to initialize: \(message)") return ZirclesEnvironment.WalletError.initializationFailed(message: "Synchronizer failed to initialize: \(message)")
case .syncFailed: case .syncFailed:
return WalletError.genericError(message: "Synchronizing failed") return ZirclesEnvironment.WalletError.genericError(message: "Synchronizing failed")
case .connectionFailed(let message): case .connectionFailed(let message):
return WalletError.connectionFailed(message: message) return ZirclesEnvironment.WalletError.connectionFailed(message: message)
case .maxRetryAttemptsReached(attempts: let attempts): case .maxRetryAttemptsReached(attempts: let attempts):
return WalletError.maxRetriesReached(attempts: attempts) return ZirclesEnvironment.WalletError.maxRetriesReached(attempts: attempts)
case .connectionError(_, let message): case .connectionError(_, let message):
return WalletError.connectionFailed(message: message) return ZirclesEnvironment.WalletError.connectionFailed(message: message)
} }
} }
return ZirclesEnvironment.WalletError.genericError(message: Self.genericErrorMessage) return ZirclesEnvironment.WalletError.genericError(message: ZirclesEnvironment.genericErrorMessage)
} }
deinit { }
cancellables.forEach {
c in extension ZirclesEnvironment: AppEnvironment {
c.cancel() func getMainAddress() -> String {
self.initializer.getAddress(index: 0) ?? "No address!!"
}
func getUsername() -> String {
ZircleDataStorage.default.username
}
func getMainSeedPhrase() -> String {
guard let phrase = try? SeedManager.default.exportPhrase() else {
return "no phrase"
} }
return phrase
} }
func getLatestHeight() -> Int64 {
Int64(synchronizer.syncBlockHeight.value)
}
} }
extension ZirclesEnvironment {
static var appBuild: String? {
Bundle.main.infoDictionary?["CFBundleVersion"] as? String
}
static var appVersion: String? {
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
}
func isValidAddress(_ address: String) -> Bool {
self.initializer.isValidShieldedAddress(address) || self.initializer.isValidTransparentAddress(address)
}
func sufficientFundsToSend(amount: Double) -> Bool {
return sufficientFunds(availableBalance: self.initializer.getVerifiedBalance(), zatoshiToSend: amount.toZatoshi())
}
private func sufficientFunds(availableBalance: Int64, zatoshiToSend: Int64) -> Bool {
availableBalance - zatoshiToSend - Int64(ZcashSDK.MINERS_FEE_ZATOSHI) >= 0
}
static var minerFee: Double {
Int64(ZcashSDK.MINERS_FEE_ZATOSHI).asHumanReadableZecBalance()
}
}

View File

@ -1,7 +1,7 @@
import SwiftUI import SwiftUI
extension Color { extension Color {
static let offWhite = Color(red: 225 / 255, green: 225 / 255, blue: 235 / 255) static let offWhite = Color(red: 228 / 255, green: 240 / 255, blue: 250 / 255)
static let darkStart = Color(red: 50 / 255, green: 60 / 255, blue: 65 / 255) static let darkStart = Color(red: 50 / 255, green: 60 / 255, blue: 65 / 255)
static let darkEnd = Color(red: 25 / 255, green: 25 / 255, blue: 30 / 255) static let darkEnd = Color(red: 25 / 255, green: 25 / 255, blue: 30 / 255)

View File

@ -8,8 +8,9 @@
import SwiftUI import SwiftUI
struct ProgressBar: View { struct NeumorphicProgressBar<S: ShapeStyle>: View {
@Binding var progress: CGFloat @Binding var progress: CGFloat
var fillStyle: S
var body: some View { var body: some View {
GeometryReader { geometry in GeometryReader { geometry in
@ -29,7 +30,7 @@ struct ProgressBar: View {
} }
.stroke(style: .init(lineWidth: geometry.size.height, lineCap: .round)) .stroke(style: .init(lineWidth: geometry.size.height, lineCap: .round))
.fill(LinearGradient.zButtonGradient) .fill(self.fillStyle)
} }
} }
@ -45,7 +46,7 @@ struct ProgressBar_Previews: PreviewProvider {
cornerRadius: 15, cornerRadius: 15,
padding: 5 padding: 5
) { ) {
ProgressBar(progress: .constant(0.6)) NeumorphicProgressBar(progress: .constant(0.6), fillStyle: LinearGradient.zButtonGradient)
.animation(.easeInOut) .animation(.easeInOut)
.frame(height: 30) .frame(height: 30)
.padding(.horizontal) .padding(.horizontal)

View File

@ -18,22 +18,33 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene. // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
_ZirclesNavigationBarLookTweaks()
// Create the SwiftUI view that provides the window contents. // Create the SwiftUI view that provides the window contents.
let isInitialized = ZirclesEnvironment.isInitialized() let isInitialized = ZirclesEnvironment.isInitialized()
let contentView = FirstScreen() { let contentView = FirstScreen() {
if isInitialized { if isInitialized {
SplashScreen() HomeScreen()
// AllZirclesView(
// zircles: [
// ZircleSummary(progress: 0.5, name: "Hackathon Drinks", paymentDue: false),
// ZircleSummary(progress: 0.02, name: "Long-term Circle", paymentDue: true)
//
// ]
// )
} else { } else {
WelcomeView() WelcomeView()
} }
} }
if isInitialized {
try? ZirclesEnvironment.shared.initialize()
ZirclesEnvironment.shared.synchronizer.start()
}
// Use a UIHostingController as window root view controller. // Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene { if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene) let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView) window.rootViewController = UIHostingController(rootView: contentView)
self.window = window self.window = window
window.makeKeyAndVisible() window.makeKeyAndVisible()
} }
} }
@ -69,3 +80,33 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
} }
extension UIApplication {
func endEditing() {
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
func _ZirclesNavigationBarLookTweaks() {
//// let appearance = UINavigationBarAppearance()
//// appearance.configureWithTransparentBackground()
//// appearance.largeTitleTextAttributes = [
//// .font : UIFont.systemFont(ofSize: 20),
//// NSAttributedString.Key.foregroundColor : UIColor.white
//// ]
////
//// appearance.titleTextAttributes = [
//// .font : UIFont.systemFont(ofSize: 20),
//// NSAttributedString.Key.foregroundColor : UIColor.white
//// ]
////
// UINavigationBar.appearance().scrollEdgeAppearance = appearance
// UINavigationBar.appearance().standardAppearance = appearance
//
let clearView = UIView()
clearView.backgroundColor = UIColor.clear
UITableViewCell.appearance().selectedBackgroundView = clearView
UITableView.appearance().backgroundColor = UIColor.clear
}

View File

@ -0,0 +1,19 @@
//
// LazyView.swift
// wallet
//
// Created by Francisco Gindre on 3/19/20.
// Copyright © 2020 Francisco Gindre. All rights reserved.
//
import SwiftUI
struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}

View File

@ -0,0 +1,27 @@
//
// MockEnvironment.swift
// Zircles
//
// Created by Francisco Gindre on 6/25/20.
// Copyright © 2020 Electric Coin Company. All rights reserved.
//
import Foundation
class MockAppEnvironment: AppEnvironment, ObservableObject {
func createNewWallet() throws {}
func nuke(abortApplication: Bool) {}
func getMainAddress() -> String {
"zsFakefejaefnq2rrneferjgbrauiebnfiosjebfeyetqoq3"
}
func getUsername() -> String {
"pacu"
}
func getMainSeedPhrase() -> String {
"kitchen renew wide common vague fold vacuum tilt amazing pear square gossip jewel month tree shock scan alpha just spot fluid toilet view dinner"
}
func getLatestHeight() -> Int64 {
999999
}
}

View File

@ -0,0 +1,111 @@
//
// AllZirclesView.swift
// Zircles
//
// Created by Francisco Gindre on 6/25/20.
// Copyright © 2020 Electric Coin Company. All rights reserved.
//
import SwiftUI
import UIKit
struct ZircleSummary {
var progress: Double
var name: String
var paymentDue: Bool
}
struct AllZirclesView: View {
@State var detailsActive = false
var zircles: [ZircleSummary]
var paymentsDueLegend: String {
let paymentsDue = zircles.filter({ $0.paymentDue}).count
return "You Have \(zircles.count) \( zircles.count > 1 ? "Zircles" : "Zircle"). \(paymentsDue > 0 ? String(paymentsDue) : "No") \(paymentsDue == 1 ? "payment" : "payments") due"
}
var body: some View {
ZStack {
Color.background.edgesIgnoringSafeArea(.all)
VStack(alignment: .leading, spacing: 24) {
HStack {
FancyLogo(progress: .constant(0.75))
.scaleEffect(0.3)
.disabled(true)
.background(EmptyView())
Text(paymentsDueLegend)
.lineLimit(2)
.foregroundColor(.black)
.font(.title)
}
.frame(height: 50)
List {
ForEach(0 ..< zircles.count) { index in
VStack {
ZircleListCard(summary: zircles[index])
}
.padding(.vertical, 30)
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
}
}
}
.onAppear() {
UITableView.appearance().separatorStyle = .none
UITableView.appearance().backgroundColor = UIColor.clear
}
.onDisappear() {
UITableView.appearance().separatorStyle = .singleLine
UITableView.appearance().backgroundColor = UIColor.white
}
.navigationBarTitle("", displayMode: .inline)
.sheet(isPresented: $detailsActive) {
AppDetails(isActive: $detailsActive,appEnvironment: MockAppEnvironment())
}
.navigationBarBackButtonHidden(true)
.navigationBarItems(trailing: Button(action: {
self.detailsActive = true
}){
Image(systemName: "z.circle")
.frame(width: 30, height: 30, alignment: .center)
}
.contentShape(Circle())
)
.sheet(isPresented: $detailsActive) {
AppDetails(isActive: $detailsActive,appEnvironment: MockAppEnvironment())
}
}
}
extension ZircleListCard {
init(summary: ZircleSummary) {
self.name = summary.name
self.progress = summary.progress
}
}
struct AllZirclesView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
ZStack{
AllZirclesView(
zircles: [
ZircleSummary(progress: 0.5, name: "Hackathon Drinks", paymentDue: false),
ZircleSummary(progress: 0.02, name: "Long-term Circle", paymentDue: true)
]
)
}
}
}
}

View File

@ -10,75 +10,126 @@ import SwiftUI
struct AppDetails: View { struct AppDetails: View {
@State var showNukeAlert = false @State var showNukeAlert = false
@Binding var isActive: Bool
var appEnvironment: AppEnvironment
var body: some View { var body: some View {
ZStack { NavigationView {
Color.background.edgesIgnoringSafeArea(.all) ZStack {
Color.background.edgesIgnoringSafeArea(.all)
VStack {
VStack(alignment: .leading, spacing: 3) {
Text("Username")
.foregroundColor(.textLightGray)
.fontWeight(.heavy)
.font(.footnote)
.frame(alignment: .leading)
Card(isOn: .constant(true),cornerRadius: 5,padding: 8) {
Text(ZircleDataStorage.default.username)
.foregroundColor(Color.textDarkGray)
.font(.system(size: 14, weight: .heavy, design: .default))
}
}.padding(.all, 0)
VStack(alignment: .leading, spacing: 3) {
Text("App Version")
.foregroundColor(.textLightGray)
.fontWeight(.heavy)
.font(.footnote)
.frame(alignment: .leading)
Card(isOn: .constant(true),cornerRadius: 5,padding: 8) {
Text("Zircles v\(ZirclesEnvironment.appVersion ?? "Unknown") - Build: \(ZirclesEnvironment.appBuild ?? "Unknown")")
.foregroundColor(Color.textDarkGray)
.font(.system(size: 14, weight: .heavy, design: .default))
}
}.padding(.all, 0)
Button(action: { VStack(alignment: .leading, spacing: 12) {
self.showNukeAlert = true VStack(alignment: .leading, spacing: 3) {
}) { Text("Username")
Text("NUKE WALLET") .foregroundColor(.textLightGray)
.foregroundColor(.red) .fontWeight(.heavy)
.zcashButtonBackground(shape: .roundedCorners(fillStyle: .outline(color: .red, lineWidth: 2))) .font(.footnote)
.frame(height: 48) .frame(alignment: .leading)
}.alert(isPresented: $showNukeAlert) { Card(isOn: .constant(true),cornerRadius: 5,padding: 8) {
Alert(title: Text("Delete Wallet?"),
message: Text("You are about to")+Text(" nuke your wallet. ").foregroundColor(.red) + Text("Are you sure you want to proceed?"), Text(appEnvironment.getUsername())
primaryButton: .default( .foregroundColor(Color.textDarkGray)
Text("I'm not sure") .font(.system(size: 14, weight: .heavy, design: .default))
,action: { self.showNukeAlert = false}
), }
secondaryButton: .destructive( }.padding(.all, 0)
Text("NUKE WALLET!"), VStack(alignment: .leading, spacing: 3) {
action: { Text("Main Account zAddress")
ZirclesEnvironment.shared.nuke(abortApplication: true) .foregroundColor(.textLightGray)
} .fontWeight(.heavy)
) .font(.footnote)
) .frame(alignment: .leading)
Card(isOn: .constant(true),cornerRadius: 5,padding: 8) {
Text(appEnvironment.getMainAddress())
.foregroundColor(Color.textDarkGray)
.font(.system(size: 14, weight: .heavy, design: .default))
}
}.padding(.all, 0)
VStack(alignment: .leading, spacing: 3) {
Text("Latest Downloaded Height")
.foregroundColor(.textLightGray)
.fontWeight(.heavy)
.font(.footnote)
.frame(alignment: .leading)
Card(isOn: .constant(true),cornerRadius: 5,padding: 8) {
Text("999999")
.foregroundColor(Color.textDarkGray)
.font(.system(size: 14, weight: .heavy, design: .default))
}
}.padding(.all, 0)
VStack(alignment: .leading, spacing: 3) {
Text("Main Account Seed Phrase")
.foregroundColor(.textLightGray)
.fontWeight(.heavy)
.font(.footnote)
.frame(alignment: .leading)
Card(isOn: .constant(true),cornerRadius: 5,padding: 8) {
Text(appEnvironment.getMainSeedPhrase())
.foregroundColor(Color.textDarkGray)
.font(.system(size: 14, weight: .heavy, design: .default))
}
}.padding(.all, 0)
VStack(alignment: .leading, spacing: 3) {
Text("App Version")
.foregroundColor(.textLightGray)
.fontWeight(.heavy)
.font(.footnote)
.frame(alignment: .leading)
Card(isOn: .constant(true),cornerRadius: 5,padding: 8) {
Text("Zircles v\(ZirclesEnvironment.appVersion ?? "Unknown") - Build: \(ZirclesEnvironment.appBuild ?? "Unknown")")
.foregroundColor(Color.textDarkGray)
.font(.system(size: 14, weight: .heavy, design: .default))
}
}.padding(.all, 0)
Spacer()
Button(action: {
self.showNukeAlert = true
}) {
Text("NUKE WALLET")
.foregroundColor(.red)
.zcashButtonBackground(shape: .roundedCorners(fillStyle: .outline(color: .red, lineWidth: 2)))
.frame(height: 48)
}.alert(isPresented: $showNukeAlert) {
Alert(title: Text("Delete Wallet?"),
message: Text("You are about to")+Text(" nuke your wallet. ").foregroundColor(.red) + Text("Are you sure you want to proceed?"),
primaryButton: .default(
Text("I'm not sure")
,action: { self.showNukeAlert = false}
),
secondaryButton: .destructive(
Text("NUKE WALLET!"),
action: {
ZirclesEnvironment.shared.nuke(abortApplication: true)
}
)
)
}
} }
.padding([.horizontal,.bottom], 30)
} }
}.navigationBarTitle(Text("Backstage")) .navigationBarTitle(Text("Backstage"))
.navigationBarItems(trailing: Button(action:{ .navigationBarItems(trailing: Button(action:{
}){ }){
Text("close") Text("close")
}) })
}
} }
} }
struct AppDetails_Previews: PreviewProvider { struct AppDetails_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
AppDetails() NavigationView{
AppDetails(isActive: .constant(true), appEnvironment: MockAppEnvironment())
}
} }
} }

View File

@ -11,7 +11,7 @@ import SwiftUI
struct CreateNewTypeOfZircle: View { struct CreateNewTypeOfZircle: View {
var body: some View { var body: some View {
ZStack { ZStack {
Color.background Color.background.edgesIgnoringSafeArea(.all)
VStack(spacing: 32 ) { VStack(spacing: 32 ) {
Spacer() Spacer()
Text("Savings Circle") Text("Savings Circle")
@ -33,7 +33,9 @@ struct CreateNewTypeOfZircle: View {
.shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.5), radius: 25, x: 10, y: 10) .shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.5), radius: 25, x: 10, y: 10)
.frame(height: 50) .frame(height: 50)
NavigationLink(
destination: CreateNewZircleDescription())
{
Text("Group Budget Goal") Text("Group Budget Goal")
.font(.system(size: 20, weight: .bold, design: .default)) .font(.system(size: 20, weight: .bold, design: .default))
.shadow(color:Color(.sRGBLinear, red: 0.2, green: 0.2, blue: 0.2, opacity: 0.5), radius: 1, x: 0, y: 2) .shadow(color:Color(.sRGBLinear, red: 0.2, green: 0.2, blue: 0.2, opacity: 0.5), radius: 1, x: 0, y: 2)
@ -42,6 +44,7 @@ struct CreateNewTypeOfZircle: View {
.shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.5), radius: 25, x: 10, y: 10) .shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.5), radius: 25, x: 10, y: 10)
.frame(height: 50) .frame(height: 50)
}
Card(isOn: .constant(false),cornerRadius: 10, padding: 16) { Card(isOn: .constant(false),cornerRadius: 10, padding: 16) {
ZircleProgress(progress: 0.7, stroke: .init(lineWidth: 5, lineCap: .round)) ZircleProgress(progress: 0.7, stroke: .init(lineWidth: 5, lineCap: .round))
.glow(vibe: .heavy, soul: .split(left: Color.gradientPink, right: Color.gradientOrange)) .glow(vibe: .heavy, soul: .split(left: Color.gradientPink, right: Color.gradientOrange))
@ -59,7 +62,7 @@ struct CreateNewTypeOfZircle: View {
} }
.padding(.horizontal, 30) .padding(.horizontal, 30)
.padding(.bottom, 30) .padding(.bottom, 30)
} }.navigationBarTitle(Text("What Type of Savings Project?"))
} }
} }

View File

@ -55,7 +55,7 @@ struct CreateNewZircleDescription: View {
var body: some View { var body: some View {
ZStack { ZStack {
Color.background Color.background.edgesIgnoringSafeArea(.all)
VStack(spacing: 30) { VStack(spacing: 30) {
VStack(alignment: .leading, spacing: 3) { VStack(alignment: .leading, spacing: 3) {
Text("Name of project") Text("Name of project")

View File

@ -8,7 +8,16 @@
import SwiftUI import SwiftUI
struct SplashScreen: View { /*
Zircles:ztestsapling16rzlnxq7wyxjctymxcnhjh2tru4hk48t2v3a32aacuyldsj3q0wgkny9w4re7n22yuemgmw8fqg
Wallet Birthday:950000
come exhibit fatal kid consider useless pigeon glove crawl stumble crunch left click labor curtain debris park hour raise wonder guilt upset eager order
*/
struct HomeScreen: View {
@State var detailsActive = false
@State var progress: Double = 0
var body: some View { var body: some View {
ZStack { ZStack {
@ -26,11 +35,15 @@ struct SplashScreen: View {
.contentShape(RoundedRectangle(cornerRadius: 5)) .contentShape(RoundedRectangle(cornerRadius: 5))
.toggleStyle(SimpleToggleStyle(shape: RoundedRectangle(cornerRadius: 5), padding: 8)) .toggleStyle(SimpleToggleStyle(shape: RoundedRectangle(cornerRadius: 5), padding: 8))
Spacer() Spacer()
FancyLogo() FancyLogo(progress: $progress)
.frame(width: 200, height: 200) .frame(width: 200, height: 200)
.animation(.easeInOut)
.onReceive(ZirclesEnvironment.shared.synchronizer.progress) { p in
self.progress = Double(p)
}
Spacer() Spacer()
VStack(spacing: 16) { if progress < 1 {
Text("Join a Zircle") Text("Syncing...")
.font(.system(size: 20, weight: .bold, design: .default)) .font(.system(size: 20, weight: .bold, design: .default))
.shadow(color:Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.2), radius: 1, x: 0, y: 2) .shadow(color:Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.2), radius: 1, x: 0, y: 2)
.foregroundColor(Color.buttonBlue) .foregroundColor(Color.buttonBlue)
@ -39,8 +52,25 @@ struct SplashScreen: View {
.shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.3), radius: 15, x: 10, y: 15) .shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.3), radius: 15, x: 10, y: 15)
.shadow(color: Color.white.opacity(0.5), radius: 25, x:-10, y: -10) .shadow(color: Color.white.opacity(0.5), radius: 25, x:-10, y: -10)
.frame(height: 50) .frame(height: 50)
} else {
VStack(spacing: 16) {
Button(action: {
}, label: {
Text("Join a Zircle")
.font(.system(size: 20, weight: .bold, design: .default))
.shadow(color:Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.2), radius: 1, x: 0, y: 2)
.foregroundColor(Color.buttonBlue)
.modifier(ZcashButtonBackground(buttonShape: .roundedCorners(fillStyle: .solid(color: Color.background))))
.shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.3), radius: 15, x: 10, y: 15)
.shadow(color: Color.white.opacity(0.5), radius: 25, x:-10, y: -10)
.frame(height: 50)
})
Button(action: {}) { NavigationLink(
destination: CreateNewTypeOfZircle()) {
Text("Create New") Text("Create New")
.font(.system(size: 20, weight: .bold, design: .default)) .font(.system(size: 20, weight: .bold, design: .default))
.shadow(color:Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.2), radius: 1, x: 0, y: 2) .shadow(color:Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.2), radius: 1, x: 0, y: 2)
@ -51,14 +81,31 @@ struct SplashScreen: View {
.frame(height: 50) .frame(height: 50)
} }
}.padding(.all, 0) }.padding(.all, 0)
}
}.padding(30) }.padding(30)
}.navigationBarTitle(Text("Welcome to Zircles")) }
.navigationBarBackButtonHidden(true)
.navigationBarTitle(Text("Welcome to Zircles"))
.navigationBarItems(trailing: Button(action: {
self.detailsActive = true
}){
Image(systemName: "z.circle")
.frame(width: 30, height: 30, alignment: .center)
}
.contentShape(Circle())
)
.sheet(isPresented: $detailsActive) {
AppDetails(isActive: $detailsActive,appEnvironment: ZirclesEnvironment.shared)
}
} }
} }
struct FancyLogo: View { struct FancyLogo: View {
@Binding var progress: Double
var body: some View { var body: some View {
ZStack { ZStack {
@ -73,8 +120,9 @@ struct FancyLogo: View {
} }
.overlay( .overlay(
ZircleProgress(progress: 0.75, stroke: .init(lineWidth: 40, lineCap: .round)) ZircleProgress(progress: progress, stroke: .init(lineWidth: 40, lineCap: .round))
.padding(23) .padding(23)
.animation(.easeIn)
) )
@ -93,6 +141,6 @@ struct FancyLogo: View {
struct ContentView_Previews: PreviewProvider { struct ContentView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
SplashScreen() HomeScreen()
} }
} }

View File

@ -8,15 +8,20 @@
import SwiftUI import SwiftUI
import MnemonicSwift import MnemonicSwift
import ZcashLightClientKit
struct WelcomeView: View { struct WelcomeView: View {
@State var username: String = "" @State var username: String = ""
@State var seedPhrase: String = "" @State var seedPhrase: String = ""
@State var birthdayHeight: String = ""
@State var isWelcome = false @State var isWelcome = false
@State var showError = false
@State var error: Error? = nil
var body: some View { var body: some View {
ZStack { ZStack {
Color.background.edgesIgnoringSafeArea(.all) Color.background.edgesIgnoringSafeArea(.all)
VStack(alignment: .leading, spacing: 16) { VStack(alignment: .leading, spacing: 16) {
Spacer()
Text("It looks like you are a new user, let's get to know you! What is your name?") Text("It looks like you are a new user, let's get to know you! What is your name?")
.fontWeight(.heavy) .fontWeight(.heavy)
.foregroundColor(Color.textDarkGray) .foregroundColor(Color.textDarkGray)
@ -52,6 +57,18 @@ struct WelcomeView: View {
.font(.system(size: 14, weight: .heavy, design: .default)) .font(.system(size: 14, weight: .heavy, design: .default))
} }
}.padding(.all, 0) }.padding(.all, 0)
VStack(alignment: .leading, spacing: 4) {
Text("Birthday height")
.foregroundColor(.textLightGray)
.fontWeight(.heavy)
.font(.footnote)
.frame(alignment: .leading)
Card(isOn: .constant(true),cornerRadius: 5,padding: 8) {
TextField("Birthday height", text: $birthdayHeight)
.foregroundColor(Color.textDarkGray)
.font(.system(size: 14, weight: .heavy, design: .default))
}
}.padding(.all, 0)
Spacer() Spacer()
Text("The Zircles app will only send ZEC to other Zircles app.") Text("The Zircles app will only send ZEC to other Zircles app.")
.foregroundColor(.textLightGray) .foregroundColor(.textLightGray)
@ -60,8 +77,11 @@ struct WelcomeView: View {
.frame(alignment: .center) .frame(alignment: .center)
Spacer() Spacer()
Button(action: { Button(action: {
do {
self.isWelcome = true try initialize()
} catch {
ZirclesEnvironment.shared.errorPublisher.send(error)
}
}) { }) {
Text("Add Wallet to Zircles") Text("Add Wallet to Zircles")
.font(.system(size: 20, weight: .bold, design: .default)) .font(.system(size: 20, weight: .bold, design: .default))
@ -72,8 +92,9 @@ struct WelcomeView: View {
.shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.5), radius: 25, x: 10, y: 10) .shadow(color: Color(red: 0.2, green: 0.2, blue: 0.2).opacity(0.5), radius: 25, x: 10, y: 10)
.frame(height: 50) .frame(height: 50)
}.disabled(!validInput()) }.disabled(!validInput())
.opacity(validInput() ? 1.0 : 0.6)
NavigationLink( NavigationLink(
destination: SplashScreen(), destination: HomeScreen(),
isActive: $isWelcome, isActive: $isWelcome,
label: { label: {
EmptyView() EmptyView()
@ -81,14 +102,34 @@ struct WelcomeView: View {
} }
.padding([.horizontal,.bottom], 30) .padding([.horizontal,.bottom], 30)
}
}.navigationBarTitle(Text("Welcome")) .navigationBarTitle(Text("Welcome"))
.alert(isPresented: $showError) {
Alert(
title: Text("Error"),
message: Text( error == nil ? "It would be embarrasing if it wasn't a hackathon" : "Error: \( ZirclesEnvironment.WalletError.mapError(error: error!).localizedDescription)"),
dismissButton: .default(Text("dismiss"), action: {
self.error = nil
}))
}.onReceive(ZirclesEnvironment.shared.errorPublisher) { e in
self.error = e
self.showError = true
if let _ = e as? SeedManager.SeedManagerError {
ZirclesEnvironment.shared.nuke()
}
}
} }
func initialize() throws {
ZircleDataStorage.default.saveUsername(self.username)
try self.importSeed()
try self.importBirthday()
try ZirclesEnvironment.shared.initialize()
self.isWelcome = true
}
func validInput() -> Bool { func validInput() -> Bool {
validSeedPhrase() && validName() validSeedPhrase() && validName() && validBirthday()
} }
func validSeedPhrase() -> Bool { func validSeedPhrase() -> Bool {
@ -98,10 +139,35 @@ struct WelcomeView: View {
func validName() -> Bool { func validName() -> Bool {
!username.isEmpty !username.isEmpty
} }
func validBirthday() -> Bool {
birthdayHeight.isEmpty || Int64(birthdayHeight) != nil
}
func validateSeed(_ seed: String) -> Bool {
MnemonicSeedProvider.default.isValid(mnemonic: seed)
}
func importBirthday() throws {
let b = BlockHeight(self.birthdayHeight.trimmingCharacters(in: .whitespacesAndNewlines)) ?? ZcashSDK.SAPLING_ACTIVATION_HEIGHT
try SeedManager.default.importBirthday(b)
}
func importSeed() throws {
let trimmedSeedPhrase = seedPhrase.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmedSeedPhrase.isEmpty, let seedBytes =
MnemonicSeedProvider.default.toSeed(mnemonic: trimmedSeedPhrase) else { throw ZirclesEnvironment.WalletError.createFailed
}
try SeedManager.default.importSeed(seedBytes)
try SeedManager.default.importPhrase(bip39: trimmedSeedPhrase)
}
} }
struct WelcomeView_Previews: PreviewProvider { struct WelcomeView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
NavigationView {
WelcomeView() WelcomeView()
}
} }
} }

Binary file not shown.

Binary file not shown.