Modify transfer ticket flow UI

pull/193/head
Hwee-Boon Yar 7 years ago
parent 3ce77d553f
commit 2ece6a6624
  1. 60
      Trust.xcodeproj/project.pbxproj
  2. 4
      Trust/Extensions/Date.swift
  3. 5
      Trust/Localization/en.lproj/Localizable.strings
  4. 84
      Trust/Sell/ViewModels/GenerateTransferMagicLinkViewControllerViewModel.swift
  5. 49
      Trust/Transactions/Coordinators/ScanQRCodeForWalletAddressToTransferTicketCoordinator.swift
  6. 185
      Trust/Transactions/Coordinators/TicketsCoordinator.swift
  7. 174
      Trust/Transfer/ViewControllers/ChooseTicketTransferModeViewController.swift
  8. 159
      Trust/Transfer/ViewControllers/GenerateTransferMagicLinkViewController.swift
  9. 336
      Trust/Transfer/ViewControllers/SetTransferTicketsExpiryDateViewController.swift
  10. 159
      Trust/Transfer/ViewControllers/TransferTicketViaWalletAddressViewController.swift
  11. 185
      Trust/Transfer/ViewControllers/TransferTicketsChooseTransferModeViewController.swift
  12. 6
      Trust/Transfer/ViewControllers/TransferTicketsQuantitySelectionViewController.swift
  13. 242
      Trust/Transfer/ViewControllers/TransferTicketsViaWalletAddressViewController.swift
  14. 84
      Trust/Transfer/ViewModels/ChooseTicketTransferModeViewControllerViewModel.swift
  15. 110
      Trust/Transfer/ViewModels/SetTransferTicketsExpiryDateViewControllerViewModel.swift
  16. 74
      Trust/Transfer/ViewModels/TransferTicketsQuantitySelectionViewControllerViewModel.swift
  17. 82
      Trust/Transfer/ViewModels/TransferTicketsViaWalletAddressViewControllerViewModel.swift

