diff --git a/secant.xcodeproj/project.pbxproj b/secant.xcodeproj/project.pbxproj index a5dccc99..bac5186f 100644 --- a/secant.xcodeproj/project.pbxproj +++ b/secant.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ 0D4E7A2626B364180058B01E /* secantUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A2526B364180058B01E /* secantUITests.swift */; }; 0D535FDE271F4214009A9E3E /* Rubik-Italic-VariableFont_wght.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0D535FDC271F4214009A9E3E /* Rubik-Italic-VariableFont_wght.ttf */; }; 0D535FDF271F4214009A9E3E /* Rubik-VariableFont_wght.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0D535FDD271F4214009A9E3E /* Rubik-VariableFont_wght.ttf */; }; + 0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D535FE1271F9476009A9E3E /* EnumeratedChip.swift */; }; 0D5D16F526E24CCF00AD33D1 /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5D16F426E24CCF00AD33D1 /* AppError.swift */; }; 0D7DF08C271DCC0E00530046 /* ScreenBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D7DF08B271DCC0E00530046 /* ScreenBackground.swift */; }; 0D864A0526E1546000A61879 /* LoadingScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D864A0426E1546000A61879 /* LoadingScreenTests.swift */; }; @@ -52,6 +53,20 @@ 0DA13CA126C1955600E3B610 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13C9F26C1955600E3B610 /* HomeScreen.swift */; }; 0DA13CA226C1955600E3B610 /* HomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13CA026C1955600E3B610 /* HomeScreenViewModel.swift */; }; 0DA13CA526C1963000E3B610 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13CA426C1963000E3B610 /* Balance.swift */; }; + 0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DACFA7E27208CE00039EEA5 /* Clamped.swift */; }; + 0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */; }; + 0DACFA9027209FA70039EEA5 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8327209FA60039EEA5 /* Roboto-Bold.ttf */; }; + 0DACFA9127209FA70039EEA5 /* Roboto-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8427209FA60039EEA5 /* Roboto-LightItalic.ttf */; }; + 0DACFA9227209FA70039EEA5 /* Roboto-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8527209FA60039EEA5 /* Roboto-Italic.ttf */; }; + 0DACFA9327209FA70039EEA5 /* Roboto-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8627209FA60039EEA5 /* Roboto-Medium.ttf */; }; + 0DACFA9427209FA70039EEA5 /* Roboto-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8727209FA60039EEA5 /* Roboto-BoldItalic.ttf */; }; + 0DACFA9527209FA70039EEA5 /* Roboto-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8827209FA60039EEA5 /* Roboto-Regular.ttf */; }; + 0DACFA9627209FA70039EEA5 /* Roboto-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8927209FA60039EEA5 /* Roboto-Thin.ttf */; }; + 0DACFA9727209FA70039EEA5 /* Roboto-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8A27209FA70039EEA5 /* Roboto-Black.ttf */; }; + 0DACFA9827209FA70039EEA5 /* Roboto-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8B27209FA70039EEA5 /* Roboto-MediumItalic.ttf */; }; + 0DACFA9927209FA70039EEA5 /* Roboto-BlackItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8C27209FA70039EEA5 /* Roboto-BlackItalic.ttf */; }; + 0DACFA9A27209FA70039EEA5 /* Roboto-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8D27209FA70039EEA5 /* Roboto-Light.ttf */; }; + 0DACFA9C27209FA70039EEA5 /* Roboto-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0DACFA8F27209FA70039EEA5 /* Roboto-ThinItalic.ttf */; }; 0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB8AA80271DC7520035BC9D /* DesignGuide.swift */; }; 660558E9270C7A54009D6954 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 660558E8270C7A54009D6954 /* Colors.xcassets */; }; 660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F5270C862F009D6954 /* Fonts+Generated.swift */; }; @@ -122,6 +137,7 @@ 0D4E7A2726B364180058B01E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 0D535FDC271F4214009A9E3E /* Rubik-Italic-VariableFont_wght.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Rubik-Italic-VariableFont_wght.ttf"; sourceTree = ""; }; 0D535FDD271F4214009A9E3E /* Rubik-VariableFont_wght.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Rubik-VariableFont_wght.ttf"; sourceTree = ""; }; + 0D535FE1271F9476009A9E3E /* EnumeratedChip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnumeratedChip.swift; sourceTree = ""; }; 0D5D16F426E24CCF00AD33D1 /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = ""; }; 0D7DF08B271DCC0E00530046 /* ScreenBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBackground.swift; sourceTree = ""; }; 0D864A0426E1546000A61879 /* LoadingScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingScreenTests.swift; sourceTree = ""; }; @@ -138,6 +154,20 @@ 0DA13C9F26C1955600E3B610 /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = ""; }; 0DA13CA026C1955600E3B610 /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = ""; }; 0DA13CA426C1963000E3B610 /* Balance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Balance.swift; sourceTree = ""; }; + 0DACFA7E27208CE00039EEA5 /* Clamped.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clamped.swift; sourceTree = ""; }; + 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt+SuperscriptText.swift"; sourceTree = ""; }; + 0DACFA8327209FA60039EEA5 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Bold.ttf"; sourceTree = ""; }; + 0DACFA8427209FA60039EEA5 /* Roboto-LightItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-LightItalic.ttf"; sourceTree = ""; }; + 0DACFA8527209FA60039EEA5 /* Roboto-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Italic.ttf"; sourceTree = ""; }; + 0DACFA8627209FA60039EEA5 /* Roboto-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Medium.ttf"; sourceTree = ""; }; + 0DACFA8727209FA60039EEA5 /* Roboto-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-BoldItalic.ttf"; sourceTree = ""; }; + 0DACFA8827209FA60039EEA5 /* Roboto-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Regular.ttf"; sourceTree = ""; }; + 0DACFA8927209FA60039EEA5 /* Roboto-Thin.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Thin.ttf"; sourceTree = ""; }; + 0DACFA8A27209FA70039EEA5 /* Roboto-Black.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Black.ttf"; sourceTree = ""; }; + 0DACFA8B27209FA70039EEA5 /* Roboto-MediumItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-MediumItalic.ttf"; sourceTree = ""; }; + 0DACFA8C27209FA70039EEA5 /* Roboto-BlackItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-BlackItalic.ttf"; sourceTree = ""; }; + 0DACFA8D27209FA70039EEA5 /* Roboto-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-Light.ttf"; sourceTree = ""; }; + 0DACFA8F27209FA70039EEA5 /* Roboto-ThinItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Roboto-ThinItalic.ttf"; sourceTree = ""; }; 0DB8AA80271DC7520035BC9D /* DesignGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DesignGuide.swift; sourceTree = ""; }; 660558E8270C7A54009D6954 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; }; 660558F5270C862F009D6954 /* Fonts+Generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Fonts+Generated.swift"; sourceTree = ""; }; @@ -238,6 +268,7 @@ 0D2ACE7E26C2C65E00D62E3C /* Fonts */ = { isa = PBXGroup; children = ( + 0DACFA8227209F930039EEA5 /* Roboto */, 0D535FDB271F3B50009A9E3E /* Rubik */, 0D2ACE7F26C2C67100D62E3C /* Zboto.otf */, ); @@ -321,6 +352,7 @@ 0D4E7A0726B364170058B01E /* secant */ = { isa = PBXGroup; children = ( + 0DACFA7D27208CC80039EEA5 /* Util */, 6654C73B2715A3F000901167 /* Features */, 660558F4270C85F7009D6954 /* Generated */, 0D5D16F326E24CB900AD33D1 /* App Errors */, @@ -379,6 +411,14 @@ path = Rubik; sourceTree = ""; }; + 0D535FE0271F945C009A9E3E /* Chips */ = { + isa = PBXGroup; + children = ( + 0D535FE1271F9476009A9E3E /* EnumeratedChip.swift */, + ); + path = Chips; + sourceTree = ""; + }; 0D5D16F326E24CB900AD33D1 /* App Errors */ = { isa = PBXGroup; children = ( @@ -417,6 +457,7 @@ 0DA13C9126C15E1900E3B610 /* UI Components */ = { isa = PBXGroup; children = ( + 0D535FE0271F945C009A9E3E /* Chips */, 663FAB9A271D873300E495F8 /* Buttons */, 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */, 0DB8AA80271DC7520035BC9D /* DesignGuide.swift */, @@ -460,6 +501,34 @@ path = Models; sourceTree = ""; }; + 0DACFA7D27208CC80039EEA5 /* Util */ = { + isa = PBXGroup; + children = ( + 0DACFA7E27208CE00039EEA5 /* Clamped.swift */, + 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */, + ); + path = Util; + sourceTree = ""; + }; + 0DACFA8227209F930039EEA5 /* Roboto */ = { + isa = PBXGroup; + children = ( + 0DACFA8A27209FA70039EEA5 /* Roboto-Black.ttf */, + 0DACFA8C27209FA70039EEA5 /* Roboto-BlackItalic.ttf */, + 0DACFA8327209FA60039EEA5 /* Roboto-Bold.ttf */, + 0DACFA8727209FA60039EEA5 /* Roboto-BoldItalic.ttf */, + 0DACFA8527209FA60039EEA5 /* Roboto-Italic.ttf */, + 0DACFA8D27209FA70039EEA5 /* Roboto-Light.ttf */, + 0DACFA8427209FA60039EEA5 /* Roboto-LightItalic.ttf */, + 0DACFA8627209FA60039EEA5 /* Roboto-Medium.ttf */, + 0DACFA8B27209FA70039EEA5 /* Roboto-MediumItalic.ttf */, + 0DACFA8827209FA60039EEA5 /* Roboto-Regular.ttf */, + 0DACFA8927209FA60039EEA5 /* Roboto-Thin.ttf */, + 0DACFA8F27209FA70039EEA5 /* Roboto-ThinItalic.ttf */, + ); + path = Roboto; + sourceTree = ""; + }; 660558F4270C85F7009D6954 /* Generated */ = { isa = PBXGroup; children = ( @@ -626,11 +695,23 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0DACFA9327209FA70039EEA5 /* Roboto-Medium.ttf in Resources */, + 0DACFA9827209FA70039EEA5 /* Roboto-MediumItalic.ttf in Resources */, + 0DACFA9427209FA70039EEA5 /* Roboto-BoldItalic.ttf in Resources */, + 0DACFA9027209FA70039EEA5 /* Roboto-Bold.ttf in Resources */, + 0DACFA9227209FA70039EEA5 /* Roboto-Italic.ttf in Resources */, 0D535FDE271F4214009A9E3E /* Rubik-Italic-VariableFont_wght.ttf in Resources */, + 0DACFA9127209FA70039EEA5 /* Roboto-LightItalic.ttf in Resources */, + 0DACFA9927209FA70039EEA5 /* Roboto-BlackItalic.ttf in Resources */, + 0DACFA9527209FA70039EEA5 /* Roboto-Regular.ttf in Resources */, 0D4E7A1026B364180058B01E /* Preview Assets.xcassets in Resources */, 660558E9270C7A54009D6954 /* Colors.xcassets in Resources */, 0D535FDF271F4214009A9E3E /* Rubik-VariableFont_wght.ttf in Resources */, + 0DACFA9A27209FA70039EEA5 /* Roboto-Light.ttf in Resources */, 0D4E7A0D26B364180058B01E /* Assets.xcassets in Resources */, + 0DACFA9727209FA70039EEA5 /* Roboto-Black.ttf in Resources */, + 0DACFA9C27209FA70039EEA5 /* Roboto-ThinItalic.ttf in Resources */, + 0DACFA9627209FA70039EEA5 /* Roboto-Thin.ttf in Resources */, 0D2ACE8026C2C67100D62E3C /* Zboto.otf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -708,7 +789,9 @@ 0D1922ED26BDE0C600052649 /* AppRouter.swift in Sources */, 0D1922F226BDE29300052649 /* ZcashSDKStubs.swift in Sources */, 0DA13C9D26C1942100E3B610 /* BackupWalletScreenViewModel.swift in Sources */, + 0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */, 0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */, + 0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */, 6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */, 0D32281E26C5867D00262533 /* ScanQrScreen.swift in Sources */, 0D864A0E26E1583000A61879 /* LoadingScreen.swift in Sources */, @@ -727,6 +810,7 @@ 0D354A0926D5A9D000315F45 /* Services.swift in Sources */, 660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */, 0DA13C9726C186FF00E3B610 /* RestoreWalletScreen.swift in Sources */, + 0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */, 0D1922EA26BDD96A00052649 /* ViewModel.swift in Sources */, 0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */, 66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */, diff --git a/secant/Colors.xcassets/Text/highlightedSuperscriptText.colorset/Contents.json b/secant/Colors.xcassets/Text/highlightedSuperscriptText.colorset/Contents.json new file mode 100644 index 00000000..ad92af09 --- /dev/null +++ b/secant/Colors.xcassets/Text/highlightedSuperscriptText.colorset/Contents.json @@ -0,0 +1,29 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.573", + "green" : "0.522", + "red" : "0.933" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/secant/Fonts/Roboto/LICENSE.txt b/secant/Fonts/Roboto/LICENSE.txt new file mode 100644 index 00000000..75b52484 --- /dev/null +++ b/secant/Fonts/Roboto/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/secant/Fonts/Roboto/Roboto-Black.ttf b/secant/Fonts/Roboto/Roboto-Black.ttf new file mode 100644 index 00000000..43a00e0d Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-Black.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-BlackItalic.ttf b/secant/Fonts/Roboto/Roboto-BlackItalic.ttf new file mode 100644 index 00000000..5082cdc4 Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-BlackItalic.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-Bold.ttf b/secant/Fonts/Roboto/Roboto-Bold.ttf new file mode 100644 index 00000000..37424579 Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-Bold.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-BoldItalic.ttf b/secant/Fonts/Roboto/Roboto-BoldItalic.ttf new file mode 100644 index 00000000..e85e7fb9 Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-BoldItalic.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-Italic.ttf b/secant/Fonts/Roboto/Roboto-Italic.ttf new file mode 100644 index 00000000..c9df607a Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-Italic.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-Light.ttf b/secant/Fonts/Roboto/Roboto-Light.ttf new file mode 100644 index 00000000..0e977514 Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-Light.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-LightItalic.ttf b/secant/Fonts/Roboto/Roboto-LightItalic.ttf new file mode 100644 index 00000000..3ad14fa7 Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-LightItalic.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-Medium.ttf b/secant/Fonts/Roboto/Roboto-Medium.ttf new file mode 100644 index 00000000..e89b0b79 Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-Medium.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-MediumItalic.ttf b/secant/Fonts/Roboto/Roboto-MediumItalic.ttf new file mode 100644 index 00000000..a5a41d3d Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-MediumItalic.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-Regular.ttf b/secant/Fonts/Roboto/Roboto-Regular.ttf new file mode 100644 index 00000000..3d6861b4 Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-Regular.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-Thin.ttf b/secant/Fonts/Roboto/Roboto-Thin.ttf new file mode 100644 index 00000000..7d084aed Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-Thin.ttf differ diff --git a/secant/Fonts/Roboto/Roboto-ThinItalic.ttf b/secant/Fonts/Roboto/Roboto-ThinItalic.ttf new file mode 100644 index 00000000..c1733896 Binary files /dev/null and b/secant/Fonts/Roboto/Roboto-ThinItalic.ttf differ diff --git a/secant/Generated/Fonts+Generated.swift b/secant/Generated/Fonts+Generated.swift index b8b003f0..518048b2 100644 --- a/secant/Generated/Fonts+Generated.swift +++ b/secant/Generated/Fonts+Generated.swift @@ -19,6 +19,21 @@ internal typealias SystemFont = FontConvertible.SystemFont // swiftlint:disable identifier_name line_length type_body_length internal enum FontFamily { + internal enum Roboto { + internal static let black = FontConvertible(name: "Roboto-Black", family: "Roboto", path: "Roboto-Black.ttf") + internal static let blackItalic = FontConvertible(name: "Roboto-BlackItalic", family: "Roboto", path: "Roboto-BlackItalic.ttf") + internal static let bold = FontConvertible(name: "Roboto-Bold", family: "Roboto", path: "Roboto-Bold.ttf") + internal static let boldItalic = FontConvertible(name: "Roboto-BoldItalic", family: "Roboto", path: "Roboto-BoldItalic.ttf") + internal static let italic = FontConvertible(name: "Roboto-Italic", family: "Roboto", path: "Roboto-Italic.ttf") + internal static let light = FontConvertible(name: "Roboto-Light", family: "Roboto", path: "Roboto-Light.ttf") + internal static let lightItalic = FontConvertible(name: "Roboto-LightItalic", family: "Roboto", path: "Roboto-LightItalic.ttf") + internal static let medium = FontConvertible(name: "Roboto-Medium", family: "Roboto", path: "Roboto-Medium.ttf") + internal static let mediumItalic = FontConvertible(name: "Roboto-MediumItalic", family: "Roboto", path: "Roboto-MediumItalic.ttf") + internal static let regular = FontConvertible(name: "Roboto-Regular", family: "Roboto", path: "Roboto-Regular.ttf") + internal static let thin = FontConvertible(name: "Roboto-Thin", family: "Roboto", path: "Roboto-Thin.ttf") + internal static let thinItalic = FontConvertible(name: "Roboto-ThinItalic", family: "Roboto", path: "Roboto-ThinItalic.ttf") + internal static let all: [FontConvertible] = [black, blackItalic, bold, boldItalic, italic, light, lightItalic, medium, mediumItalic, regular, thin, thinItalic] + } internal enum Rubik { internal static let light = FontConvertible(name: "Rubik-Light", family: "Rubik", path: "Rubik-VariableFont_wght.ttf") internal static let lightItalic = FontConvertible(name: "Rubik-LightItalic", family: "Rubik", path: "Rubik-Italic-VariableFont_wght.ttf") @@ -40,7 +55,7 @@ internal enum FontFamily { internal static let regular = FontConvertible(name: "ZbotoRegular", family: "Zboto", path: "Zboto.otf") internal static let all: [FontConvertible] = [regular] } - internal static let allCustomFonts: [FontConvertible] = [Rubik.all, Zboto.all].flatMap { $0 } + internal static let allCustomFonts: [FontConvertible] = [Roboto.all, Rubik.all, Zboto.all].flatMap { $0 } internal static func registerAllCustomFonts() { allCustomFonts.forEach { $0.register() } } diff --git a/secant/Generated/XCAssets+Generated.swift b/secant/Generated/XCAssets+Generated.swift index a68fd678..6791c14a 100644 --- a/secant/Generated/XCAssets+Generated.swift +++ b/secant/Generated/XCAssets+Generated.swift @@ -65,6 +65,7 @@ internal enum Asset { internal static let regular = ColorAsset(name: "Regular") internal static let secondaryButtonText = ColorAsset(name: "SecondaryButtonText") internal static let titleText = ColorAsset(name: "TitleText") + internal static let highlightedSuperscriptText = ColorAsset(name: "highlightedSuperscriptText") } } } diff --git a/secant/Info.plist b/secant/Info.plist index 295d4507..c2d1142a 100644 --- a/secant/Info.plist +++ b/secant/Info.plist @@ -32,6 +32,18 @@ Zboto.otf Rubik-Italic-VariableFont_wght.ttf Rubik-VariableFont_wght.ttf + Roboto-Thin.ttf + Roboto-BlackItalic.ttf + Roboto-Black.ttf + Roboto-BoldItalic.ttf + Roboto-Bold.ttf + Roboto-MediumItalic.ttf + Roboto-Medium.ttf + Roboto-Italic.ttf + Roboto-Regular.ttf + Roboto-LightItalic.ttf + Roboto-Light.ttf + Roboto-ThinItalic.ttf UIApplicationSceneManifest diff --git a/secant/UI Components/Chips/EnumeratedChip.swift b/secant/UI Components/Chips/EnumeratedChip.swift new file mode 100644 index 00000000..ea3bedca --- /dev/null +++ b/secant/UI Components/Chips/EnumeratedChip.swift @@ -0,0 +1,127 @@ +// +// EnumeratedChip.swift +// secant-testnet +// +// Created by Francisco Gindre on 10/19/21. +// + +import SwiftUI + +struct EnumeratedChip: View { + @Clamped(1...24) + var index: Int = 1 + + var text: String + + var body: some View { + NumberedText(number: index, text: text) + .frame( + minWidth: 0, + maxWidth: .infinity, + minHeight: 30, + maxHeight: .infinity, + alignment: .leading + ) + .padding(.horizontal, 16) + .padding(.vertical, 8) + .background( + Asset.Colors.Buttons.primaryButtonPressed.color + ) + .cornerRadius(6) + } +} + +struct NumberedText: View { + @Clamped(1...24) var number: Int = 1 + + var text: String + + @ViewBuilder var numberedText: some View { + Text(number.superscriptRepresentation) + .foregroundColor( + Asset.Colors.Text.highlightedSuperscriptText.color + ) + .font( + .custom( + FontFamily.Roboto.black.name, + size: 24 + ) + ) + + Text(" \(text)") + .foregroundColor( + Asset.Colors.Text.button.color + ) + .font( + .custom( + FontFamily.Rubik.regular.name, + size: 15 + ) + ) + } + + var body: some View { + numberedText + .layoutPriority(1) + .fixedSize(horizontal: false, vertical: false) + } +} + +struct EnumeratedChip_Previews: PreviewProvider { + private static var threeColumnGrid = Array( + repeating: GridItem( + .flexible(minimum: 60, maximum: 120), + spacing: 15, + alignment: .topLeading + ), + count: 3 + ) + + static var words = [ + "pyramid", "negative", "page", + "crown", "secret", "zebra" + ] + + @ViewBuilder static var grid: some View { + LazyVGrid( + columns: threeColumnGrid, + alignment: .leading, + spacing: 15 + ) { + ForEach(Array(zip(words.indices, words)), id: \.1) { i, word in + EnumeratedChip(index: (i + 1),text: word) + .frame(minWidth: 0, maxWidth: .infinity, minHeight: 50) + } + } + .padding() + .applyScreenBackground() + } + static var previews: some View { + grid + .previewLayout(.fixed(width: 428, height: 200)) + + grid + .preferredColorScheme(.dark) + .previewLayout(.fixed(width: 428, height: 200)) + + grid + .previewLayout(.fixed(width: 390, height: 200)) + + grid + .preferredColorScheme(.dark) + .previewLayout(.fixed(width: 390, height: 200)) + + grid + .previewLayout(.fixed(width: 375, height: 200)) + + grid + .preferredColorScheme(.dark) + .previewLayout(.fixed(width: 375, height: 200)) + + grid + .previewLayout(.fixed(width: 320, height: 200)) + + grid + .preferredColorScheme(.dark) + .previewLayout(.fixed(width: 320, height: 200)) + } +} diff --git a/secant/Util/Clamped.swift b/secant/Util/Clamped.swift new file mode 100644 index 00000000..2b19ef8e --- /dev/null +++ b/secant/Util/Clamped.swift @@ -0,0 +1,31 @@ +// +// Clamped.swift +// secant-testnet +// +// Created by Francisco Gindre on 10/20/21. +// +// credits: https://iteo.medium.com/swift-property-wrappers-how-to-use-them-right-77095817d1b +import Foundation + +/** +Limits a value to an enclosing range +*/ +@propertyWrapper +struct Clamped { + var value: Value + let range: ClosedRange + var wrappedValue: Value { + get { value } + set { + value = min( + max(range.lowerBound, newValue), + range.upperBound + ) + } + } + + init(wrappedValue: Value, _ range: ClosedRange) { + self.value = wrappedValue + self.range = range + } +} diff --git a/secant/Util/UInt+SuperscriptText.swift b/secant/Util/UInt+SuperscriptText.swift new file mode 100644 index 00000000..4f9e018e --- /dev/null +++ b/secant/Util/UInt+SuperscriptText.swift @@ -0,0 +1,40 @@ +// +// UInt+SuperscriptText.swift +// secant-testnet +// +// Created by Francisco Gindre on 10/20/21. +// + +import Foundation + +extension Int { + private func toScalarSuperscript() -> String { + precondition(self >= 0 && self <= 9) + return [ + "\u{2070}", // 0 + "\u{00B9}", // 1 + "\u{00B2}", // 2 + "\u{00B3}", // 3 + "\u{2074}", // 4 + "\u{2075}", // 5 + "\u{2076}", // 6 + "\u{2077}", // 7 + "\u{2078}", // 8 + "\u{2079}" // 9 + ][Int(self)] + } + + /** + Returns a superscript string representation this unsigned integer using Unicode Scalars + */ + var superscriptRepresentation: String { + precondition(self >= 0) + var number = self + var superscript = "" + repeat { + superscript = (number % 10).toScalarSuperscript() + superscript + number /= 10 + } while number > 0 + return superscript + } +} diff --git a/secantTests/secantTests.swift b/secantTests/secantTests.swift index 7631ea98..0485b563 100644 --- a/secantTests/secantTests.swift +++ b/secantTests/secantTests.swift @@ -9,25 +9,88 @@ import XCTest @testable import secant_testnet class SecantTests: XCTestCase { - override func setUp() { - super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDown() { - super.tearDown() - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testExample() throws { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - - func testPerformanceExample() throws { - // This is an example of a performance test case. - self.measure { - // Put the code you want to measure the time of here. - } + func testSubscriptRepresentation() throws { + XCTAssertEqual(Int(0).superscriptRepresentation, "\u{2070}") + XCTAssertEqual(Int(1).superscriptRepresentation, "\u{00B9}") + XCTAssertEqual(Int(11).superscriptRepresentation, "\u{00B9}\u{00B9}") + XCTAssertEqual(Int(111).superscriptRepresentation, "\u{00B9}\u{00B9}\u{00B9}") + XCTAssertEqual(Int(2).superscriptRepresentation, "\u{00B2}") + XCTAssertEqual(Int(22).superscriptRepresentation, "\u{00B2}\u{00B2}") + XCTAssertEqual(Int(222).superscriptRepresentation, "\u{00B2}\u{00B2}\u{00B2}") + XCTAssertEqual(Int(12).superscriptRepresentation, "\u{00B9}\u{00B2}") + XCTAssertEqual(Int(3).superscriptRepresentation, "\u{00B3}") + XCTAssertEqual(Int(33).superscriptRepresentation, "\u{00B3}\u{00B3}") + XCTAssertEqual(Int(333).superscriptRepresentation, "\u{00B3}\u{00B3}\u{00B3}") + XCTAssertEqual(Int(123).superscriptRepresentation, "\u{00B9}\u{00B2}\u{00B3}") + XCTAssertEqual(Int(4).superscriptRepresentation, "\u{2074}") + XCTAssertEqual(Int(5).superscriptRepresentation, "\u{2075}") + XCTAssertEqual(Int(6).superscriptRepresentation, "\u{2076}") + XCTAssertEqual(Int(7).superscriptRepresentation, "\u{2077}") + XCTAssertEqual(Int(8).superscriptRepresentation, "\u{2078}") + XCTAssertEqual(Int(9).superscriptRepresentation, "\u{2079}") + XCTAssertEqual( + Int(10).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(0).superscriptRepresentation + ) + XCTAssertEqual( + Int(100).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(0).superscriptRepresentation + Int(0).superscriptRepresentation + ) + XCTAssertEqual( + Int(11).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(1).superscriptRepresentation + ) + XCTAssertEqual( + Int(12).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(2).superscriptRepresentation + ) + XCTAssertEqual( + Int(13).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(3).superscriptRepresentation + ) + XCTAssertEqual( + Int(14).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(4).superscriptRepresentation + ) + XCTAssertEqual( + Int(15).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(5).superscriptRepresentation + ) + XCTAssertEqual( + Int(16).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(6).superscriptRepresentation + ) + XCTAssertEqual( + Int(17).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(7).superscriptRepresentation + ) + XCTAssertEqual( + Int(18).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(8).superscriptRepresentation + ) + XCTAssertEqual( + Int(19).superscriptRepresentation, + Int(1).superscriptRepresentation + Int(9).superscriptRepresentation + ) + XCTAssertEqual( + Int(20).superscriptRepresentation, + Int(2).superscriptRepresentation + Int(0).superscriptRepresentation + ) + XCTAssertEqual( + Int(21).superscriptRepresentation, + Int(2).superscriptRepresentation + Int(1).superscriptRepresentation + ) + XCTAssertEqual( + Int(22).superscriptRepresentation, + Int(2).superscriptRepresentation + Int(2).superscriptRepresentation + ) + XCTAssertEqual( + Int(23).superscriptRepresentation, + Int(2).superscriptRepresentation + Int(3).superscriptRepresentation + ) + XCTAssertEqual( + Int(24).superscriptRepresentation, + Int(2).superscriptRepresentation + Int(4).superscriptRepresentation + ) } } diff --git a/swiftgen.yml b/swiftgen.yml index bb72ba00..d371e28b 100644 --- a/swiftgen.yml +++ b/swiftgen.yml @@ -15,6 +15,7 @@ fonts: inputs: - Fonts/Zboto.otf - Fonts/Rubik + - Fonts/Roboto outputs: templatePath: Templates/fonts/fonts_swift5_swiftui.stencil output: Fonts+Generated.swift