@ -283,7 +283,6 @@
4AEDE35A1DC3B1F4B885A073 /* Pods_AlphaWallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BD60178B937124277D81CCD /* Pods_AlphaWallet.framework */; };
5E7C701BFF4469B35A074EB9 /* RequestViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C767497AD8DEE83F384D7 /* RequestViewModel.swift */; };
5E7C70BE9AE35408038E1971 /* HelpContentsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B089FD4C96810DD10FD /* HelpContentsViewController.swift */; };
5E7C70EEFB9D9745C6CF7578 /* ChooseTicketTransferModeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7D177F5297D4A3DB3F33 /* ChooseTicketTransferModeViewController.swift */; };
5E7C70FF17622C0FFD45A542 /* AlphaWalletSettingPushRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7D2AAB777BF35B8B56BD /* AlphaWalletSettingPushRow.swift */; };
5E7C710331196CD591B51785 /* LockCreatePasscodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C741196D9D9C9C3EE5E30 /* LockCreatePasscodeViewController.swift */; };
5E7C713ACE8C72642B1C9F93 /* SendHeaderViewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B7A45EDFA8ED1E25863 /* SendHeaderViewViewModel.swift */; };
@ -291,6 +290,7 @@
5E7C71A7D2BD6FCE3980CC51 /* ImportWalletHelpBubbleViewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7A16ABC8BD5D508AA641 /* ImportWalletHelpBubbleViewViewModel.swift */; };
5E7C71B52A77008694BFA5D1 /* TokensDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C74B9EB81C51E956566E7 /* TokensDataStore.swift */; };
5E7C71C3356BF80240720EFE /* LockEnterPasscodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C73495E0C0A207152EC25 /* LockEnterPasscodeViewController.swift */; };
5E7C71DAA5DAFF764F92587D /* SetTransferTicketsExpiryDateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C727433F7B8E322B3C68A /* SetTransferTicketsExpiryDateViewController.swift */; };
5E7C71F8050CCF990539B293 /* LockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C79D674D45A07E694CE31 /* LockView.swift */; };
5E7C7208A83399C27AE57E44 /* ImportWalletHelpBubbleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C70CC85B337061151724E /* ImportWalletHelpBubbleView.swift */; };
5E7C7248A9A732452BDC27D7 /* AdvancedSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C78581AA28CA5C3CBC468 /* AdvancedSettingsViewController.swift */; };
@ -306,19 +306,25 @@
5E7C7376B566E5A59CC8F463 /* ImportTicketViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C72D0E7CA03ADE5CFAE7A /* ImportTicketViewControllerViewModel.swift */; };
5E7C73FC3990D110C474C3D6 /* WalletFilterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C75CC640BAFFE0E789F44 /* WalletFilterViewModel.swift */; };
5E7C73FD5BD75D90C8D0EF3C /* WalletFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7C58586099F082973073 /* WalletFilterView.swift */; };
5E7C745C725F3F34037DCC68 /* SetTransferTicketsExpiryDateViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C754C0E2E57F32A61F9A3 /* SetTransferTicketsExpiryDateViewControllerViewModel.swift */; };
5E7C745DACB5FCCEBCEB49CA /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C793E23E2364B73C4D813 /* WelcomeViewController.swift */; };
5E7C7499A8D6814F7950DA70 /* LockCreatePasscodeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7AB3440C01136DF4F3E9 /* LockCreatePasscodeCoordinator.swift */; };
5E7C74B5796FB59C8427C7A0 /* GenerateTransferMagicLinkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7D46C7CABC31A7477F37 /* GenerateTransferMagicLinkViewController.swift */; };
5E7C74B99922D0CAB635970E /* PasscodeCharacterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B9220E616F82EDA956F /* PasscodeCharacterView.swift */; };
5E7C74DBAE43954C185057B3 /* ChooseTicketTransferModeViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7BA578BE5FB0E613A6D6 /* ChooseTicketTransferModeViewControllerViewModel.swift */; };
5E7C7567A690B6B8F889AE83 /* SendViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C70088832B2D161EB4AAB /* SendViewController.swift */; };
5E7C75C99B9F595F26EDC405 /* LockPasscodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7D5F3CAE69CF932AB236 /* LockPasscodeViewController.swift */; };
5E7C75D46140FACBD12333BF /* EthTokenViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7EE374A74F2B00013C18 /* EthTokenViewCell.swift */; };
5E7C75E3C4BAE885746BD1B3 /* TransferTicketViaWalletAddressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C72B37551451352EBB9F9 /* TransferTicketViaWalletAddressViewController.swift */; };
5E7C75E5C64619ABFD246183 /* TransferTicketsViaWalletAddressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C78B63FDE2FAF25389260 /* TransferTicketsViaWalletAddressViewController.swift */; };
5E7C75E81F85353844CACECC /* EnterSellTicketsPriceQuantityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7F610139D24D947B1625 /* EnterSellTicketsPriceQuantityViewController.swift */; };
5E7C75F80A7E178B49830BCD /* TicketsViewControllerHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C796039C0F47CDCA236C0 /* TicketsViewControllerHeader.swift */; };
5E7C76037119D18718068C66 /* TransferTicketsChooseTransferModeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C777F35DFD4021FB8D198 /* TransferTicketsChooseTransferModeViewController.swift */; };
5E7C760C7D55C97424F55138 /* TicketTableViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C75F877B2F2E24C7EF258 /* TicketTableViewCellViewModel.swift */; };
5E7C764D3C130AAB26E80EC1 /* AmountTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C73617E3A4C0B9A90A5F8 /* AmountTextField.swift */; };
5E7C76605A5102FBD376F32A /* ImportTicketViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7535095323B035CA47C0 /* ImportTicketViewController.swift */; };
5E7C76696EF7F27EC0788CDD /* GenerateTransferMagicLinkViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7EEAAE9C23B68419E9F5 /* GenerateTransferMagicLinkViewControllerViewModel.swift */; };
5E7C7669BBE6255A2377E070 /* SetSellTicketsExpiryDateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7962AE417E12F13FF58E /* SetSellTicketsExpiryDateViewController.swift */; };
5E7C7692C981580CD32228EB /* ChooseTicketTransferModeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C70FB40612BB02594EC00 /* ChooseTicketTransferModeViewController.swift */; };
5E7C76A0365D128B7F19A0C2 /* ProtectionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C74BEC095303B66FB4B1E /* ProtectionCoordinator.swift */; };
5E7C76A65C14D0F11AF7848F /* TicketRowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7742709724B3BD0C2A0D /* TicketRowViewModel.swift */; };
5E7C76B917517C93D1E26B0A /* LockEnterPasscodeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7981AB6584B25C72D46B /* LockEnterPasscodeCoordinator.swift */; };
@ -330,7 +336,6 @@
5E7C7793AB6B577906F2BCA3 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7AFE9AF9FE6B58C925D4 /* SettingsViewController.swift */; };
5E7C77AD9FAAC18211B6F355 /* TransferTicketsQuantitySelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7419F47CC8B2996AA8F9 /* TransferTicketsQuantitySelectionViewController.swift */; };
5E7C77E844D710D7AFBC58D4 /* RequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C74DCC21272EC231A20E2 /* RequestViewController.swift */; };
5E7C782C7894C44E9D6897F4 /* ChooseTicketTransferModeViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C75BE23CDD9CD271EC30C /* ChooseTicketTransferModeViewControllerViewModel.swift */; };
5E7C783B4784DE76971EEBB4 /* StatusViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7BD9B4BDAFC2D9EBD741 /* StatusViewControllerViewModel.swift */; };
5E7C78407F6DCB0EDD562DF6 /* TicketTokenViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C731B6F01534683227123 /* TicketTokenViewCellViewModel.swift */; };
5E7C78B3FD5CA87E395E1861 /* OnboardingPageStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7AF9A592D7224ED58016 /* OnboardingPageStyle.swift */; };
@ -338,11 +343,9 @@
5E7C797BE2C8DB7EF6F217B3 /* OnboardingPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7103135DCCCAB96EE5FC /* OnboardingPage.swift */; };
5E7C798E5F5EE00D405B91AE /* TicketRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7ACB94CEE493AC37487F /* TicketRowView.swift */; };
5E7C79F30A324D75DF42DDDE /* SellTicketsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7EB14E787BC019660389 /* SellTicketsViewModel.swift */; };
5E7C7A41B07499B607476300 /* ScanQRCodeForWalletAddressToTransferTicketCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7F4A5956D5C5C310ADB2 /* ScanQRCodeForWalletAddressToTransferTicketCoordinator.swift */; };
5E7C7A4384A8E3F22D3F8249 /* SetSellTicketsExpiryDateViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C700CD3E43689E88FBE9B /* SetSellTicketsExpiryDateViewControllerViewModel.swift */; };
5E7C7AB2ECFB589632F2A26C /* WalletFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7E2DCCE0D775ECF83088 /* WalletFilter.swift */; };
5E7C7AB6950E43BD6E8D0CBE /* TokensViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B3302309706CA0F972A /* TokensViewController.swift */; };
5E7C7AD4DF6DFA6B3AF206E7 /* TransferTicketViaWalletAddressViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7610C8DD3223230E3951 /* TransferTicketViaWalletAddressViewControllerViewModel.swift */; };
5E7C7B0367CFB413C6885474 /* GenerateSellMagicLinkViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7624D6F7EA55F6F167B3 /* GenerateSellMagicLinkViewControllerViewModel.swift */; };
5E7C7B3E08EEA63C5B68B9C4 /* TicketRedemptionInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C778F20D32B70D7FF2135 /* TicketRedemptionInfoViewController.swift */; };
5E7C7C0FAC500A6651E663FD /* TransferTicketsQuantitySelectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C703BA1D0E9ACB7399155 /* TransferTicketsQuantitySelectionViewModel.swift */; };
@ -362,11 +365,13 @@
5E7C7D8AFC9BA1E8C1D05167 /* TicketSellInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C74A2C738BF2412D412A7 /* TicketSellInfoViewController.swift */; };
5E7C7DD506747B6224C28721 /* TransferTicketsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7E2486CDE31871C98FC7 /* TransferTicketsViewModel.swift */; };
5E7C7E04D4DDD7D8881A2AB1 /* UniversalLinkCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C76AF81B8DFF605558499 /* UniversalLinkCoordinator.swift */; };
5E7C7E0C977265B96199354A /* TransferTicketsQuantitySelectionViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C720151BC95DB1F0A454B /* TransferTicketsQuantitySelectionViewControllerViewModel.swift */; };
5E7C7E1B18EC7F7FD6D64439 /* SellTicketsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7FF84A4377FC395772C3 /* SellTicketsViewController.swift */; };
5E7C7E2C03099D78A9D911D7 /* WhatIsASeedPhraseInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B0BE9EE3B198AE7D92D /* WhatIsASeedPhraseInfoViewController.swift */; };
5E7C7E2F558A1DFF078B61F9 /* TransferTicketsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7011D8E5C9FFE0E59D55 /* TransferTicketsViewController.swift */; };
5E7C7E4B4054AAD41C5BE3EC /* SettingsAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7564AF453BAB0BDAAA57 /* SettingsAction.swift */; };
5E7C7E5C30EFDC70DF1E00C1 /* TicketsViewControllerHeaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C77316522DF2B256F1F92 /* TicketsViewControllerHeaderViewModel.swift */; };
5E7C7EAEBB435F3909DA36FB /* TransferTicketsViaWalletAddressViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C76D3CFA12C2236E73E10 /* TransferTicketsViaWalletAddressViewControllerViewModel.swift */; };
5E7C7EEE563D81793CB96FA0 /* TransferTicketsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C755132D9B6F95080A1BE /* TransferTicketsCoordinator.swift */; };
5E7C7FAF2A07E7AE21BF09AF /* AlphaWalletSettingsTextRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C71684B93F60206992E10 /* AlphaWalletSettingsTextRow.swift */; };
5E7C7FC0770A411DB09F8C09 /* TokenViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7C077372C3F2A4349FA1 /* TokenViewCell.swift */; };
@ -799,14 +804,16 @@
5E7C7011D8E5C9FFE0E59D55 /* TransferTicketsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsViewController.swift; sourceTree = "<group>"; };
5E7C703BA1D0E9ACB7399155 /* TransferTicketsQuantitySelectionViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsQuantitySelectionViewModel.swift; sourceTree = "<group>"; };
5E7C70CC85B337061151724E /* ImportWalletHelpBubbleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletHelpBubbleView.swift; sourceTree = "<group>"; };
5E7C70FB40612BB02594EC00 /* ChooseTicketTransferModeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChooseTicketTransferModeViewController.swift; sourceTree = "<group>"; };
5E7C7103135DCCCAB96EE5FC /* OnboardingPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingPage.swift; sourceTree = "<group>"; };
5E7C715F395B973FB61056CF /* HelpViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelpViewController.swift; sourceTree = "<group>"; };
5E7C71684B93F60206992E10 /* AlphaWalletSettingsTextRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AlphaWalletSettingsTextRow.swift; path = Views/AlphaWalletSettingsTextRow.swift; sourceTree = "<group>"; };
5E7C719B717E002583B1E2E9 /* AdvancedSettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsViewModel.swift; sourceTree = "<group>"; };
5E7C71CE10548877F1124BF2 /* WelcomeViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeViewModel.swift; sourceTree = "<group>"; };
5E7C71EBD4C95AD4E11F3352 /* AlphaWalletSettingsButtonRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AlphaWalletSettingsButtonRow.swift; path = Views/AlphaWalletSettingsButtonRow.swift; sourceTree = "<group>"; };
5E7C720151BC95DB1F0A454B /* TransferTicketsQuantitySelectionViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsQuantitySelectionViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C72142D5817EF8FA8CADA /* PrivacyPolicyViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrivacyPolicyViewController.swift; sourceTree = "<group>"; };
5E7C72B37551451352EBB9F9 /* TransferTicketViaWalletAddressViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketViaWalletAddressViewController.swift; sourceTree = "<group>"; };
5E7C727433F7B8E322B3C68A /* SetTransferTicketsExpiryDateViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetTransferTicketsExpiryDateViewController.swift; sourceTree = "<group>"; };
5E7C72D0E7CA03ADE5CFAE7A /* ImportTicketViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportTicketViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C731B6F01534683227123 /* TicketTokenViewCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketTokenViewCellViewModel.swift; sourceTree = "<group>"; };
5E7C73495E0C0A207152EC25 /* LockEnterPasscodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LockEnterPasscodeViewController.swift; path = Trust/AlphaWalletLock/ViewControllers/LockEnterPasscodeViewController.swift; sourceTree = SOURCE_ROOT; };
@ -821,25 +828,26 @@
5E7C74FABE14B7B1BEEC4F5E /* WhyUseEthereumInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WhyUseEthereumInfoViewController.swift; sourceTree = "<group>"; };
5E7C7534FB6BF4D199643246 /* AlphaWalletSettingsSwitchRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AlphaWalletSettingsSwitchRow.swift; path = Views/AlphaWalletSettingsSwitchRow.swift; sourceTree = "<group>"; };
5E7C7535095323B035CA47C0 /* ImportTicketViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportTicketViewController.swift; sourceTree = "<group>"; };
5E7C754C0E2E57F32A61F9A3 /* SetTransferTicketsExpiryDateViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetTransferTicketsExpiryDateViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C755132D9B6F95080A1BE /* TransferTicketsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsCoordinator.swift; sourceTree = "<group>"; };
5E7C7564AF453BAB0BDAAA57 /* SettingsAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsAction.swift; sourceTree = "<group>"; };
5E7C75BE23CDD9CD271EC30C /* ChooseTicketTransferModeViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChooseTicketTransferModeViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C75CC640BAFFE0E789F44 /* WalletFilterViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletFilterViewModel.swift; sourceTree = "<group>"; };
5E7C75CE3F1D6B7993E7A840 /* OnboardingCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingCollectionViewController.swift; sourceTree = "<group>"; };
5E7C75F877B2F2E24C7EF258 /* TicketTableViewCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketTableViewCellViewModel.swift; sourceTree = "<group>"; };
5E7C7607B0EF9B8F1BC41073 /* TermsOfServiceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TermsOfServiceViewController.swift; sourceTree = "<group>"; };
5E7C7610C8DD3223230E3951 /* TransferTicketViaWalletAddressViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketViaWalletAddressViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C7624D6F7EA55F6F167B3 /* GenerateSellMagicLinkViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateSellMagicLinkViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C7646352F10C96B5FC6F6 /* HelpViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelpViewCell.swift; sourceTree = "<group>"; };
5E7C764B98F526271E4C2A6A /* StaticHTMLViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticHTMLViewController.swift; sourceTree = "<group>"; };
5E7C765E0DC0174E9788CCF9 /* EnterSellTicketsPriceQuantityViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterSellTicketsPriceQuantityViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C767497AD8DEE83F384D7 /* RequestViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestViewModel.swift; sourceTree = "<group>"; };
5E7C76AF81B8DFF605558499 /* UniversalLinkCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UniversalLinkCoordinator.swift; sourceTree = "<group>"; };
5E7C76D3CFA12C2236E73E10 /* TransferTicketsViaWalletAddressViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsViaWalletAddressViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C77061BEF269BCE358086 /* BaseTicketTableViewCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTicketTableViewCellViewModel.swift; sourceTree = "<group>"; };
5E7C7717D829205D1E254AC1 /* ShareModeButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareModeButton.swift; sourceTree = "<group>"; };
5E7C77316522DF2B256F1F92 /* TicketsViewControllerHeaderViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketsViewControllerHeaderViewModel.swift; sourceTree = "<group>"; };
5E7C7742709724B3BD0C2A0D /* TicketRowViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketRowViewModel.swift; sourceTree = "<group>"; };
5E7C774BCA281E4B077DBBFA /* WhatIsEthereumInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WhatIsEthereumInfoViewController.swift; sourceTree = "<group>"; };
5E7C777F35DFD4021FB8D198 /* TransferTicketsChooseTransferModeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsChooseTransferModeViewController.swift; sourceTree = "<group>"; };
5E7C778F20D32B70D7FF2135 /* TicketRedemptionInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketRedemptionInfoViewController.swift; sourceTree = "<group>"; };
5E7C77E1E6194F5A1DC8D645 /* ScreenChecker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScreenChecker.swift; sourceTree = "<group>"; };
5E7C7821694C489D5114DB18 /* TicketsViewControllerTitleHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketsViewControllerTitleHeader.swift; sourceTree = "<group>"; };
@ -847,6 +855,7 @@
5E7C783E3ADA4CF9554A0E7D /* TicketTokenViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketTokenViewCell.swift; sourceTree = "<group>"; };
5E7C78581AA28CA5C3CBC468 /* AdvancedSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsViewController.swift; sourceTree = "<group>"; };
5E7C78B001F9F95F404D5FEF /* HowDoIGetMyMoneyInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HowDoIGetMyMoneyInfoViewController.swift; sourceTree = "<group>"; };
5E7C78B63FDE2FAF25389260 /* TransferTicketsViaWalletAddressViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsViaWalletAddressViewController.swift; sourceTree = "<group>"; };
5E7C793E23E2364B73C4D813 /* WelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = "<group>"; };
5E7C794F8EBAEE5E8F2821C2 /* MarketplaceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarketplaceViewController.swift; sourceTree = "<group>"; };
5E7C796039C0F47CDCA236C0 /* TicketsViewControllerHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketsViewControllerHeader.swift; sourceTree = "<group>"; };
@ -869,11 +878,12 @@
5E7C7B7A45EDFA8ED1E25863 /* SendHeaderViewViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendHeaderViewViewModel.swift; sourceTree = "<group>"; };
5E7C7B82CC07F290B9CAA4E4 /* StatusViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusViewController.swift; sourceTree = "<group>"; };
5E7C7B9220E616F82EDA956F /* PasscodeCharacterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasscodeCharacterView.swift; sourceTree = "<group>"; };
5E7C7BA578BE5FB0E613A6D6 /* ChooseTicketTransferModeViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChooseTicketTransferModeViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C7BD9B4BDAFC2D9EBD741 /* StatusViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C7C077372C3F2A4349FA1 /* TokenViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenViewCell.swift; sourceTree = "<group>"; };
5E7C7C58586099F082973073 /* WalletFilterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletFilterView.swift; sourceTree = "<group>"; };
5E7C7D177F5297D4A3DB3F33 /* ChooseTicketTransferModeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChooseTicketTransferModeViewController.swift; sourceTree = "<group>"; };
5E7C7D2AAB777BF35B8B56BD /* AlphaWalletSettingPushRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AlphaWalletSettingPushRow.swift; path = Views/AlphaWalletSettingPushRow.swift; sourceTree = "<group>"; };
5E7C7D46C7CABC31A7477F37 /* GenerateTransferMagicLinkViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateTransferMagicLinkViewController.swift; sourceTree = "<group>"; };
5E7C7D4F7C566EDD30EF1C19 /* HowDoITransferETHIntoMyWalletInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HowDoITransferETHIntoMyWalletInfoViewController.swift; sourceTree = "<group>"; };
5E7C7D5F3CAE69CF932AB236 /* LockPasscodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockPasscodeViewController.swift; sourceTree = "<group>"; };
5E7C7E2486CDE31871C98FC7 /* TransferTicketsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsViewModel.swift; sourceTree = "<group>"; };
@ -883,7 +893,7 @@
5E7C7EB14E787BC019660389 /* SellTicketsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SellTicketsViewModel.swift; sourceTree = "<group>"; };
5E7C7EE374A74F2B00013C18 /* EthTokenViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EthTokenViewCell.swift; sourceTree = "<group>"; };
5E7C7EE467A7F5F2E5B1F660 /* TokensViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokensViewModel.swift; sourceTree = "<group>"; };
5E7C7F4A5956D5C5C310ADB2 /* ScanQRCodeForWalletAddressToTransferTicketCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanQRCodeForWalletAddressToTransferTicketCoordinator.swift; sourceTree = "<group>"; };
5E7C7EEAAE9C23B68419E9F5 /* GenerateTransferMagicLinkViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateTransferMagicLinkViewControllerViewModel.swift; sourceTree = "<group>"; };
5E7C7F5C10E3895E805EA7E0 /* BaseTicketTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTicketTableViewCell.swift; sourceTree = "<group>"; };
5E7C7F610139D24D947B1625 /* EnterSellTicketsPriceQuantityViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterSellTicketsPriceQuantityViewController.swift; sourceTree = "<group>"; };
5E7C7F932B48011A24C26733 /* TokensCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokensCoordinator.swift; sourceTree = "<group>"; };
@ -1508,7 +1518,6 @@
2932045D1F8EEE760095B7C1 /* BalanceCoordinator.swift */,
613D048A1FDE162B008DE72E /* TrustProvider.swift */,
442FCC8150042FE9179D574A /* TicketsCoordinator.swift */,
5E7C7F4A5956D5C5C310ADB2 /* ScanQRCodeForWalletAddressToTransferTicketCoordinator.swift */,
);
path = Coordinators;
sourceTree = "<group>";
@ -1890,9 +1899,12 @@
5E7C74DCC21272EC231A20E2 /* RequestViewController.swift */,
5E7C7011D8E5C9FFE0E59D55 /* TransferTicketsViewController.swift */,
5E7C7419F47CC8B2996AA8F9 /* TransferTicketsQuantitySelectionViewController.swift */,
5E7C7D177F5297D4A3DB3F33 /* ChooseTicketTransferModeViewController.swift */,
5E7C72B37551451352EBB9F9 /* TransferTicketViaWalletAddressViewController.swift */,
5E7C70088832B2D161EB4AAB /* SendViewController.swift */,
5E7C777F35DFD4021FB8D198 /* TransferTicketsChooseTransferModeViewController.swift */,
5E7C70FB40612BB02594EC00 /* ChooseTicketTransferModeViewController.swift */,
5E7C727433F7B8E322B3C68A /* SetTransferTicketsExpiryDateViewController.swift */,
5E7C7D46C7CABC31A7477F37 /* GenerateTransferMagicLinkViewController.swift */,
5E7C78B63FDE2FAF25389260 /* TransferTicketsViaWalletAddressViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
@ -1907,9 +1919,11 @@
5E7C767497AD8DEE83F384D7 /* RequestViewModel.swift */,
5E7C7E2486CDE31871C98FC7 /* TransferTicketsViewModel.swift */,
5E7C703BA1D0E9ACB7399155 /* TransferTicketsQuantitySelectionViewModel.swift */,
5E7C75BE23CDD9CD271EC30C /* ChooseTicketTransferModeViewControllerViewModel.swift */,
5E7C7610C8DD3223230E3951 /* TransferTicketViaWalletAddressViewControllerViewModel.swift */,
5E7C7B7A45EDFA8ED1E25863 /* SendHeaderViewViewModel.swift */,
5E7C720151BC95DB1F0A454B /* TransferTicketsQuantitySelectionViewControllerViewModel.swift */,
5E7C7BA578BE5FB0E613A6D6 /* ChooseTicketTransferModeViewControllerViewModel.swift */,
5E7C754C0E2E57F32A61F9A3 /* SetTransferTicketsExpiryDateViewControllerViewModel.swift */,
5E7C76D3CFA12C2236E73E10 /* TransferTicketsViaWalletAddressViewControllerViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
@ -2321,6 +2335,7 @@
5E7C765E0DC0174E9788CCF9 /* EnterSellTicketsPriceQuantityViewControllerViewModel.swift */,
5E7C700CD3E43689E88FBE9B /* SetSellTicketsExpiryDateViewControllerViewModel.swift */,
5E7C7624D6F7EA55F6F167B3 /* GenerateSellMagicLinkViewControllerViewModel.swift */,
5E7C7EEAAE9C23B68419E9F5 /* GenerateTransferMagicLinkViewControllerViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
@ -3575,12 +3590,7 @@
5E7C776BE1B19F824954962D /* BaseTicketTableViewCell.swift in Sources */,
5E7C7C0FAC500A6651E663FD /* TransferTicketsQuantitySelectionViewModel.swift in Sources */,
5E7C77AD9FAAC18211B6F355 /* TransferTicketsQuantitySelectionViewController.swift in Sources */,
5E7C70EEFB9D9745C6CF7578 /* ChooseTicketTransferModeViewController.swift in Sources */,
5E7C782C7894C44E9D6897F4 /* ChooseTicketTransferModeViewControllerViewModel.swift in Sources */,
5E7C73305DF984B99E94D9F9 /* ShareModeButton.swift in Sources */,
5E7C75E3C4BAE885746BD1B3 /* TransferTicketViaWalletAddressViewController.swift in Sources */,
5E7C7AD4DF6DFA6B3AF206E7 /* TransferTicketViaWalletAddressViewControllerViewModel.swift in Sources */,
5E7C7A41B07499B607476300 /* ScanQRCodeForWalletAddressToTransferTicketCoordinator.swift in Sources */,
5E7C7EEE563D81793CB96FA0 /* TransferTicketsCoordinator.swift in Sources */,
5E7C7567A690B6B8F889AE83 /* SendViewController.swift in Sources */,
5E7C72E1D4B4B4C8443F3DA1 /* SendHeaderView.swift in Sources */,
@ -3598,6 +3608,16 @@
5E7C7A4384A8E3F22D3F8249 /* SetSellTicketsExpiryDateViewControllerViewModel.swift in Sources */,
5E7C776CF721EBBD43195926 /* GenerateSellMagicLinkViewController.swift in Sources */,
5E7C7B0367CFB413C6885474 /* GenerateSellMagicLinkViewControllerViewModel.swift in Sources */,
5E7C76037119D18718068C66 /* TransferTicketsChooseTransferModeViewController.swift in Sources */,
5E7C7E0C977265B96199354A /* TransferTicketsQuantitySelectionViewControllerViewModel.swift in Sources */,
5E7C7692C981580CD32228EB /* ChooseTicketTransferModeViewController.swift in Sources */,
5E7C74DBAE43954C185057B3 /* ChooseTicketTransferModeViewControllerViewModel.swift in Sources */,
5E7C71DAA5DAFF764F92587D /* SetTransferTicketsExpiryDateViewController.swift in Sources */,
5E7C745C725F3F34037DCC68 /* SetTransferTicketsExpiryDateViewControllerViewModel.swift in Sources */,
5E7C74B5796FB59C8427C7A0 /* GenerateTransferMagicLinkViewController.swift in Sources */,
5E7C76696EF7F27EC0788CDD /* GenerateTransferMagicLinkViewControllerViewModel.swift in Sources */,
5E7C75E5C64619ABFD246183 /* TransferTicketsViaWalletAddressViewController.swift in Sources */,
5E7C7EAEBB435F3909DA36FB /* TransferTicketsViaWalletAddressViewControllerViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -35,6 +35,10 @@ public extension Date {
return foundFormatter!
}
public static var yesterday: Date {
return Calendar.current.date(byAdding: .day, value: -1, to: Date())!
}
public static var tomorrow: Date {
return Calendar.current.date(byAdding: .day, value: 1, to: Date())!
}

@ -229,8 +229,10 @@
"a.wallet.ticketToken.transfer.selectTickets.title" = "Select Tickets To Transfer:";
"a.wallet.ticketToken.transfer.selectTicketQuantity.atLeastOne.title" = "Please select quantity of tickets";
"a.wallet.ticketToken.transfer.selectTickets.atLeastOne.title" = "Please select a ticket to transfer";
"a.wallet.ticketToken.transfer.selectQuantity.title" = "Select Quantity of Tickets";
"a.wallet.ticketToken.transfer.selectQuantity.title" = "Transfer Tickets";
"a.wallet.ticketToken.transfer.quantity.title" = "QUANTITY OF TICKETS";
"a.wallet.ticketToken.transfer.mode.magicLink.button.title" = "MagicLink for Picking Up";
"a.wallet.ticketToken.transfer.mode.now.button.title" = "Transfer now";
"a.wallet.ticketToken.transfer.mode.choose.title" = "Send your 24 hour transfer link";
"a.wallet.ticketToken.transfer.mode.choose.text.title" = "Send SMS/iMessage";
"a.wallet.ticketToken.transfer.mode.choose.email.title" = "Send Email";
@ -242,6 +244,7 @@
"a.wallet.ticketToken.transfer.mode.walletAddress.confirmation" = "Transfer to wallet address %@?";
"a.wallet.ticketToken.transfer.mode.text.title" = "Transfer Ticket via Text link";
"a.wallet.ticketToken.transfer.mode.text.target.title" = "PHONE NUMBER";
"a.wallet.ticketToken.transfer.linkExpiryTime.atLeastNow.title" = "Please select a date in the future";
"a.wallet.ticketToken.transfer" = "PHONE NUMBER";
"a.wallet.ticketToken.transfer.success.title" = "Your ticket has been transferred";
"a.wallet.ticketToken.transfer.failed.title" = "Your ticket was not transferred";

@ -0,0 +1,84 @@
// Copyright © 2018 Stormbird PTE. LTD.
import UIKit
struct GenerateTransferMagicLinkViewControllerViewModel {
var ticketHolder: TicketHolder
var linkExpiryDate: Date
var contentsBackgroundColor: UIColor {
return Colors.appWhite
}
var subtitleColor: UIColor {
return Colors.appText
}
var subtitleFont: UIFont {
return Fonts.light(size: 25)!
}
var subtitleLabelText: String {
return R.string.localizable.aWalletTicketTokenSellConfirmSubtitle()
}
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenSellConfirmTitle()
}
var actionButtonTitleColor: UIColor {
return Colors.appWhite
}
var actionButtonBackgroundColor: UIColor {
return Colors.appBackground
}
var actionButtonTitleFont: UIFont {
return Fonts.regular(size: 20)!
}
var cancelButtonTitleColor: UIColor {
return Colors.appRed
}
var cancelButtonBackgroundColor: UIColor {
return .clear
}
var cancelButtonTitleFont: UIFont {
return Fonts.regular(size: 20)!
}
var actionButtonTitle: String {
return R.string.localizable.aWalletTicketTokenSellConfirmButtonTitle()
}
var cancelButtonTitle: String {
return R.string.localizable.aWalletTicketTokenSellConfirmCancelButtonTitle()
}
var ticketSaleDetailsLabelFont: UIFont {
return Fonts.semibold(size: 21)!
}
var ticketSaleDetailsLabelColor: UIColor {
return Colors.appBackground
}
var descriptionLabelText: String {
//TODO Should format be localized?
return R.string.localizable.aWalletTicketTokenSellConfirmExpiryDateDescription(linkExpiryDate.format("dd MMM yyyy hh:mm"))
}
var ticketCountLabelText: String {
if ticketCount == 1 {
return R.string.localizable.aWalletTicketTokenSellConfirmSingleTicketSelectedTitle()
} else {
return R.string.localizable.aWalletTicketTokenSellConfirmMultipleTicketSelectedTitle(ticketHolder.ticketCount)
}
}
var detailsBackgroundBackgroundColor: UIColor {
return UIColor(red: 236, green: 236, blue: 236)
}
private var ticketCount: Int {
return Int(ticketHolder.ticketCount)!
}
init(ticketHolder: TicketHolder, linkExpiryDate: Date) {
self.ticketHolder = ticketHolder
self.linkExpiryDate = linkExpiryDate
}
}

@ -1,49 +0,0 @@
// Copyright © 2018 Stormbird PTE. LTD.
import Foundation
import QRCodeReaderViewController
protocol ScanQRCodeForWalletAddressToTransferTicketCoordinatorDelegate: class {
func scanned(walletAddress: String, in coordinator: ScanQRCodeForWalletAddressToTransferTicketCoordinator)
func cancelled(in coordinator: ScanQRCodeForWalletAddressToTransferTicketCoordinator)
}
class ScanQRCodeForWalletAddressToTransferTicketCoordinator: NSObject, Coordinator {
var coordinators: [Coordinator] = []
var ticketHolder: TicketHolder
var viewController: UIViewController
var paymentFlow: PaymentFlow
weak var delegate: ScanQRCodeForWalletAddressToTransferTicketCoordinatorDelegate?
init(ticketHolder: TicketHolder, paymentFlow: PaymentFlow, in viewController: UIViewController) {
self.ticketHolder = ticketHolder
self.paymentFlow = paymentFlow
self.viewController = viewController
}
func start() {
let controller = QRCodeReaderViewController()
controller.delegate = self
viewController.present(controller, animated: true, completion: nil)
}
}
extension ScanQRCodeForWalletAddressToTransferTicketCoordinator: QRCodeReaderDelegate {
func readerDidCancel(_ reader: QRCodeReaderViewController!) {
reader.stopScanning()
reader.dismiss(animated: true) { [weak self] in
if let celf = self {
celf.delegate?.cancelled(in: celf)
}
}
}
func reader(_ reader: QRCodeReaderViewController!, didScanResult result: String!) {
reader.stopScanning()
reader.dismiss(animated: true) { [weak self] in
if let celf = self {
celf.delegate?.scanned(walletAddress: result, in: celf)
}
}
}
}

@ -40,7 +40,6 @@ class TicketsCoordinator: NSObject, Coordinator {
let tokensStorage: TokensDataStore
let navigationController: UINavigationController
var coordinators: [Coordinator] = []
var scanQRCodeForWalletAddressToTransferTicketCoordinator: ScanQRCodeForWalletAddressToTransferTicketCoordinator?
init(
session: WalletSession,
@ -106,6 +105,13 @@ class TicketsCoordinator: NSObject, Coordinator {
viewController.navigationController?.present(vc, animated: true)
}
private func showTransferConfirmationScreen(for ticketHolder: TicketHolder,
linkExpiryDate: Date,
in viewController: SetTransferTicketsExpiryDateViewController) {
let vc = makeGenerateTransferMagicLinkViewController(paymentFlow: viewController.paymentFlow, ticketHolder: ticketHolder, linkExpiryDate: linkExpiryDate)
viewController.navigationController?.present(vc, animated: true)
}
private func makeGenerateSellMagicLinkViewController(paymentFlow: PaymentFlow, ticketHolder: TicketHolder, ethCost: String, dollarCost: String, linkExpiryDate: Date) -> GenerateSellMagicLinkViewController{
let vc = GenerateSellMagicLinkViewController(
paymentFlow: paymentFlow,
@ -124,6 +130,21 @@ class TicketsCoordinator: NSObject, Coordinator {
return vc
}
private func makeGenerateTransferMagicLinkViewController(paymentFlow: PaymentFlow, ticketHolder: TicketHolder, linkExpiryDate: Date) -> GenerateTransferMagicLinkViewController {
let vc = GenerateTransferMagicLinkViewController(
paymentFlow: paymentFlow,
ticketHolder: ticketHolder,
linkExpiryDate: linkExpiryDate
)
vc.delegate = self
vc.configure(viewModel: .init(
ticketHolder: ticketHolder,
linkExpiryDate: linkExpiryDate
))
vc.modalPresentationStyle = .overCurrentContext
return vc
}
private func showEnterSellTicketsExpiryDateViewController(for ticketHolder: TicketHolder,
ethCost: String,
dollarCost: String,
@ -182,6 +203,22 @@ class TicketsCoordinator: NSObject, Coordinator {
return controller
}
private func makeEnterTransferTicketsExpiryDateViewController(for ticketHolder: TicketHolder, paymentFlow: PaymentFlow) -> SetTransferTicketsExpiryDateViewController {
let controller = SetTransferTicketsExpiryDateViewController(ticketHolder: ticketHolder, paymentFlow: paymentFlow)
let viewModel = SetTransferTicketsExpiryDateViewControllerViewModel(ticketHolder: ticketHolder)
controller.configure(viewModel: viewModel)
controller.delegate = self
return controller
}
private func makeTransferTicketsViaWalletAddressViewController(for ticketHolder: TicketHolder, paymentFlow: PaymentFlow) -> TransferTicketsViaWalletAddressViewController {
let controller = TransferTicketsViaWalletAddressViewController(ticketHolder: ticketHolder, paymentFlow: paymentFlow)
let viewModel = TransferTicketsViaWalletAddressViewControllerViewModel(ticketHolder: ticketHolder)
controller.configure(viewModel: viewModel)
controller.delegate = self
return controller
}
private func makeEnterSellTicketsExpiryDateViewController(for ticketHolder: TicketHolder, ethCost: String, dollarCost: String, paymentFlow: PaymentFlow) -> SetSellTicketsExpiryDateViewController {
let controller = SetSellTicketsExpiryDateViewController(storage: tokensStorage, paymentFlow: paymentFlow, ticketHolder: ticketHolder, ethCost: ethCost, dollarCost: dollarCost)
let viewModel = SetSellTicketsExpiryDateViewControllerViewModel(ticketHolder: ticketHolder, ethCost: ethCost, dollarCost: dollarCost)
@ -221,7 +258,7 @@ class TicketsCoordinator: NSObject, Coordinator {
private func makeChooseTicketTransferModeViewController(for ticketHolder: TicketHolder, paymentFlow: PaymentFlow) -> ChooseTicketTransferModeViewController {
let controller = ChooseTicketTransferModeViewController(ticketHolder: ticketHolder, paymentFlow: paymentFlow)
let viewModel = ChooseTicketTransferModeViewControllerViewModel()
let viewModel = ChooseTicketTransferModeViewControllerViewModel(ticketHolder: ticketHolder)
controller.configure(viewModel: viewModel)
controller.delegate = self
return controller
@ -249,32 +286,6 @@ class TicketsCoordinator: NSObject, Coordinator {
return "https://app.awallet.com/a_sell_link"
}
private func transferViaWalletAddressTextEntry(ticketHolder: TicketHolder, paymentFlow: PaymentFlow) {
let controller = TransferTicketViaWalletAddressViewController(ticketHolder: ticketHolder, paymentFlow: paymentFlow)
controller.delegate = self
controller.configure(viewModel: .init(ticketHolder: ticketHolder))
navigationController.pushViewController(controller, animated: true)
}
private func transferViaReadingWalletAddressFromQRCode(ticketHolder: TicketHolder, paymentFlow: PaymentFlow) {
scanQRCodeForWalletAddressToTransferTicketCoordinator = ScanQRCodeForWalletAddressToTransferTicketCoordinator(ticketHolder: ticketHolder, paymentFlow: paymentFlow, in: navigationController)
scanQRCodeForWalletAddressToTransferTicketCoordinator?.delegate = self
scanQRCodeForWalletAddressToTransferTicketCoordinator?.start()
}
private func transferViaActivitySheet(ticketHolder: TicketHolder, paymentFlow: PaymentFlow, sender: UIView) {
let url = generateTransferLink(ticketHolder: ticketHolder, paymentFlow: paymentFlow)
let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil)
vc.popoverPresentationController?.sourceView = sender
vc.completionWithItemsHandler = { activityType, completed, returnedItems, error in
//Be annoying if user copies and we close the transfer process
if completed && activityType != UIActivityType.copyToPasteboard {
self.navigationController.dismiss(animated: true)
}
}
navigationController.present(vc, animated: true)
}
private func sellViaActivitySheet(ticketHolder: TicketHolder, linkExpiryDate: Date, ethCost: String, dollarCost: String, paymentFlow: PaymentFlow, in viewController: UIViewController) {
let url = generateSellLink(ticketHolder: ticketHolder, linkExpiryDate: linkExpiryDate, ethCost: ethCost, dollarCost: dollarCost, paymentFlow: paymentFlow)
let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil)
@ -289,22 +300,19 @@ class TicketsCoordinator: NSObject, Coordinator {
viewController.present(vc, animated: true)
}
private func transfer(ticketHolder: TicketHolder, to walletAddress: String, paymentFlow: PaymentFlow) {
UIAlertController.alert(title: "", message: R.string.localizable.aWalletTicketTokenTransferModeWalletAddressConfirmation(walletAddress), alertButtonTitles: [R.string.localizable.aWalletTicketTokenTransferButtonTitle(), R.string.localizable.cancel()], alertButtonStyles: [.default, .cancel], viewController: navigationController) {
guard $0 == 0 else { return }
//Defensive. Should already be checked before this
guard let address = Address(string: walletAddress) else {
return self.navigationController.displayError(error: Errors.invalidAddress)
}
if case .real(let account) = self.session.account.type {
let coordinator = TransferTicketsCoordinator(ticketHolder: ticketHolder, walletAddress: walletAddress, paymentFlow: paymentFlow, keystore: self.keystore, session: self.session, account: account, on: self.navigationController)
coordinator.delegate = self
coordinator.start()
self.addCoordinator(coordinator)
private func transferViaActivitySheet(ticketHolder: TicketHolder, linkExpiryDate: Date, paymentFlow: PaymentFlow, in viewController: UIViewController, sender: UIView) {
let url = generateTransferLink(ticketHolder: ticketHolder, paymentFlow: paymentFlow)
let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil)
vc.popoverPresentationController?.sourceView = sender
vc.completionWithItemsHandler = { activityType, completed, returnedItems, error in
//Be annoying if user copies and we close the transfer process
if completed && activityType != UIActivityType.copyToPasteboard {
self.navigationController.dismiss(animated: false) {
self.delegate?.didCancel(in: self)
}
}
}
viewController.present(vc, animated: true)
}
}
@ -390,21 +398,6 @@ extension TicketsCoordinator: SetSellTicketsExpiryDateViewControllerDelegate {
}
}
extension TicketsCoordinator: ChooseTicketTransferModeViewControllerDelegate {
func didChoose(transferMode: TicketTransferMode, in viewController: ChooseTicketTransferModeViewController, sender: UIView) {
let ticketHolder = viewController.ticketHolder
switch transferMode {
case .walletAddressTextEntry:
transferViaWalletAddressTextEntry(ticketHolder: ticketHolder, paymentFlow: viewController.paymentFlow)
case .walletAddressFromQRCode:
transferViaReadingWalletAddressFromQRCode(ticketHolder: ticketHolder, paymentFlow: viewController.paymentFlow)
case .other:
transferViaActivitySheet(ticketHolder: ticketHolder, paymentFlow: viewController.paymentFlow, sender: sender)
}
}
}
extension TicketsCoordinator: TransferTicketsViewControllerDelegate {
func didSelectTicketHolder(ticketHolder: TicketHolder, in viewController: TransferTicketsViewController) {
showQuantityViewController(for: ticketHolder, in: viewController)
@ -415,22 +408,6 @@ extension TicketsCoordinator: TransferTicketsViewControllerDelegate {
}
}
extension TicketsCoordinator: TransferTicketViaWalletAddressViewControllerDelegate {
func didChooseTransfer(to walletAddress: String, viewController: TransferTicketViaWalletAddressViewController) {
transfer(ticketHolder: viewController.ticketHolder, to: walletAddress, paymentFlow: viewController.paymentFlow)
}
}
extension TicketsCoordinator: ScanQRCodeForWalletAddressToTransferTicketCoordinatorDelegate {
func scanned(walletAddress: String, in coordinator: ScanQRCodeForWalletAddressToTransferTicketCoordinator) {
transfer(ticketHolder: coordinator.ticketHolder, to: walletAddress, paymentFlow: coordinator.paymentFlow)
}
func cancelled(in coordinator: ScanQRCodeForWalletAddressToTransferTicketCoordinator) {
//no-op
}
}
extension TicketsCoordinator: TransferTicketsCoordinatorDelegate {
private func cleanUpAfterTransfer(coordinator: TransferTicketsCoordinator) {
navigationController.dismiss(animated: true)
@ -459,3 +436,65 @@ extension TicketsCoordinator: GenerateSellMagicLinkViewControllerDelegate {
viewController.dismiss(animated: true)
}
}
extension TicketsCoordinator: ChooseTicketTransferModeViewControllerDelegate {
func didChooseTransferViaMagicLink(ticketHolder: TicketHolder, in viewController: ChooseTicketTransferModeViewController) {
let vc = makeEnterTransferTicketsExpiryDateViewController(for: ticketHolder, paymentFlow: viewController.paymentFlow)
viewController.navigationController?.pushViewController(vc, animated: true)
}
func didChooseTransferNow(ticketHolder: TicketHolder, in viewController: ChooseTicketTransferModeViewController) {
let vc = makeTransferTicketsViaWalletAddressViewController(for: ticketHolder, paymentFlow: viewController.paymentFlow)
viewController.navigationController?.pushViewController(vc, animated: true)
}
func didPressViewInfo(in viewController: ChooseTicketTransferModeViewController) {
delegate?.didPressViewRedemptionInfo(in: viewController)
}
}
extension TicketsCoordinator: SetTransferTicketsExpiryDateViewControllerDelegate {
func didPressNext(ticketHolder: TicketHolder, linkExpiryDate: Date, in viewController: SetTransferTicketsExpiryDateViewController) {
showTransferConfirmationScreen(for: ticketHolder, linkExpiryDate: linkExpiryDate, in: viewController)
}
func didPressViewInfo(in viewController: SetTransferTicketsExpiryDateViewController) {
delegate?.didPressViewRedemptionInfo(in: viewController)
}
}
extension TicketsCoordinator: GenerateTransferMagicLinkViewControllerDelegate {
func didPressShare(in viewController: GenerateTransferMagicLinkViewController, sender: UIView) {
transferViaActivitySheet(ticketHolder: viewController.ticketHolder, linkExpiryDate: viewController.linkExpiryDate, paymentFlow: viewController.paymentFlow, in: viewController, sender: sender)
}
func didPressCancel(in viewController: GenerateTransferMagicLinkViewController) {
viewController.dismiss(animated: true)
}
}
extension TicketsCoordinator: TransferTicketsViaWalletAddressViewControllerDelegate {
func didEnterWalletAddress(ticketHolder: TicketHolder, to walletAddress: String, paymentFlow: PaymentFlow, in viewController: TransferTicketsViaWalletAddressViewController) {
UIAlertController.alert(title: "", message: R.string.localizable.aWalletTicketTokenTransferModeWalletAddressConfirmation(walletAddress), alertButtonTitles: [R.string.localizable.aWalletTicketTokenTransferButtonTitle(), R.string.localizable.cancel()], alertButtonStyles: [.default, .cancel], viewController: navigationController) {
guard $0 == 0 else {
return
}
//Defensive. Should already be checked before this
guard let address = Address(string: walletAddress) else {
return self.navigationController.displayError(error: Errors.invalidAddress)
}
if case .real(let account) = self.session.account.type {
let coordinator = TransferTicketsCoordinator(ticketHolder: ticketHolder, walletAddress: walletAddress, paymentFlow: paymentFlow, keystore: self.keystore, session: self.session, account: account, on: self.navigationController)
coordinator.delegate = self
coordinator.start()
self.addCoordinator(coordinator)
}
}
}
func didPressViewInfo(in viewController: TransferTicketsViaWalletAddressViewController) {
delegate?.didPressViewEthereumInfo(in: viewController)
}
}

@ -1,103 +1,98 @@
// Copyright © 2018 Stormbird PTE. LTD.
import UIKit
import MessageUI
enum TicketTransferMode {
case walletAddressTextEntry
case walletAddressFromQRCode
case other
}
protocol ChooseTicketTransferModeViewControllerDelegate: class {
func didChoose(transferMode: TicketTransferMode, in viewController: ChooseTicketTransferModeViewController, sender: UIView)
func didChooseTransferViaMagicLink(ticketHolder: TicketHolder, in viewController: ChooseTicketTransferModeViewController)
func didChooseTransferNow(ticketHolder: TicketHolder, in viewController: ChooseTicketTransferModeViewController)
func didPressViewInfo(in viewController: ChooseTicketTransferModeViewController)
}
class ChooseTicketTransferModeViewController: UIViewController {
//roundedBackground is used to achieve the top 2 rounded corners-only effect since maskedCorners to not round bottom corners is not available in iOS 10
let roundedBackground = UIView()
let titleLabel = UILabel()
let inputWalletAddressButton = ShareModeButton()
let qrCodeScannerButton = ShareModeButton()
let otherButton = ShareModeButton()
let ticketHolder: TicketHolder
let header = TicketsViewControllerTitleHeader()
let ticketView = TicketRowView()
let generateMagicLinkButton = UIButton(type: .system)
let transferNowButton = UIButton(type: .system)
var viewModel: ChooseTicketTransferModeViewControllerViewModel!
var ticketHolder: TicketHolder
var paymentFlow: PaymentFlow
weak var delegate: ChooseTicketTransferModeViewControllerDelegate?
init(ticketHolder: TicketHolder, paymentFlow: PaymentFlow) {
self.ticketHolder = ticketHolder
self.paymentFlow = paymentFlow
super.init(nibName: nil, bundle: nil)
view.backgroundColor = Colors.appBackground
navigationItem.rightBarButtonItem = UIBarButtonItem(image: R.image.location(), style: .plain, target: self, action: #selector(showInfo))
roundedBackground.translatesAutoresizingMaskIntoConstraints = false
roundedBackground.backgroundColor = Colors.appWhite
roundedBackground.cornerRadius = 20
view.addSubview(roundedBackground)
inputWalletAddressButton.callback = {
self.delegate?.didChoose(transferMode: .walletAddressTextEntry, in: self, sender: self.inputWalletAddressButton)
}
inputWalletAddressButton.translatesAutoresizingMaskIntoConstraints = false
qrCodeScannerButton.callback = {
self.delegate?.didChoose(transferMode: .walletAddressFromQRCode, in: self, sender: self.qrCodeScannerButton)
}
qrCodeScannerButton.translatesAutoresizingMaskIntoConstraints = false
generateMagicLinkButton.setTitle(R.string.localizable.aWalletTicketTokenTransferModeMagicLinkButtonTitle(), for: .normal)
generateMagicLinkButton.addTarget(self, action: #selector(generateMagicLinkTapped), for: .touchUpInside)
otherButton.callback = {
self.delegate?.didChoose(transferMode: .other, in: self, sender: self.otherButton)
}
otherButton.translatesAutoresizingMaskIntoConstraints = false
transferNowButton.setTitle(R.string.localizable.aWalletTicketTokenTransferModeNowButtonTitle(), for: .normal)
transferNowButton.addTarget(self, action: #selector(transferNowTapped), for: .touchUpInside)
let buttonRow1 = UIStackView(arrangedSubviews: [
inputWalletAddressButton,
qrCodeScannerButton,
])
buttonRow1.translatesAutoresizingMaskIntoConstraints = false
buttonRow1.axis = .horizontal
buttonRow1.spacing = 12
buttonRow1.distribution = .fill
let buttonPlaceholder = UIView()
let buttonRow2 = UIStackView(arrangedSubviews: [
otherButton,
buttonPlaceholder,
])
buttonRow2.translatesAutoresizingMaskIntoConstraints = false
buttonRow2.axis = .horizontal
buttonRow2.spacing = 12
buttonRow2.distribution = .fill
ticketView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(ticketView)
let stackView = UIStackView(arrangedSubviews: [
.spacer(height: 7),
titleLabel,
.spacer(height: 20),
buttonRow1,
.spacer(height: 12),
buttonRow2,
header,
ticketView,
])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 0
stackView.distribution = .fill
stackView.alignment = .center
roundedBackground.addSubview(stackView)
let buttonsStackView = UIStackView(arrangedSubviews: [generateMagicLinkButton, transferNowButton])
buttonsStackView.translatesAutoresizingMaskIntoConstraints = false
buttonsStackView.axis = .horizontal
buttonsStackView.spacing = 0
buttonsStackView.distribution = .fillEqually
buttonsStackView.setContentHuggingPriority(.required, for: .horizontal)
let marginToHideBottomRoundedCorners = CGFloat(30)
let footerBar = UIView()
footerBar.translatesAutoresizingMaskIntoConstraints = false
footerBar.backgroundColor = Colors.appHighlightGreen
roundedBackground.addSubview(footerBar)
let buttonsHeight = CGFloat(60)
footerBar.addSubview(buttonsStackView)
NSLayoutConstraint.activate([
otherButton.widthAnchor.constraint(equalTo: inputWalletAddressButton.widthAnchor),
otherButton.heightAnchor.constraint(equalTo: inputWalletAddressButton.heightAnchor),
otherButton.widthAnchor.constraint(equalTo: buttonPlaceholder.widthAnchor),
otherButton.heightAnchor.constraint(equalTo: buttonPlaceholder.heightAnchor),
header.heightAnchor.constraint(equalToConstant: 90),
stackView.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor, constant: 30),
stackView.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor, constant: -30),
stackView.topAnchor.constraint(equalTo: roundedBackground.topAnchor, constant: 16),
ticketView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
ticketView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
roundedBackground.leadingAnchor.constraint(equalTo: view.leadingAnchor),
roundedBackground.trailingAnchor.constraint(equalTo: view.trailingAnchor),
roundedBackground.topAnchor.constraint(equalTo: view.topAnchor),
roundedBackground.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: marginToHideBottomRoundedCorners),
stackView.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor),
stackView.topAnchor.constraint(equalTo: roundedBackground.topAnchor),
buttonsStackView.leadingAnchor.constraint(equalTo: footerBar.leadingAnchor),
buttonsStackView.trailingAnchor.constraint(equalTo: footerBar.trailingAnchor),
buttonsStackView.topAnchor.constraint(equalTo: footerBar.topAnchor),
buttonsStackView.heightAnchor.constraint(equalToConstant: buttonsHeight),
footerBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
footerBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
footerBar.heightAnchor.constraint(equalToConstant: buttonsHeight),
footerBar.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
@ -105,38 +100,49 @@ class ChooseTicketTransferModeViewController: UIViewController {
fatalError("init(coder:) has not been implemented")
}
@objc func generateMagicLinkTapped() {
delegate?.didChooseTransferViaMagicLink(ticketHolder: ticketHolder, in: self)
}
@objc func transferNowTapped() {
delegate?.didChooseTransferNow(ticketHolder: ticketHolder, in: self)
}
@objc func showInfo() {
delegate?.didPressViewInfo(in: self)
}
func configure(viewModel: ChooseTicketTransferModeViewControllerViewModel) {
roundedBackground.backgroundColor = viewModel.contentsBackgroundColor
roundedBackground.layer.cornerRadius = 20
self.viewModel = viewModel
titleLabel.numberOfLines = 0
titleLabel.textColor = viewModel.titleColor
titleLabel.font = viewModel.titleFont
titleLabel.textAlignment = .center
titleLabel.text = viewModel.titleLabelText
view.backgroundColor = viewModel.backgroundColor
inputWalletAddressButton.title = viewModel.inputWalletAddressButtonTitle
inputWalletAddressButton.image = viewModel.inputWalletAddressButtonImage
header.configure(title: viewModel.headerTitle)
qrCodeScannerButton.title = viewModel.qrCodeScannerButtonTitle
qrCodeScannerButton.image = viewModel.qrCodeScannerButtonImage
ticketView.configure(viewModel: .init())
otherButton.title = viewModel.otherButtonTitle
otherButton.image = viewModel.otherButtonImage
ticketView.stateLabel.isHidden = true
inputWalletAddressButton.label.font = viewModel.buttonTitleFont
qrCodeScannerButton.label.font = viewModel.buttonTitleFont
otherButton.label.font = viewModel.buttonTitleFont
ticketView.ticketCountLabel.text = viewModel.ticketCount
inputWalletAddressButton.label.textColor = viewModel.buttonTitleColor
qrCodeScannerButton.label.textColor = viewModel.buttonTitleColor
otherButton.label.textColor = viewModel.buttonTitleColor
}
ticketView.titleLabel.text = viewModel.title
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
inputWalletAddressButton.layer.cornerRadius = inputWalletAddressButton.frame.size.height / 2
qrCodeScannerButton.layer.cornerRadius = qrCodeScannerButton.frame.size.height / 2
ticketView.venueLabel.text = viewModel.venue
ticketView.dateLabel.text = viewModel.date
ticketView.seatRangeLabel.text = viewModel.seatRange
ticketView.zoneNameLabel.text = viewModel.zoneName
generateMagicLinkButton.setTitleColor(viewModel.buttonTitleColor, for: .normal)
generateMagicLinkButton.backgroundColor = viewModel.buttonBackgroundColor
generateMagicLinkButton.titleLabel?.font = viewModel.buttonFont
//Hardcode position because text is very long compared to the transferNowButton
generateMagicLinkButton.titleEdgeInsets = .init(top: 0, left: 20, bottom: 0, right: 0)
transferNowButton.setTitleColor(viewModel.buttonTitleColor, for: .normal)
transferNowButton.backgroundColor = viewModel.buttonBackgroundColor
transferNowButton.titleLabel?.font = viewModel.buttonFont
}
}

@ -0,0 +1,159 @@
// Copyright © 2018 Stormbird PTE. LTD.
import Foundation
import UIKit
protocol GenerateTransferMagicLinkViewControllerDelegate: class {
func didPressShare(in viewController: GenerateTransferMagicLinkViewController, sender: UIView)
func didPressCancel(in viewController: GenerateTransferMagicLinkViewController)
}
class GenerateTransferMagicLinkViewController: UIViewController {
weak var delegate: GenerateTransferMagicLinkViewControllerDelegate?
let background = UIView()
let header = TicketsViewControllerTitleHeader()
let detailsBackground = UIView()
let subtitleLabel = UILabel()
let ticketCountLabel = UILabel()
let descriptionLabel = UILabel()
let actionButton = UIButton()
let cancelButton = UIButton()
var paymentFlow: PaymentFlow
var ticketHolder: TicketHolder
var linkExpiryDate: Date
var viewModel: GenerateTransferMagicLinkViewControllerViewModel?
init(paymentFlow: PaymentFlow, ticketHolder: TicketHolder, linkExpiryDate: Date) {
self.paymentFlow = paymentFlow
self.ticketHolder = ticketHolder
self.linkExpiryDate = linkExpiryDate
super.init(nibName: nil, bundle: nil)
view.backgroundColor = .clear
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
view.insertSubview(visualEffectView, at: 0)
view.addSubview(background)
background.translatesAutoresizingMaskIntoConstraints = false
ticketCountLabel.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
detailsBackground.translatesAutoresizingMaskIntoConstraints = false
background.addSubview(detailsBackground)
actionButton.addTarget(self, action: #selector(share), for: .touchUpInside)
cancelButton.addTarget(self, action: #selector(cancel), for: .touchUpInside)
let stackView = UIStackView(arrangedSubviews: [
header,
.spacer(height: 20),
subtitleLabel,
ticketCountLabel,
.spacer(height: 20),
descriptionLabel,
.spacer(height: 30),
actionButton,
.spacer(height: 10),
cancelButton,
.spacer(height: 1)
])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 0
stackView.distribution = .fill
background.addSubview(stackView)
NSLayoutConstraint.activate([
header.heightAnchor.constraint(equalToConstant: 60),
//Strange repositioning of header horizontally while typing without this
header.leadingAnchor.constraint(equalTo: stackView.leadingAnchor),
header.trailingAnchor.constraint(equalTo: stackView.trailingAnchor),
visualEffectView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
visualEffectView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
visualEffectView.topAnchor.constraint(equalTo: view.topAnchor),
visualEffectView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
detailsBackground.leadingAnchor.constraint(equalTo: background.leadingAnchor),
detailsBackground.trailingAnchor.constraint(equalTo: background.trailingAnchor),
detailsBackground.topAnchor.constraint(equalTo: subtitleLabel.topAnchor, constant: -12),
detailsBackground.bottomAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, constant: 12),
actionButton.heightAnchor.constraint(equalToConstant: 47),
cancelButton.heightAnchor.constraint(equalTo: actionButton.heightAnchor),
stackView.leadingAnchor.constraint(equalTo: background.leadingAnchor, constant: 40),
stackView.trailingAnchor.constraint(equalTo: background.trailingAnchor, constant: -40),
stackView.topAnchor.constraint(equalTo: background.topAnchor, constant: 16),
stackView.bottomAnchor.constraint(equalTo: background.bottomAnchor, constant: -16),
background.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 42),
background.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -42),
background.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(viewModel: GenerateTransferMagicLinkViewControllerViewModel) {
self.viewModel = viewModel
if let viewModel = self.viewModel {
background.backgroundColor = viewModel.contentsBackgroundColor
background.layer.cornerRadius = 20
header.configure(title: viewModel.headerTitle)
subtitleLabel.numberOfLines = 0
subtitleLabel.textColor = viewModel.subtitleColor
subtitleLabel.font = viewModel.subtitleFont
subtitleLabel.textAlignment = .center
subtitleLabel.text = viewModel.subtitleLabelText
ticketCountLabel.textAlignment = .center
ticketCountLabel.textColor = viewModel.ticketSaleDetailsLabelColor
ticketCountLabel.font = viewModel.ticketSaleDetailsLabelFont
ticketCountLabel.text = viewModel.ticketCountLabelText
descriptionLabel.textAlignment = .center
descriptionLabel.numberOfLines = 0
descriptionLabel.textColor = viewModel.ticketSaleDetailsLabelColor
descriptionLabel.font = viewModel.ticketSaleDetailsLabelFont
descriptionLabel.text = viewModel.descriptionLabelText
detailsBackground.backgroundColor = viewModel.detailsBackgroundBackgroundColor
actionButton.setTitleColor(viewModel.actionButtonTitleColor, for: .normal)
actionButton.setBackgroundColor(viewModel.actionButtonBackgroundColor, forState: .normal)
actionButton.titleLabel?.font = viewModel.actionButtonTitleFont
actionButton.setTitle(viewModel.actionButtonTitle, for: .normal)
actionButton.layer.masksToBounds = true
cancelButton.setTitleColor(viewModel.cancelButtonTitleColor, for: .normal)
cancelButton.setBackgroundColor(viewModel.cancelButtonBackgroundColor, forState: .normal)
cancelButton.titleLabel?.font = viewModel.cancelButtonTitleFont
cancelButton.setTitle(viewModel.cancelButtonTitle, for: .normal)
cancelButton.layer.masksToBounds = true
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
actionButton.layer.cornerRadius = actionButton.frame.size.height / 2
}
@objc func share() {
delegate?.didPressShare(in: self, sender: actionButton)
}
@objc func cancel() {
if let delegate = delegate {
delegate.didPressCancel(in: self)
} else {
dismiss(animated: true)
}
}
}

@ -0,0 +1,336 @@
// Copyright © 2018 Stormbird PTE. LTD.
import UIKit
protocol SetTransferTicketsExpiryDateViewControllerDelegate: class {
func didPressNext(ticketHolder: TicketHolder, linkExpiryDate: Date, in viewController: SetTransferTicketsExpiryDateViewController)
func didPressViewInfo(in viewController: SetTransferTicketsExpiryDateViewController)
}
class SetTransferTicketsExpiryDateViewController: UIViewController {
//roundedBackground is used to achieve the top 2 rounded corners-only effect since maskedCorners to not round bottom corners is not available in iOS 10
let roundedBackground = UIView()
let scrollView = UIScrollView()
let header = TicketsViewControllerTitleHeader()
let ticketView = TicketRowView()
let linkExpiryDateLabel = UILabel()
let linkExpiryDateField = DateEntryField()
let linkExpiryTimeLabel = UILabel()
let linkExpiryTimeField = TimeEntryField()
var datePicker = UIDatePicker()
var timePicker = UIDatePicker()
let descriptionLabel = UILabel()
let noteTitleLabel = UILabel()
let noteLabel = UILabel()
let noteBorderView = UIView()
let nextButton = UIButton(type: .system)
var viewModel: SetTransferTicketsExpiryDateViewControllerViewModel!
var ticketHolder: TicketHolder
var paymentFlow: PaymentFlow
weak var delegate: SetTransferTicketsExpiryDateViewControllerDelegate?
init(ticketHolder: TicketHolder, paymentFlow: PaymentFlow) {
self.ticketHolder = ticketHolder
self.paymentFlow = paymentFlow
super.init(nibName: nil, bundle: nil)
navigationItem.rightBarButtonItem = UIBarButtonItem(image: R.image.location(), style: .plain, target: self, action: #selector(showInfo))
roundedBackground.translatesAutoresizingMaskIntoConstraints = false
roundedBackground.backgroundColor = Colors.appWhite
roundedBackground.cornerRadius = 20
view.addSubview(roundedBackground)
scrollView.translatesAutoresizingMaskIntoConstraints = false
roundedBackground.addSubview(scrollView)
linkExpiryDateLabel.translatesAutoresizingMaskIntoConstraints = false
linkExpiryTimeLabel.translatesAutoresizingMaskIntoConstraints = false
nextButton.setTitle(R.string.localizable.aWalletNextButtonTitle(), for: .normal)
nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
ticketView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(ticketView)
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
noteTitleLabel.translatesAutoresizingMaskIntoConstraints = false
noteLabel.translatesAutoresizingMaskIntoConstraints = false
noteBorderView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(noteBorderView)
let col0 = UIStackView(arrangedSubviews: [
linkExpiryDateLabel,
.spacer(height: 4),
linkExpiryDateField,
])
col0.translatesAutoresizingMaskIntoConstraints = false
col0.axis = .vertical
col0.spacing = 0
col0.distribution = .fill
let col1 = UIStackView(arrangedSubviews: [
linkExpiryTimeLabel,
.spacer(height: 4),
linkExpiryTimeField,
])
col1.translatesAutoresizingMaskIntoConstraints = false
col1.axis = .vertical
col1.spacing = 0
col1.distribution = .fill
let choicesStackView = UIStackView(arrangedSubviews: [
col0,
.spacerWidth(10),
col1,
])
choicesStackView.translatesAutoresizingMaskIntoConstraints = false
choicesStackView.axis = .horizontal
choicesStackView.spacing = 0
choicesStackView.distribution = .fill
let noteStackView = UIStackView(arrangedSubviews: [
noteTitleLabel,
.spacer(height: 4),
noteLabel,
])
noteStackView.translatesAutoresizingMaskIntoConstraints = false
noteStackView.axis = .vertical
noteStackView.spacing = 0
noteStackView.distribution = .fill
noteBorderView.addSubview(noteStackView)
datePicker.datePickerMode = .date
datePicker.minimumDate = Date()
datePicker.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)
datePicker.isHidden = true
timePicker.datePickerMode = .time
timePicker.minimumDate = Date.yesterday
timePicker.addTarget(self, action: #selector(timePickerValueChanged), for: .valueChanged)
timePicker.isHidden = true
let stackView = UIStackView(arrangedSubviews: [
header,
ticketView,
.spacer(height: 18),
descriptionLabel,
.spacer(height: 18),
choicesStackView,
datePicker,
timePicker,
.spacer(height: 10),
noteBorderView,
])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 0
stackView.distribution = .fill
stackView.alignment = .center
scrollView.addSubview(stackView)
linkExpiryDateField.translatesAutoresizingMaskIntoConstraints = false
linkExpiryDateField.value = Date.tomorrow
linkExpiryDateField.delegate = self
linkExpiryTimeField.translatesAutoresizingMaskIntoConstraints = false
linkExpiryTimeField.delegate = self
let buttonsStackView = UIStackView(arrangedSubviews: [nextButton])
buttonsStackView.translatesAutoresizingMaskIntoConstraints = false
buttonsStackView.axis = .horizontal
buttonsStackView.spacing = 0
buttonsStackView.distribution = .fillEqually
buttonsStackView.setContentHuggingPriority(.required, for: .horizontal)
let marginToHideBottomRoundedCorners = CGFloat(30)
let footerBar = UIView()
footerBar.translatesAutoresizingMaskIntoConstraints = false
footerBar.backgroundColor = Colors.appHighlightGreen
roundedBackground.addSubview(footerBar)
let buttonsHeight = CGFloat(60)
footerBar.addSubview(buttonsStackView)
NSLayoutConstraint.activate([
header.heightAnchor.constraint(equalToConstant: 90),
ticketView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
ticketView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
roundedBackground.leadingAnchor.constraint(equalTo: view.leadingAnchor),
roundedBackground.trailingAnchor.constraint(equalTo: view.trailingAnchor),
roundedBackground.topAnchor.constraint(equalTo: view.topAnchor),
roundedBackground.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: marginToHideBottomRoundedCorners),
linkExpiryDateField.leadingAnchor.constraint(equalTo: ticketView.background.leadingAnchor),
linkExpiryTimeField.rightAnchor.constraint(equalTo: ticketView.background.rightAnchor),
linkExpiryDateField.heightAnchor.constraint(equalToConstant: 50),
linkExpiryDateField.widthAnchor.constraint(equalTo: linkExpiryTimeField.widthAnchor),
linkExpiryDateField.heightAnchor.constraint(equalTo: linkExpiryTimeField.heightAnchor),
datePicker.leadingAnchor.constraint(equalTo: ticketView.background.leadingAnchor),
datePicker.trailingAnchor.constraint(equalTo: ticketView.background.trailingAnchor),
timePicker.leadingAnchor.constraint(equalTo: ticketView.background.leadingAnchor),
timePicker.trailingAnchor.constraint(equalTo: ticketView.background.trailingAnchor),
noteBorderView.leadingAnchor.constraint(equalTo: ticketView.background.leadingAnchor),
noteBorderView.trailingAnchor.constraint(equalTo: ticketView.background.trailingAnchor),
noteStackView.leadingAnchor.constraint(equalTo: noteBorderView.leadingAnchor, constant: 10),
noteStackView.trailingAnchor.constraint(equalTo: noteBorderView.trailingAnchor, constant: -10),
noteStackView.topAnchor.constraint(equalTo: noteBorderView.topAnchor, constant: 10),
noteStackView.bottomAnchor.constraint(equalTo: noteBorderView.bottomAnchor, constant: -10),
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
buttonsStackView.leadingAnchor.constraint(equalTo: footerBar.leadingAnchor),
buttonsStackView.trailingAnchor.constraint(equalTo: footerBar.trailingAnchor),
buttonsStackView.topAnchor.constraint(equalTo: footerBar.topAnchor),
buttonsStackView.heightAnchor.constraint(equalToConstant: buttonsHeight),
footerBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
footerBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
footerBar.heightAnchor.constraint(equalToConstant: buttonsHeight),
footerBar.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: footerBar.topAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func nextButtonTapped() {
let expiryDate = linkExpiryDate()
guard expiryDate > Date() else {
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenTransferLinkExpiryTimeAtLeastNowTitle(),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,
completion: nil)
return
}
delegate?.didPressNext(ticketHolder: ticketHolder, linkExpiryDate: expiryDate, in: self)
}
private func linkExpiryDate() -> Date {
let hour = NSCalendar.current.component(.hour, from: linkExpiryTimeField.value)
let minutes = NSCalendar.current.component(.minute, from: linkExpiryTimeField.value)
let seconds = NSCalendar.current.component(.second, from: linkExpiryTimeField.value)
if let date = NSCalendar.current.date(bySettingHour: hour, minute: minutes, second: seconds, of: linkExpiryDateField.value) {
return date
} else {
return Date()
}
}
@objc func showInfo() {
delegate?.didPressViewInfo(in: self)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
linkExpiryDateField.layer.cornerRadius = linkExpiryDateField.frame.size.height / 2
linkExpiryTimeField.layer.cornerRadius = linkExpiryTimeField.frame.size.height / 2
}
@objc func datePickerValueChanged() {
linkExpiryDateField.value = datePicker.date
}
@objc func timePickerValueChanged() {
linkExpiryTimeField.value = timePicker.date
}
func configure(viewModel: SetTransferTicketsExpiryDateViewControllerViewModel) {
self.viewModel = viewModel
view.backgroundColor = viewModel.backgroundColor
header.configure(title: viewModel.headerTitle)
ticketView.configure(viewModel: .init())
linkExpiryDateLabel.textAlignment = .center
linkExpiryDateLabel.textColor = viewModel.choiceLabelColor
linkExpiryDateLabel.font = viewModel.choiceLabelFont
linkExpiryDateLabel.text = viewModel.linkExpiryDateLabelText
linkExpiryTimeLabel.textAlignment = .center
linkExpiryTimeLabel.textColor = viewModel.choiceLabelColor
linkExpiryTimeLabel.font = viewModel.choiceLabelFont
linkExpiryTimeLabel.text = viewModel.linkExpiryTimeLabelText
ticketView.stateLabel.isHidden = true
ticketView.ticketCountLabel.text = viewModel.ticketCount
ticketView.titleLabel.text = viewModel.title
ticketView.venueLabel.text = viewModel.venue
ticketView.dateLabel.text = viewModel.date
ticketView.seatRangeLabel.text = viewModel.seatRange
ticketView.zoneNameLabel.text = viewModel.zoneName
descriptionLabel.textAlignment = .center
descriptionLabel.numberOfLines = 0
descriptionLabel.textColor = viewModel.descriptionLabelColor
descriptionLabel.font = viewModel.descriptionLabelFont
descriptionLabel.text = viewModel.descriptionLabelText
noteTitleLabel.textAlignment = .center
noteTitleLabel.textColor = viewModel.noteTitleLabelColor
noteTitleLabel.font = viewModel.noteTitleLabelFont
noteTitleLabel.text = viewModel.noteTitleLabelText
noteLabel.textAlignment = .center
noteLabel.numberOfLines = 0
noteLabel.textColor = viewModel.noteLabelColor
noteLabel.font = viewModel.noteLabelFont
noteLabel.text = viewModel.noteLabelText
noteBorderView.layer.cornerRadius = 20
noteBorderView.layer.borderColor = viewModel.noteBorderColor.cgColor
noteBorderView.layer.borderWidth = 1
nextButton.setTitleColor(viewModel.buttonTitleColor, for: .normal)
nextButton.backgroundColor = viewModel.buttonBackgroundColor
nextButton.titleLabel?.font = viewModel.buttonFont
}
}
extension SetTransferTicketsExpiryDateViewController: DateEntryFieldDelegate {
func didTap(in dateEntryField: DateEntryField) {
datePicker.isHidden = !datePicker.isHidden
if !datePicker.isHidden {
datePicker.date = linkExpiryDateField.value
timePicker.isHidden = true
}
}
}
extension SetTransferTicketsExpiryDateViewController: TimeEntryFieldDelegate {
func didTap(in timeEntryField: TimeEntryField) {
timePicker.isHidden = !timePicker.isHidden
if !timePicker.isHidden {
timePicker.date = linkExpiryTimeField.value
datePicker.isHidden = true
}
}
}

@ -1,159 +0,0 @@
// Copyright © 2018 Stormbird PTE. LTD.
import UIKit
import TrustKeystore
protocol TransferTicketViaWalletAddressViewControllerDelegate: class {
func didChooseTransfer(to walletAddress: String, viewController: TransferTicketViaWalletAddressViewController)
}
class TransferTicketViaWalletAddressViewController: UIViewController {
//roundedBackground is used to achieve the top 2 rounded corners-only effect since maskedCorners to not round bottom corners is not available in iOS 10
let roundedBackground = UIView()
let titleLabel = UILabel()
let subtitleLabel = UILabel()
let textField = UITextField()
let ticketView = TicketRowView()
let actionButton = UIButton(type: .system)
var paymentFlow: PaymentFlow
weak var delegate: TransferTicketViaWalletAddressViewControllerDelegate?
let ticketHolder: TicketHolder
init(ticketHolder: TicketHolder, paymentFlow: PaymentFlow) {
self.ticketHolder = ticketHolder
self.paymentFlow = paymentFlow
super.init(nibName: nil, bundle: nil)
view.backgroundColor = Colors.appBackground
roundedBackground.translatesAutoresizingMaskIntoConstraints = false
roundedBackground.cornerRadius = 20
view.addSubview(roundedBackground)
textField.translatesAutoresizingMaskIntoConstraints = false
textField.delegate = self
textField.returnKeyType = .done
actionButton.translatesAutoresizingMaskIntoConstraints = false
actionButton.addTarget(self, action: #selector(transfer), for: .touchUpInside)
roundedBackground.addSubview(actionButton)
ticketView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(ticketView)
let stackView = UIStackView(arrangedSubviews: [
.spacer(height: 7),
titleLabel,
.spacer(height: 20),
subtitleLabel,
.spacer(height: 10),
textField,
.spacer(height: 40),
ticketView,
])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 0
stackView.distribution = .fill
stackView.alignment = .center
roundedBackground.addSubview(stackView)
let marginToHideBottomRoundedCorners = CGFloat(30)
NSLayoutConstraint.activate([
textField.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor, constant: 30),
textField.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor, constant: -30),
textField.heightAnchor.constraint(equalToConstant: 50),
ticketView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
ticketView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
stackView.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor),
stackView.topAnchor.constraint(equalTo: roundedBackground.topAnchor, constant: 16),
actionButton.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor),
actionButton.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor),
actionButton.heightAnchor.constraint(equalToConstant: 60),
actionButton.bottomAnchor.constraint(equalTo: roundedBackground.bottomAnchor, constant: -marginToHideBottomRoundedCorners),
roundedBackground.leadingAnchor.constraint(equalTo: view.leadingAnchor),
roundedBackground.trailingAnchor.constraint(equalTo: view.trailingAnchor),
roundedBackground.topAnchor.constraint(equalTo: view.topAnchor),
roundedBackground.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: marginToHideBottomRoundedCorners),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(viewModel: TransferTicketViaWalletAddressViewControllerViewModel) {
roundedBackground.backgroundColor = viewModel.contentsBackgroundColor
roundedBackground.layer.cornerRadius = 20
titleLabel.numberOfLines = 0
titleLabel.textColor = viewModel.titleColor
titleLabel.font = viewModel.titleFont
titleLabel.textAlignment = .center
titleLabel.text = viewModel.titleLabelText
subtitleLabel.textColor = viewModel.subtitleColor
subtitleLabel.font = viewModel.subtitleFont
subtitleLabel.textAlignment = .center
subtitleLabel.text = viewModel.subtitleLabelText
textField.textColor = viewModel.textFieldTextColor
textField.font = viewModel.textFieldFont
textField.layer.borderColor = viewModel.textFieldBorderColor.cgColor
textField.layer.borderWidth = viewModel.textFieldBorderWidth
textField.leftView = .spacerWidth(viewModel.textFieldHorizontalPadding)
textField.leftViewMode = .always
textField.rightView = .spacerWidth(viewModel.textFieldHorizontalPadding)
textField.rightViewMode = .always
ticketView.configure(viewModel: .init())
ticketView.stateLabel.isHidden = true
ticketView.ticketCountLabel.text = viewModel.ticketCount
ticketView.titleLabel.text = viewModel.title
ticketView.venueLabel.text = viewModel.venue
ticketView.dateLabel.text = viewModel.date
ticketView.seatRangeLabel.text = viewModel.seatRange
ticketView.zoneNameLabel.text = viewModel.zoneName
actionButton.setTitle(viewModel.actionButtonTitle, for: .normal)
actionButton.setTitleColor(viewModel.actionButtonTitleColor, for: .normal)
actionButton.setBackgroundColor(viewModel.actionButtonBackgroundColor, forState: .normal)
actionButton.titleLabel?.font = viewModel.actionButtonTitleFont
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
actionButton.layer.cornerRadius = actionButton.frame.size.height / 2
textField.layer.cornerRadius = textField.frame.size.height / 2
}
@objc func transfer() {
if let address = textField.text, !address.isEmpty {
guard let _ = Address(string: address) else {
displayError(error: Errors.invalidAddress)
return
}
delegate?.didChooseTransfer(to: address, viewController: self)
}
}
}
extension TransferTicketViaWalletAddressViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}

@ -0,0 +1,185 @@
// Copyright © 2018 Stormbird PTE. LTD.
import UIKit
protocol TransferTicketsChooseTransferModeViewControllerDelegate: class {
func didSelectQuantity(ticketHolder: TicketHolder, in viewController: TransferTicketsChooseTransferModeViewController)
func didPressViewInfo(in viewController: TransferTicketsChooseTransferModeViewController)
}
class TransferTicketsChooseTransferModeViewController: UIViewController {
//roundedBackground is used to achieve the top 2 rounded corners-only effect since maskedCorners to not round bottom corners is not available in iOS 10
let roundedBackground = UIView()
let header = TicketsViewControllerTitleHeader()
let subtitleLabel = UILabel()
var quantityStepper = NumberStepper()
let ticketView = TicketRowView()
let nextButton = UIButton(type: .system)
var viewModel: TransferTicketsChooseTransferModeViewControllerViewModel!
var paymentFlow: PaymentFlow
weak var delegate: TransferTicketsChooseTransferModeViewControllerDelegate?
init(paymentFlow: PaymentFlow) {
self.paymentFlow = paymentFlow
super.init(nibName: nil, bundle: nil)
navigationItem.rightBarButtonItem = UIBarButtonItem(image: R.image.location(), style: .plain, target: self, action: #selector(showInfo))
roundedBackground.translatesAutoresizingMaskIntoConstraints = false
roundedBackground.backgroundColor = Colors.appWhite
roundedBackground.cornerRadius = 20
view.addSubview(roundedBackground)
subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
nextButton.setTitle(R.string.localizable.aWalletNextButtonTitle(), for: .normal)
nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
ticketView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(ticketView)
quantityStepper.translatesAutoresizingMaskIntoConstraints = false
quantityStepper.minimumValue = 1
quantityStepper.value = 1
view.addSubview(quantityStepper)
let stackView = UIStackView(arrangedSubviews: [
header,
ticketView,
.spacer(height: 20),
subtitleLabel,
.spacer(height: 4),
quantityStepper,
])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 0
stackView.distribution = .fill
stackView.alignment = .center
roundedBackground.addSubview(stackView)
let buttonsStackView = UIStackView(arrangedSubviews: [nextButton])
buttonsStackView.translatesAutoresizingMaskIntoConstraints = false
buttonsStackView.axis = .horizontal
buttonsStackView.spacing = 0
buttonsStackView.distribution = .fillEqually
buttonsStackView.setContentHuggingPriority(.required, for: .horizontal)
let marginToHideBottomRoundedCorners = CGFloat(30)
let footerBar = UIView()
footerBar.translatesAutoresizingMaskIntoConstraints = false
footerBar.backgroundColor = Colors.appHighlightGreen
roundedBackground.addSubview(footerBar)
let buttonsHeight = CGFloat(60)
footerBar.addSubview(buttonsStackView)
NSLayoutConstraint.activate([
header.heightAnchor.constraint(equalToConstant: 90),
quantityStepper.heightAnchor.constraint(equalToConstant: 50),
ticketView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
ticketView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
roundedBackground.leadingAnchor.constraint(equalTo: view.leadingAnchor),
roundedBackground.trailingAnchor.constraint(equalTo: view.trailingAnchor),
roundedBackground.topAnchor.constraint(equalTo: view.topAnchor),
roundedBackground.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: marginToHideBottomRoundedCorners),
stackView.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor),
stackView.topAnchor.constraint(equalTo: roundedBackground.topAnchor),
buttonsStackView.leadingAnchor.constraint(equalTo: footerBar.leadingAnchor),
buttonsStackView.trailingAnchor.constraint(equalTo: footerBar.trailingAnchor),
buttonsStackView.topAnchor.constraint(equalTo: footerBar.topAnchor),
buttonsStackView.heightAnchor.constraint(equalToConstant: buttonsHeight),
footerBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
footerBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
footerBar.heightAnchor.constraint(equalToConstant: buttonsHeight),
footerBar.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc
func nextButtonTapped() {
if quantityStepper.value == 0 {
UIAlertController.alert(title: "",
message: R.string.localizable.aWalletTicketTokenTransferSelectTicketQuantityAtLeastOneTitle(),
alertButtonTitles: [R.string.localizable.oK()],
alertButtonStyles: [.cancel],
viewController: self,
completion: nil)
} else {
delegate?.didSelectQuantity(ticketHolder: getTicketHolderFromQuantity(), in: self)
}
}
@objc func showInfo() {
delegate?.didPressViewInfo(in: self)
}
func configure(viewModel: TransferTicketsChooseTransferModeViewControllerViewModel) {
self.viewModel = viewModel
view.backgroundColor = viewModel.backgroundColor
header.configure(title: viewModel.headerTitle)
subtitleLabel.textAlignment = .center
subtitleLabel.textColor = viewModel.subtitleColor
subtitleLabel.font = viewModel.subtitleFont
subtitleLabel.text = viewModel.subtitleText
ticketView.configure(viewModel: .init())
quantityStepper.borderWidth = 2
quantityStepper.clipsToBounds = true
quantityStepper.borderColor = viewModel.stepperBorderColor
quantityStepper.maximumValue = viewModel.maxValue
ticketView.stateLabel.isHidden = true
ticketView.ticketCountLabel.text = viewModel.ticketCount
ticketView.titleLabel.text = viewModel.title
ticketView.venueLabel.text = viewModel.venue
ticketView.dateLabel.text = viewModel.date
ticketView.seatRangeLabel.text = viewModel.seatRange
ticketView.zoneNameLabel.text = viewModel.zoneName
nextButton.setTitleColor(viewModel.buttonTitleColor, for: .normal)
nextButton.backgroundColor = viewModel.buttonBackgroundColor
nextButton.titleLabel?.font = viewModel.buttonFont
}
private func getTicketHolderFromQuantity() -> TicketHolder {
let quantity = quantityStepper.value
let ticketHolder = viewModel.ticketHolder
let tickets = Array(ticketHolder.tickets[..<quantity])
return TicketHolder(
tickets: tickets,
zone: ticketHolder.zone,
name: ticketHolder.name,
venue: ticketHolder.venue,
date: ticketHolder.date,
status: ticketHolder.status
)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
quantityStepper.layer.cornerRadius = quantityStepper.frame.size.height / 2
}
}

@ -33,7 +33,7 @@ class TransferTicketsQuantitySelectionViewController: UIViewController {
subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
nextButton.setTitle(R.string.localizable.aWalletTicketTokenTransferButtonTitle(), for: .normal)
nextButton.setTitle(R.string.localizable.aWalletNextButtonTitle(), for: .normal)
nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
ticketView.translatesAutoresizingMaskIntoConstraints = false
@ -46,11 +46,11 @@ class TransferTicketsQuantitySelectionViewController: UIViewController {
let stackView = UIStackView(arrangedSubviews: [
header,
ticketView,
.spacer(height: 20),
subtitleLabel,
.spacer(height: 4),
quantityStepper,
.spacer(height: 50),
ticketView,
])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical

@ -0,0 +1,242 @@
// Copyright © 2018 Stormbird PTE. LTD.
import UIKit
import QRCodeReaderViewController
protocol TransferTicketsViaWalletAddressViewControllerDelegate: class {
func didEnterWalletAddress(ticketHolder: TicketHolder, to walletAddress: String, paymentFlow: PaymentFlow, in viewController: TransferTicketsViaWalletAddressViewController)
func didPressViewInfo(in viewController: TransferTicketsViaWalletAddressViewController)
}
class TransferTicketsViaWalletAddressViewController: UIViewController {
//roundedBackground is used to achieve the top 2 rounded corners-only effect since maskedCorners to not round bottom corners is not available in iOS 10
let roundedBackground = UIView()
let header = TicketsViewControllerTitleHeader()
let ticketView = TicketRowView()
let targetAddressLabel = UILabel()
let targetAddressTextField = UITextField()
let nextButton = UIButton(type: .system)
var viewModel: TransferTicketsViaWalletAddressViewControllerViewModel!
var ticketHolder: TicketHolder
var paymentFlow: PaymentFlow
weak var delegate: TransferTicketsViaWalletAddressViewControllerDelegate?
init(ticketHolder: TicketHolder, paymentFlow: PaymentFlow) {
self.ticketHolder = ticketHolder
self.paymentFlow = paymentFlow
super.init(nibName: nil, bundle: nil)
navigationItem.rightBarButtonItem = UIBarButtonItem(image: R.image.location(), style: .plain, target: self, action: #selector(showInfo))
roundedBackground.translatesAutoresizingMaskIntoConstraints = false
roundedBackground.backgroundColor = Colors.appWhite
roundedBackground.cornerRadius = 20
view.addSubview(roundedBackground)
targetAddressTextField.translatesAutoresizingMaskIntoConstraints = false
targetAddressTextField.delegate = self
targetAddressTextField.returnKeyType = .done
targetAddressTextField.leftViewMode = .always
targetAddressTextField.rightViewMode = .always
nextButton.setTitle(R.string.localizable.aWalletNextButtonTitle(), for: .normal)
nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
ticketView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(ticketView)
let stackView = UIStackView(arrangedSubviews: [
header,
ticketView,
.spacer(height: 10),
targetAddressLabel,
.spacer(height: ScreenChecker().isNarrowScreen() ? 2 : 4),
targetAddressTextField,
])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 0
stackView.distribution = .fill
stackView.alignment = .center
roundedBackground.addSubview(stackView)
let buttonsStackView = UIStackView(arrangedSubviews: [nextButton])
buttonsStackView.translatesAutoresizingMaskIntoConstraints = false
buttonsStackView.axis = .horizontal
buttonsStackView.spacing = 0
buttonsStackView.distribution = .fillEqually
buttonsStackView.setContentHuggingPriority(.required, for: .horizontal)
let marginToHideBottomRoundedCorners = CGFloat(30)
let footerBar = UIView()
footerBar.translatesAutoresizingMaskIntoConstraints = false
footerBar.backgroundColor = Colors.appHighlightGreen
roundedBackground.addSubview(footerBar)
let buttonsHeight = CGFloat(60)
footerBar.addSubview(buttonsStackView)
NSLayoutConstraint.activate([
header.heightAnchor.constraint(equalToConstant: 90),
ticketView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
ticketView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
targetAddressTextField.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor, constant: 30),
targetAddressTextField.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor, constant: -30),
targetAddressTextField.heightAnchor.constraint(equalToConstant: ScreenChecker().isNarrowScreen() ? 30 : 50),
roundedBackground.leadingAnchor.constraint(equalTo: view.leadingAnchor),
roundedBackground.trailingAnchor.constraint(equalTo: view.trailingAnchor),
roundedBackground.topAnchor.constraint(equalTo: view.topAnchor),
roundedBackground.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: marginToHideBottomRoundedCorners),
stackView.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor),
stackView.topAnchor.constraint(equalTo: roundedBackground.topAnchor),
buttonsStackView.leadingAnchor.constraint(equalTo: footerBar.leadingAnchor),
buttonsStackView.trailingAnchor.constraint(equalTo: footerBar.trailingAnchor),
buttonsStackView.topAnchor.constraint(equalTo: footerBar.topAnchor),
buttonsStackView.heightAnchor.constraint(equalToConstant: buttonsHeight),
footerBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
footerBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
footerBar.heightAnchor.constraint(equalToConstant: buttonsHeight),
footerBar.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func nextButtonTapped() {
let address = targetAddressTextField.text?.trimmed ?? ""
delegate?.didEnterWalletAddress(ticketHolder: ticketHolder, to: address, paymentFlow: paymentFlow, in: self)
}
@objc func showInfo() {
delegate?.didPressViewInfo(in: self)
}
func configure(viewModel: TransferTicketsViaWalletAddressViewControllerViewModel) {
let firstConfigure = self.viewModel == nil
self.viewModel = viewModel
if firstConfigure {
targetAddressTextField.leftView = .spacerWidth(viewModel.textFieldHorizontalPadding)
targetAddressTextField.rightView = makeTargetAddressRightView()
}
view.backgroundColor = viewModel.backgroundColor
header.configure(title: viewModel.headerTitle)
ticketView.configure(viewModel: .init())
ticketView.stateLabel.isHidden = true
ticketView.ticketCountLabel.text = viewModel.ticketCount
ticketView.titleLabel.text = viewModel.title
ticketView.venueLabel.text = viewModel.venue
ticketView.dateLabel.text = viewModel.date
ticketView.seatRangeLabel.text = viewModel.seatRange
ticketView.zoneNameLabel.text = viewModel.zoneName
targetAddressTextField.textColor = viewModel.textFieldTextColor
targetAddressTextField.font = viewModel.textFieldFont
targetAddressTextField.layer.borderColor = viewModel.textFieldBorderColor.cgColor
targetAddressTextField.layer.borderWidth = viewModel.textFieldBorderWidth
targetAddressLabel.text = R.string.localizable.aSendRecipientAddressTitle()
targetAddressLabel.font = viewModel.textFieldsLabelFont
targetAddressLabel.textColor = viewModel.textFieldsLabelTextColor
nextButton.setTitleColor(viewModel.buttonTitleColor, for: .normal)
nextButton.backgroundColor = viewModel.buttonBackgroundColor
nextButton.titleLabel?.font = viewModel.buttonFont
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
roundCornersBasedOnHeight()
}
private func roundCornersBasedOnHeight() {
targetAddressTextField.layer.cornerRadius = targetAddressTextField.frame.size.height / 2
}
@objc func openReader() {
let controller = QRCodeReaderViewController()
controller.delegate = self
present(controller, animated: true, completion: nil)
}
@objc func pasteAction() {
guard let value = UIPasteboard.general.string?.trimmed else {
return displayError(error: SendInputErrors.emptyClipBoard)
}
guard CryptoAddressValidator.isValidAddress(value) else {
return displayError(error: Errors.invalidAddress)
}
targetAddressTextField.text = value
}
private func makeTargetAddressRightView() -> UIView {
let pasteButton = Button(size: .normal, style: .borderless)
pasteButton.translatesAutoresizingMaskIntoConstraints = false
pasteButton.setTitle(R.string.localizable.sendPasteButtonTitle(), for: .normal)
pasteButton.titleLabel?.font = Fonts.regular(size: 14)!
pasteButton.setTitleColor(UIColor(red: 155, green: 155, blue: 155), for: .normal)
pasteButton.addTarget(self, action: #selector(pasteAction), for: .touchUpInside)
let scanQRCodeButton = Button(size: .normal, style: .borderless)
scanQRCodeButton.translatesAutoresizingMaskIntoConstraints = false
scanQRCodeButton.setImage(R.image.qr_code_icon(), for: .normal)
scanQRCodeButton.setTitleColor(UIColor(red: 155, green: 155, blue: 155), for: .normal)
scanQRCodeButton.addTarget(self, action: #selector(openReader), for: .touchUpInside)
let targetAddressRightView = UIStackView(arrangedSubviews: [
pasteButton,
scanQRCodeButton,
])
targetAddressRightView.translatesAutoresizingMaskIntoConstraints = false
targetAddressRightView.distribution = .equalSpacing
targetAddressRightView.spacing = 0
targetAddressRightView.axis = .horizontal
return targetAddressRightView
}
}
extension TransferTicketsViaWalletAddressViewController: QRCodeReaderDelegate {
func readerDidCancel(_ reader: QRCodeReaderViewController!) {
reader.stopScanning()
reader.dismiss(animated: true, completion: nil)
}
func reader(_ reader: QRCodeReaderViewController!, didScanResult result: String!) {
reader.stopScanning()
reader.dismiss(animated: true)
guard let result = QRURLParser.from(string: result) else {
return
}
targetAddressTextField.text = result.address
}
}
extension TransferTicketsViaWalletAddressViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
view.endEditing(true)
return true
}
}

@ -1,58 +1,58 @@
// Copyright © 2018 Stormbird PTE. LTD.
import Foundation
import UIKit
class ChooseTicketTransferModeViewControllerViewModel {
var contentsBackgroundColor: UIColor {
return Colors.appWhite
}
var titleColor: UIColor {
return Colors.appText
}
var titleFont: UIFont {
return Fonts.light(size: 25)!
}
var titleLabelText: String {
return R.string.localizable.aWalletTicketTokenTransferModeChooseTitle()
}
var textButtonTitle: String {
return R.string.localizable.aWalletTicketTokenTransferModeChooseTextTitle()
}
var textButtonImage: UIImage? {
return R.image.transfer_text()
struct ChooseTicketTransferModeViewControllerViewModel {
var ticketHolder: TicketHolder
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle()
}
var emailButtonTitle: String {
return R.string.localizable.aWalletTicketTokenTransferModeChooseEmailTitle()
var backgroundColor: UIColor {
return Colors.appBackground
}
var emailButtonImage: UIImage? {
return R.image.transfer_email()
var buttonTitleColor: UIColor {
return Colors.appWhite
}
var inputWalletAddressButtonTitle: String {
return R.string.localizable.aWalletTicketTokenTransferModeChooseInputWalletAddressTitle()
var buttonBackgroundColor: UIColor {
return Colors.appHighlightGreen
}
var inputWalletAddressButtonImage: UIImage? {
return R.image.transfer_wallet_address()
var buttonFont: UIFont {
if ScreenChecker().isNarrowScreen() {
return Fonts.regular(size: 13)!
} else {
return Fonts.regular(size: 16)!
}
}
var qrCodeScannerButtonTitle: String {
return R.string.localizable.aWalletTicketTokenTransferModeChooseWalletAddressViaQRCodeScannerTitle()
var ticketCount: String {
return "x\(ticketHolder.tickets.count)"
}
var qrCodeScannerButtonImage: UIImage? {
return R.image.transfer_qr_code()
var title: String {
return ticketHolder.name
}
var otherButtonTitle: String {
return R.string.localizable.aWalletTicketTokenTransferModeChooseOtherTitle()
var seatRange: String {
return ticketHolder.seatRange
}
var otherButtonImage: UIImage? {
return R.image.transfer_others()
var zoneName: String {
return ticketHolder.zone
}
var buttonTitleFont: UIFont {
if ScreenChecker().isNarrowScreen() {
return Fonts.light(size: 18)!
} else {
return Fonts.light(size: 21)!
}
var venue: String {
return ticketHolder.venue
}
var buttonTitleColor: UIColor {
return Colors.appText
var date: String {
//TODO Should format be localized?
return ticketHolder.date.format("dd MMM yyyy")
}
}

@ -0,0 +1,110 @@
// Copyright © 2018 Stormbird PTE. LTD.
import Foundation
import UIKit
struct SetTransferTicketsExpiryDateViewControllerViewModel {
var ticketHolder: TicketHolder
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle()
}
var backgroundColor: UIColor {
return Colors.appBackground
}
var buttonTitleColor: UIColor {
return Colors.appWhite
}
var buttonBackgroundColor: UIColor {
return Colors.appHighlightGreen
}
var buttonFont: UIFont {
return Fonts.regular(size: 20)!
}
var ticketCount: String {
return "x\(ticketHolder.tickets.count)"
}
var title: String {
return ticketHolder.name
}
var seatRange: String {
return ticketHolder.seatRange
}
var zoneName: String {
return ticketHolder.zone
}
var venue: String {
return ticketHolder.venue
}
var date: String {
//TODO Should format be localized?
return ticketHolder.date.format("dd MMM yyyy")
}
var descriptionLabelText: String {
return R.string.localizable.aWalletTicketTokenSellMagicLinkDescriptionTitle()
}
var descriptionLabelFont: UIFont {
return Fonts.light(size: 21)!
}
var descriptionLabelColor: UIColor {
return Colors.appText
}
var noteTitleLabelText: String {
return R.string.localizable.aWalletTicketTokenSellNoteTitleLabelTitle()
}
var noteTitleLabelFont: UIFont {
return Fonts.semibold(size: 21)!
}
var noteTitleLabelColor: UIColor {
return Colors.appRed
}
var noteLabelText: String {
return R.string.localizable.aWalletTicketTokenSellNoteLabelTitle()
}
var noteLabelFont: UIFont {
return Fonts.light(size: 21)!
}
var noteLabelColor: UIColor {
return Colors.appRed
}
var noteBorderColor: UIColor {
return Colors.appRed
}
var choiceLabelColor: UIColor {
return UIColor(red: 155, green: 155, blue: 155)
}
var choiceLabelFont: UIFont {
return Fonts.regular(size: 10)!
}
var linkExpiryDateLabelText: String {
return R.string.localizable.aWalletTicketTokenSellLinkExpiryDateTitle()
}
var linkExpiryTimeLabelText: String {
return R.string.localizable.aWalletTicketTokenSellLinkExpiryTimeTitle()
}
}

@ -0,0 +1,74 @@
// Copyright © 2018 Stormbird PTE. LTD.
import Foundation
import UIKit
struct TransferTicketsChooseTransferModeViewControllerViewModel {
var ticketHolder: TicketHolder
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle()
}
var maxValue: Int {
return ticketHolder.tickets.count
}
var backgroundColor: UIColor {
return Colors.appBackground
}
var buttonTitleColor: UIColor {
return Colors.appWhite
}
var buttonBackgroundColor: UIColor {
return Colors.appHighlightGreen
}
var buttonFont: UIFont {
return Fonts.regular(size: 20)!
}
var subtitleColor: UIColor {
return UIColor(red: 155, green: 155, blue: 155)
}
var subtitleFont: UIFont {
return Fonts.regular(size: 10)!
}
var stepperBorderColor: UIColor {
return Colors.appBackground
}
var ticketCount: String {
return "x\(ticketHolder.tickets.count)"
}
var title: String {
return ticketHolder.name
}
var seatRange: String {
return ticketHolder.seatRange
}
var zoneName: String {
return ticketHolder.zone
}
var venue: String {
return ticketHolder.venue
}
var subtitleText: String {
return R.string.localizable.aWalletTicketTokenTransferQuantityTitle()
}
var date: String {
//TODO Should format be localized?
return ticketHolder.date.format("dd MMM yyyy")
}
}

@ -1,58 +1,31 @@
// Copyright © 2018 Stormbird PTE. LTD.
import Foundation
import UIKit
struct TransferTicketViaWalletAddressViewControllerViewModel {
struct TransferTicketsViaWalletAddressViewControllerViewModel {
var ticketHolder: TicketHolder
var contentsBackgroundColor: UIColor {
return Colors.appWhite
}
var titleColor: UIColor {
return Colors.appText
}
var titleFont: UIFont {
return Fonts.light(size: 25)!
}
var subtitleColor: UIColor {
return UIColor(red: 155, green: 155, blue: 155)
var headerTitle: String {
return R.string.localizable.aWalletTicketTokenTransferSelectQuantityTitle()
}
var subtitleFont: UIFont {
return Fonts.regular(size: 10)!
var backgroundColor: UIColor {
return Colors.appBackground
}
var actionButtonTitleColor: UIColor {
var buttonTitleColor: UIColor {
return Colors.appWhite
}
var actionButtonBackgroundColor: UIColor {
var buttonBackgroundColor: UIColor {
return Colors.appHighlightGreen
}
var actionButtonTitleFont: UIFont {
var buttonFont: UIFont {
return Fonts.regular(size: 20)!
}
var titleLabelText: String {
return R.string.localizable.aWalletTicketTokenTransferModeWalletAddressTitle()
}
var subtitleLabelText: String {
return R.string.localizable.aWalletTicketTokenTransferModeWalletAddressTargetTitle()
}
var actionButtonTitle: String {
return R.string.localizable.aWalletTicketTokenTransferButtonTitle()
}
var textFieldTextColor: UIColor {
return Colors.appText
}
var textFieldFont: UIFont {
return Fonts.light(size: 15)!
}
var textFieldBorderColor: UIColor {
return Colors.appBackground
}
var textFieldBorderWidth: CGFloat {
return 1
}
var textFieldHorizontalPadding: CGFloat {
return 22
}
var ticketCount: String {
return "x\(ticketHolder.tickets.count)"
@ -70,7 +43,7 @@ struct TransferTicketViaWalletAddressViewControllerViewModel {
return ticketHolder.zone
}
var venue: String {
var venue: String {
return ticketHolder.venue
}
@ -78,4 +51,29 @@ struct TransferTicketViaWalletAddressViewControllerViewModel {
//TODO Should format be localized?
return ticketHolder.date.format("dd MMM yyyy")
}
var textFieldTextColor: UIColor {
return Colors.appText
}
var textFieldFont: UIFont {
if ScreenChecker().isNarrowScreen() {
return Fonts.light(size: 11)!
} else {
return Fonts.light(size: 15)!
}
}
var textFieldBorderColor: UIColor {
return Colors.appBackground
}
var textFieldBorderWidth: CGFloat {
return 1
}
var textFieldHorizontalPadding: CGFloat {
return 22
}
var textFieldsLabelTextColor: UIColor {
return UIColor(red: 155, green: 155, blue: 155)
}
var textFieldsLabelFont: UIFont {
return Fonts.regular(size: 10)!
}
}
Loading…
Cancel
Save