Pārlūkot izejas kodu

fix submodule loction, put it to libraries, remove accidentally added files from View folder

cyberta 3 gadi atpakaļ
vecāks
revīzija
e0bc09e4b0
42 mainītis faili ar 191 papildinājumiem un 5550 dzēšanām
  1. 1 1
      .gitmodules
  2. 190 209
      deltachat-ios.xcodeproj/project.pbxproj
  3. 0 354
      deltachat-ios/View/InputBarAccessoryView/Controls/InputBarButtonItem.swift
  4. 0 96
      deltachat-ios/View/InputBarAccessoryView/Controls/InputBarSendButton.swift
  5. 0 98
      deltachat-ios/View/InputBarAccessoryView/Extensions/NSMutableAttributedString+Extensions.swift
  6. 0 89
      deltachat-ios/View/InputBarAccessoryView/Extensions/NSNotification+Extensions.swift
  7. 0 17
      deltachat-ios/View/InputBarAccessoryView/Extensions/String+Extensions.swift
  8. 0 64
      deltachat-ios/View/InputBarAccessoryView/Extensions/UITextView+Extensions.swift
  9. 0 96
      deltachat-ios/View/InputBarAccessoryView/Extensions/UIView+AutoLayout.swift
  10. 0 903
      deltachat-ios/View/InputBarAccessoryView/InputBarAccessoryView.swift
  11. 0 354
      deltachat-ios/View/InputBarAccessoryView/InputBarButtonItem.swift
  12. 0 96
      deltachat-ios/View/InputBarAccessoryView/InputBarSendButton.swift
  13. 0 53
      deltachat-ios/View/InputBarAccessoryView/KeyboardManager/KeyboardEvent.swift
  14. 0 301
      deltachat-ios/View/InputBarAccessoryView/KeyboardManager/KeyboardManager.swift
  15. 0 66
      deltachat-ios/View/InputBarAccessoryView/KeyboardManager/KeyboardNotification.swift
  16. 0 16
      deltachat-ios/View/InputBarAccessoryView/Models/HorizontalEdgeInsets.swift.swift
  17. 0 82
      deltachat-ios/View/InputBarAccessoryView/Models/NSConstraintLayoutSet.swift
  18. 0 235
      deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/AttachmentManager.swift
  19. 0 41
      deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Protocols/AttachmentManagerDataSource.swift
  20. 0 81
      deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Protocols/AttachmentManagerDelegate.swift
  21. 0 132
      deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Views/AttachmentCell.swift
  22. 0 82
      deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Views/AttachmentsView.swift
  23. 0 67
      deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Views/ImageAttachmentCell.swift
  24. 0 506
      deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/AutocompleteManager.swift
  25. 0 48
      deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Models/AutocompleteCompletion.swift
  26. 0 52
      deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Models/AutocompleteSession.swift
  27. 0 67
      deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Protocols/AutocompleteManagerDataSource.swift
  28. 0 82
      deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Protocols/AutocompleteManagerDelegate.swift
  29. 0 98
      deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Views/AutocompleteCell.swift
  30. 0 41
      deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Views/AutocompleteTableView.swift
  31. 0 74
      deltachat-ios/View/InputBarAccessoryView/Protocols/InputBarAccessoryViewDelegate.swift
  32. 0 50
      deltachat-ios/View/InputBarAccessoryView/Protocols/InputItem.swift
  33. 0 43
      deltachat-ios/View/InputBarAccessoryView/Protocols/InputPlugin.swift
  34. 0 185
      deltachat-ios/View/InputBarAccessoryView/RxInputBarAccessoryView/RxInputBarAccessoryView.swift
  35. 0 24
      deltachat-ios/View/InputBarAccessoryView/Supporting Files/Info.plist
  36. 0 91
      deltachat-ios/View/InputBarAccessoryView/Supporting Files/InputBarAccessoryView+Availability.swift
  37. 0 19
      deltachat-ios/View/InputBarAccessoryView/Supporting Files/InputBarAccessoryView-Bridging-Header.h
  38. 0 88
      deltachat-ios/View/InputBarAccessoryView/ViewControllers/InputBarViewController.swift
  39. 0 76
      deltachat-ios/View/InputBarAccessoryView/Views/InputStackView.swift
  40. 0 401
      deltachat-ios/View/InputBarAccessoryView/Views/InputTextView.swift
  41. 0 72
      deltachat-ios/View/InputBarAccessoryView/Views/SeparatorLine.swift
  42. 0 0
      deltachat-ios/libraries/InputBarAccessoryView

+ 1 - 1
.gitmodules

@@ -2,5 +2,5 @@
 	path = deltachat-ios/libraries/deltachat-core-rust
 	url = https://github.com/deltachat/deltachat-core-rust.git
 [submodule "deltachat-ios/InputBarAccessoryView"]
-	path = deltachat-ios/InputBarAccessoryView
+	path = deltachat-ios/libraries/InputBarAccessoryView
 	url = https://github.com/cyBerta/InputBarAccessoryView.git

+ 190 - 209
deltachat-ios.xcodeproj/project.pbxproj

@@ -45,41 +45,39 @@
 		304F769925DD23D70094B5E2 /* FullMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304F769825DD23D70094B5E2 /* FullMessageViewController.swift */; };
 		3052C60A253F082E007D13EA /* MessageLabelDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3052C609253F082E007D13EA /* MessageLabelDelegate.swift */; };
 		3052C60E253F088E007D13EA /* DetectorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3052C60D253F088E007D13EA /* DetectorType.swift */; };
-		30558A3927709AFA008781EE /* NSNotification+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0427709AF5008781EE /* NSNotification+Extensions.swift */; };
-		30558A3A27709AFA008781EE /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0527709AF5008781EE /* String+Extensions.swift */; };
-		30558A3B27709AFA008781EE /* UITextView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0627709AF5008781EE /* UITextView+Extensions.swift */; };
-		30558A3C27709AFA008781EE /* NSMutableAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0727709AF5008781EE /* NSMutableAttributedString+Extensions.swift */; };
-		30558A3D27709AFA008781EE /* UIView+AutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0827709AF5008781EE /* UIView+AutoLayout.swift */; };
-		30558A3E27709AFA008781EE /* KeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0A27709AF6008781EE /* KeyboardManager.swift */; };
-		30558A3F27709AFA008781EE /* KeyboardNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0B27709AF6008781EE /* KeyboardNotification.swift */; };
-		30558A4027709AFA008781EE /* KeyboardEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0C27709AF6008781EE /* KeyboardEvent.swift */; };
-		30558A4127709AFA008781EE /* RxInputBarAccessoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A0E27709AF6008781EE /* RxInputBarAccessoryView.swift */; };
-		30558A4227709AFA008781EE /* AttachmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1127709AF7008781EE /* AttachmentManager.swift */; };
-		30558A4327709AFA008781EE /* ImageAttachmentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1327709AF7008781EE /* ImageAttachmentCell.swift */; };
-		30558A4427709AFA008781EE /* AttachmentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1427709AF7008781EE /* AttachmentCell.swift */; };
-		30558A4527709AFA008781EE /* AttachmentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1527709AF7008781EE /* AttachmentsView.swift */; };
-		30558A4627709AFA008781EE /* AttachmentManagerDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1727709AF7008781EE /* AttachmentManagerDataSource.swift */; };
-		30558A4727709AFA008781EE /* AttachmentManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1827709AF7008781EE /* AttachmentManagerDelegate.swift */; };
-		30558A4827709AFA008781EE /* AutocompleteManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1A27709AF7008781EE /* AutocompleteManager.swift */; };
-		30558A4927709AFA008781EE /* AutocompleteSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1C27709AF7008781EE /* AutocompleteSession.swift */; };
-		30558A4A27709AFA008781EE /* AutocompleteCompletion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1D27709AF7008781EE /* AutocompleteCompletion.swift */; };
-		30558A4B27709AFA008781EE /* AutocompleteTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A1F27709AF7008781EE /* AutocompleteTableView.swift */; };
-		30558A4C27709AFA008781EE /* AutocompleteCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2027709AF7008781EE /* AutocompleteCell.swift */; };
-		30558A4D27709AFA008781EE /* AutocompleteManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2227709AF7008781EE /* AutocompleteManagerDelegate.swift */; };
-		30558A4E27709AFA008781EE /* AutocompleteManagerDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2327709AF7008781EE /* AutocompleteManagerDataSource.swift */; };
-		30558A4F27709AFA008781EE /* InputStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2527709AF7008781EE /* InputStackView.swift */; };
-		30558A5027709AFA008781EE /* InputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2627709AF7008781EE /* InputTextView.swift */; };
-		30558A5127709AFA008781EE /* SeparatorLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2727709AF7008781EE /* SeparatorLine.swift */; };
-		30558A5227709AFA008781EE /* InputBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2927709AF8008781EE /* InputBarButtonItem.swift */; };
-		30558A5327709AFA008781EE /* InputBarSendButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2A27709AF8008781EE /* InputBarSendButton.swift */; };
-		30558A5427709AFA008781EE /* InputBarAccessoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2B27709AF8008781EE /* InputBarAccessoryView.swift */; };
-		30558A5527709AFA008781EE /* HorizontalEdgeInsets.swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2D27709AF8008781EE /* HorizontalEdgeInsets.swift.swift */; };
-		30558A5627709AFA008781EE /* NSConstraintLayoutSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A2E27709AF8008781EE /* NSConstraintLayoutSet.swift */; };
-		30558A5727709AFA008781EE /* InputPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A3027709AF9008781EE /* InputPlugin.swift */; };
-		30558A5827709AFA008781EE /* InputBarAccessoryViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A3127709AF9008781EE /* InputBarAccessoryViewDelegate.swift */; };
-		30558A5927709AFA008781EE /* InputItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A3227709AF9008781EE /* InputItem.swift */; };
-		30558A5A27709AFA008781EE /* InputBarAccessoryView+Availability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A3527709AF9008781EE /* InputBarAccessoryView+Availability.swift */; };
-		30558A5C27709AFA008781EE /* InputBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558A3827709AFA008781EE /* InputBarViewController.swift */; };
+		30558B3627752C72008781EE /* InputBarAccessoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B0627752C71008781EE /* InputBarAccessoryView.swift */; };
+		30558B3727752C72008781EE /* NSNotification+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B0827752C71008781EE /* NSNotification+Extensions.swift */; };
+		30558B3827752C72008781EE /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B0927752C71008781EE /* String+Extensions.swift */; };
+		30558B3927752C72008781EE /* UITextView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B0A27752C71008781EE /* UITextView+Extensions.swift */; };
+		30558B3A27752C72008781EE /* NSMutableAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B0B27752C71008781EE /* NSMutableAttributedString+Extensions.swift */; };
+		30558B3B27752C72008781EE /* UIView+AutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B0C27752C71008781EE /* UIView+AutoLayout.swift */; };
+		30558B3C27752C72008781EE /* HorizontalEdgePadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B0E27752C71008781EE /* HorizontalEdgePadding.swift */; };
+		30558B3D27752C72008781EE /* NSConstraintLayoutSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B0F27752C71008781EE /* NSConstraintLayoutSet.swift */; };
+		30558B3E27752C72008781EE /* AttachmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1227752C71008781EE /* AttachmentManager.swift */; };
+		30558B3F27752C72008781EE /* ImageAttachmentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1427752C71008781EE /* ImageAttachmentCell.swift */; };
+		30558B4027752C72008781EE /* AttachmentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1527752C71008781EE /* AttachmentCell.swift */; };
+		30558B4127752C72008781EE /* AttachmentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1627752C71008781EE /* AttachmentsView.swift */; };
+		30558B4227752C72008781EE /* AttachmentManagerDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1827752C71008781EE /* AttachmentManagerDataSource.swift */; };
+		30558B4327752C72008781EE /* AttachmentManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1927752C71008781EE /* AttachmentManagerDelegate.swift */; };
+		30558B4427752C72008781EE /* AutocompleteManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1B27752C71008781EE /* AutocompleteManager.swift */; };
+		30558B4527752C72008781EE /* AutocompleteSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1D27752C71008781EE /* AutocompleteSession.swift */; };
+		30558B4627752C72008781EE /* AutocompleteCompletion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B1E27752C71008781EE /* AutocompleteCompletion.swift */; };
+		30558B4727752C72008781EE /* AutocompleteTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2027752C71008781EE /* AutocompleteTableView.swift */; };
+		30558B4827752C72008781EE /* AutocompleteCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2127752C71008781EE /* AutocompleteCell.swift */; };
+		30558B4927752C72008781EE /* AutocompleteManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2327752C71008781EE /* AutocompleteManagerDelegate.swift */; };
+		30558B4A27752C72008781EE /* AutocompleteManagerDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2427752C71008781EE /* AutocompleteManagerDataSource.swift */; };
+		30558B4B27752C72008781EE /* InputBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2627752C71008781EE /* InputBarViewController.swift */; };
+		30558B4C27752C72008781EE /* InputStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2827752C72008781EE /* InputStackView.swift */; };
+		30558B4D27752C72008781EE /* InputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2927752C72008781EE /* InputTextView.swift */; };
+		30558B4E27752C73008781EE /* SeparatorLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2A27752C72008781EE /* SeparatorLine.swift */; };
+		30558B4F27752C73008781EE /* KeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2C27752C72008781EE /* KeyboardManager.swift */; };
+		30558B5027752C73008781EE /* KeyboardNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2D27752C72008781EE /* KeyboardNotification.swift */; };
+		30558B5127752C73008781EE /* KeyboardEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B2E27752C72008781EE /* KeyboardEvent.swift */; };
+		30558B5227752C73008781EE /* InputPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B3027752C72008781EE /* InputPlugin.swift */; };
+		30558B5327752C73008781EE /* InputBarAccessoryViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B3127752C72008781EE /* InputBarAccessoryViewDelegate.swift */; };
+		30558B5427752C73008781EE /* InputItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B3227752C72008781EE /* InputItem.swift */; };
+		30558B5527752C73008781EE /* InputBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B3427752C72008781EE /* InputBarButtonItem.swift */; };
+		30558B5627752C73008781EE /* InputBarSendButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30558B3527752C72008781EE /* InputBarSendButton.swift */; };
 		3057027F24C5B2F800D84EFC /* ChatListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3057027E24C5B2F800D84EFC /* ChatListViewModel.swift */; };
 		3057028724C5C88300D84EFC /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 306011B422E5E7FB00C1CE6F /* Localizable.stringsdict */; };
 		3057028C24C5E7B600D84EFC /* ContactCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE77838E23E4276D0093EABD /* ContactCellViewModel.swift */; };
@@ -298,42 +296,39 @@
 		304F769825DD23D70094B5E2 /* FullMessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullMessageViewController.swift; sourceTree = "<group>"; };
 		3052C609253F082E007D13EA /* MessageLabelDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageLabelDelegate.swift; sourceTree = "<group>"; };
 		3052C60D253F088E007D13EA /* DetectorType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetectorType.swift; sourceTree = "<group>"; };
-		30558A0427709AF5008781EE /* NSNotification+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSNotification+Extensions.swift"; sourceTree = "<group>"; };
-		30558A0527709AF5008781EE /* String+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
-		30558A0627709AF5008781EE /* UITextView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextView+Extensions.swift"; sourceTree = "<group>"; };
-		30558A0727709AF5008781EE /* NSMutableAttributedString+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSMutableAttributedString+Extensions.swift"; sourceTree = "<group>"; };
-		30558A0827709AF5008781EE /* UIView+AutoLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+AutoLayout.swift"; sourceTree = "<group>"; };
-		30558A0A27709AF6008781EE /* KeyboardManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardManager.swift; sourceTree = "<group>"; };
-		30558A0B27709AF6008781EE /* KeyboardNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardNotification.swift; sourceTree = "<group>"; };
-		30558A0C27709AF6008781EE /* KeyboardEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardEvent.swift; sourceTree = "<group>"; };
-		30558A0E27709AF6008781EE /* RxInputBarAccessoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxInputBarAccessoryView.swift; sourceTree = "<group>"; };
-		30558A1127709AF7008781EE /* AttachmentManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentManager.swift; sourceTree = "<group>"; };
-		30558A1327709AF7008781EE /* ImageAttachmentCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageAttachmentCell.swift; sourceTree = "<group>"; };
-		30558A1427709AF7008781EE /* AttachmentCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentCell.swift; sourceTree = "<group>"; };
-		30558A1527709AF7008781EE /* AttachmentsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentsView.swift; sourceTree = "<group>"; };
-		30558A1727709AF7008781EE /* AttachmentManagerDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentManagerDataSource.swift; sourceTree = "<group>"; };
-		30558A1827709AF7008781EE /* AttachmentManagerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentManagerDelegate.swift; sourceTree = "<group>"; };
-		30558A1A27709AF7008781EE /* AutocompleteManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteManager.swift; sourceTree = "<group>"; };
-		30558A1C27709AF7008781EE /* AutocompleteSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteSession.swift; sourceTree = "<group>"; };
-		30558A1D27709AF7008781EE /* AutocompleteCompletion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteCompletion.swift; sourceTree = "<group>"; };
-		30558A1F27709AF7008781EE /* AutocompleteTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteTableView.swift; sourceTree = "<group>"; };
-		30558A2027709AF7008781EE /* AutocompleteCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteCell.swift; sourceTree = "<group>"; };
-		30558A2227709AF7008781EE /* AutocompleteManagerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteManagerDelegate.swift; sourceTree = "<group>"; };
-		30558A2327709AF7008781EE /* AutocompleteManagerDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteManagerDataSource.swift; sourceTree = "<group>"; };
-		30558A2527709AF7008781EE /* InputStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputStackView.swift; sourceTree = "<group>"; };
-		30558A2627709AF7008781EE /* InputTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTextView.swift; sourceTree = "<group>"; };
-		30558A2727709AF7008781EE /* SeparatorLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SeparatorLine.swift; sourceTree = "<group>"; };
-		30558A2927709AF8008781EE /* InputBarButtonItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarButtonItem.swift; sourceTree = "<group>"; };
-		30558A2A27709AF8008781EE /* InputBarSendButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarSendButton.swift; sourceTree = "<group>"; };
-		30558A2B27709AF8008781EE /* InputBarAccessoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarAccessoryView.swift; sourceTree = "<group>"; };
-		30558A2D27709AF8008781EE /* HorizontalEdgeInsets.swift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HorizontalEdgeInsets.swift.swift; sourceTree = "<group>"; };
-		30558A2E27709AF8008781EE /* NSConstraintLayoutSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSConstraintLayoutSet.swift; sourceTree = "<group>"; };
-		30558A3027709AF9008781EE /* InputPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputPlugin.swift; sourceTree = "<group>"; };
-		30558A3127709AF9008781EE /* InputBarAccessoryViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarAccessoryViewDelegate.swift; sourceTree = "<group>"; };
-		30558A3227709AF9008781EE /* InputItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputItem.swift; sourceTree = "<group>"; };
-		30558A3427709AF9008781EE /* InputBarAccessoryView-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "InputBarAccessoryView-Bridging-Header.h"; sourceTree = "<group>"; };
-		30558A3527709AF9008781EE /* InputBarAccessoryView+Availability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "InputBarAccessoryView+Availability.swift"; sourceTree = "<group>"; };
-		30558A3827709AFA008781EE /* InputBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarViewController.swift; sourceTree = "<group>"; };
+		30558B0627752C71008781EE /* InputBarAccessoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InputBarAccessoryView.swift; path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/InputBarAccessoryView.swift"; sourceTree = SOURCE_ROOT; };
+		30558B0827752C71008781EE /* NSNotification+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSNotification+Extensions.swift"; sourceTree = "<group>"; };
+		30558B0927752C71008781EE /* String+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
+		30558B0A27752C71008781EE /* UITextView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextView+Extensions.swift"; sourceTree = "<group>"; };
+		30558B0B27752C71008781EE /* NSMutableAttributedString+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSMutableAttributedString+Extensions.swift"; sourceTree = "<group>"; };
+		30558B0C27752C71008781EE /* UIView+AutoLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+AutoLayout.swift"; sourceTree = "<group>"; };
+		30558B0E27752C71008781EE /* HorizontalEdgePadding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HorizontalEdgePadding.swift; sourceTree = "<group>"; };
+		30558B0F27752C71008781EE /* NSConstraintLayoutSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSConstraintLayoutSet.swift; sourceTree = "<group>"; };
+		30558B1227752C71008781EE /* AttachmentManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentManager.swift; sourceTree = "<group>"; };
+		30558B1427752C71008781EE /* ImageAttachmentCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageAttachmentCell.swift; sourceTree = "<group>"; };
+		30558B1527752C71008781EE /* AttachmentCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentCell.swift; sourceTree = "<group>"; };
+		30558B1627752C71008781EE /* AttachmentsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentsView.swift; sourceTree = "<group>"; };
+		30558B1827752C71008781EE /* AttachmentManagerDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentManagerDataSource.swift; sourceTree = "<group>"; };
+		30558B1927752C71008781EE /* AttachmentManagerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentManagerDelegate.swift; sourceTree = "<group>"; };
+		30558B1B27752C71008781EE /* AutocompleteManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteManager.swift; sourceTree = "<group>"; };
+		30558B1D27752C71008781EE /* AutocompleteSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteSession.swift; sourceTree = "<group>"; };
+		30558B1E27752C71008781EE /* AutocompleteCompletion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteCompletion.swift; sourceTree = "<group>"; };
+		30558B2027752C71008781EE /* AutocompleteTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteTableView.swift; sourceTree = "<group>"; };
+		30558B2127752C71008781EE /* AutocompleteCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteCell.swift; sourceTree = "<group>"; };
+		30558B2327752C71008781EE /* AutocompleteManagerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteManagerDelegate.swift; sourceTree = "<group>"; };
+		30558B2427752C71008781EE /* AutocompleteManagerDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutocompleteManagerDataSource.swift; sourceTree = "<group>"; };
+		30558B2627752C71008781EE /* InputBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarViewController.swift; sourceTree = "<group>"; };
+		30558B2827752C72008781EE /* InputStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputStackView.swift; sourceTree = "<group>"; };
+		30558B2927752C72008781EE /* InputTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTextView.swift; sourceTree = "<group>"; };
+		30558B2A27752C72008781EE /* SeparatorLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SeparatorLine.swift; sourceTree = "<group>"; };
+		30558B2C27752C72008781EE /* KeyboardManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardManager.swift; sourceTree = "<group>"; };
+		30558B2D27752C72008781EE /* KeyboardNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardNotification.swift; sourceTree = "<group>"; };
+		30558B2E27752C72008781EE /* KeyboardEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardEvent.swift; sourceTree = "<group>"; };
+		30558B3027752C72008781EE /* InputPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputPlugin.swift; sourceTree = "<group>"; };
+		30558B3127752C72008781EE /* InputBarAccessoryViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarAccessoryViewDelegate.swift; sourceTree = "<group>"; };
+		30558B3227752C72008781EE /* InputItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputItem.swift; sourceTree = "<group>"; };
+		30558B3427752C72008781EE /* InputBarButtonItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarButtonItem.swift; sourceTree = "<group>"; };
+		30558B3527752C72008781EE /* InputBarSendButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputBarSendButton.swift; sourceTree = "<group>"; };
 		3057027E24C5B2F800D84EFC /* ChatListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListViewModel.swift; sourceTree = "<group>"; };
 		3057029A24C6441300D84EFC /* EmptyStateLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptyStateLabel.swift; sourceTree = "<group>"; };
 		305702A024C6453700D84EFC /* TypeAlias.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeAlias.swift; sourceTree = "<group>"; };
@@ -625,185 +620,173 @@
 			path = View;
 			sourceTree = "<group>";
 		};
-		305589FD27709A6A008781EE /* InputBarAccessoryView */ = {
+		30558B0527752C09008781EE /* InputBarAccessoryView */ = {
 			isa = PBXGroup;
 			children = (
-				30558A2827709AF8008781EE /* Controls */,
-				30558A0327709AF5008781EE /* Extensions */,
-				30558A2B27709AF8008781EE /* InputBarAccessoryView.swift */,
-				30558A0927709AF6008781EE /* KeyboardManager */,
-				30558A2C27709AF8008781EE /* Models */,
-				30558A0F27709AF7008781EE /* Plugins */,
-				30558A2F27709AF9008781EE /* Protocols */,
-				30558A0D27709AF6008781EE /* RxInputBarAccessoryView */,
-				30558A3327709AF9008781EE /* Supporting Files */,
-				30558A3727709AFA008781EE /* ViewControllers */,
-				30558A2427709AF7008781EE /* Views */,
-			);
-			name = InputBarAccessoryView;
-			path = View/InputBarAccessoryView;
+				30558B3327752C72008781EE /* Controls */,
+				30558B0727752C71008781EE /* Extensions */,
+				30558B0627752C71008781EE /* InputBarAccessoryView.swift */,
+				30558B2B27752C72008781EE /* KeyboardManager */,
+				30558B0D27752C71008781EE /* Models */,
+				30558B1027752C71008781EE /* Plugins */,
+				30558B2F27752C72008781EE /* Protocols */,
+				30558B2527752C71008781EE /* ViewControllers */,
+				30558B2727752C72008781EE /* Views */,
+			);
+			path = InputBarAccessoryView;
 			sourceTree = "<group>";
 		};
-		30558A0327709AF5008781EE /* Extensions */ = {
+		30558B0727752C71008781EE /* Extensions */ = {
 			isa = PBXGroup;
 			children = (
-				30558A0427709AF5008781EE /* NSNotification+Extensions.swift */,
-				30558A0527709AF5008781EE /* String+Extensions.swift */,
-				30558A0627709AF5008781EE /* UITextView+Extensions.swift */,
-				30558A0727709AF5008781EE /* NSMutableAttributedString+Extensions.swift */,
-				30558A0827709AF5008781EE /* UIView+AutoLayout.swift */,
+				30558B0827752C71008781EE /* NSNotification+Extensions.swift */,
+				30558B0927752C71008781EE /* String+Extensions.swift */,
+				30558B0A27752C71008781EE /* UITextView+Extensions.swift */,
+				30558B0B27752C71008781EE /* NSMutableAttributedString+Extensions.swift */,
+				30558B0C27752C71008781EE /* UIView+AutoLayout.swift */,
 			);
-			path = Extensions;
-			sourceTree = "<group>";
+			name = Extensions;
+			path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/Extensions";
+			sourceTree = SOURCE_ROOT;
 		};
-		30558A0927709AF6008781EE /* KeyboardManager */ = {
+		30558B0D27752C71008781EE /* Models */ = {
 			isa = PBXGroup;
 			children = (
-				30558A0A27709AF6008781EE /* KeyboardManager.swift */,
-				30558A0B27709AF6008781EE /* KeyboardNotification.swift */,
-				30558A0C27709AF6008781EE /* KeyboardEvent.swift */,
+				30558B0E27752C71008781EE /* HorizontalEdgePadding.swift */,
+				30558B0F27752C71008781EE /* NSConstraintLayoutSet.swift */,
 			);
-			path = KeyboardManager;
-			sourceTree = "<group>";
+			name = Models;
+			path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/Models";
+			sourceTree = SOURCE_ROOT;
 		};
-		30558A0D27709AF6008781EE /* RxInputBarAccessoryView */ = {
+		30558B1027752C71008781EE /* Plugins */ = {
 			isa = PBXGroup;
 			children = (
-				30558A0E27709AF6008781EE /* RxInputBarAccessoryView.swift */,
+				30558B1127752C71008781EE /* AttachmentManager */,
+				30558B1A27752C71008781EE /* AutocompleteManager */,
 			);
-			path = RxInputBarAccessoryView;
-			sourceTree = "<group>";
+			name = Plugins;
+			path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/Plugins";
+			sourceTree = SOURCE_ROOT;
 		};
-		30558A0F27709AF7008781EE /* Plugins */ = {
+		30558B1127752C71008781EE /* AttachmentManager */ = {
 			isa = PBXGroup;
 			children = (
-				30558A1027709AF7008781EE /* AttachmentManager */,
-				30558A1927709AF7008781EE /* AutocompleteManager */,
-			);
-			path = Plugins;
-			sourceTree = "<group>";
-		};
-		30558A1027709AF7008781EE /* AttachmentManager */ = {
-			isa = PBXGroup;
-			children = (
-				30558A1127709AF7008781EE /* AttachmentManager.swift */,
-				30558A1227709AF7008781EE /* Views */,
-				30558A1627709AF7008781EE /* Protocols */,
+				30558B1227752C71008781EE /* AttachmentManager.swift */,
+				30558B1327752C71008781EE /* Views */,
+				30558B1727752C71008781EE /* Protocols */,
 			);
 			path = AttachmentManager;
 			sourceTree = "<group>";
 		};
-		30558A1227709AF7008781EE /* Views */ = {
+		30558B1327752C71008781EE /* Views */ = {
 			isa = PBXGroup;
 			children = (
-				30558A1327709AF7008781EE /* ImageAttachmentCell.swift */,
-				30558A1427709AF7008781EE /* AttachmentCell.swift */,
-				30558A1527709AF7008781EE /* AttachmentsView.swift */,
+				30558B1427752C71008781EE /* ImageAttachmentCell.swift */,
+				30558B1527752C71008781EE /* AttachmentCell.swift */,
+				30558B1627752C71008781EE /* AttachmentsView.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
 		};
-		30558A1627709AF7008781EE /* Protocols */ = {
+		30558B1727752C71008781EE /* Protocols */ = {
 			isa = PBXGroup;
 			children = (
-				30558A1727709AF7008781EE /* AttachmentManagerDataSource.swift */,
-				30558A1827709AF7008781EE /* AttachmentManagerDelegate.swift */,
+				30558B1827752C71008781EE /* AttachmentManagerDataSource.swift */,
+				30558B1927752C71008781EE /* AttachmentManagerDelegate.swift */,
 			);
 			path = Protocols;
 			sourceTree = "<group>";
 		};
-		30558A1927709AF7008781EE /* AutocompleteManager */ = {
+		30558B1A27752C71008781EE /* AutocompleteManager */ = {
 			isa = PBXGroup;
 			children = (
-				30558A1A27709AF7008781EE /* AutocompleteManager.swift */,
-				30558A1B27709AF7008781EE /* Models */,
-				30558A1E27709AF7008781EE /* Views */,
-				30558A2127709AF7008781EE /* Protocols */,
+				30558B1B27752C71008781EE /* AutocompleteManager.swift */,
+				30558B1C27752C71008781EE /* Models */,
+				30558B1F27752C71008781EE /* Views */,
+				30558B2227752C71008781EE /* Protocols */,
 			);
 			path = AutocompleteManager;
 			sourceTree = "<group>";
 		};
-		30558A1B27709AF7008781EE /* Models */ = {
+		30558B1C27752C71008781EE /* Models */ = {
 			isa = PBXGroup;
 			children = (
-				30558A1C27709AF7008781EE /* AutocompleteSession.swift */,
-				30558A1D27709AF7008781EE /* AutocompleteCompletion.swift */,
+				30558B1D27752C71008781EE /* AutocompleteSession.swift */,
+				30558B1E27752C71008781EE /* AutocompleteCompletion.swift */,
 			);
 			path = Models;
 			sourceTree = "<group>";
 		};
-		30558A1E27709AF7008781EE /* Views */ = {
+		30558B1F27752C71008781EE /* Views */ = {
 			isa = PBXGroup;
 			children = (
-				30558A1F27709AF7008781EE /* AutocompleteTableView.swift */,
-				30558A2027709AF7008781EE /* AutocompleteCell.swift */,
+				30558B2027752C71008781EE /* AutocompleteTableView.swift */,
+				30558B2127752C71008781EE /* AutocompleteCell.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
 		};
-		30558A2127709AF7008781EE /* Protocols */ = {
+		30558B2227752C71008781EE /* Protocols */ = {
 			isa = PBXGroup;
 			children = (
-				30558A2227709AF7008781EE /* AutocompleteManagerDelegate.swift */,
-				30558A2327709AF7008781EE /* AutocompleteManagerDataSource.swift */,
+				30558B2327752C71008781EE /* AutocompleteManagerDelegate.swift */,
+				30558B2427752C71008781EE /* AutocompleteManagerDataSource.swift */,
 			);
 			path = Protocols;
 			sourceTree = "<group>";
 		};
-		30558A2427709AF7008781EE /* Views */ = {
-			isa = PBXGroup;
-			children = (
-				30558A2527709AF7008781EE /* InputStackView.swift */,
-				30558A2627709AF7008781EE /* InputTextView.swift */,
-				30558A2727709AF7008781EE /* SeparatorLine.swift */,
-			);
-			path = Views;
-			sourceTree = "<group>";
-		};
-		30558A2827709AF8008781EE /* Controls */ = {
+		30558B2527752C71008781EE /* ViewControllers */ = {
 			isa = PBXGroup;
 			children = (
-				30558A2927709AF8008781EE /* InputBarButtonItem.swift */,
-				30558A2A27709AF8008781EE /* InputBarSendButton.swift */,
+				30558B2627752C71008781EE /* InputBarViewController.swift */,
 			);
-			path = Controls;
-			sourceTree = "<group>";
+			name = ViewControllers;
+			path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/ViewControllers";
+			sourceTree = SOURCE_ROOT;
 		};
-		30558A2C27709AF8008781EE /* Models */ = {
+		30558B2727752C72008781EE /* Views */ = {
 			isa = PBXGroup;
 			children = (
-				30558A2D27709AF8008781EE /* HorizontalEdgeInsets.swift.swift */,
-				30558A2E27709AF8008781EE /* NSConstraintLayoutSet.swift */,
+				30558B2827752C72008781EE /* InputStackView.swift */,
+				30558B2927752C72008781EE /* InputTextView.swift */,
+				30558B2A27752C72008781EE /* SeparatorLine.swift */,
 			);
-			path = Models;
-			sourceTree = "<group>";
+			name = Views;
+			path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/Views";
+			sourceTree = SOURCE_ROOT;
 		};
-		30558A2F27709AF9008781EE /* Protocols */ = {
+		30558B2B27752C72008781EE /* KeyboardManager */ = {
 			isa = PBXGroup;
 			children = (
-				30558A3027709AF9008781EE /* InputPlugin.swift */,
-				30558A3127709AF9008781EE /* InputBarAccessoryViewDelegate.swift */,
-				30558A3227709AF9008781EE /* InputItem.swift */,
+				30558B2C27752C72008781EE /* KeyboardManager.swift */,
+				30558B2D27752C72008781EE /* KeyboardNotification.swift */,
+				30558B2E27752C72008781EE /* KeyboardEvent.swift */,
 			);
-			path = Protocols;
-			sourceTree = "<group>";
+			name = KeyboardManager;
+			path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/KeyboardManager";
+			sourceTree = SOURCE_ROOT;
 		};
-		30558A3327709AF9008781EE /* Supporting Files */ = {
+		30558B2F27752C72008781EE /* Protocols */ = {
 			isa = PBXGroup;
 			children = (
-				30558A3427709AF9008781EE /* InputBarAccessoryView-Bridging-Header.h */,
-				30558A3527709AF9008781EE /* InputBarAccessoryView+Availability.swift */,
+				30558B3027752C72008781EE /* InputPlugin.swift */,
+				30558B3127752C72008781EE /* InputBarAccessoryViewDelegate.swift */,
+				30558B3227752C72008781EE /* InputItem.swift */,
 			);
-			path = "Supporting Files";
-			sourceTree = "<group>";
+			name = Protocols;
+			path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/Protocols";
+			sourceTree = SOURCE_ROOT;
 		};
-		30558A3727709AFA008781EE /* ViewControllers */ = {
+		30558B3327752C72008781EE /* Controls */ = {
 			isa = PBXGroup;
 			children = (
-				30558A3827709AFA008781EE /* InputBarViewController.swift */,
+				30558B3427752C72008781EE /* InputBarButtonItem.swift */,
+				30558B3527752C72008781EE /* InputBarSendButton.swift */,
 			);
-			path = ViewControllers;
-			sourceTree = "<group>";
+			name = Controls;
+			path = "deltachat-ios/libraries/InputBarAccessoryView/Sources/Controls";
+			sourceTree = SOURCE_ROOT;
 		};
 		3057027D24C5B2C700D84EFC /* ViewModel */ = {
 			isa = PBXGroup;
@@ -930,7 +913,7 @@
 		7A9FB1421FB061E2001FEA36 /* deltachat-ios */ = {
 			isa = PBXGroup;
 			children = (
-				305589FD27709A6A008781EE /* InputBarAccessoryView */,
+				30558B0527752C09008781EE /* InputBarAccessoryView */,
 				AE57C07E2552BBC0003CFE70 /* Model */,
 				304219D7244072E600516852 /* DC */,
 				AE1988AA23EB3C7600B4CD5F /* Assets */,
@@ -1530,7 +1513,6 @@
 			buildActionMask = 2147483647;
 			files = (
 				3059620E234614E700C80F33 /* DcContact+Extension.swift in Sources */,
-				30558A5227709AFA008781EE /* InputBarButtonItem.swift in Sources */,
 				AED423D7249F580700B6B2BB /* BlockedContactsViewController.swift in Sources */,
 				303492B32577E40700A523D0 /* DocumentPreview.swift in Sources */,
 				3008CB7424F9436C00E6A617 /* AudioPlayerView.swift in Sources */,
@@ -1539,111 +1521,114 @@
 				AE9DAF0F22C278C6004C9591 /* ChatTitleView.swift in Sources */,
 				AE4AEE3522B1030D000AA495 /* PreviewController.swift in Sources */,
 				7070FB9B2101ECBB000DC258 /* NewGroupController.swift in Sources */,
-				30558A4827709AFA008781EE /* AutocompleteManager.swift in Sources */,
 				AE57C084255310BB003CFE70 /* ContextMenuController.swift in Sources */,
 				304219D92440734A00516852 /* DcMsg+Extension.swift in Sources */,
+				30558B4727752C72008781EE /* AutocompleteTableView.swift in Sources */,
+				30558B4927752C72008781EE /* AutocompleteManagerDelegate.swift in Sources */,
 				303492CF2587C2DC00A523D0 /* ChatInputBar.swift in Sources */,
 				AE52EA19229EB53C00C586C9 /* ContactDetailHeader.swift in Sources */,
-				30558A4D27709AFA008781EE /* AutocompleteManagerDelegate.swift in Sources */,
 				78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */,
-				30558A4227709AFA008781EE /* AttachmentManager.swift in Sources */,
-				30558A3F27709AFA008781EE /* KeyboardNotification.swift in Sources */,
 				30734326249A280B00BF9AD1 /* MediaQualityController.swift in Sources */,
 				AE6EC5282497B9B200A400E4 /* ThumbnailCache.swift in Sources */,
-				30558A5327709AFA008781EE /* InputBarSendButton.swift in Sources */,
-				30558A4B27709AFA008781EE /* AutocompleteTableView.swift in Sources */,
-				30558A5127709AFA008781EE /* SeparatorLine.swift in Sources */,
 				30FDB70524D1C1000066C48D /* ChatViewController.swift in Sources */,
 				AE52EA20229EB9F000C586C9 /* EditGroupViewController.swift in Sources */,
-				30558A5627709AFA008781EE /* NSConstraintLayoutSet.swift in Sources */,
-				30558A4127709AFA008781EE /* RxInputBarAccessoryView.swift in Sources */,
 				AE18F294228C602A0007B1BE /* SecuritySettingsController.swift in Sources */,
-				30558A3B27709AFA008781EE /* UITextView+Extensions.swift in Sources */,
+				30558B4E27752C73008781EE /* SeparatorLine.swift in Sources */,
+				30558B4827752C72008781EE /* AutocompleteCell.swift in Sources */,
 				30C2BFFE27032375005505DA /* ChatSearchAccessoryBar.swift in Sources */,
 				AE39D323249CFC1A007346A1 /* DocumentGalleryController.swift in Sources */,
 				AE8DD451249D1DFB009A4BC1 /* DocumentGalleryFileCell.swift in Sources */,
-				30558A3A27709AFA008781EE /* String+Extensions.swift in Sources */,
 				3095A351237DD1F700AB07F7 /* MediaPicker.swift in Sources */,
 				B21005DB23383664004C70C5 /* SettingsClassicViewController.swift in Sources */,
 				AEC67A1C241CE9E4007DDBE1 /* AppStateRestorer.swift in Sources */,
 				3008CB7224F93EB900E6A617 /* AudioMessageCell.swift in Sources */,
+				30558B3D27752C72008781EE /* NSConstraintLayoutSet.swift in Sources */,
 				302E1BB4252B5AB4008F4264 /* PlayButtonView.swift in Sources */,
-				30558A3927709AFA008781EE /* NSNotification+Extensions.swift in Sources */,
 				303492AD2577CAC300A523D0 /* FileView.swift in Sources */,
+				30558B5327752C73008781EE /* InputBarAccessoryViewDelegate.swift in Sources */,
 				7AE0A5491FC42F65005ECB4B /* NewChatViewController.swift in Sources */,
-				30558A3E27709AFA008781EE /* KeyboardManager.swift in Sources */,
 				AE77838F23E4276D0093EABD /* ContactCellViewModel.swift in Sources */,
+				30558B4327752C72008781EE /* AttachmentManagerDelegate.swift in Sources */,
 				B20462E62440C99600367A57 /* SettingsAutodelSetController.swift in Sources */,
 				3015634423A003BA00E9DEF4 /* AudioRecorderController.swift in Sources */,
+				30558B4027752C72008781EE /* AttachmentCell.swift in Sources */,
 				AE57C0802552BBD0003CFE70 /* GalleryItem.swift in Sources */,
+				30558B4B27752C72008781EE /* InputBarViewController.swift in Sources */,
+				30558B3727752C72008781EE /* NSNotification+Extensions.swift in Sources */,
+				30558B4227752C72008781EE /* AttachmentManagerDataSource.swift in Sources */,
 				AE25F09022807AD800CDEA66 /* AvatarSelectionCell.swift in Sources */,
 				30A4149724F6EFBE00EC91EB /* InfoMessageCell.swift in Sources */,
-				30558A5727709AFA008781EE /* InputPlugin.swift in Sources */,
 				302B84C6239676F0001C261F /* AvatarHelper.swift in Sources */,
 				AE77838D23E32ED20093EABD /* ContactDetailViewModel.swift in Sources */,
 				30DAF71C275901610073C154 /* SettingsBackgroundSelectionController.swift in Sources */,
 				3010968926838A050032CBA0 /* VideoInviteCell.swift in Sources */,
 				303492CB257A814200A523D0 /* DraftArea.swift in Sources */,
 				AEE6EC3F2282C59C00EDC689 /* GroupMembersViewController.swift in Sources */,
-				30558A4527709AFA008781EE /* AttachmentsView.swift in Sources */,
 				B26B3BC7236DC3DC008ED35A /* SwitchCell.swift in Sources */,
 				AEE700252438E0E500D6992E /* ProgressAlertHandler.swift in Sources */,
 				30E348E524F6647D005C93D1 /* FileTextCell.swift in Sources */,
+				30558B5527752C73008781EE /* InputBarButtonItem.swift in Sources */,
 				306C32322445CDE9001D89F3 /* DcLogger.swift in Sources */,
-				30558A5827709AFA008781EE /* InputBarAccessoryViewDelegate.swift in Sources */,
 				307A82CC25B8D26700748B57 /* ChatEditingBar.swift in Sources */,
+				30558B5227752C73008781EE /* InputPlugin.swift in Sources */,
+				30558B3927752C72008781EE /* UITextView+Extensions.swift in Sources */,
+				30558B3A27752C72008781EE /* NSMutableAttributedString+Extensions.swift in Sources */,
 				303492952565AABC00A523D0 /* DraftModel.swift in Sources */,
 				78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */,
 				AE8519EA2272FDCA00ED86F0 /* DeviceContactsHandler.swift in Sources */,
-				30558A4327709AFA008781EE /* ImageAttachmentCell.swift in Sources */,
 				302E592426A5CF4800DD4F58 /* ConnectivityViewController.swift in Sources */,
+				30558B4127752C72008781EE /* AttachmentsView.swift in Sources */,
 				78ED838321D5379000243125 /* TextFieldCell.swift in Sources */,
+				30558B5027752C73008781EE /* KeyboardNotification.swift in Sources */,
 				305702A124C6453700D84EFC /* TypeAlias.swift in Sources */,
 				AE19887523EB264000B4CD5F /* HelpViewController.swift in Sources */,
 				AE0D26FD1FB1FE88002FAFCE /* ChatListController.swift in Sources */,
 				302D5450268B6B2300A8B271 /* MessageUtils.swift in Sources */,
 				30149D9322F21129003C12B5 /* QrViewController.swift in Sources */,
-				30558A4C27709AFA008781EE /* AutocompleteCell.swift in Sources */,
 				AEE56D80225504DB007DC082 /* Extensions.swift in Sources */,
 				7A0052C81FBE6CB40048C3BF /* NewContactController.swift in Sources */,
-				30558A3D27709AFA008781EE /* UIView+AutoLayout.swift in Sources */,
+				30558B4427752C72008781EE /* AutocompleteManager.swift in Sources */,
 				30860EE926F49E64002651A6 /* DownloadOnDemandViewController.swift in Sources */,
 				AEE56D762253431E007DC082 /* AccountSetupController.swift in Sources */,
 				AE8F503524753DFE007FEE0B /* GalleryViewController.swift in Sources */,
 				B2C42570265C325C00B95377 /* MultilineLabelCell.swift in Sources */,
+				30558B4A27752C72008781EE /* AutocompleteManagerDataSource.swift in Sources */,
 				AEF53BD5248904BF00D309C1 /* GalleryTimeLabel.swift in Sources */,
-				30558A5C27709AFA008781EE /* InputBarViewController.swift in Sources */,
 				AEE6EC482283045D00EDC689 /* EditSettingsController.swift in Sources */,
 				30653081254358B10093E196 /* QuoteView.swift in Sources */,
+				30558B5127752C73008781EE /* KeyboardEvent.swift in Sources */,
+				30558B3827752C72008781EE /* String+Extensions.swift in Sources */,
+				30558B4C27752C72008781EE /* InputStackView.swift in Sources */,
 				3067AAC62667F3FE00525036 /* ImageFormat.swift in Sources */,
-				30558A4F27709AFA008781EE /* InputStackView.swift in Sources */,
 				30E348DF24F3F819005C93D1 /* ChatTableView.swift in Sources */,
+				30558B3F27752C72008781EE /* ImageAttachmentCell.swift in Sources */,
 				30EF7308252F6A3300E2C54A /* PaddingTextView.swift in Sources */,
-				30558A4E27709AFA008781EE /* AutocompleteManagerDataSource.swift in Sources */,
 				30E348E124F53772005C93D1 /* ImageTextCell.swift in Sources */,
 				3008CB7624F95B6D00E6A617 /* AudioController.swift in Sources */,
 				302B84CE2397F6CD001C261F /* URL+Extension.swift in Sources */,
 				7A9FB1441FB061E2001FEA36 /* AppDelegate.swift in Sources */,
+				30558B5627752C73008781EE /* InputBarSendButton.swift in Sources */,
 				3034929F25752FC800A523D0 /* MediaPreview.swift in Sources */,
+				30558B5427752C73008781EE /* InputItem.swift in Sources */,
 				AE76E5EE242BF2EA003CF461 /* WelcomeViewController.swift in Sources */,
+				30558B4F27752C73008781EE /* KeyboardManager.swift in Sources */,
 				3052C60A253F082E007D13EA /* MessageLabelDelegate.swift in Sources */,
+				30558B3E27752C72008781EE /* AttachmentManager.swift in Sources */,
 				AE0AA9562478191900D42A7F /* GridCollectionViewFlowLayout.swift in Sources */,
 				AEA0F6A124474146009F887B /* ProfileInfoViewController.swift in Sources */,
 				303492A5257546B400A523D0 /* DraftPreview.swift in Sources */,
+				30558B4527752C72008781EE /* AutocompleteSession.swift in Sources */,
 				305961D02346125100C80F33 /* NSAttributedString+Extensions.swift in Sources */,
-				30558A5A27709AFA008781EE /* InputBarAccessoryView+Availability.swift in Sources */,
+				30558B4D27752C72008781EE /* InputTextView.swift in Sources */,
 				21D6C941260623F500D0755A /* NotificationManager.swift in Sources */,
-				30558A5527709AFA008781EE /* HorizontalEdgeInsets.swift.swift in Sources */,
 				302B84C72396770B001C261F /* RelayHelper.swift in Sources */,
+				30558B3B27752C72008781EE /* UIView+AutoLayout.swift in Sources */,
 				305961CF2346125100C80F33 /* UIColor+Extensions.swift in Sources */,
-				30558A5027709AFA008781EE /* InputTextView.swift in Sources */,
 				AEACE2E51FB32E1900DCDD78 /* Utils.swift in Sources */,
 				3052C60E253F088E007D13EA /* DetectorType.swift in Sources */,
-				30558A4A27709AFA008781EE /* AutocompleteCompletion.swift in Sources */,
 				30349291256441E200A523D0 /* QuotePreview.swift in Sources */,
 				AEC67A1E241FCFE0007DDBE1 /* ChatListViewModel.swift in Sources */,
 				30FDB71F24D8170E0066C48D /* TextMessageCell.swift in Sources */,
-				30558A3C27709AFA008781EE /* NSMutableAttributedString+Extensions.swift in Sources */,
 				AE1988A523EB2FBA00B4CD5F /* Errors.swift in Sources */,
 				302D5454268B84CB00A8B271 /* SettingsVideoChatViewController.swift in Sources */,
 				AEFBE22F23FEF23D0045327A /* ProviderInfoCell.swift in Sources */,
@@ -1657,34 +1642,30 @@
 				305961D22346125100C80F33 /* CGRect+Extensions.swift in Sources */,
 				3057029B24C6441300D84EFC /* EmptyStateLabel.swift in Sources */,
 				30260CA7238F02F700D8D52C /* MultilineTextFieldCell.swift in Sources */,
-				30558A5427709AFA008781EE /* InputBarAccessoryView.swift in Sources */,
 				70B8882E2091B8550074812E /* ContactCell.swift in Sources */,
 				305961CD2346125100C80F33 /* UIEdgeInsets+Extensions.swift in Sources */,
 				30EF7324252FF15F00E2C54A /* MessageLabel.swift in Sources */,
 				30C0D49D237C4908008E2A0E /* CertificateCheckController.swift in Sources */,
-				30558A4727709AFA008781EE /* AttachmentManagerDelegate.swift in Sources */,
 				304F769525DD237B0094B5E2 /* WebViewViewController.swift in Sources */,
 				7092474120B3869500AF8799 /* ContactDetailViewController.swift in Sources */,
-				30558A4627709AFA008781EE /* AttachmentManagerDataSource.swift in Sources */,
 				30F9B9EC235F2116006E7ACF /* MessageCounter.swift in Sources */,
 				304F769925DD23D70094B5E2 /* FullMessageViewController.swift in Sources */,
 				AE0AA952247800E700D42A7F /* GalleryCell.swift in Sources */,
 				AE0AA958247834A400D42A7F /* Date+Extension.swift in Sources */,
-				30558A4427709AFA008781EE /* AttachmentCell.swift in Sources */,
 				307D822E241669C7006D2490 /* LocationManager.swift in Sources */,
-				30558A4927709AFA008781EE /* AutocompleteSession.swift in Sources */,
 				AE851AD0227DF50900ED86F0 /* GroupChatDetailViewController.swift in Sources */,
 				30FDB72124D838240066C48D /* BaseMessageCell.swift in Sources */,
+				30558B3C27752C72008781EE /* HorizontalEdgePadding.swift in Sources */,
 				7A451DB01FB1F84900177250 /* AppCoordinator.swift in Sources */,
 				AE38B31822672DFC00EC37A1 /* ActionCell.swift in Sources */,
 				AE9DAF0D22C1215D004C9591 /* EditContactController.swift in Sources */,
 				302D546A2693591700A8B271 /* ChatContactRequestBar.swift in Sources */,
 				305DDD8725DD97BF00974489 /* DynamicFontButton.swift in Sources */,
-				30558A4027709AFA008781EE /* KeyboardEvent.swift in Sources */,
 				785BE16821E247F1003BE98C /* MessageInfoViewController.swift in Sources */,
 				AED423D3249F578B00B6B2BB /* AddGroupMembersViewController.swift in Sources */,
+				30558B4627752C72008781EE /* AutocompleteCompletion.swift in Sources */,
+				30558B3627752C72008781EE /* InputBarAccessoryView.swift in Sources */,
 				AE851AC5227C755A00ED86F0 /* Protocols.swift in Sources */,
-				30558A5927709AFA008781EE /* InputItem.swift in Sources */,
 				AE728F15229D5C390047565B /* PhotoPickerAlertAction.swift in Sources */,
 				AECEF03E244F2D55006C90DA /* QrPageController.swift in Sources */,
 				AEACE2E31FB32B5C00DCDD78 /* Constants.swift in Sources */,

+ 0 - 354
deltachat-ios/View/InputBarAccessoryView/Controls/InputBarButtonItem.swift

@@ -1,354 +0,0 @@
-//
-//  InputBarButtonItem.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import UIKit
-
-/**
- A InputItem that inherits from UIButton
- 
- ## Important Notes ##
- 1. Intended to be used in an `InputStackView`
- */
-open class InputBarButtonItem: UIButton, InputItem {
-    
-    /// The spacing properties of the InputBarButtonItem
-    ///
-    /// - fixed: The spacing is fixed
-    /// - flexible: The spacing is flexible
-    /// - none: There is no spacing
-    public enum Spacing {
-        case fixed(CGFloat)
-        case flexible
-        case none
-    }
-    
-    public typealias InputBarButtonItemAction = ((InputBarButtonItem) -> Void)
-    
-    // MARK: - Properties
-    
-    /// A weak reference to the InputBarAccessoryView that the InputBarButtonItem used in
-    open weak var inputBarAccessoryView: InputBarAccessoryView?
-    
-    /// The spacing property of the InputBarButtonItem that determines the contentHuggingPriority and any
-    /// additional space to the intrinsicContentSize
-    open var spacing: Spacing = .none {
-        didSet {
-            switch spacing {
-            case .flexible:
-                setContentHuggingPriority(UILayoutPriority(rawValue: 1), for: .horizontal)
-            case .fixed:
-                setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .horizontal)
-            case .none:
-                setContentHuggingPriority(UILayoutPriority(rawValue: 500), for: .horizontal)
-            }
-        }
-    }
-    
-    /// When not nil this size overrides the intrinsicContentSize
-    private var size: CGSize? = CGSize(width: 20, height: 20) {
-        didSet {
-            invalidateIntrinsicContentSize()
-        }
-    }
-    
-    open override var intrinsicContentSize: CGSize {
-        var contentSize = size ?? super.intrinsicContentSize
-        switch spacing {
-        case .fixed(let width):
-            contentSize.width += width
-        case .flexible, .none:
-            break
-        }
-        return contentSize
-    }
-    
-    /// A reference to the stack view position that the InputBarButtonItem is held in
-    open var parentStackViewPosition: InputStackView.Position?
-    
-    /// The title for the UIControlState.normal
-    open var title: String? {
-        get {
-            return title(for: .normal)
-        }
-        set {
-            setTitle(newValue, for: .normal)
-        }
-    }
-    
-    /// The image for the UIControlState.normal
-    open var image: UIImage? {
-        get {
-            return image(for: .normal)
-        }
-        set {
-            setImage(newValue, for: .normal)
-        }
-    }
-    
-    /// Calls the onSelectedAction or onDeselectedAction when set
-    open override var isHighlighted: Bool {
-        get {
-            return super.isHighlighted
-        }
-        set {
-            guard newValue != isHighlighted else { return }
-            super.isHighlighted = newValue
-            if newValue {
-                onSelectedAction?(self)
-            } else {
-                onDeselectedAction?(self)
-            }
-
-        }
-    }
-
-    /// Calls the onEnabledAction or onDisabledAction when set
-    open override var isEnabled: Bool {
-        didSet {
-            if isEnabled {
-                onEnabledAction?(self)
-            } else {
-                onDisabledAction?(self)
-            }
-        }
-    }
-    
-    // MARK: - Reactive Hooks
-    
-    private var onTouchUpInsideAction: InputBarButtonItemAction?
-    private var onKeyboardEditingBeginsAction: InputBarButtonItemAction?
-    private var onKeyboardEditingEndsAction: InputBarButtonItemAction?
-    private var onKeyboardSwipeGestureAction: ((InputBarButtonItem, UISwipeGestureRecognizer) -> Void)?
-    private var onTextViewDidChangeAction: ((InputBarButtonItem, InputTextView) -> Void)?
-    private var onSelectedAction: InputBarButtonItemAction?
-    private var onDeselectedAction: InputBarButtonItemAction?
-    private var onEnabledAction: InputBarButtonItemAction?
-    private var onDisabledAction: InputBarButtonItemAction?
-    
-    // MARK: - Initialization
-    
-    public convenience init() {
-        self.init(frame: .zero)
-    }
-    
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    // MARK: - Setup
-    
-    /// Sets up the default properties
-    open func setup() {
-        contentVerticalAlignment = .center
-        contentHorizontalAlignment = .center
-        imageView?.contentMode = .scaleAspectFit
-        setContentHuggingPriority(UILayoutPriority(rawValue: 500), for: .horizontal)
-        setContentHuggingPriority(UILayoutPriority(rawValue: 500), for: .vertical)
-        setTitleColor(UIColor(red: 0, green: 122/255, blue: 1, alpha: 1), for: .normal)
-        setTitleColor(UIColor(red: 0, green: 122/255, blue: 1, alpha: 0.3), for: .highlighted)
-        setTitleColor(.lightGray, for: .disabled)
-        adjustsImageWhenHighlighted = false
-        addTarget(self, action: #selector(InputBarButtonItem.touchUpInsideAction), for: .touchUpInside)
-    }
-    
-    // MARK: - Size Adjustment
-    
-    /// Sets the size of the InputBarButtonItem which overrides the intrinsicContentSize. When set to nil
-    /// the default intrinsicContentSize is used. The new size will be laid out in the UIStackView that
-    /// the InputBarButtonItem is held in
-    ///
-    /// - Parameters:
-    ///   - newValue: The new size
-    ///   - animated: If the layout should be animated
-    open func setSize(_ newValue: CGSize?, animated: Bool) {
-        size = newValue
-        if animated, let position = parentStackViewPosition {
-            inputBarAccessoryView?.performLayout(animated) { [weak self] in
-                self?.inputBarAccessoryView?.layoutStackViews([position])
-            }
-        }
-    }
-    
-    // MARK: - Hook Setup Methods
-    
-    /// Used to setup your own initial properties
-    ///
-    /// - Parameter item: A reference to Self
-    /// - Returns: Self
-    @discardableResult
-    open func configure(_ item: InputBarButtonItemAction) -> Self {
-        item(self)
-        return self
-    }
-    
-    /// Sets the onKeyboardEditingBeginsAction
-    ///
-    /// - Parameter action: The new onKeyboardEditingBeginsAction
-    /// - Returns: Self
-    @discardableResult
-    open func onKeyboardEditingBegins(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onKeyboardEditingBeginsAction = action
-        return self
-    }
-    
-    /// Sets the onKeyboardEditingEndsAction
-    ///
-    /// - Parameter action: The new onKeyboardEditingEndsAction
-    /// - Returns: Self
-    @discardableResult
-    open func onKeyboardEditingEnds(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onKeyboardEditingEndsAction = action
-        return self
-    }
-    
-    
-    /// Sets the onKeyboardSwipeGestureAction
-    ///
-    /// - Parameter action: The new onKeyboardSwipeGestureAction
-    /// - Returns: Self
-    @discardableResult
-    open func onKeyboardSwipeGesture(_ action: @escaping (_ item: InputBarButtonItem, _ gesture: UISwipeGestureRecognizer) -> Void) -> Self {
-        onKeyboardSwipeGestureAction = action
-        return self
-    }
-    
-    /// Sets the onTextViewDidChangeAction
-    ///
-    /// - Parameter action: The new onTextViewDidChangeAction
-    /// - Returns: Self
-    @discardableResult
-    open func onTextViewDidChange(_ action: @escaping (_ item: InputBarButtonItem, _ textView: InputTextView) -> Void) -> Self {
-        onTextViewDidChangeAction = action
-        return self
-    }
-    
-    /// Sets the onTouchUpInsideAction
-    ///
-    /// - Parameter action: The new onTouchUpInsideAction
-    /// - Returns: Self
-    @discardableResult
-    open func onTouchUpInside(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onTouchUpInsideAction = action
-        return self
-    }
-    
-    /// Sets the onSelectedAction
-    ///
-    /// - Parameter action: The new onSelectedAction
-    /// - Returns: Self
-    @discardableResult
-    open func onSelected(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onSelectedAction = action
-        return self
-    }
-    
-    /// Sets the onDeselectedAction
-    ///
-    /// - Parameter action: The new onDeselectedAction
-    /// - Returns: Self
-    @discardableResult
-    open func onDeselected(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onDeselectedAction = action
-        return self
-    }
-    
-    /// Sets the onEnabledAction
-    ///
-    /// - Parameter action: The new onEnabledAction
-    /// - Returns: Self
-    @discardableResult
-    open func onEnabled(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onEnabledAction = action
-        return self
-    }
-    
-    /// Sets the onDisabledAction
-    ///
-    /// - Parameter action: The new onDisabledAction
-    /// - Returns: Self
-    @discardableResult
-    open func onDisabled(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onDisabledAction = action
-        return self
-    }
-    
-    // MARK: - InputItem Protocol
-    
-    /// Executes the onTextViewDidChangeAction with the given textView
-    ///
-    /// - Parameter textView: A reference to the InputTextView
-    open func textViewDidChangeAction(with textView: InputTextView) {
-        onTextViewDidChangeAction?(self, textView)
-    }
-    
-    /// Executes the onKeyboardSwipeGestureAction with the given gesture
-    ///
-    /// - Parameter gesture: A reference to the gesture that was recognized
-    open func keyboardSwipeGestureAction(with gesture: UISwipeGestureRecognizer) {
-        onKeyboardSwipeGestureAction?(self, gesture)
-    }
-    
-    /// Executes the onKeyboardEditingEndsAction
-    open func keyboardEditingEndsAction() {
-        onKeyboardEditingEndsAction?(self)
-    }
-    
-    /// Executes the onKeyboardEditingBeginsAction
-    open func keyboardEditingBeginsAction() {
-        onKeyboardEditingBeginsAction?(self)
-    }
-    
-    /// Executes the onTouchUpInsideAction
-    @objc
-    open func touchUpInsideAction() {
-        onTouchUpInsideAction?(self)
-    }
-    
-    // MARK: - Static Spacers
-    
-    /// An InputBarButtonItem that's spacing property is set to be .flexible
-    public static var flexibleSpace: InputBarButtonItem {
-        let item = InputBarButtonItem()
-        item.setSize(.zero, animated: false)
-        item.spacing = .flexible
-        return item
-    }
-    
-    /// An InputBarButtonItem that's spacing property is set to be .fixed with the width arguement
-    public static func fixedSpace(_ width: CGFloat) -> InputBarButtonItem {
-        let item = InputBarButtonItem()
-        item.setSize(.zero, animated: false)
-        item.spacing = .fixed(width)
-        return item
-    }
-}

+ 0 - 96
deltachat-ios/View/InputBarAccessoryView/Controls/InputBarSendButton.swift

@@ -1,96 +0,0 @@
-//
-//  InputBarSendButton.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import UIKit
-
-open class InputBarSendButton: InputBarButtonItem {
-
-    /// A flag indicating the animation state of the `InputBarSendButton`
-    open private(set) var isAnimating: Bool = false
-
-    /// Accessor to modify the color of the activity view
-    open var activityViewColor: UIColor! {
-        get {
-            return activityView.color
-        }
-        set {
-            activityView.color = newValue
-        }
-    }
-
-    private let activityView: UIActivityIndicatorView = {
-        let view = UIActivityIndicatorView(style: .gray)
-        view.isUserInteractionEnabled = false
-        view.isHidden = true
-        return view
-    }()
-
-    public convenience init() {
-        self.init(frame: .zero)
-    }
-
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setupSendButton()
-    }
-
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setupSendButton()
-    }
-
-    private func setupSendButton() {
-        addSubview(activityView)
-    }
-
-    open override func layoutSubviews() {
-        super.layoutSubviews()
-        activityView.frame = bounds
-    }
-
-    /// Starts the animation of the activity view, hiding other elements
-    open func startAnimating() {
-        guard !isAnimating else { return }
-        defer { isAnimating = true }
-        activityView.startAnimating()
-        activityView.isHidden = false
-        // Setting isHidden doesn't hide the elements
-        titleLabel?.alpha = 0
-        imageView?.layer.transform = CATransform3DMakeScale(0.0, 0.0, 0.0)
-    }
-
-    /// Stops the animation of the activity view, shows other elements
-    open func stopAnimating() {
-        guard isAnimating else { return }
-        defer { isAnimating = false }
-        activityView.stopAnimating()
-        activityView.isHidden = true
-        titleLabel?.alpha = 1
-        imageView?.layer.transform = CATransform3DIdentity
-    }
-
-}

+ 0 - 98
deltachat-ios/View/InputBarAccessoryView/Extensions/NSMutableAttributedString+Extensions.swift

@@ -1,98 +0,0 @@
-//
-//  NSMutableAttributedString+Extensions.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/25/17.
-//
-
-import UIKit
-
-internal extension NSMutableAttributedString {
- 
-    @discardableResult
-    func bold(_ text: String, fontSize: CGFloat = UIFont.preferredFont(forTextStyle: .body).pointSize, textColor: UIColor = .black) -> NSMutableAttributedString {
-        let attrs: [NSAttributedString.Key:AnyObject] = [
-            NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: fontSize),
-            NSAttributedString.Key.foregroundColor : textColor
-        ]
-        let boldString = NSMutableAttributedString(string: text, attributes: attrs)
-        self.append(boldString)
-        return self
-    }
-    
-    @discardableResult
-    func medium(_ text: String, fontSize: CGFloat = UIFont.preferredFont(forTextStyle: .body).pointSize, textColor: UIColor = .black) -> NSMutableAttributedString {
-        let attrs: [NSAttributedString.Key:AnyObject] = [
-            NSAttributedString.Key.font : UIFont.systemFont(ofSize: fontSize, weight: UIFont.Weight.medium),
-            NSAttributedString.Key.foregroundColor : textColor
-        ]
-        let mediumString = NSMutableAttributedString(string: text, attributes: attrs)
-        self.append(mediumString)
-        return self
-    }
-    
-    @discardableResult
-    func italic(_ text: String, fontSize: CGFloat = UIFont.preferredFont(forTextStyle: .body).pointSize, textColor: UIColor = .black) -> NSMutableAttributedString {
-        let attrs: [NSAttributedString.Key:AnyObject] = [
-            NSAttributedString.Key.font : UIFont.italicSystemFont(ofSize: fontSize),
-            NSAttributedString.Key.foregroundColor : textColor
-        ]
-        let italicString = NSMutableAttributedString(string: text, attributes: attrs)
-        self.append(italicString)
-        return self
-    }
-    
-    @discardableResult
-    func normal(_ text: String, fontSize: CGFloat = UIFont.preferredFont(forTextStyle: .body).pointSize, textColor: UIColor = .black) -> NSMutableAttributedString {
-        let attrs:[NSAttributedString.Key:AnyObject] = [
-            NSAttributedString.Key.font : UIFont.systemFont(ofSize: fontSize),
-            NSAttributedString.Key.foregroundColor : textColor
-        ]
-        let normal =  NSMutableAttributedString(string: text, attributes: attrs)
-        self.append(normal)
-        return self
-    }
-
-}
-
-internal extension NSAttributedString {
-
-    func replacingCharacters(in range: NSRange, with attributedString: NSAttributedString) -> NSMutableAttributedString {
-        let ns = NSMutableAttributedString(attributedString: self)
-        ns.replaceCharacters(in: range, with: attributedString)
-        return ns
-    }
-    
-    static func += (lhs: inout NSAttributedString, rhs: NSAttributedString) {
-        let ns = NSMutableAttributedString(attributedString: lhs)
-        ns.append(rhs)
-        lhs = ns
-    }
-    
-    static func + (lhs: NSAttributedString, rhs: NSAttributedString) -> NSAttributedString {
-        let ns = NSMutableAttributedString(attributedString: lhs)
-        ns.append(rhs)
-        return NSAttributedString(attributedString: ns)
-    }
-    
-}

+ 0 - 89
deltachat-ios/View/InputBarAccessoryView/Extensions/NSNotification+Extensions.swift

@@ -1,89 +0,0 @@
-//
-//  NSNotification+Extensions.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/25/17.
-//
-
-import UIKit
-
-internal extension NSNotification {
-    
-    var event: KeyboardEvent {
-        switch self.name {
-        case UIResponder.keyboardWillShowNotification:
-            return .willShow
-        case UIResponder.keyboardDidShowNotification:
-            return .didShow
-        case UIResponder.keyboardWillHideNotification:
-            return .willHide
-        case UIResponder.keyboardDidHideNotification:
-            return .didHide
-        case UIResponder.keyboardWillChangeFrameNotification:
-            return .willChangeFrame
-        case UIResponder.keyboardDidChangeFrameNotification:
-            return .didChangeFrame
-        default:
-            return .unknown
-        }
-    }
-    
-    var timeInterval: TimeInterval? {
-        guard let value = userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber else { return nil }
-        return TimeInterval(truncating: value)
-    }
-    
-    var animationCurve: UIView.AnimationCurve? {
-        guard let index = (userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.intValue else { return nil }
-        guard index >= 0 && index <= 3 else { return .linear }
-        return UIView.AnimationCurve.init(rawValue: index) ?? .linear
-    }
-    
-    var animationOptions: UIView.AnimationOptions {
-        guard let curve = animationCurve else { return [] }
-        switch curve {
-        case .easeIn:
-            return .curveEaseIn
-        case .easeOut:
-            return .curveEaseOut
-        case .easeInOut:
-            return .curveEaseInOut
-        case .linear:
-            return .curveLinear
-        }
-    }
-    
-    var startFrame: CGRect? {
-        return (userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
-    }
-    
-    var endFrame: CGRect? {
-        return (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
-    }
-    
-    var isForCurrentApp: Bool? {
-        return (userInfo?[UIResponder.keyboardIsLocalUserInfoKey] as? NSNumber)?.boolValue
-    }
-    
-}
-

+ 0 - 17
deltachat-ios/View/InputBarAccessoryView/Extensions/String+Extensions.swift

@@ -1,17 +0,0 @@
-//
-//  String+Extensions.swift
-//  InputBarAccessoryView
-//
-//  Created by Ryan Nystrom on 12/22/17.
-//  Modified by Nathan Tannar on 09/18/18
-//  Copyright © 2017 Ryan Nystrom. All rights reserved.
-//
-
-import Foundation
-
-internal extension Character {
-    
-    static var space: Character {
-        return " "
-    }
-}

+ 0 - 64
deltachat-ios/View/InputBarAccessoryView/Extensions/UITextView+Extensions.swift

@@ -1,64 +0,0 @@
-//
-//  UITextView+Extensions.swift
-//  InputBarAccessoryView
-//
-//  Created by Nathan Tannar on 09/18/18.
-//  Copyright © 2018 Nathan Tannar. All rights reserved.
-//
-
-import UIKit
-
-internal extension UITextView {
-
-    typealias Match = (prefix: String, word: String, range: NSRange)
-    
-    func find(prefixes: Set<String>, with delimiterSet: CharacterSet) -> Match? {
-        guard !prefixes.isEmpty else { return nil }
-
-        for prefix in prefixes {
-            if let match = find(prefix: prefix, with: delimiterSet) {
-                return match
-            }
-        }
-        return nil
-    }
-    
-    func find(prefix: String, with delimiterSet: CharacterSet) -> Match? {
-        guard !prefix.isEmpty else { return nil }
-        guard let caretRange = self.caretRange else { return nil }
-        guard let cursorRange = Range(caretRange, in: text) else { return nil }
-        
-        let leadingText = text[..<cursorRange.upperBound]
-        var prefixStartIndex: String.Index!
-        for (i, char) in prefix.enumerated() {
-            guard let index = leadingText.lastIndex(of: char) else { return nil }
-            if i == 0 {
-                prefixStartIndex = index
-            } else if index.encodedOffset == prefixStartIndex.encodedOffset + 1 {
-                prefixStartIndex = index
-            } else {
-                return nil
-            }
-        }
-
-        let wordRange = prefixStartIndex..<cursorRange.upperBound
-        let word = leadingText[wordRange]
-        
-        let location = wordRange.lowerBound.encodedOffset
-        let length = wordRange.upperBound.encodedOffset - location
-        let range = NSRange(location: location, length: length)
-        
-        return (String(prefix), String(word), range)
-    }
-
-    var caretRange: NSRange? {
-        guard let selectedRange = self.selectedTextRange else { return nil }
-        return NSRange(
-            location: offset(from: beginningOfDocument, to: selectedRange.start),
-            length: offset(from: selectedRange.start, to: selectedRange.end)
-        )
-    }
-    
-}
-
-

+ 0 - 96
deltachat-ios/View/InputBarAccessoryView/Extensions/UIView+AutoLayout.swift

@@ -1,96 +0,0 @@
-//
-//  UIView+Autolayout.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 2/12/17.
-//
-
-import UIKit
-
-internal extension UIView {
-    
-    func fillSuperview() {
-        guard let superview = self.superview else {
-            return
-        }
-        translatesAutoresizingMaskIntoConstraints = false
-        leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true
-        rightAnchor.constraint(equalTo: superview.rightAnchor).isActive = true
-        topAnchor.constraint(equalTo: superview.topAnchor).isActive = true
-        bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true
-    }
-
-    @discardableResult
-    func addConstraints(_ top: NSLayoutYAxisAnchor? = nil, left: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil, right: NSLayoutXAxisAnchor? = nil, topConstant: CGFloat = 0, leftConstant: CGFloat = 0, bottomConstant: CGFloat = 0, rightConstant: CGFloat = 0, widthConstant: CGFloat = 0, heightConstant: CGFloat = 0) -> [NSLayoutConstraint] {
-        
-        if self.superview == nil {
-            return []
-        }
-        translatesAutoresizingMaskIntoConstraints = false
-        
-        var constraints = [NSLayoutConstraint]()
-        
-        if let top = top {
-            let constraint = topAnchor.constraint(equalTo: top, constant: topConstant)
-            constraint.identifier = "top"
-            constraints.append(constraint)
-        }
-        
-        if let left = left {
-            let constraint = leftAnchor.constraint(equalTo: left, constant: leftConstant)
-            constraint.identifier = "left"
-            constraints.append(constraint)
-        }
-        
-        if let bottom = bottom {
-            let constraint = bottomAnchor.constraint(equalTo: bottom, constant: -bottomConstant)
-            constraint.identifier = "bottom"
-            constraints.append(constraint)
-        }
-        
-        if let right = right {
-            let constraint = rightAnchor.constraint(equalTo: right, constant: -rightConstant)
-            constraint.identifier = "right"
-            constraints.append(constraint)
-        }
-        
-        if widthConstant > 0 {
-            let constraint = widthAnchor.constraint(equalToConstant: widthConstant)
-            constraint.identifier = "width"
-            constraints.append(constraint)
-        }
-        
-        if heightConstant > 0 {
-            let constraint = heightAnchor.constraint(equalToConstant: heightConstant)
-            constraint.identifier = "height"
-            constraints.append(constraint)
-        }
-        
-        constraints.forEach { $0.isActive = true }
-        return constraints
-    }
-    
-    func removeAllConstraints() {
-        constraints.forEach { removeConstraint($0) }
-    }
-}

+ 0 - 903
deltachat-ios/View/InputBarAccessoryView/InputBarAccessoryView.swift

@@ -1,903 +0,0 @@
-//
-//  InputBarAccessoryView.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import UIKit
-
-/// A powerful InputAccessoryView ideal for messaging applications
-open class InputBarAccessoryView: UIView {
-    
-    // MARK: - Properties
-    
-    /// A delegate to broadcast notifications from the `InputBarAccessoryView`
-    open weak var delegate: InputBarAccessoryViewDelegate?
-    
-    /// The background UIView anchored to the bottom, left, and right of the InputBarAccessoryView
-    /// with a top anchor equal to the bottom of the top InputStackView
-    open var backgroundView: UIView = {
-        let view = UIView()
-        view.translatesAutoresizingMaskIntoConstraints = false
-        view.backgroundColor = .white
-        return view
-    }()
-    
-    /// A content UIView that holds the left/right/bottom InputStackViews
-    /// and the middleContentView. Anchored to the bottom of the
-    /// topStackView and inset by the padding UIEdgeInsets
-    open var contentView: UIView = {
-        let view = UIView()
-        view.translatesAutoresizingMaskIntoConstraints = false
-        return view
-    }()
-    
-    /**
-     A UIVisualEffectView that adds a blur effect to make the view appear transparent.
-     
-     ## Important Notes ##
-     1. The blurView is initially not added to the backgroundView to improve performance when not needed. When `isTranslucent` is set to TRUE for the first time the blurView is added and anchored to the `backgroundView`s edge anchors
-    */
-    open var blurView: UIVisualEffectView = {
-        let blurEffect = UIBlurEffect(style: .light)
-        let view = UIVisualEffectView(effect: blurEffect)
-        view.translatesAutoresizingMaskIntoConstraints = false
-        return view
-    }()
-    
-    /// Determines if the InputBarAccessoryView should have a translucent effect
-    open var isTranslucent: Bool = false {
-        didSet {
-            if isTranslucent && blurView.superview == nil {
-                backgroundView.addSubview(blurView)
-                blurView.fillSuperview()
-            }
-            blurView.isHidden = !isTranslucent
-            let color: UIColor = backgroundView.backgroundColor ?? .white
-            backgroundView.backgroundColor = isTranslucent ? color.withAlphaComponent(0.75) : color
-        }
-    }
-
-    /// A SeparatorLine that is anchored at the top of the InputBarAccessoryView
-    public let separatorLine = SeparatorLine()
-    
-    /**
-     The InputStackView at the InputStackView.top position
-     
-     ## Important Notes ##
-     1. It's axis is initially set to .vertical
-     2. It's alignment is initially set to .fill
-     */
-    public let topStackView: InputStackView = {
-        let stackView = InputStackView(axis: .vertical, spacing: 0)
-        stackView.alignment = .fill
-        return stackView
-    }()
-    
-    /**
-     The InputStackView at the InputStackView.left position
-     
-     ## Important Notes ##
-     1. It's axis is initially set to .horizontal
-     */
-    public let leftStackView = InputStackView(axis: .horizontal, spacing: 0)
-    
-    /**
-     The InputStackView at the InputStackView.right position
-     
-     ## Important Notes ##
-     1. It's axis is initially set to .horizontal
-     */
-    public let rightStackView = InputStackView(axis: .horizontal, spacing: 0)
-    
-    /**
-     The InputStackView at the InputStackView.bottom position
-     
-     ## Important Notes ##
-     1. It's axis is initially set to .horizontal
-     2. It's spacing is initially set to 15
-     */
-    public let bottomStackView = InputStackView(axis: .horizontal, spacing: 15)
-
-    /**
-     The main view component of the InputBarAccessoryView
-
-     The default value is the `InputTextView`.
-
-     ## Important Notes ##
-     1. This view should self-size with constraints or an
-        intrinsicContentSize to auto-size the InputBarAccessoryView
-     2. Override with `setMiddleContentView(view: UIView?, animated: Bool)`
-     */
-    public private(set) weak var middleContentView: UIView?
-
-    /// A view to wrap the `middleContentView` inside
-    private let middleContentViewWrapper: UIView = {
-        let view = UIView()
-        view.translatesAutoresizingMaskIntoConstraints = false
-        return view
-    }()
-    
-    /// The InputTextView a user can input a message in
-    open lazy var inputTextView: InputTextView = { [weak self] in
-        let inputTextView = InputTextView()
-        inputTextView.translatesAutoresizingMaskIntoConstraints = false
-        inputTextView.inputBarAccessoryView = self
-        return inputTextView
-    }()
-    
-    /// A InputBarButtonItem used as the send button and initially placed in the rightStackView
-    open var sendButton: InputBarSendButton = {
-        return InputBarSendButton()
-            .configure {
-                $0.setSize(CGSize(width: 52, height: 36), animated: false)
-                $0.isEnabled = false
-                $0.title = "Send"
-                $0.titleLabel?.font = UIFont.systemFont(ofSize: 15, weight: .bold)
-            }.onTouchUpInside {
-                $0.inputBarAccessoryView?.didSelectSendButton()
-        }
-    }()
-
-    /**
-     The anchor contants used to add horizontal inset from the InputBarAccessoryView and the
-     window. By default, an `inputAccessoryView` spans the entire width of the UIWindow. You
-     can manage these insets if you wish to implement designs that do not have the bar spanning
-     the entire width.
-
-     ## Important Notes ##
-
-     USE AT YOUR OWN RISK
-
-     ````
-     H:|-(frameInsets.left)-[InputBarAccessoryView]-(frameInsets.right)-|
-     ````
-
-     */
-    open var frameInsets: HorizontalEdgePadding = .zero {
-        didSet {
-            updateFrameInsets()
-        }
-    }
-    
-    /**
-     The anchor constants used by the InputStackView's and InputTextView to create padding
-     within the InputBarAccessoryView
-     
-     ## Important Notes ##
-     
-     ````
-     V:|...[InputStackView.top]-(padding.top)-[contentView]-(padding.bottom)-|
-     
-     H:|-(frameInsets.left)-(padding.left)-[contentView]-(padding.right)-(frameInsets.right)-|
-     ````
-     
-     */
-    open var padding: UIEdgeInsets = UIEdgeInsets(top: 6, left: 12, bottom: 6, right: 12) {
-        didSet {
-            updatePadding()
-        }
-    }
-    
-    /**
-     The anchor constants used by the top InputStackView
-     
-     ## Important Notes ##
-     1. The topStackViewPadding.bottom property is not used. Use padding.top
-     
-     ````
-     V:|-(topStackViewPadding.top)-[InputStackView.top]-(padding.top)-[middleContentView]-...|
-     
-     H:|-(frameInsets.left)-(topStackViewPadding.left)-[InputStackView.top]-(topStackViewPadding.right)-(frameInsets.right)-|
-     ````
-     
-     */
-    open var topStackViewPadding: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) {
-        didSet {
-            updateTopStackViewPadding()
-        }
-    }
-    
-    /**
-     The anchor constants used by the middleContentView
-     
-     ````
-     V:|...-(padding.top)-(middleContentViewPadding.top)-[middleContentView]-(middleContentViewPadding.bottom)-[InputStackView.bottom]-...|
-     
-     H:|...-[InputStackView.left]-(middleContentViewPadding.left)-[middleContentView]-(middleContentViewPadding.right)-[InputStackView.right]-...|
-     ````
-     
-     */
-    open var middleContentViewPadding: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 8) {
-        didSet {
-            updateMiddleContentViewPadding()
-        }
-    }
-    
-    /// Returns the most recent size calculated by `calculateIntrinsicContentSize()`
-    open override var intrinsicContentSize: CGSize {
-        return cachedIntrinsicContentSize
-    }
-    
-    /// The intrinsicContentSize can change a lot so the delegate method
-    /// `inputBar(self, didChangeIntrinsicContentTo: size)` only needs to be called
-    /// when it's different
-    public private(set) var previousIntrinsicContentSize: CGSize?
-    
-    /// The most recent calculation of the intrinsicContentSize
-    private lazy var cachedIntrinsicContentSize: CGSize = calculateIntrinsicContentSize()
-    
-    /// A boolean that indicates if the maxTextViewHeight has been met. Keeping track of this
-    /// improves the performance
-    public private(set) var isOverMaxTextViewHeight = false
-    
-    /// A boolean that when set as `TRUE` will always enable the `InputTextView` to be anchored to the
-    /// height of `maxTextViewHeight`
-    /// The default value is `FALSE`
-    public private(set) var shouldForceTextViewMaxHeight = false
-    
-    /// A boolean that determines if the `maxTextViewHeight` should be maintained automatically.
-    /// To control the maximum height of the view yourself, set this to `false`.
-    open var shouldAutoUpdateMaxTextViewHeight = true
-
-    /// The maximum height that the InputTextView can reach.
-    /// This is set automatically when `shouldAutoUpdateMaxTextViewHeight` is true.
-    /// To control the height yourself, make sure to set `shouldAutoUpdateMaxTextViewHeight` to false.
-    open var maxTextViewHeight: CGFloat = 0 {
-        didSet {
-            textViewHeightAnchor?.constant = maxTextViewHeight
-        }
-    }
-    
-    /// A boolean that determines whether the sendButton's `isEnabled` state should be managed automatically.
-    open var shouldManageSendButtonEnabledState = true
-    
-    /// The height that will fit the current text in the InputTextView based on its current bounds
-    public var requiredInputTextViewHeight: CGFloat {
-        guard middleContentView == inputTextView else {
-            return middleContentView?.intrinsicContentSize.height ?? 0
-        }
-        let maxTextViewSize = CGSize(width: inputTextView.bounds.width, height: .greatestFiniteMagnitude)
-        return inputTextView.sizeThatFits(maxTextViewSize).height.rounded(.down)
-    }
-    
-    /// The fixed widthAnchor constant of the leftStackView
-    public private(set) var leftStackViewWidthConstant: CGFloat = 0 {
-        didSet {
-            leftStackViewLayoutSet?.width?.constant = leftStackViewWidthConstant
-        }
-    }
-    
-    /// The fixed widthAnchor constant of the rightStackView
-    public private(set) var rightStackViewWidthConstant: CGFloat = 52 {
-        didSet {
-            rightStackViewLayoutSet?.width?.constant = rightStackViewWidthConstant
-        }
-    }
-    
-    /// Holds the InputPlugin plugins that can be used to extend the functionality of the InputBarAccessoryView
-    open var inputPlugins = [InputPlugin]()
-
-    /// The InputBarItems held in the leftStackView
-    public private(set) var leftStackViewItems: [InputItem] = []
-    
-    /// The InputBarItems held in the rightStackView
-    public private(set) var rightStackViewItems: [InputItem] = []
-    
-    /// The InputBarItems held in the bottomStackView
-    public private(set) var bottomStackViewItems: [InputItem] = []
-    
-    /// The InputBarItems held in the topStackView
-    public private(set) var topStackViewItems: [InputItem] = []
-    
-    /// The InputBarItems held to make use of their hooks but they are not automatically added to a UIStackView
-    open var nonStackViewItems: [InputItem] = []
-    
-    /// Returns a flatMap of all the items in each of the UIStackViews
-    public var items: [InputItem] {
-        return [leftStackViewItems, rightStackViewItems, bottomStackViewItems, topStackViewItems, nonStackViewItems].flatMap { $0 }
-    }
-
-    // MARK: - Auto-Layout Constraint Sets
-    
-    private var middleContentViewLayoutSet: NSLayoutConstraintSet?
-    private var textViewHeightAnchor: NSLayoutConstraint?
-    private var topStackViewLayoutSet: NSLayoutConstraintSet?
-    private var leftStackViewLayoutSet: NSLayoutConstraintSet?
-    private var rightStackViewLayoutSet: NSLayoutConstraintSet?
-    private var bottomStackViewLayoutSet: NSLayoutConstraintSet?
-    private var contentViewLayoutSet: NSLayoutConstraintSet?
-    private var windowAnchor: NSLayoutConstraint?
-    private var backgroundViewLayoutSet: NSLayoutConstraintSet?
-    
-    // MARK: - Initialization
-    
-    public convenience init() {
-        self.init(frame: .zero)
-    }
-    
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    deinit {
-        NotificationCenter.default.removeObserver(self)
-    }
-
-    open override func willMove(toSuperview newSuperview: UIView?) {
-        super.willMove(toSuperview: newSuperview)
-        guard newSuperview != nil else {
-            deactivateConstraints()
-            return
-        }
-        activateConstraints()
-    }
-
-    open override func didMoveToWindow() {
-        super.didMoveToWindow()
-        setupConstraints(to: window)
-    }
-    
-    // MARK: - Setup
-    
-    /// Sets up the default properties
-    open func setup() {
-
-        backgroundColor = .white
-        autoresizingMask = [.flexibleHeight]
-        setupSubviews()
-        setupConstraints()
-        setupObservers()
-        setupGestureRecognizers()
-    }
-    
-    /// Adds the required notification observers
-    private func setupObservers() {
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(InputBarAccessoryView.orientationDidChange),
-                                               name: UIDevice.orientationDidChangeNotification, object: nil)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(InputBarAccessoryView.inputTextViewDidChange),
-                                               name: UITextView.textDidChangeNotification, object: inputTextView)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(InputBarAccessoryView.inputTextViewDidBeginEditing),
-                                               name: UITextView.textDidBeginEditingNotification, object: inputTextView)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(InputBarAccessoryView.inputTextViewDidEndEditing),
-                                               name: UITextView.textDidEndEditingNotification, object: inputTextView)
-    }
-    
-    /// Adds a UISwipeGestureRecognizer for each direction to the InputTextView
-    private func setupGestureRecognizers() {
-        let directions: [UISwipeGestureRecognizer.Direction] = [.left, .right]
-        for direction in directions {
-            let gesture = UISwipeGestureRecognizer(target: self,
-                                                   action: #selector(InputBarAccessoryView.didSwipeTextView(_:)))
-            gesture.direction = direction
-            inputTextView.addGestureRecognizer(gesture)
-        }
-    }
-    
-    /// Adds all of the subviews
-    private func setupSubviews() {
-        
-        addSubview(backgroundView)
-        addSubview(topStackView)
-        addSubview(contentView)
-        addSubview(separatorLine)
-        contentView.addSubview(middleContentViewWrapper)
-        contentView.addSubview(leftStackView)
-        contentView.addSubview(rightStackView)
-        contentView.addSubview(bottomStackView)
-        middleContentViewWrapper.addSubview(inputTextView)
-        middleContentView = inputTextView
-        setStackViewItems([sendButton], forStack: .right, animated: false)
-    }
-    
-    /// Sets up the initial constraints of each subview
-    private func setupConstraints() {
-        
-        // The constraints within the InputBarAccessoryView
-        separatorLine.addConstraints(topAnchor, left: backgroundView.leftAnchor, right: backgroundView.rightAnchor, heightConstant: separatorLine.height)
-
-        backgroundViewLayoutSet = NSLayoutConstraintSet(
-            top: backgroundView.topAnchor.constraint(equalTo: topStackView.bottomAnchor),
-            bottom: backgroundView.bottomAnchor.constraint(equalTo: bottomAnchor),
-            left: backgroundView.leftAnchor.constraint(equalTo: leftAnchor, constant: frameInsets.left),
-            right: backgroundView.rightAnchor.constraint(equalTo: rightAnchor, constant: -frameInsets.right)
-        )
-        
-        topStackViewLayoutSet = NSLayoutConstraintSet(
-            top:    topStackView.topAnchor.constraint(equalTo: topAnchor, constant: topStackViewPadding.top),
-            bottom: topStackView.bottomAnchor.constraint(equalTo: contentView.topAnchor, constant: -padding.top),
-            left:   topStackView.leftAnchor.constraint(equalTo: leftAnchor, constant: topStackViewPadding.left + frameInsets.left),
-            right:  topStackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -(topStackViewPadding.right + frameInsets.right))
-        )
-        
-        contentViewLayoutSet = NSLayoutConstraintSet(
-            top:    contentView.topAnchor.constraint(equalTo: topStackView.bottomAnchor, constant: padding.top),
-            bottom: contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -padding.bottom),
-            left:   contentView.leftAnchor.constraint(equalTo: leftAnchor, constant: padding.left + frameInsets.left),
-            right:  contentView.rightAnchor.constraint(equalTo: rightAnchor, constant: -(padding.right + frameInsets.right))
-        )
-        
-        if #available(iOS 11.0, *) {
-            // Switch to safeAreaLayoutGuide
-            contentViewLayoutSet?.bottom = contentView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -padding.bottom)
-            contentViewLayoutSet?.left = contentView.leftAnchor.constraint(equalTo: safeAreaLayoutGuide.leftAnchor, constant: padding.left + frameInsets.left)
-            contentViewLayoutSet?.right = contentView.rightAnchor.constraint(equalTo: safeAreaLayoutGuide.rightAnchor, constant: -(padding.right + frameInsets.right))
-            
-            topStackViewLayoutSet?.left = topStackView.leftAnchor.constraint(equalTo: safeAreaLayoutGuide.leftAnchor, constant: topStackViewPadding.left + frameInsets.left)
-            topStackViewLayoutSet?.right = topStackView.rightAnchor.constraint(equalTo: safeAreaLayoutGuide.rightAnchor, constant: -(topStackViewPadding.right + frameInsets.right))
-        }
-
-        // Constraints Within the contentView
-        middleContentViewLayoutSet = NSLayoutConstraintSet(
-            top:    middleContentViewWrapper.topAnchor.constraint(equalTo: contentView.topAnchor, constant: middleContentViewPadding.top),
-            bottom: middleContentViewWrapper.bottomAnchor.constraint(equalTo: bottomStackView.topAnchor, constant: -middleContentViewPadding.bottom),
-            left:   middleContentViewWrapper.leftAnchor.constraint(equalTo: leftStackView.rightAnchor, constant: middleContentViewPadding.left),
-            right:  middleContentViewWrapper.rightAnchor.constraint(equalTo: rightStackView.leftAnchor, constant: -middleContentViewPadding.right)
-        )
-
-        inputTextView.fillSuperview()
-        maxTextViewHeight = calculateMaxTextViewHeight()
-        textViewHeightAnchor = inputTextView.heightAnchor.constraint(equalToConstant: maxTextViewHeight)
-        
-        leftStackViewLayoutSet = NSLayoutConstraintSet(
-            top:    leftStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0),
-            bottom: leftStackView.bottomAnchor.constraint(equalTo: middleContentViewWrapper.bottomAnchor, constant: 0),
-            left:   leftStackView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0),
-            width:  leftStackView.widthAnchor.constraint(equalToConstant: leftStackViewWidthConstant)
-        )
-        
-        rightStackViewLayoutSet = NSLayoutConstraintSet(
-            top:    rightStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0),
-            bottom: rightStackView.bottomAnchor.constraint(equalTo: middleContentViewWrapper.bottomAnchor, constant: 0),
-            right:  rightStackView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0),
-            width:  rightStackView.widthAnchor.constraint(equalToConstant: rightStackViewWidthConstant)
-        )
-        
-        bottomStackViewLayoutSet = NSLayoutConstraintSet(
-            top:    bottomStackView.topAnchor.constraint(equalTo: middleContentViewWrapper.bottomAnchor, constant: middleContentViewPadding.bottom),
-            bottom: bottomStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0),
-            left:   bottomStackView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0),
-            right:  bottomStackView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0)
-        )
-    }
-    
-    /// Respect window safeAreaInsets
-    /// Adds a constraint to anchor the bottomAnchor of the contentView to the window's safeAreaLayoutGuide.bottomAnchor
-    ///
-    /// - Parameter window: The window to anchor to
-    private func setupConstraints(to window: UIWindow?) {
-        if #available(iOS 11.0, *) {
-            if let window = window {
-                guard window.safeAreaInsets.bottom > 0 else { return }
-                windowAnchor?.isActive = false
-                windowAnchor = contentView.bottomAnchor.constraint(lessThanOrEqualToSystemSpacingBelow: window.safeAreaLayoutGuide.bottomAnchor, multiplier: 1)
-                windowAnchor?.constant = -padding.bottom
-                windowAnchor?.priority = UILayoutPriority(rawValue: 750)
-                windowAnchor?.isActive = true
-                backgroundViewLayoutSet?.bottom?.constant = window.safeAreaInsets.bottom
-            }
-        }
-    }
-    
-    // MARK: - Constraint Layout Updates
-
-    private func updateFrameInsets() {
-        backgroundViewLayoutSet?.left?.constant = frameInsets.left
-        backgroundViewLayoutSet?.right?.constant = -frameInsets.right
-        updatePadding()
-        updateTopStackViewPadding()
-    }
-    
-    /// Updates the constraint constants that correspond to the padding UIEdgeInsets
-    private func updatePadding() {
-        topStackViewLayoutSet?.bottom?.constant = -padding.top
-        contentViewLayoutSet?.top?.constant = padding.top
-        contentViewLayoutSet?.left?.constant = padding.left + frameInsets.left
-        contentViewLayoutSet?.right?.constant = -(padding.right + frameInsets.right)
-        contentViewLayoutSet?.bottom?.constant = -padding.bottom
-        windowAnchor?.constant = -padding.bottom
-    }
-    
-    /// Updates the constraint constants that correspond to the middleContentViewPadding UIEdgeInsets
-    private func updateMiddleContentViewPadding() {
-        middleContentViewLayoutSet?.top?.constant = middleContentViewPadding.top
-        middleContentViewLayoutSet?.left?.constant = middleContentViewPadding.left
-        middleContentViewLayoutSet?.right?.constant = -middleContentViewPadding.right
-        middleContentViewLayoutSet?.bottom?.constant = -middleContentViewPadding.bottom
-        bottomStackViewLayoutSet?.top?.constant = middleContentViewPadding.bottom
-    }
-    
-    /// Updates the constraint constants that correspond to the topStackViewPadding UIEdgeInsets
-    private func updateTopStackViewPadding() {
-        topStackViewLayoutSet?.top?.constant = topStackViewPadding.top
-        topStackViewLayoutSet?.left?.constant = topStackViewPadding.left + frameInsets.left
-        topStackViewLayoutSet?.right?.constant = -(topStackViewPadding.right + frameInsets.right)
-    }
-
-    /// Invalidates the view’s intrinsic content size
-    open override func invalidateIntrinsicContentSize() {
-        super.invalidateIntrinsicContentSize()
-        cachedIntrinsicContentSize = calculateIntrinsicContentSize()
-        if previousIntrinsicContentSize != cachedIntrinsicContentSize {
-            delegate?.inputBar(self, didChangeIntrinsicContentTo: cachedIntrinsicContentSize)
-            previousIntrinsicContentSize = cachedIntrinsicContentSize
-        }
-    }
-    
-    /// Calculates the correct intrinsicContentSize of the InputBarAccessoryView
-    ///
-    /// - Returns: The required intrinsicContentSize
-    open func calculateIntrinsicContentSize() -> CGSize {
-        
-        var inputTextViewHeight = requiredInputTextViewHeight
-        if inputTextViewHeight >= maxTextViewHeight {
-            if !isOverMaxTextViewHeight {
-                textViewHeightAnchor?.isActive = true
-                inputTextView.isScrollEnabled = true
-                isOverMaxTextViewHeight = true
-            }
-            inputTextViewHeight = maxTextViewHeight
-        } else {
-            if isOverMaxTextViewHeight {
-                textViewHeightAnchor?.isActive = false || shouldForceTextViewMaxHeight
-                inputTextView.isScrollEnabled = false
-                isOverMaxTextViewHeight = false
-                inputTextView.invalidateIntrinsicContentSize()
-            }
-        }
-        
-        // Calculate the required height
-        let totalPadding = padding.top + padding.bottom + topStackViewPadding.top + middleContentViewPadding.top + middleContentViewPadding.bottom
-        let topStackViewHeight = !topStackView.arrangedSubviews.isEmpty ? topStackView.bounds.height : 0
-        let bottomStackViewHeight = !bottomStackView.arrangedSubviews.isEmpty ? bottomStackView.bounds.height : 0
-        let verticalStackViewHeight = topStackViewHeight + bottomStackViewHeight
-        let requiredHeight = inputTextViewHeight + totalPadding + verticalStackViewHeight
-        return CGSize(width: UIView.noIntrinsicMetric, height: requiredHeight)
-    }
-
-    open override func layoutIfNeeded() {
-        super.layoutIfNeeded()
-        inputTextView.layoutIfNeeded()
-    }
-
-    open override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
-        guard frameInsets.left != 0 || frameInsets.right != 0 else {
-            return super.point(inside: point, with: event)
-        }
-        // Allow touches to pass through base view
-        return subviews.contains {
-            !$0.isHidden && $0.point(inside: convert(point, to: $0), with: event)
-        }
-    }
-    
-    /// Returns the max height the InputTextView can grow to based on the UIScreen
-    ///
-    /// - Returns: Max Height
-    open func calculateMaxTextViewHeight() -> CGFloat {
-        if traitCollection.verticalSizeClass == .regular {
-            return (UIScreen.main.bounds.height / 3).rounded(.down)
-        }
-        return (UIScreen.main.bounds.height / 5).rounded(.down)
-    }
-    
-    // MARK: - Layout Helper Methods
-    
-    /// Layout the given InputStackView's
-    ///
-    /// - Parameter positions: The InputStackView's to layout
-    public func layoutStackViews(_ positions: [InputStackView.Position] = [.left, .right, .bottom, .top]) {
-        
-        guard superview != nil else { return }
-        for position in positions {
-            switch position {
-            case .left:
-                leftStackView.setNeedsLayout()
-                leftStackView.layoutIfNeeded()
-            case .right:
-                rightStackView.setNeedsLayout()
-                rightStackView.layoutIfNeeded()
-            case .bottom:
-                bottomStackView.setNeedsLayout()
-                bottomStackView.layoutIfNeeded()
-            case .top:
-                topStackView.setNeedsLayout()
-                topStackView.layoutIfNeeded()
-            }
-        }
-    }
-    
-    /// Performs a layout over the main thread
-    ///
-    /// - Parameters:
-    ///   - animated: If the layout should be animated
-    ///   - animations: Animation logic
-    internal func performLayout(_ animated: Bool, _ animations: @escaping () -> Void) {
-        deactivateConstraints()
-        if animated {
-            DispatchQueue.main.async {
-                UIView.animate(withDuration: 0.3, animations: animations)
-            }
-        } else {
-            UIView.performWithoutAnimation { animations() }
-        }
-        activateConstraints()
-    }
-    
-    /// Activates the NSLayoutConstraintSet's
-    private func activateConstraints() {
-        backgroundViewLayoutSet?.activate()
-        contentViewLayoutSet?.activate()
-        middleContentViewLayoutSet?.activate()
-        leftStackViewLayoutSet?.activate()
-        rightStackViewLayoutSet?.activate()
-        bottomStackViewLayoutSet?.activate()
-        topStackViewLayoutSet?.activate()
-    }
-    
-    /// Deactivates the NSLayoutConstraintSet's
-    private func deactivateConstraints() {
-        backgroundViewLayoutSet?.deactivate()
-        contentViewLayoutSet?.deactivate()
-        middleContentViewLayoutSet?.deactivate()
-        leftStackViewLayoutSet?.deactivate()
-        rightStackViewLayoutSet?.deactivate()
-        bottomStackViewLayoutSet?.deactivate()
-        topStackViewLayoutSet?.deactivate()
-    }
-
-    /// Removes the current `middleContentView` and assigns a new one.
-    ///
-    /// WARNING: This will remove the `InputTextView`
-    ///
-    /// - Parameters:
-    ///   - view: New view
-    ///   - animated: If the layout should be animated
-    open func setMiddleContentView(_ view: UIView?, animated: Bool) {
-        middleContentView?.removeFromSuperview()
-        middleContentView = view
-        guard let view = view else { return }
-        middleContentViewWrapper.addSubview(view)
-        view.fillSuperview()
-
-        performLayout(animated) { [weak self] in
-            guard self?.superview != nil else { return }
-            self?.middleContentViewWrapper.layoutIfNeeded()
-            self?.invalidateIntrinsicContentSize()
-        }
-    }
-    
-    /// Removes all of the arranged subviews from the InputStackView and adds the given items.
-    /// Sets the inputBarAccessoryView property of the InputBarButtonItem
-    ///
-    /// - Parameters:
-    ///   - items: New InputStackView arranged views
-    ///   - position: The targeted InputStackView
-    ///   - animated: If the layout should be animated
-    open func setStackViewItems(_ items: [InputItem], forStack position: InputStackView.Position, animated: Bool) {
-        
-        func setNewItems() {
-            switch position {
-            case .left:
-                leftStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
-                leftStackViewItems = items
-                leftStackViewItems.forEach {
-                    $0.inputBarAccessoryView = self
-                    $0.parentStackViewPosition = position
-                    if let view = $0 as? UIView {
-                        leftStackView.addArrangedSubview(view)
-                    }
-                }
-                guard superview != nil else { return }
-                leftStackView.layoutIfNeeded()
-            case .right:
-                rightStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
-                rightStackViewItems = items
-                rightStackViewItems.forEach {
-                    $0.inputBarAccessoryView = self
-                    $0.parentStackViewPosition = position
-                    if let view = $0 as? UIView {
-                        rightStackView.addArrangedSubview(view)
-                    }
-                }
-                guard superview != nil else { return }
-                rightStackView.layoutIfNeeded()
-            case .bottom:
-                bottomStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
-                bottomStackViewItems = items
-                bottomStackViewItems.forEach {
-                    $0.inputBarAccessoryView = self
-                    $0.parentStackViewPosition = position
-                    if let view = $0 as? UIView {
-                        bottomStackView.addArrangedSubview(view)
-                    }
-                }
-                guard superview != nil else { return }
-                bottomStackView.layoutIfNeeded()
-            case .top:
-                topStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
-                topStackViewItems = items
-                topStackViewItems.forEach {
-                    $0.inputBarAccessoryView = self
-                    $0.parentStackViewPosition = position
-                    if let view = $0 as? UIView {
-                        topStackView.addArrangedSubview(view)
-                    }
-                }
-                guard superview != nil else { return }
-                topStackView.layoutIfNeeded()
-            }
-            invalidateIntrinsicContentSize()
-        }
-        
-        performLayout(animated) {
-            setNewItems()
-        }
-    }
-    
-    /// Sets the leftStackViewWidthConstant
-    ///
-    /// - Parameters:
-    ///   - newValue: New widthAnchor constant
-    ///   - animated: If the layout should be animated
-    open func setLeftStackViewWidthConstant(to newValue: CGFloat, animated: Bool) {
-        performLayout(animated) { 
-            self.leftStackViewWidthConstant = newValue
-            self.layoutStackViews([.left])
-            guard self.superview?.superview != nil else { return }
-            self.superview?.superview?.layoutIfNeeded()
-        }
-    }
-    
-    /// Sets the rightStackViewWidthConstant
-    ///
-    /// - Parameters:
-    ///   - newValue: New widthAnchor constant
-    ///   - animated: If the layout should be animated
-    open func setRightStackViewWidthConstant(to newValue: CGFloat, animated: Bool) {
-        performLayout(animated) { 
-            self.rightStackViewWidthConstant = newValue
-            self.layoutStackViews([.right])
-            guard self.superview?.superview != nil else { return }
-            self.superview?.superview?.layoutIfNeeded()
-        }
-    }
-    
-    /// Sets the `shouldForceTextViewMaxHeight` property
-    ///
-    /// - Parameters:
-    ///   - newValue: New boolean value
-    ///   - animated: If the layout should be animated
-    open func setShouldForceMaxTextViewHeight(to newValue: Bool, animated: Bool) {
-        performLayout(animated) {
-            self.shouldForceTextViewMaxHeight = newValue
-            self.textViewHeightAnchor?.isActive = newValue
-            guard self.superview?.superview != nil else { return }
-            self.superview?.superview?.layoutIfNeeded()
-        }
-    }
-    
-    // MARK: - Notifications/Hooks
-    
-    /// Invalidates the intrinsicContentSize
-    open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
-        super.traitCollectionDidChange(previousTraitCollection)
-        if traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass || traitCollection.horizontalSizeClass != previousTraitCollection?.horizontalSizeClass {
-            if shouldAutoUpdateMaxTextViewHeight {
-                maxTextViewHeight = calculateMaxTextViewHeight()
-            } else {
-                invalidateIntrinsicContentSize()
-            }
-        }
-    }
-    
-    /// Invalidates the intrinsicContentSize
-    @objc
-    open func orientationDidChange() {
-        if shouldAutoUpdateMaxTextViewHeight {
-            maxTextViewHeight = calculateMaxTextViewHeight()
-        }
-        invalidateIntrinsicContentSize()
-    }
-
-    /// Enables/Disables the sendButton based on the InputTextView's text being empty
-    /// Calls each items `textViewDidChangeAction` method
-    /// Calls the delegates `textViewTextDidChangeTo` method
-    /// Invalidates the intrinsicContentSize
-    @objc
-    open func inputTextViewDidChange() {
-        
-        let trimmedText = inputTextView.text.trimmingCharacters(in: .whitespacesAndNewlines)
-        
-        if shouldManageSendButtonEnabledState {
-            var isEnabled = !trimmedText.isEmpty
-            if !isEnabled {
-                // The images property is more resource intensive so only use it if needed
-                isEnabled = !inputTextView.images.isEmpty
-            }
-            sendButton.isEnabled = isEnabled
-        }
-        
-        // Capture change before iterating over the InputItem's
-        let shouldInvalidateIntrinsicContentSize = requiredInputTextViewHeight != inputTextView.bounds.height
-        
-        items.forEach { $0.textViewDidChangeAction(with: self.inputTextView) }
-        delegate?.inputBar(self, textViewTextDidChangeTo: trimmedText)
-        
-        if shouldInvalidateIntrinsicContentSize {
-            // Prevent un-needed content size invalidation
-            invalidateIntrinsicContentSize()
-        }
-    }
-    
-    /// Calls each items `keyboardEditingBeginsAction` method
-    @objc
-    open func inputTextViewDidBeginEditing() {
-        items.forEach { $0.keyboardEditingBeginsAction() }
-    }
-    
-    /// Calls each items `keyboardEditingEndsAction` method
-    @objc
-    open func inputTextViewDidEndEditing() {
-        items.forEach { $0.keyboardEditingEndsAction() }
-    }
-    
-    // MARK: - Plugins
-    
-    /// Reloads each of the plugins
-    open func reloadPlugins() {
-        inputPlugins.forEach { $0.reloadData() }
-    }
-    
-    /// Invalidates each of the plugins
-    open func invalidatePlugins() {
-        inputPlugins.forEach { $0.invalidate() }
-    }
-    
-    // MARK: - User Actions
-    
-    /// Calls each items `keyboardSwipeGestureAction` method
-    /// Calls the delegates `didSwipeTextViewWith` method
-    @objc
-    open func didSwipeTextView(_ gesture: UISwipeGestureRecognizer) {
-        items.forEach { $0.keyboardSwipeGestureAction(with: gesture) }
-        delegate?.inputBar(self, didSwipeTextViewWith: gesture)
-    }
-    
-    /// Calls the delegates `didPressSendButtonWith` method
-    /// Assumes that the InputTextView's text has been set to empty and calls `inputTextViewDidChange()`
-    /// Invalidates each of the InputPlugins
-    open func didSelectSendButton() {
-        delegate?.inputBar(self, didPressSendButtonWith: inputTextView.text)
-    }
-}

+ 0 - 354
deltachat-ios/View/InputBarAccessoryView/InputBarButtonItem.swift

@@ -1,354 +0,0 @@
-//
-//  InputBarButtonItem.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import UIKit
-
-/**
- A InputItem that inherits from UIButton
- 
- ## Important Notes ##
- 1. Intended to be used in an `InputStackView`
- */
-open class InputBarButtonItem: UIButton, InputItem {
-    
-    /// The spacing properties of the InputBarButtonItem
-    ///
-    /// - fixed: The spacing is fixed
-    /// - flexible: The spacing is flexible
-    /// - none: There is no spacing
-    public enum Spacing {
-        case fixed(CGFloat)
-        case flexible
-        case none
-    }
-    
-    public typealias InputBarButtonItemAction = ((InputBarButtonItem) -> Void)
-    
-    // MARK: - Properties
-    
-    /// A weak reference to the InputBarAccessoryView that the InputBarButtonItem used in
-    open weak var inputBarAccessoryView: InputBarAccessoryView?
-    
-    /// The spacing property of the InputBarButtonItem that determines the contentHuggingPriority and any
-    /// additional space to the intrinsicContentSize
-    open var spacing: Spacing = .none {
-        didSet {
-            switch spacing {
-            case .flexible:
-                setContentHuggingPriority(UILayoutPriority(rawValue: 1), for: .horizontal)
-            case .fixed:
-                setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .horizontal)
-            case .none:
-                setContentHuggingPriority(UILayoutPriority(rawValue: 500), for: .horizontal)
-            }
-        }
-    }
-    
-    /// When not nil this size overrides the intrinsicContentSize
-    private var size: CGSize? = CGSize(width: 20, height: 20) {
-        didSet {
-            invalidateIntrinsicContentSize()
-        }
-    }
-    
-    open override var intrinsicContentSize: CGSize {
-        var contentSize = size ?? super.intrinsicContentSize
-        switch spacing {
-        case .fixed(let width):
-            contentSize.width += width
-        case .flexible, .none:
-            break
-        }
-        return contentSize
-    }
-    
-    /// A reference to the stack view position that the InputBarButtonItem is held in
-    open var parentStackViewPosition: InputStackView.Position?
-    
-    /// The title for the UIControlState.normal
-    open var title: String? {
-        get {
-            return title(for: .normal)
-        }
-        set {
-            setTitle(newValue, for: .normal)
-        }
-    }
-    
-    /// The image for the UIControlState.normal
-    open var image: UIImage? {
-        get {
-            return image(for: .normal)
-        }
-        set {
-            setImage(newValue, for: .normal)
-        }
-    }
-    
-    /// Calls the onSelectedAction or onDeselectedAction when set
-    open override var isHighlighted: Bool {
-        get {
-            return super.isHighlighted
-        }
-        set {
-            guard newValue != isHighlighted else { return }
-            super.isHighlighted = newValue
-            if newValue {
-                onSelectedAction?(self)
-            } else {
-                onDeselectedAction?(self)
-            }
-
-        }
-    }
-
-    /// Calls the onEnabledAction or onDisabledAction when set
-    open override var isEnabled: Bool {
-        didSet {
-            if isEnabled {
-                onEnabledAction?(self)
-            } else {
-                onDisabledAction?(self)
-            }
-        }
-    }
-    
-    // MARK: - Reactive Hooks
-    
-    private var onTouchUpInsideAction: InputBarButtonItemAction?
-    private var onKeyboardEditingBeginsAction: InputBarButtonItemAction?
-    private var onKeyboardEditingEndsAction: InputBarButtonItemAction?
-    private var onKeyboardSwipeGestureAction: ((InputBarButtonItem, UISwipeGestureRecognizer) -> Void)?
-    private var onTextViewDidChangeAction: ((InputBarButtonItem, InputTextView) -> Void)?
-    private var onSelectedAction: InputBarButtonItemAction?
-    private var onDeselectedAction: InputBarButtonItemAction?
-    private var onEnabledAction: InputBarButtonItemAction?
-    private var onDisabledAction: InputBarButtonItemAction?
-    
-    // MARK: - Initialization
-    
-    public convenience init() {
-        self.init(frame: .zero)
-    }
-    
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    // MARK: - Setup
-    
-    /// Sets up the default properties
-    open func setup() {
-        contentVerticalAlignment = .center
-        contentHorizontalAlignment = .center
-        imageView?.contentMode = .scaleAspectFit
-        setContentHuggingPriority(UILayoutPriority(rawValue: 500), for: .horizontal)
-        setContentHuggingPriority(UILayoutPriority(rawValue: 500), for: .vertical)
-        setTitleColor(UIColor(red: 0, green: 122/255, blue: 1, alpha: 1), for: .normal)
-        setTitleColor(UIColor(red: 0, green: 122/255, blue: 1, alpha: 0.3), for: .highlighted)
-        setTitleColor(.lightGray, for: .disabled)
-        adjustsImageWhenHighlighted = false
-        addTarget(self, action: #selector(InputBarButtonItem.touchUpInsideAction), for: .touchUpInside)
-    }
-    
-    // MARK: - Size Adjustment
-    
-    /// Sets the size of the InputBarButtonItem which overrides the intrinsicContentSize. When set to nil
-    /// the default intrinsicContentSize is used. The new size will be laid out in the UIStackView that
-    /// the InputBarButtonItem is held in
-    ///
-    /// - Parameters:
-    ///   - newValue: The new size
-    ///   - animated: If the layout should be animated
-    open func setSize(_ newValue: CGSize?, animated: Bool) {
-        size = newValue
-        if animated, let position = parentStackViewPosition {
-            inputBarAccessoryView?.performLayout(animated) { [weak self] in
-                self?.inputBarAccessoryView?.layoutStackViews([position])
-            }
-        }
-    }
-    
-    // MARK: - Hook Setup Methods
-    
-    /// Used to setup your own initial properties
-    ///
-    /// - Parameter item: A reference to Self
-    /// - Returns: Self
-    @discardableResult
-    open func configure(_ item: InputBarButtonItemAction) -> Self {
-        item(self)
-        return self
-    }
-    
-    /// Sets the onKeyboardEditingBeginsAction
-    ///
-    /// - Parameter action: The new onKeyboardEditingBeginsAction
-    /// - Returns: Self
-    @discardableResult
-    open func onKeyboardEditingBegins(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onKeyboardEditingBeginsAction = action
-        return self
-    }
-    
-    /// Sets the onKeyboardEditingEndsAction
-    ///
-    /// - Parameter action: The new onKeyboardEditingEndsAction
-    /// - Returns: Self
-    @discardableResult
-    open func onKeyboardEditingEnds(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onKeyboardEditingEndsAction = action
-        return self
-    }
-    
-    
-    /// Sets the onKeyboardSwipeGestureAction
-    ///
-    /// - Parameter action: The new onKeyboardSwipeGestureAction
-    /// - Returns: Self
-    @discardableResult
-    open func onKeyboardSwipeGesture(_ action: @escaping (_ item: InputBarButtonItem, _ gesture: UISwipeGestureRecognizer) -> Void) -> Self {
-        onKeyboardSwipeGestureAction = action
-        return self
-    }
-    
-    /// Sets the onTextViewDidChangeAction
-    ///
-    /// - Parameter action: The new onTextViewDidChangeAction
-    /// - Returns: Self
-    @discardableResult
-    open func onTextViewDidChange(_ action: @escaping (_ item: InputBarButtonItem, _ textView: InputTextView) -> Void) -> Self {
-        onTextViewDidChangeAction = action
-        return self
-    }
-    
-    /// Sets the onTouchUpInsideAction
-    ///
-    /// - Parameter action: The new onTouchUpInsideAction
-    /// - Returns: Self
-    @discardableResult
-    open func onTouchUpInside(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onTouchUpInsideAction = action
-        return self
-    }
-    
-    /// Sets the onSelectedAction
-    ///
-    /// - Parameter action: The new onSelectedAction
-    /// - Returns: Self
-    @discardableResult
-    open func onSelected(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onSelectedAction = action
-        return self
-    }
-    
-    /// Sets the onDeselectedAction
-    ///
-    /// - Parameter action: The new onDeselectedAction
-    /// - Returns: Self
-    @discardableResult
-    open func onDeselected(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onDeselectedAction = action
-        return self
-    }
-    
-    /// Sets the onEnabledAction
-    ///
-    /// - Parameter action: The new onEnabledAction
-    /// - Returns: Self
-    @discardableResult
-    open func onEnabled(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onEnabledAction = action
-        return self
-    }
-    
-    /// Sets the onDisabledAction
-    ///
-    /// - Parameter action: The new onDisabledAction
-    /// - Returns: Self
-    @discardableResult
-    open func onDisabled(_ action: @escaping InputBarButtonItemAction) -> Self {
-        onDisabledAction = action
-        return self
-    }
-    
-    // MARK: - InputItem Protocol
-    
-    /// Executes the onTextViewDidChangeAction with the given textView
-    ///
-    /// - Parameter textView: A reference to the InputTextView
-    open func textViewDidChangeAction(with textView: InputTextView) {
-        onTextViewDidChangeAction?(self, textView)
-    }
-    
-    /// Executes the onKeyboardSwipeGestureAction with the given gesture
-    ///
-    /// - Parameter gesture: A reference to the gesture that was recognized
-    open func keyboardSwipeGestureAction(with gesture: UISwipeGestureRecognizer) {
-        onKeyboardSwipeGestureAction?(self, gesture)
-    }
-    
-    /// Executes the onKeyboardEditingEndsAction
-    open func keyboardEditingEndsAction() {
-        onKeyboardEditingEndsAction?(self)
-    }
-    
-    /// Executes the onKeyboardEditingBeginsAction
-    open func keyboardEditingBeginsAction() {
-        onKeyboardEditingBeginsAction?(self)
-    }
-    
-    /// Executes the onTouchUpInsideAction
-    @objc
-    open func touchUpInsideAction() {
-        onTouchUpInsideAction?(self)
-    }
-    
-    // MARK: - Static Spacers
-    
-    /// An InputBarButtonItem that's spacing property is set to be .flexible
-    public static var flexibleSpace: InputBarButtonItem {
-        let item = InputBarButtonItem()
-        item.setSize(.zero, animated: false)
-        item.spacing = .flexible
-        return item
-    }
-    
-    /// An InputBarButtonItem that's spacing property is set to be .fixed with the width arguement
-    public static func fixedSpace(_ width: CGFloat) -> InputBarButtonItem {
-        let item = InputBarButtonItem()
-        item.setSize(.zero, animated: false)
-        item.spacing = .fixed(width)
-        return item
-    }
-}

+ 0 - 96
deltachat-ios/View/InputBarAccessoryView/InputBarSendButton.swift

@@ -1,96 +0,0 @@
-//
-//  InputBarSendButton.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import UIKit
-
-open class InputBarSendButton: InputBarButtonItem {
-
-    /// A flag indicating the animation state of the `InputBarSendButton`
-    open private(set) var isAnimating: Bool = false
-
-    /// Accessor to modify the color of the activity view
-    open var activityViewColor: UIColor! {
-        get {
-            return activityView.color
-        }
-        set {
-            activityView.color = newValue
-        }
-    }
-
-    private let activityView: UIActivityIndicatorView = {
-        let view = UIActivityIndicatorView(style: .gray)
-        view.isUserInteractionEnabled = false
-        view.isHidden = true
-        return view
-    }()
-
-    public convenience init() {
-        self.init(frame: .zero)
-    }
-
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setupSendButton()
-    }
-
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setupSendButton()
-    }
-
-    private func setupSendButton() {
-        addSubview(activityView)
-    }
-
-    open override func layoutSubviews() {
-        super.layoutSubviews()
-        activityView.frame = bounds
-    }
-
-    /// Starts the animation of the activity view, hiding other elements
-    open func startAnimating() {
-        guard !isAnimating else { return }
-        defer { isAnimating = true }
-        activityView.startAnimating()
-        activityView.isHidden = false
-        // Setting isHidden doesn't hide the elements
-        titleLabel?.alpha = 0
-        imageView?.layer.transform = CATransform3DMakeScale(0.0, 0.0, 0.0)
-    }
-
-    /// Stops the animation of the activity view, shows other elements
-    open func stopAnimating() {
-        guard isAnimating else { return }
-        defer { isAnimating = false }
-        activityView.stopAnimating()
-        activityView.isHidden = true
-        titleLabel?.alpha = 1
-        imageView?.layer.transform = CATransform3DIdentity
-    }
-
-}

+ 0 - 53
deltachat-ios/View/InputBarAccessoryView/KeyboardManager/KeyboardEvent.swift

@@ -1,53 +0,0 @@
-//
-//  KeyboardEvent.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-import Foundation
-
-/// Keyboard events that can happen. Translates directly to `UIKeyboard` notifications from UIKit.
-public enum KeyboardEvent {
-    
-    /// Event raised by UIKit's `.UIKeyboardWillShow`.
-    case willShow
-    
-    /// Event raised by UIKit's `.UIKeyboardDidShow`.
-    case didShow
-    
-    /// Event raised by UIKit's `.UIKeyboardWillShow`.
-    case willHide
-    
-    /// Event raised by UIKit's `.UIKeyboardDidHide`.
-    case didHide
-    
-    /// Event raised by UIKit's `.UIKeyboardWillChangeFrame`.
-    case willChangeFrame
-    
-    /// Event raised by UIKit's `.UIKeyboardDidChangeFrame`.
-    case didChangeFrame
-    
-    /// Non-keyboard based event raised by UIKit
-    case unknown
-    
-}

+ 0 - 301
deltachat-ios/View/InputBarAccessoryView/KeyboardManager/KeyboardManager.swift

@@ -1,301 +0,0 @@
-//
-//  KeyboardManager.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import UIKit
-
-/// An object that observes keyboard notifications such that event callbacks can be set for each notification
-open class KeyboardManager: NSObject, UIGestureRecognizerDelegate {
-    
-    /// A callback that passes a `KeyboardNotification` as an input
-    public typealias EventCallback = (KeyboardNotification)->Void
-    
-    // MARK: - Properties [Public]
-    
-    /// A weak reference to a view bounded to the top of the keyboard to act as an `InputAccessoryView`
-    /// but kept within the bounds of the `UIViewController`s view
-    open weak var inputAccessoryView: UIView?
-    
-    /// A flag that indicates if a portion of the keyboard is visible on the screen
-    private(set) public var isKeyboardHidden: Bool = true
-    
-    // MARK: - Properties [Private]
-    
-    /// The `NSLayoutConstraintSet` that holds the `inputAccessoryView` to the bottom if its superview
-    private var constraints: NSLayoutConstraintSet?
-    
-    /// A weak reference to a `UIScrollView` that has been attached for interactive keyboard dismissal
-    private weak var scrollView: UIScrollView?
-    
-    /// The `EventCallback` actions for each `KeyboardEvent`. Default value is EMPTY
-    private var callbacks: [KeyboardEvent: EventCallback] = [:]
-    
-    /// The pan gesture that handles dragging on the `scrollView`
-    private var panGesture: UIPanGestureRecognizer?
-
-    /// A cached notification used as a starting point when a user dragging the `scrollView` down
-    /// to interactively dismiss the keyboard
-    private var cachedNotification: KeyboardNotification?
-    
-    // MARK: - Initialization
-    
-    /// Creates a `KeyboardManager` object an binds the view as fake `InputAccessoryView`
-    ///
-    /// - Parameter inputAccessoryView: The view to bind to the top of the keyboard but within its superview
-    public convenience init(inputAccessoryView: UIView) {
-        self.init()
-        self.bind(inputAccessoryView: inputAccessoryView)
-    }
-    
-    /// Creates a `KeyboardManager` object that observes the state of the keyboard
-    public override init() {
-        super.init()
-        addObservers()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    // MARK: - De-Initialization
-    
-    deinit {
-        NotificationCenter.default.removeObserver(self)
-    }
-    
-    // MARK: - Keyboard Observer
-    
-    /// Add an observer for each keyboard notification
-    private func addObservers() {
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(keyboardWillShow(notification:)),
-                                               name: UIResponder.keyboardWillShowNotification,
-                                               object: nil)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(keyboardDidShow(notification:)),
-                                               name: UIResponder.keyboardDidShowNotification,
-                                               object: nil)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(keyboardWillHide(notification:)),
-                                               name: UIResponder.keyboardWillHideNotification,
-                                               object: nil)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(keyboardDidHide(notification:)),
-                                               name: UIResponder.keyboardDidHideNotification,
-                                               object: nil)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(keyboardWillChangeFrame(notification:)),
-                                               name: UIResponder.keyboardWillChangeFrameNotification,
-                                               object: nil)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(keyboardDidChangeFrame(notification:)),
-                                               name: UIResponder.keyboardDidChangeFrameNotification,
-                                               object: nil)
-    }
-    
-    // MARK: - Mutate Callback Dictionary
-    
-    /// Sets the `EventCallback` for a `KeyboardEvent`
-    ///
-    /// - Parameters:
-    ///   - event: KeyboardEvent
-    ///   - callback: EventCallback
-    /// - Returns: Self
-    @discardableResult
-    open func on(event: KeyboardEvent, do callback: EventCallback?) -> Self {
-        callbacks[event] = callback
-        return self
-    }
-    
-    /// Constrains the `inputAccessoryView` to the bottom of its superview and sets the
-    /// `.willChangeFrame` and `.willHide` event callbacks such that it mimics an `InputAccessoryView`
-    /// that is bound to the top of the keyboard
-    ///
-    /// - Parameter inputAccessoryView: The view to bind to the top of the keyboard but within its superview
-    /// - Returns: Self
-    @discardableResult
-    open func bind(inputAccessoryView: UIView) -> Self {
-        
-        guard let superview = inputAccessoryView.superview else {
-            fatalError("`inputAccessoryView` must have a superview")
-        }
-        self.inputAccessoryView = inputAccessoryView
-        inputAccessoryView.translatesAutoresizingMaskIntoConstraints = false
-        constraints = NSLayoutConstraintSet(
-            bottom: inputAccessoryView.bottomAnchor.constraint(equalTo: superview.bottomAnchor),
-            left: inputAccessoryView.leftAnchor.constraint(equalTo: superview.leftAnchor),
-            right: inputAccessoryView.rightAnchor.constraint(equalTo: superview.rightAnchor)
-        ).activate()
-        
-        callbacks[.willShow] = { [weak self] (notification) in
-            let keyboardHeight = notification.endFrame.height
-            guard
-                self?.isKeyboardHidden == false,
-                self?.constraints?.bottom?.constant == 0,
-                notification.isForCurrentApp else { return }
-            self?.animateAlongside(notification) {
-                self?.constraints?.bottom?.constant = -keyboardHeight
-                self?.inputAccessoryView?.superview?.layoutIfNeeded()
-            }
-        }
-        callbacks[.willChangeFrame] = { [weak self] (notification) in
-            let keyboardHeight = notification.endFrame.height
-            guard
-                self?.isKeyboardHidden == false,
-                notification.isForCurrentApp else { return }
-            self?.animateAlongside(notification) {
-                self?.constraints?.bottom?.constant = -keyboardHeight
-                self?.inputAccessoryView?.superview?.layoutIfNeeded()
-            }
-        }
-        callbacks[.willHide] = { [weak self] (notification) in
-            guard notification.isForCurrentApp else { return }
-            self?.animateAlongside(notification) { [weak self] in
-                self?.constraints?.bottom?.constant = 0
-                self?.inputAccessoryView?.superview?.layoutIfNeeded()
-            }
-        }
-        return self
-    }
-    
-    /// Adds a `UIPanGestureRecognizer` to the `scrollView` to enable interactive dismissal`
-    ///
-    /// - Parameter scrollView: UIScrollView
-    /// - Returns: Self
-    @discardableResult
-    open func bind(to scrollView: UIScrollView) -> Self {
-        self.scrollView = scrollView
-        self.scrollView?.keyboardDismissMode = .interactive // allows dismissing keyboard interactively
-        let recognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestureRecognizer))
-        recognizer.delegate = self
-        self.panGesture = recognizer
-        self.scrollView?.addGestureRecognizer(recognizer)
-        return self
-    }
-    
-    // MARK: - Keyboard Notifications
-    
-    /// An observer method called last in the lifecycle of a keyboard becoming visible
-    ///
-    /// - Parameter notification: NSNotification
-    @objc
-    open func keyboardDidShow(notification: NSNotification) {
-        guard let keyboardNotification = KeyboardNotification(from: notification) else { return }
-        callbacks[.didShow]?(keyboardNotification)
-    }
-    
-    /// An observer method called last in the lifecycle of a keyboard becoming hidden
-    ///
-    /// - Parameter notification: NSNotification
-    @objc
-    open func keyboardDidHide(notification: NSNotification) {
-        isKeyboardHidden = true
-        guard let keyboardNotification = KeyboardNotification(from: notification) else { return }
-        callbacks[.didHide]?(keyboardNotification)
-    }
-    
-    /// An observer method called third in the lifecycle of a keyboard becoming visible/hidden
-    ///
-    /// - Parameter notification: NSNotification
-    @objc
-    open func keyboardDidChangeFrame(notification: NSNotification) {
-        guard let keyboardNotification = KeyboardNotification(from: notification) else { return }
-        callbacks[.didChangeFrame]?(keyboardNotification)
-        cachedNotification = keyboardNotification
-    }
-    
-    /// An observer method called first in the lifecycle of a keyboard becoming visible/hidden
-    ///
-    /// - Parameter notification: NSNotification
-    @objc
-    open func keyboardWillChangeFrame(notification: NSNotification) {
-        guard let keyboardNotification = KeyboardNotification(from: notification) else { return }
-        callbacks[.willChangeFrame]?(keyboardNotification)
-        cachedNotification = keyboardNotification
-    }
-    
-    /// An observer method called second in the lifecycle of a keyboard becoming visible
-    ///
-    /// - Parameter notification: NSNotification
-    @objc
-    open func keyboardWillShow(notification: NSNotification) {
-        isKeyboardHidden = false
-        guard let keyboardNotification = KeyboardNotification(from: notification) else { return }
-        callbacks[.willShow]?(keyboardNotification)
-    }
-    
-    /// An observer method called second in the lifecycle of a keyboard becoming hidden
-    ///
-    /// - Parameter notification: NSNotification
-    @objc
-    open func keyboardWillHide(notification: NSNotification) {
-        guard let keyboardNotification = KeyboardNotification(from: notification) else { return }
-        callbacks[.willHide]?(keyboardNotification)
-    }
-    
-    // MARK: - Helper Methods
-    
-    private func animateAlongside(_ notification: KeyboardNotification, animations: @escaping ()->Void) {
-        UIView.animate(withDuration: notification.timeInterval, delay: 0,
-                       options: [notification.animationOptions, .allowAnimatedContent, .beginFromCurrentState],
-                       animations: animations, completion: nil)
-    }
-    
-    // MARK: - UIGestureRecognizerDelegate
-    
-    /// Starts with the cached `KeyboardNotification` and calculates a new `endFrame` based
-    /// on the `UIPanGestureRecognizer` then calls the `.willChangeFrame` `EventCallback` action
-    ///
-    /// - Parameter recognizer: UIPanGestureRecognizer
-    @objc
-    open func handlePanGestureRecognizer(recognizer: UIPanGestureRecognizer) {
-        guard
-            var keyboardNotification = cachedNotification,
-            case .changed = recognizer.state,
-            let view = recognizer.view,
-            let window = UIApplication.shared.windows.first
-            else { return }
-        
-        let location = recognizer.location(in: view)
-        let absoluteLocation = view.convert(location, to: window)
-        var frame = keyboardNotification.endFrame
-        frame.origin.y = max(absoluteLocation.y, window.bounds.height - frame.height)
-        frame.size.height = window.bounds.height - frame.origin.y
-        keyboardNotification.endFrame = frame
-        callbacks[.willChangeFrame]?(keyboardNotification)
-    }
-    
-    /// Only receive a `UITouch` event when the `scrollView`'s keyboard dismiss mode is interactive
-    open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
-        return scrollView?.keyboardDismissMode == .interactive
-    }
-    
-    /// Only recognice simultaneous gestures when its the `panGesture`
-    open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
-        return gestureRecognizer === panGesture
-    }
-    
-}

+ 0 - 66
deltachat-ios/View/InputBarAccessoryView/KeyboardManager/KeyboardNotification.swift

@@ -1,66 +0,0 @@
-//
-//  KeyboardNotification.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import UIKit
-
-/// An object containing the key animation properties from NSNotification
-public struct KeyboardNotification {
-    
-    // MARK: - Properties
-    
-    /// The event that triggered the transition
-    public let event: KeyboardEvent
-    
-    /// The animation length the keyboards transition
-    public let timeInterval: TimeInterval
-    
-    /// The animation properties of the keyboards transition
-    public let animationOptions: UIView.AnimationOptions
-    
-    /// iPad supports split-screen apps, this indicates if the notification was for the current app
-    public let isForCurrentApp: Bool
-    
-    /// The keyboards frame at the start of its transition
-    public var startFrame: CGRect
-    
-    /// The keyboards frame at the beginning of its transition
-    public var endFrame: CGRect
-    
-    /// Requires that the `NSNotification` is based on a `UIKeyboard...` event
-    ///
-    /// - Parameter notification: `KeyboardNotification`
-    public init?(from notification: NSNotification) {
-        guard notification.event != .unknown else { return nil }
-        self.event = notification.event
-        self.timeInterval = notification.timeInterval ?? 0.25
-        self.animationOptions = notification.animationOptions
-        self.isForCurrentApp = notification.isForCurrentApp ?? true
-        self.startFrame = notification.startFrame ?? .zero
-        self.endFrame = notification.endFrame ?? .zero
-    }
-    
-}

+ 0 - 16
deltachat-ios/View/InputBarAccessoryView/Models/HorizontalEdgeInsets.swift.swift

@@ -1,16 +0,0 @@
-//
-//  HorizontalEdgePadding.swift
-//  InputBarAccessoryView
-//
-//  Created by Nathan Tannar on 2018-11-07.
-//  Copyright © 2018 Nathan Tannar. All rights reserved.
-//
-
-import CoreGraphics
-
-public struct HorizontalEdgePadding {
-    public let left: CGFloat
-    public let right: CGFloat
-
-    static let zero = HorizontalEdgePadding(left: 0, right: 0)
-}

+ 0 - 82
deltachat-ios/View/InputBarAccessoryView/Models/NSConstraintLayoutSet.swift

@@ -1,82 +0,0 @@
-//
-//  NSConstraintLayoutSet.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/25/17.
-//
-
-import Foundation
-import UIKit
-
-class NSLayoutConstraintSet {
-    
-    var top: NSLayoutConstraint?
-    var bottom: NSLayoutConstraint?
-    var left: NSLayoutConstraint?
-    var right: NSLayoutConstraint?
-    var centerX: NSLayoutConstraint?
-    var centerY: NSLayoutConstraint?
-    var width: NSLayoutConstraint?
-    var height: NSLayoutConstraint?
-    
-    public init(top: NSLayoutConstraint? = nil, bottom: NSLayoutConstraint? = nil,
-                left: NSLayoutConstraint? = nil, right: NSLayoutConstraint? = nil,
-                centerX: NSLayoutConstraint? = nil, centerY: NSLayoutConstraint? = nil,
-                width: NSLayoutConstraint? = nil, height: NSLayoutConstraint? = nil) {
-        self.top = top
-        self.bottom = bottom
-        self.left = left
-        self.right = right
-        self.centerX = centerX
-        self.centerY = centerY
-        self.width = width
-        self.height = height
-    }
-    
-    /// All of the currently configured constraints
-    private var availableConstraints: [NSLayoutConstraint] {
-        #if swift(>=4.1)
-            return [top, bottom, left, right, centerX, centerY, width, height].compactMap {$0}
-        #else
-            return [top, bottom, left, right, centerX, centerY, width, height].flatMap {$0}
-        #endif
-    }
-    
-    /// Activates all of the non-nil constraints
-    ///
-    /// - Returns: Self
-    @discardableResult
-    func activate() -> Self {
-        NSLayoutConstraint.activate(availableConstraints)
-        return self
-    }
-    
-    /// Deactivates all of the non-nil constraints
-    ///
-    /// - Returns: Self
-    @discardableResult
-    func deactivate() -> Self {
-        NSLayoutConstraint.deactivate(availableConstraints)
-        return self
-    }
-}

+ 0 - 235
deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/AttachmentManager.swift

@@ -1,235 +0,0 @@
-//
-//  AttachmentManager.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import UIKit
-
-open class AttachmentManager: NSObject, InputPlugin {
-    
-    public enum Attachment {
-        case image(UIImage)
-        case url(URL)
-        case data(Data)
-        
-        @available(*, deprecated, message: ".other(AnyObject) has been depricated as of 2.0.0")
-        case other(AnyObject)
-    }
-    
-    // MARK: - Properties [Public]
-    
-    /// A protocol that can recieve notifications from the `AttachmentManager`
-    open weak var delegate: AttachmentManagerDelegate?
-    
-    /// A protocol to passes data to the `AttachmentManager`
-    open weak var dataSource: AttachmentManagerDataSource?
-    
-    open lazy var attachmentView: AttachmentCollectionView = { [weak self] in
-        let attachmentView = AttachmentCollectionView()
-        attachmentView.dataSource = self
-        attachmentView.delegate = self
-        return attachmentView
-    }()
-    
-    /// The attachments that the managers holds
-    private(set) public var attachments = [Attachment]() { didSet { reloadData() } }
-    
-    /// A flag you can use to determine if you want the manager to be always visible
-    open var isPersistent = false { didSet { attachmentView.reloadData() } }
-    
-    /// A flag to determine if the AddAttachmentCell is visible
-    open var showAddAttachmentCell = true { didSet { attachmentView.reloadData() } }
-    
-    /// The color applied to the backgroundColor of the deleteButton in each `AttachmentCell`
-    open var tintColor: UIColor = UIColor(red: 0, green: 0.5, blue: 1, alpha: 1)
-    
-    // MARK: - Initialization
-    
-    public override init() {
-        super.init()
-    }
-    
-    // MARK: - InputPlugin
-    
-    open func reloadData() {
-        attachmentView.reloadData()
-        delegate?.attachmentManager(self, didReloadTo: attachments)
-        delegate?.attachmentManager(self, shouldBecomeVisible: !attachments.isEmpty || isPersistent)
-    }
-    
-    /// Invalidates the `AttachmentManagers` session by removing all attachments
-    open func invalidate() {
-        attachments = []
-    }
-    
-    /// Appends the object to the attachments
-    ///
-    /// - Parameter object: The object to append
-    @discardableResult
-    open func handleInput(of object: AnyObject) -> Bool {
-        let attachment: Attachment
-        if let image = object as? UIImage {
-            attachment = .image(image)
-        } else if let url = object as? URL {
-            attachment = .url(url)
-        } else if let data = object as? Data {
-            attachment = .data(data)
-        } else {
-            return false
-        }
-        
-        insertAttachment(attachment, at: attachments.count)
-        return true
-    }
-    
-    // MARK: - API [Public]
-    
-    /// Performs an animated insertion of an attachment at an index
-    ///
-    /// - Parameter index: The index to insert the attachment at
-    open func insertAttachment(_ attachment: Attachment, at index: Int) {
-        
-        attachmentView.performBatchUpdates({
-            self.attachments.insert(attachment, at: index)
-            self.attachmentView.insertItems(at: [IndexPath(row: index, section: 0)])
-        }, completion: { success in
-            self.attachmentView.reloadData()
-            self.delegate?.attachmentManager(self, didInsert: attachment, at: index)
-            self.delegate?.attachmentManager(self, shouldBecomeVisible: !self.attachments.isEmpty || self.isPersistent)
-        })
-    }
-    
-    /// Performs an animated removal of an attachment at an index
-    ///
-    /// - Parameter index: The index to remove the attachment at
-    open func removeAttachment(at index: Int) {
-        
-        let attachment = attachments[index]
-        attachmentView.performBatchUpdates({
-            self.attachments.remove(at: index)
-            self.attachmentView.deleteItems(at: [IndexPath(row: index, section: 0)])
-        }, completion: { success in
-            self.attachmentView.reloadData()
-            self.delegate?.attachmentManager(self, didRemove: attachment, at: index)
-            self.delegate?.attachmentManager(self, shouldBecomeVisible: !self.attachments.isEmpty || self.isPersistent)
-        })
-    }
-    
-}
-
-extension AttachmentManager: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
-    
-    // MARK: - UICollectionViewDelegate
-    
-    final public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
-        if indexPath.row == attachments.count {
-            delegate?.attachmentManager(self, didSelectAddAttachmentAt: indexPath.row)
-            delegate?.attachmentManager(self, shouldBecomeVisible: !attachments.isEmpty || isPersistent)
-        }
-    }
-    
-    // MARK: - UICollectionViewDataSource
-    
-    final public func numberOfItems(inSection section: Int) -> Int {
-        return 1
-    }
-    
-    final public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
-        return attachments.count + (showAddAttachmentCell ? 1 : 0)
-    }
-    
-    final public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-        
-        if indexPath.row == attachments.count && showAddAttachmentCell {
-            return createAttachmentCell(in: collectionView, at: indexPath)
-        }
-        
-        let attachment = attachments[indexPath.row]
-        
-        if let cell = dataSource?.attachmentManager(self, cellFor: attachment, at: indexPath.row) {
-            return cell
-        } else {
-            
-            // Only images are supported by default
-            switch attachment {
-            case .image(let image):
-                guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ImageAttachmentCell.reuseIdentifier, for: indexPath) as? ImageAttachmentCell else {
-                    fatalError()
-                }
-                cell.attachment = attachment
-                cell.indexPath = indexPath
-                cell.manager = self
-                cell.imageView.image = image
-                cell.imageView.tintColor = tintColor
-                cell.deleteButton.backgroundColor = tintColor
-                return cell
-            default:
-                return collectionView.dequeueReusableCell(withReuseIdentifier: AttachmentCell.reuseIdentifier, for: indexPath) as! AttachmentCell
-            }
-            
-        }
-    }
-    
-    // MARK: - UICollectionViewDelegateFlowLayout
-    
-    final public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
-        
-        var height = attachmentView.intrinsicContentHeight
-        if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
-            height -= (layout.sectionInset.bottom + layout.sectionInset.top + collectionView.contentInset.top + collectionView.contentInset.bottom)
-        }
-        return CGSize(width: height, height: height)
-    }
-    
-    open func createAttachmentCell(in collectionView: UICollectionView, at indexPath: IndexPath) -> AttachmentCell {
-        
-        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AttachmentCell.reuseIdentifier, for: indexPath) as? AttachmentCell else {
-            fatalError()
-        }
-        cell.deleteButton.isHidden = true
-        // Draw a plus
-        let frame = CGRect(origin: CGPoint(x: cell.bounds.origin.x,
-                                           y: cell.bounds.origin.y),
-                           size: CGSize(width: cell.bounds.width - cell.padding.left - cell.padding.right,
-                                        height: cell.bounds.height - cell.padding.top - cell.padding.bottom))
-        let strokeWidth: CGFloat = 3
-        let length: CGFloat = frame.width / 2
-        let vLayer = CAShapeLayer()
-        vLayer.path = UIBezierPath(roundedRect: CGRect(x: frame.midX - (strokeWidth / 2),
-                                                       y: frame.midY - (length / 2),
-                                                       width: strokeWidth,
-                                                       height: length), cornerRadius: 5).cgPath
-        vLayer.fillColor = UIColor.lightGray.cgColor
-        let hLayer = CAShapeLayer()
-        hLayer.path = UIBezierPath(roundedRect: CGRect(x: frame.midX - (length / 2),
-                                                       y: frame.midY - (strokeWidth / 2),
-                                                       width: length,
-                                                       height: strokeWidth), cornerRadius: 5).cgPath
-        hLayer.fillColor = UIColor.lightGray.cgColor
-        cell.containerView.layer.addSublayer(vLayer)
-        cell.containerView.layer.addSublayer(hLayer)
-        return cell
-    }
-}

+ 0 - 41
deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Protocols/AttachmentManagerDataSource.swift

@@ -1,41 +0,0 @@
-//
-//  AttachmentManagerDataSource.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/6/17.
-//
-
-import Foundation
-
-/// AttachmentManagerDataSource is a protocol to passes data to the AttachmentManager
-public protocol AttachmentManagerDataSource: AnyObject {
-    
-    /// The AttachmentCell for the attachment that is to be inserted into the AttachmentView
-    ///
-    /// - Parameters:
-    ///   - manager: The AttachmentManager
-    ///   - attachment: The object
-    ///   - index: The index in the AttachmentView
-    /// - Returns: An AttachmentCell
-    func attachmentManager(_ manager: AttachmentManager, cellFor attachment: AttachmentManager.Attachment, at index: Int) -> AttachmentCell
-}

+ 0 - 81
deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Protocols/AttachmentManagerDelegate.swift

@@ -1,81 +0,0 @@
-//
-//  AttachmentManagerDelegate.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/6/17.
-//
-
-import UIKit
-
-/// AttachmentManagerDelegate is a protocol that can recieve notifications from the AttachmentManager
-public protocol AttachmentManagerDelegate: AnyObject {
-    
-    /// Can be used to determine if the AttachmentManager should be inserted into an InputStackView
-    ///
-    /// - Parameters:
-    ///   - manager: The AttachmentManager
-    ///   - shouldBecomeVisible: If the AttachmentManager should be presented or dismissed
-    func attachmentManager(_ manager: AttachmentManager, shouldBecomeVisible: Bool)
-    
-    
-    /// Notifys when an attachment has been inserted into the AttachmentManager
-    ///
-    /// - Parameters:
-    ///   - manager: The AttachmentManager
-    ///   - attachment: The attachment that was inserted
-    ///   - index: The index of the attachment in the AttachmentManager's attachments array
-    func attachmentManager(_ manager: AttachmentManager, didInsert attachment: AttachmentManager.Attachment, at index: Int)
-    
-    /// Notifys when an attachment has been removed from the AttachmentManager
-    ///
-    /// - Parameters:
-    ///   - manager: The AttachmentManager
-    ///   - attachment: The attachment that was removed
-    ///   - index: The index of the attachment in the AttachmentManager's attachments array
-    func attachmentManager(_ manager: AttachmentManager, didRemove attachment: AttachmentManager.Attachment, at index: Int)
-    
-    /// Notifys when the AttachmentManager was reloaded
-    ///
-    /// - Parameters:
-    ///   - manager: The AttachmentManager
-    ///   - attachments: The AttachmentManager's attachments array
-    func attachmentManager(_ manager: AttachmentManager, didReloadTo attachments: [AttachmentManager.Attachment])
-    
-    /// Notifys when the AddAttachmentCell was selected
-    ///
-    /// - Parameters:
-    ///   - manager: The AttachmentManager
-    ///   - attachments: The index of the AddAttachmentCell
-    func attachmentManager(_ manager: AttachmentManager, didSelectAddAttachmentAt index: Int)
-}
-
-public extension AttachmentManagerDelegate {
-    
-    func attachmentManager(_ manager: AttachmentManager, didInsert attachment: AttachmentManager.Attachment, at index: Int) {}
-    
-    func attachmentManager(_ manager: AttachmentManager, didRemove attachment: AttachmentManager.Attachment, at index: Int) {}
-    
-    func attachmentManager(_ manager: AttachmentManager, didReloadTo attachments: [AttachmentManager.Attachment]) {}
-    
-    func attachmentManager(_ manager: AttachmentManager, didSelectAddAttachmentAt index: Int) {}
-}

+ 0 - 132
deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Views/AttachmentCell.swift

@@ -1,132 +0,0 @@
-//
-//  AttachmentCell.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import UIKit
-
-open class AttachmentCell: UICollectionViewCell {
-    
-    // MARK: - Properties
-    
-    class var reuseIdentifier: String {
-        return "AttachmentCell"
-    }
-    
-    public let containerView: UIView = {
-        let view = UIView()
-        view.translatesAutoresizingMaskIntoConstraints = false
-        view.backgroundColor = .groupTableViewBackground
-        view.layer.cornerRadius = 8
-        view.clipsToBounds = true
-        return view
-    }()
-    
-    open var padding: UIEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5) {
-        didSet {
-            updateContainerPadding()
-        }
-    }
-    
-    open lazy var deleteButton: UIButton = { [weak self] in
-        let button = UIButton()
-        button.setAttributedTitle(NSMutableAttributedString().bold("X", fontSize: 15, textColor: .white), for: .normal)
-        button.setAttributedTitle(NSMutableAttributedString().bold("X", fontSize: 15, textColor: UIColor.white.withAlphaComponent(0.5)), for: .highlighted)
-        button.layer.cornerRadius = 10
-        button.clipsToBounds = true
-        button.backgroundColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1)
-        button.addTarget(self, action: #selector(deleteAttachment), for: .touchUpInside)
-        return button
-    }()
-    
-    open var attachment: AttachmentManager.Attachment?
-    
-    open var indexPath: IndexPath?
-    
-    open weak var manager: AttachmentManager?
-    
-    private var containerViewLayoutSet: NSLayoutConstraintSet?
-    
-    // MARK: - Initialization
-    
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    open override func prepareForReuse() {
-        super.prepareForReuse()
-        indexPath = nil
-        manager = nil
-        attachment = nil
-    }
-    
-    // MARK: - Setup
-    
-    private func setup() {
-        
-        setupSubviews()
-        setupConstraints()
-    }
-    
-    private func setupSubviews() {
-        
-        contentView.addSubview(containerView)
-        contentView.addSubview(deleteButton)
-    }
-
-    private func setupConstraints() {
-        
-        containerViewLayoutSet = NSLayoutConstraintSet(
-            top:    containerView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: padding.top),
-            bottom: containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -padding.bottom),
-            left:   containerView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: padding.left),
-            right:  containerView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -padding.right)
-        ).activate()
-        deleteButton.addConstraints(contentView.topAnchor, right: contentView.rightAnchor, widthConstant: 20, heightConstant: 20)
-    }
-    
-    private func updateContainerPadding() {
-        
-        containerViewLayoutSet?.top?.constant = padding.top
-        containerViewLayoutSet?.bottom?.constant = -padding.bottom
-        containerViewLayoutSet?.left?.constant = padding.left
-        containerViewLayoutSet?.right?.constant = -padding.right
-    }
-    
-    // MARK: - User Actions
-    
-    @objc
-    func deleteAttachment() {
-        
-        guard let index = indexPath?.row else { return }
-        manager?.removeAttachment(at: index)
-    }
-}

+ 0 - 82
deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Views/AttachmentsView.swift

@@ -1,82 +0,0 @@
-//
-//  AttachmentCollectionView.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import UIKit
-
-@available(*, deprecated, message: "AttachmentsView has been renamed to AttachmentCollectionView")
-public typealias AttachmentsView = AttachmentCollectionView
-
-open class AttachmentCollectionView: UICollectionView {
-    
-    // MARK: - Properties
-    
-    open var intrinsicContentHeight: CGFloat = 100 {
-        didSet {
-            invalidateIntrinsicContentSize()
-        }
-    }
-    
-    open override var intrinsicContentSize: CGSize {
-        return CGSize(width: 0, height: intrinsicContentHeight)
-    }
-    
-    // MARK: - Initialization
-    
-    public init() {
-        let layout = UICollectionViewFlowLayout()
-        layout.scrollDirection = .horizontal
-        layout.minimumLineSpacing = 0
-        layout.sectionInset.top = 5
-        layout.sectionInset.bottom = 5
-        layout.headerReferenceSize = CGSize(width: 12, height: 0)
-        layout.footerReferenceSize = CGSize(width: 12, height: 0)
-        super.init(frame: .zero, collectionViewLayout: layout)
-        setup()
-    }
-    
-    public override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
-        super.init(frame: frame, collectionViewLayout: layout)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    // MARK: - Setup
-    
-    private func setup() {
-        
-        backgroundColor = .white
-        alwaysBounceHorizontal = true
-        showsHorizontalScrollIndicator = true
-        setContentHuggingPriority(UILayoutPriority.defaultHigh, for: .vertical)
-        register(AttachmentCell.self, forCellWithReuseIdentifier: AttachmentCell.reuseIdentifier)
-        register(ImageAttachmentCell.self, forCellWithReuseIdentifier: ImageAttachmentCell.reuseIdentifier)
-    }
-}

+ 0 - 67
deltachat-ios/View/InputBarAccessoryView/Plugins/AttachmentManager/Views/ImageAttachmentCell.swift

@@ -1,67 +0,0 @@
-//
-//  ImageAttachmentCell.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/6/17.
-//
-
-import UIKit
-
-open class ImageAttachmentCell: AttachmentCell {
-    
-    // MARK: - Properties
-    
-    override class var reuseIdentifier: String {
-        return "ImageAttachmentCell"
-    }
-    
-    public let imageView: UIImageView = {
-        let imageView = UIImageView()
-        imageView.contentMode = .scaleAspectFill
-        return imageView
-    }()
-    
-    // MARK: - Initialization
-    
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    open override func prepareForReuse() {
-        super.prepareForReuse()
-        imageView.image = nil
-    }
-    
-    // MARK: - Setup
-    
-    private func setup() {
-        containerView.addSubview(imageView)
-        imageView.fillSuperview()
-    }
-}

+ 0 - 506
deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/AutocompleteManager.swift

@@ -1,506 +0,0 @@
-//
-//  AttachmentManager.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import UIKit
-
-public extension NSAttributedString.Key {
-    
-    /// A key used for referencing which substrings were autocompleted
-    /// by InputBarAccessoryView.AutocompleteManager
-    static let autocompleted = NSAttributedString.Key("com.system.autocompletekey")
-    
-    /// A key used for referencing the context of autocompleted substrings
-    /// by InputBarAccessoryView.AutocompleteManager
-    static let autocompletedContext = NSAttributedString.Key("com.system.autocompletekey.context")
-}
-
-open class AutocompleteManager: NSObject, InputPlugin, UITextViewDelegate, UITableViewDelegate, UITableViewDataSource {
-    
-    // MARK: - Properties [Public]
-    
-    /// A protocol that passes data to the `AutocompleteManager`
-    open weak var dataSource: AutocompleteManagerDataSource?
-    
-    /// A protocol that more precisely defines `AutocompleteManager` logic
-    open weak var delegate: AutocompleteManagerDelegate?
-    
-    /// A reference to the `InputTextView` that the `AutocompleteManager` is using
-    private(set) public weak var textView: UITextView?
-    
-    @available(*, deprecated, message: "`inputTextView` has been renamed to `textView` of type `UITextView`")
-    public var inputTextView: InputTextView? { return textView as? InputTextView }
-    
-    /// An ongoing session reference that holds the prefix, range and text to complete with
-    private(set) public var currentSession: AutocompleteSession?
-    
-    /// The `AutocompleteTableView` that renders available autocompletes for the `currentSession`
-    open lazy var tableView: AutocompleteTableView = { [weak self] in
-        let tableView = AutocompleteTableView()
-        tableView.register(AutocompleteCell.self, forCellReuseIdentifier: AutocompleteCell.reuseIdentifier)
-        tableView.separatorStyle = .none
-        tableView.backgroundColor = .white
-        tableView.rowHeight = 44
-        tableView.delegate = self
-        tableView.dataSource = self
-        return tableView
-    }()
-    
-    /// Adds an additional space after the autocompleted text when true.
-    /// Default value is `TRUE`
-    open var appendSpaceOnCompletion = true
-    
-    /// Keeps the prefix typed when text is autocompleted.
-    /// Default value is `TRUE`
-    open var keepPrefixOnCompletion = true
-    
-    /// Allows a single space character to be entered mid autocompletion.
-    ///
-    /// For example, your autocomplete is "Nathan Tannar", the .whitespace deliminater
-    /// set would terminate the session after "Nathan". By setting `maxSpaceCountDuringCompletion`
-    /// the session termination will disregard that number of spaces
-    ///
-    /// Default value is `0`
-    open var maxSpaceCountDuringCompletion: Int = 0
-
-    /// When enabled, autocomplete completions that contain whitespace will be deleted in parts.
-    /// This meands backspacing on "@Nathan Tannar" will result in " Tannar" being removed first
-    /// with a second backspace action required to delete "@Nathan"
-    ///
-    /// Default value is `TRUE`
-    open var deleteCompletionByParts = true
-    
-    /// The default text attributes
-    open var defaultTextAttributes: [NSAttributedString.Key: Any] =
-        [.font: UIFont.preferredFont(forTextStyle: .body), .foregroundColor: UIColor.black]
-    
-    /// The NSAttributedString.Key.paragraphStyle value applied to attributed strings
-    public let paragraphStyle: NSMutableParagraphStyle = {
-        let style = NSMutableParagraphStyle()
-        style.paragraphSpacingBefore = 2
-        style.lineHeightMultiple = 1
-        return style
-    }()
-
-    /// A block that filters the `AutocompleteCompletion`'s sourced
-    /// from the `dataSource`, based on the `AutocompleteSession`.
-    /// The default function requires the `AutocompleteCompletion.text`
-    /// string contains the `AutocompleteSession.filter`
-    /// string ignoring case
-    open var filterBlock: (AutocompleteSession, AutocompleteCompletion) -> (Bool) = { session, completion in completion.text.lowercased().contains(session.filter.lowercased())
-    }
-    
-    // MARK: - Properties [Private]
-    
-    /// The prefices that the manager will recognize
-    public private(set) var autocompletePrefixes = Set<String>()
-    
-    /// The delimiters that the manager will terminate a session with
-    /// The default value is: [.whitespaces, .newlines]
-    public private(set) var autocompleteDelimiterSets: Set<CharacterSet> = [.whitespaces, .newlines]
-    
-    /// The text attributes applied to highlighted substrings for each prefix
-    public private(set) var autocompleteTextAttributes = [String: [NSAttributedString.Key: Any]]()
-    
-    /// A reference to `defaultTextAttributes` that adds the NSAttributedAutocompleteKey
-    private var typingTextAttributes: [NSAttributedString.Key: Any] {
-        var attributes = defaultTextAttributes
-        attributes[.autocompleted] = false
-        attributes[.autocompletedContext] = nil
-        attributes[.paragraphStyle] = paragraphStyle
-        return attributes
-    }
-    
-    /// The current autocomplete text options filtered by the text after the prefix
-    private var currentAutocompleteOptions: [AutocompleteCompletion] {
-        
-        guard let session = currentSession, let completions = dataSource?.autocompleteManager(self, autocompleteSourceFor: session.prefix) else { return [] }
-        guard !session.filter.isEmpty else { return completions }
-        return completions.filter { completion in
-            return filterBlock(session, completion)
-        }
-    }
-    
-    // MARK: - Initialization
-    
-    public init(for textView: UITextView) {
-        super.init()
-        self.textView = textView
-        self.textView?.delegate = self
-    }
-    
-    // MARK: - InputPlugin
-    
-    /// Reloads the InputPlugin's session
-    open func reloadData() {
-
-        var delimiterSet = autocompleteDelimiterSets.reduce(CharacterSet()) { result, set in
-            return result.union(set)
-        }
-        let query = textView?.find(prefixes: autocompletePrefixes, with: delimiterSet)
-        
-        guard let result = query else {
-            if let session = currentSession, session.spaceCounter <= maxSpaceCountDuringCompletion {
-                delimiterSet = delimiterSet.subtracting(.whitespaces)
-                guard let result = textView?.find(prefixes: [session.prefix], with: delimiterSet) else {
-                    unregisterCurrentSession()
-                    return
-                }
-                let wordWithoutPrefix = (result.word as NSString).substring(from: result.prefix.utf16.count)
-                updateCurrentSession(to: wordWithoutPrefix)
-            } else {
-                unregisterCurrentSession()
-            }
-            return
-        }
-        let wordWithoutPrefix = (result.word as NSString).substring(from: result.prefix.utf16.count)
-        guard let session = AutocompleteSession(prefix: result.prefix, range: result.range, filter: wordWithoutPrefix) else { return }
-        guard let currentSession = currentSession else {
-            registerCurrentSession(to: session)
-            return
-        }
-        if currentSession == session {
-            updateCurrentSession(to: wordWithoutPrefix)
-        } else {
-            registerCurrentSession(to: session)
-        }
-    }
-    
-    /// Invalidates the InputPlugin's session
-    open func invalidate() {
-        unregisterCurrentSession()
-    }
-    
-    /// Passes an object into the InputPlugin's session to handle
-    ///
-    /// - Parameter object: A string to append
-    @discardableResult
-    open func handleInput(of object: AnyObject) -> Bool {
-        guard let newText = object as? String, let textView = textView else { return false }
-        let attributedString = NSMutableAttributedString(attributedString: textView.attributedText)
-        let newAttributedString = NSAttributedString(string: newText, attributes: typingTextAttributes)
-        attributedString.append(newAttributedString)
-        textView.attributedText = attributedString
-        reloadData()
-        return true
-    }
-    
-    // MARK: - API [Public]
-    
-    /// Registers a prefix and its the attributes to apply to its autocompleted strings
-    ///
-    /// - Parameters:
-    ///   - prefix: The prefix such as: @, # or !
-    ///   - attributedTextAttributes: The attributes to apply to the NSAttributedString
-    open func register(prefix: String, with attributedTextAttributes: [NSAttributedString.Key:Any]? = nil) {
-        autocompletePrefixes.insert(prefix)
-        autocompleteTextAttributes[prefix] = attributedTextAttributes
-        autocompleteTextAttributes[prefix]?[.paragraphStyle] = paragraphStyle
-    }
-    
-    /// Unregisters a prefix and removes its associated cached attributes
-    ///
-    /// - Parameter prefix: The prefix such as: @, # or !
-    open func unregister(prefix: String) {
-        autocompletePrefixes.remove(prefix)
-        autocompleteTextAttributes[prefix] = nil
-    }
-    
-    /// Registers a CharacterSet as a delimiter
-    ///
-    /// - Parameter delimiterSet: The `CharacterSet` to recognize as a delimiter
-    open func register(delimiterSet set: CharacterSet) {
-        autocompleteDelimiterSets.insert(set)
-    }
-    
-    /// Unregisters a CharacterSet
-    ///
-    /// - Parameter delimiterSet: The `CharacterSet` to recognize as a delimiter
-    open func unregister(delimiterSet set: CharacterSet) {
-        autocompleteDelimiterSets.remove(set)
-    }
-    
-    /// Replaces the current prefix and filter text with the supplied text
-    ///
-    /// - Parameters:
-    ///   - text: The replacement text
-    open func autocomplete(with session: AutocompleteSession) {
-        
-        guard let textView = textView else { return }
-        guard delegate?.autocompleteManager(self, shouldComplete: session.prefix, with: session.filter) != false else { return }
-        
-        // Create a range that overlaps the prefix
-        let prefixLength = session.prefix.utf16.count
-        let insertionRange = NSRange(
-            location: session.range.location + (keepPrefixOnCompletion ? prefixLength : 0),
-            length: session.filter.utf16.count + (!keepPrefixOnCompletion ? prefixLength : 0)
-        )
-        
-        // Transform range
-        guard let range = Range(insertionRange, in: textView.text) else { return }
-        let nsrange = NSRange(range, in: textView.text)
-        
-        // Replace the attributedText with a modified version
-        let autocomplete = session.completion?.text ?? ""
-        insertAutocomplete(autocomplete, at: session, for: nsrange)
-        
-        // Move Cursor to the end of the inserted text
-        let selectedLocation = insertionRange.location + autocomplete.utf16.count + (appendSpaceOnCompletion ? 1 : 0)
-        textView.selectedRange = NSRange(
-            location: selectedLocation,
-            length: 0
-        )
-        
-        // End the session
-        unregisterCurrentSession()
-    }
-    
-    /// Returns an attributed string with bolded characters matching the characters typed in the session
-    ///
-    /// - Parameter session: The `AutocompleteSession` to form an `NSMutableAttributedString` with
-    /// - Returns: An `NSMutableAttributedString`
-    open func attributedText(matching session: AutocompleteSession,
-                             fontSize: CGFloat = 15,
-                             keepPrefix: Bool = true) -> NSMutableAttributedString {
-        
-        guard let completion = session.completion else {
-            return NSMutableAttributedString()
-        }
-        
-        // Bolds the text that currently matches the filter
-        let matchingRange = (completion.text as NSString).range(of: session.filter, options: .caseInsensitive)
-        let attributedString = NSMutableAttributedString().normal(completion.text, fontSize: fontSize)
-        attributedString.addAttributes([.font: UIFont.boldSystemFont(ofSize: fontSize)], range: matchingRange)
-        
-        guard keepPrefix else { return attributedString }
-        let stringWithPrefix = NSMutableAttributedString().normal(String(session.prefix), fontSize: fontSize)
-        stringWithPrefix.append(attributedString)
-        return stringWithPrefix
-    }
-    
-    // MARK: - API [Private]
-    
-    /// Resets the `InputTextView`'s typingAttributes to `defaultTextAttributes`
-    private func preserveTypingAttributes() {
-        textView?.typingAttributes = typingTextAttributes
-    }
-    
-    
-    /// Inserts an autocomplete for a given selection
-    ///
-    /// - Parameters:
-    ///   - autocomplete: The 'String' to autocomplete to
-    ///   - sesstion: The 'AutocompleteSession'
-    ///   - range: The 'NSRange' to insert over
-    private func insertAutocomplete(_ autocomplete: String, at session: AutocompleteSession, for range: NSRange) {
-        
-        guard let textView = textView else { return }
-        
-        // Apply the autocomplete attributes
-        var attrs = autocompleteTextAttributes[session.prefix] ?? defaultTextAttributes
-        attrs[.autocompleted] = true
-        attrs[.autocompletedContext] = session.completion?.context
-        let newString = (keepPrefixOnCompletion ? session.prefix : "") + autocomplete
-        let newAttributedString = NSAttributedString(string: newString, attributes: attrs)
-        
-        // Modify the NSRange to include the prefix length
-        let rangeModifier = keepPrefixOnCompletion ? session.prefix.count : 0
-        let highlightedRange = NSRange(location: range.location - rangeModifier, length: range.length + rangeModifier)
-        
-        // Replace the attributedText with a modified version including the autocompete
-        let newAttributedText = textView.attributedText.replacingCharacters(in: highlightedRange, with: newAttributedString)
-        if appendSpaceOnCompletion {
-            newAttributedText.append(NSAttributedString(string: " ", attributes: typingTextAttributes))
-        }
-        
-        // Set to a blank attributed string to prevent keyboard autocorrect from cloberring the insert
-        textView.attributedText = NSAttributedString()
-
-        textView.attributedText = newAttributedText
-    }
-    
-    /// Initializes a session with a new `AutocompleteSession` object
-    ///
-    /// - Parameters:
-    ///   - session: The session to register
-    private func registerCurrentSession(to session: AutocompleteSession) {
-        
-        guard delegate?.autocompleteManager(self, shouldRegister: session.prefix, at: session.range) != false else { return }
-        currentSession = session
-        layoutIfNeeded()
-        delegate?.autocompleteManager(self, shouldBecomeVisible: true)
-    }
-    
-    /// Updates the session to a new String to filter results with
-    ///
-    /// - Parameters:
-    ///   - filterText: The String to filter `AutocompleteCompletion`s
-    private func updateCurrentSession(to filterText: String) {
-        
-        currentSession?.filter = filterText
-        layoutIfNeeded()
-        delegate?.autocompleteManager(self, shouldBecomeVisible: true)
-    }
-    
-    /// Invalidates the `currentSession` session if it existed
-    private func unregisterCurrentSession() {
-        
-        guard let session = currentSession else { return }
-        guard delegate?.autocompleteManager(self, shouldUnregister: session.prefix) != false else { return }
-        currentSession = nil
-        layoutIfNeeded()
-        delegate?.autocompleteManager(self, shouldBecomeVisible: false)
-    }
-    
-    /// Calls the required methods to relayout the `AutocompleteTableView` in it's superview
-    private func layoutIfNeeded() {
-        
-        tableView.reloadData()
-        
-        // Resize the table to be fit properly in an `InputStackView`
-        tableView.invalidateIntrinsicContentSize()
-        
-        // Layout the table's superview
-        tableView.superview?.layoutIfNeeded()
-    }
-    
-    // MARK: - UITextViewDelegate
-    
-    public func textViewDidChange(_ textView: UITextView) {
-        reloadData()
-    }
-    
-    public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
-        
-        // Ensure that the text to be inserted is not using previous attributes
-        preserveTypingAttributes()
-        
-        if let session = currentSession {
-            let textToReplace = (textView.text as NSString).substring(with: range)
-            let deleteSpaceCount = textToReplace.filter { $0 == .space }.count
-            let insertSpaceCount = text.filter { $0 == .space }.count
-            let spaceCountDiff = insertSpaceCount - deleteSpaceCount
-            session.spaceCounter = spaceCountDiff
-        }
-        
-        let totalRange = NSRange(location: 0, length: textView.attributedText.length)
-        let selectedRange = textView.selectedRange
-        
-        // range.length > 0: Backspace/removing text
-        // range.lowerBound < textView.selectedRange.lowerBound: Ignore trying to delete
-        //      the substring if the user is already doing so
-        // range == selectedRange: User selected a chunk to delete
-        if range.length > 0, range.location < selectedRange.location {
-            
-            // Backspace/removing text
-            let attributes = textView.attributedText.attributes(at: range.location, longestEffectiveRange: nil, in: range)
-            let isAutocompleted = attributes[.autocompleted] as? Bool ?? false
-            
-            if isAutocompleted {
-                textView.attributedText.enumerateAttribute(.autocompleted, in: totalRange, options: .reverse) { _, subrange, stop in
-                    
-                    let intersection = NSIntersectionRange(range, subrange)
-                    guard intersection.length > 0 else { return }
-                    defer { stop.pointee = true }
-
-                    let nothing = NSAttributedString(string: "", attributes: typingTextAttributes)
-
-                    let textToReplace = textView.attributedText.attributedSubstring(from: subrange).string
-                    guard deleteCompletionByParts,
-                            let delimiterRange = textToReplace.rangeOfCharacter(from: .whitespacesAndNewlines,
-                                                                                options: .backwards,
-                                                                                range: Range(subrange, in: textToReplace)) else {
-                        // Replace entire autocomplete
-                        textView.attributedText = textView.attributedText.replacingCharacters(in: subrange, with: nothing)
-                        textView.selectedRange = NSRange(location: subrange.location, length: 0)
-                        return
-                    }
-                    // Delete up to delimiter
-                    let delimiterLocation = delimiterRange.lowerBound.encodedOffset
-                    let length = subrange.length - delimiterLocation
-                    let rangeFromDelimiter = NSRange(location: delimiterLocation + subrange.location, length: length)
-                    textView.attributedText = textView.attributedText.replacingCharacters(in: rangeFromDelimiter, with: nothing)
-                    textView.selectedRange = NSRange(location: subrange.location + delimiterLocation, length: 0)
-                }
-                unregisterCurrentSession()
-                return false
-            }
-        } else if range.length >= 0, range.location < totalRange.length {
-            
-            // Inserting text in the middle of an autocompleted string
-            let attributes = textView.attributedText.attributes(at: range.location, longestEffectiveRange: nil, in: range)
-            let isAutocompleted = attributes[.autocompleted] as? Bool ?? false
-            if isAutocompleted {
-                textView.attributedText.enumerateAttribute(.autocompleted, in: totalRange, options: .reverse) { _, subrange, stop in
-                    
-                    let compareRange = range.length == 0 ? NSRange(location: range.location, length: 1) : range
-                    let intersection = NSIntersectionRange(compareRange, subrange)
-                    guard intersection.length > 0 else { return }
-                    
-                    let mutable = NSMutableAttributedString(attributedString: textView.attributedText)
-                    mutable.setAttributes(typingTextAttributes, range: subrange)
-                    let replacementText = NSAttributedString(string: text, attributes: typingTextAttributes)
-                    textView.attributedText = mutable.replacingCharacters(in: range, with: replacementText)
-                    textView.selectedRange = NSRange(location: range.location + text.count, length: 0)
-                    stop.pointee = true
-                }
-                unregisterCurrentSession()
-                return false
-            }
-        }
-        return true
-    }
-    
-    // MARK: - UITableViewDataSource
-    
-    open func numberOfSections(in tableView: UITableView) -> Int {
-        return 1
-    }
-    
-    open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        return currentAutocompleteOptions.count
-    }
-    
-    open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        
-        guard let session = currentSession else { fatalError("Attempted to render a cell for a nil `AutocompleteSession`") }
-        session.completion = currentAutocompleteOptions[indexPath.row]
-        guard let cell = dataSource?.autocompleteManager(self, tableView: tableView, cellForRowAt: indexPath, for: session) else {
-            fatalError("Failed to return a cell from `dataSource: AutocompleteManagerDataSource`")
-        }
-        return cell
-    }
-    
-    // MARK: - UITableViewDelegate
-    
-    open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-        
-        guard let session = currentSession else { return }
-        session.completion = currentAutocompleteOptions[indexPath.row]
-        autocomplete(with: session)
-    }
-    
-}

+ 0 - 48
deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Models/AutocompleteCompletion.swift

@@ -1,48 +0,0 @@
-//
-//  AutocompleteCompletion.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import Foundation
-
-public struct AutocompleteCompletion {
-    
-    // The String to insert/replace upon autocompletion
-    public let text: String
-    
-    // The context of the completion that you may need later when completed
-    public let context: [String: Any]?
-    
-    public init(text: String, context: [String: Any]? = nil) {
-        self.text = text
-        self.context = context
-    }
-    
-    @available(*, deprecated, message: "`displayText` should no longer be used, use `context: [String: Any]` instead")
-    public init(_ text: String, displayText: String) {
-        self.text = text
-        self.context = nil
-    }
-}

+ 0 - 52
deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Models/AutocompleteSession.swift

@@ -1,52 +0,0 @@
-//
-//  AutocompleteSession.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import Foundation
-
-/// A class containing data on the `AutocompleteManager`'s session
-public class AutocompleteSession {
-    
-    public let prefix: String
-    public let range: NSRange
-    public var filter: String
-    public var completion: AutocompleteCompletion?
-    internal var spaceCounter: Int = 0
-    
-    public init?(prefix: String?, range: NSRange?, filter: String?) {
-        guard let pfx = prefix, let rng = range, let flt = filter else { return nil }
-        self.prefix = pfx
-        self.range = rng
-        self.filter = flt
-    }
-}
-
-extension AutocompleteSession: Equatable {
-
-    public static func == (lhs: AutocompleteSession, rhs: AutocompleteSession) -> Bool {
-        return lhs.prefix == rhs.prefix && lhs.range == rhs.range
-    }
-}

+ 0 - 67
deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Protocols/AutocompleteManagerDataSource.swift

@@ -1,67 +0,0 @@
-//
-//  AutocompleteManagerDataSource.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/1/17.
-//
-
-import UIKit
-
-/// AutocompleteManagerDataSource is a protocol that passes data to the AutocompleteManager
-public protocol AutocompleteManagerDataSource: AnyObject {
-    
-    /// The autocomplete options for the registered prefix.
-    ///
-    /// - Parameters:
-    ///   - manager: The AutocompleteManager
-    ///   - prefix: The registered prefix
-    /// - Returns: An array of `AutocompleteCompletion` options for the given prefix
-    func autocompleteManager(_ manager: AutocompleteManager, autocompleteSourceFor prefix: String) -> [AutocompleteCompletion]
-    
-    /// The cell to populate the `AutocompleteTableView` with
-    ///
-    /// - Parameters:
-    ///   - manager: The `AttachmentManager` that sources the UITableViewDataSource
-    ///   - tableView: The `AttachmentManager`'s `AutocompleteTableView`
-    ///   - indexPath: The `IndexPath` of the cell
-    ///   - session: The current `Session` of the `AutocompleteManager`
-    /// - Returns: A UITableViewCell to populate the `AutocompleteTableView`
-    func autocompleteManager(_ manager: AutocompleteManager, tableView: UITableView, cellForRowAt indexPath: IndexPath, for session: AutocompleteSession) -> UITableViewCell
-}
-
-public extension AutocompleteManagerDataSource {
-    
-    func autocompleteManager(_ manager: AutocompleteManager, tableView: UITableView, cellForRowAt indexPath: IndexPath, for session: AutocompleteSession) -> UITableViewCell {
-        
-        guard let cell = tableView.dequeueReusableCell(withIdentifier: AutocompleteCell.reuseIdentifier, for: indexPath) as? AutocompleteCell else {
-            fatalError("AutocompleteCell is not registered")
-        }
-        
-        cell.textLabel?.attributedText = manager.attributedText(matching: session, fontSize: 13)
-        cell.backgroundColor = .white
-        cell.separatorLine.isHidden = tableView.numberOfRows(inSection: indexPath.section) - 1 == indexPath.row
-        return cell
-        
-    }
-    
-}

+ 0 - 82
deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Protocols/AutocompleteManagerDelegate.swift

@@ -1,82 +0,0 @@
-//
-//  AutocompleteManagerDelegate.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import UIKit
-
-/// AutocompleteManagerDelegate is a protocol that more precisely define AutocompleteManager logic
-public protocol AutocompleteManagerDelegate: AnyObject {
-    
-    /// Can be used to determine if the AutocompleteManager should be inserted into an InputStackView
-    ///
-    /// - Parameters:
-    ///   - manager: The AutocompleteManager
-    ///   - shouldBecomeVisible: If the AutocompleteManager should be presented or dismissed
-    func autocompleteManager(_ manager: AutocompleteManager, shouldBecomeVisible: Bool)
-    
-    /// Determines if a prefix character should be registered to initialize the auto-complete selection table
-    ///
-    /// - Parameters:
-    ///   - manager: The AutocompleteManager
-    ///   - prefix: The prefix `Character` could be registered
-    ///   - range: The `NSRange` of the prefix in the UITextView managed by the AutocompleteManager
-    /// - Returns: If the prefix should be registered. Default is TRUE
-    func autocompleteManager(_ manager: AutocompleteManager, shouldRegister prefix: String, at range: NSRange) -> Bool
-    
-    /// Determines if a prefix character should be unregistered to de-initialize the auto-complete selection table
-    ///
-    /// - Parameters:
-    ///   - manager: The AutocompleteManager
-    ///   - prefix: The prefix character could be unregistered
-    ///   - range: The range of the prefix in the UITextView managed by the AutocompleteManager
-    /// - Returns: If the prefix should be unregistered. Default is TRUE
-    func autocompleteManager(_ manager: AutocompleteManager, shouldUnregister prefix: String) -> Bool
-    
-    /// Determines if a prefix character can should be autocompleted
-    ///
-    /// - Parameters:
-    ///   - manager: The AutocompleteManager
-    ///   - prefix: The prefix character that is currently registered
-    ///   - text: The text to autocomplete with
-    /// - Returns: If the prefix can be autocompleted. Default is TRUE
-    func autocompleteManager(_ manager: AutocompleteManager, shouldComplete prefix: String, with text: String) -> Bool
-}
-
-public extension AutocompleteManagerDelegate {
-    
-    func autocompleteManager(_ manager: AutocompleteManager, shouldRegister prefix: String, at range: NSRange) -> Bool {
-        return true
-    }
-    
-    func autocompleteManager(_ manager: AutocompleteManager, shouldUnregister prefix: String) -> Bool {
-        return true
-    }
-    
-    func autocompleteManager(_ manager: AutocompleteManager, shouldComplete prefix: String, with text: String) -> Bool {
-        return true
-    }
-}
-

+ 0 - 98
deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Views/AutocompleteCell.swift

@@ -1,98 +0,0 @@
-//
-//  AutocompleteCell.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import UIKit
-
-open class AutocompleteCell: UITableViewCell {
-    
-    // MARK: - Properties
-    
-    open class var reuseIdentifier: String {
-        return "AutocompleteCell"
-    }
-    
-    /// A boarder line anchored to the top of the view
-    public let separatorLine = SeparatorLine()
-    
-    open var imageViewEdgeInsets: UIEdgeInsets = .zero { didSet { setNeedsLayout() } }
-    
-    // MARK: - Initialization
-    
-    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    open override func prepareForReuse() {
-        super.prepareForReuse()
-        textLabel?.text = nil
-        detailTextLabel?.text = nil
-        imageView?.image = nil
-        imageViewEdgeInsets = .zero
-        separatorLine.backgroundColor = .lightGray
-        separatorLine.isHidden = false
-    }
-    
-    // MARK: - Setup
-    
-    private func setup() {
-        
-        setupSubviews()
-        setupConstraints()
-    }
-    
-    open func setupSubviews() {
-        
-        addSubview(separatorLine)
-    }
-    
-    open func setupConstraints() {
-        
-        separatorLine.addConstraints(left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, heightConstant: 0.5)
-    }
-    
-    open override func layoutSubviews() {
-        super.layoutSubviews()
-        guard let imageViewFrame = imageView?.frame else { return }
-        let imageViewOrigin = CGPoint(x: imageViewFrame.origin.x + imageViewEdgeInsets.left, y: imageViewFrame.origin.y + imageViewEdgeInsets.top)
-        let imageViewSize = CGSize(width: imageViewFrame.size.width - imageViewEdgeInsets.left - imageViewEdgeInsets.right,
-                                   height: imageViewFrame.size.height - imageViewEdgeInsets.top - imageViewEdgeInsets.bottom)
-        imageView?.frame = CGRect(origin: imageViewOrigin, size: imageViewSize)
-    }
-    
-    // MARK: - API [Public]
-    
-    @available(*, deprecated, message: "This function has been moved to the `AutocompleteManager`")
-    open func attributedText(matching session: AutocompleteSession) -> NSMutableAttributedString {
-        fatalError("Please use `func attributedText(matching:, fontSize:)` implemented in the `AutocompleteManager`")
-    }
-}

+ 0 - 41
deltachat-ios/View/InputBarAccessoryView/Plugins/AutocompleteManager/Views/AutocompleteTableView.swift

@@ -1,41 +0,0 @@
-//
-//  AutocompleteTableView.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import UIKit
-
-open class AutocompleteTableView: UITableView {
-    
-    /// The max visible rows visible in the autocomplete table before the user has to scroll throught them
-    open var maxVisibleRows = 3 { didSet { invalidateIntrinsicContentSize() } }
-    
-    open override var intrinsicContentSize: CGSize {
-        
-        let rows = numberOfRows(inSection: 0) < maxVisibleRows ? numberOfRows(inSection: 0) : maxVisibleRows
-        return CGSize(width: super.intrinsicContentSize.width, height: (CGFloat(rows) * rowHeight))
-    }
-    
-}

+ 0 - 74
deltachat-ios/View/InputBarAccessoryView/Protocols/InputBarAccessoryViewDelegate.swift

@@ -1,74 +0,0 @@
-//
-//  InputBarAccessoryViewDelegate.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import Foundation
-import UIKit
-
-/// InputBarAccessoryViewDelegate is a protocol that can recieve notifications from the InputBarAccessoryView
-public protocol InputBarAccessoryViewDelegate: AnyObject {
-    
-    /// Called when the default send button has been selected
-    ///
-    /// - Parameters:
-    ///   - inputBar: The InputBarAccessoryView
-    ///   - text: The current text in the InputBarAccessoryView's InputTextView
-    func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String)
-    
-    /// Called when the instrinsicContentSize of the InputBarAccessoryView has changed. Can be used for adjusting content insets
-    /// on other views to make sure the InputBarAccessoryView does not cover up any other view
-    ///
-    /// - Parameters:
-    ///   - inputBar: The InputBarAccessoryView
-    ///   - size: The new instrinsicContentSize
-    func inputBar(_ inputBar: InputBarAccessoryView, didChangeIntrinsicContentTo size: CGSize)
-    
-    /// Called when the InputBarAccessoryView's InputTextView's text has changed. Useful for adding your own logic without the
-    /// need of assigning a delegate or notification
-    ///
-    /// - Parameters:
-    ///   - inputBar: The InputBarAccessoryView
-    ///   - text: The current text in the InputBarAccessoryView's InputTextView
-    func inputBar(_ inputBar: InputBarAccessoryView, textViewTextDidChangeTo text: String)
-    
-    /// Called when a swipe gesture was recognized on the InputBarAccessoryView's InputTextView
-    ///
-    /// - Parameters:
-    ///   - inputBar: The InputBarAccessoryView
-    ///   - gesture: The gesture that was recognized
-    func inputBar(_ inputBar: InputBarAccessoryView, didSwipeTextViewWith gesture: UISwipeGestureRecognizer)
-}
-
-public extension InputBarAccessoryViewDelegate {
-    
-    func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) {}
-    
-    func inputBar(_ inputBar: InputBarAccessoryView, didChangeIntrinsicContentTo size: CGSize) {}
-    
-    func inputBar(_ inputBar: InputBarAccessoryView, textViewTextDidChangeTo text: String) {}
-    
-    func inputBar(_ inputBar: InputBarAccessoryView, didSwipeTextViewWith gesture: UISwipeGestureRecognizer) {}
-}

+ 0 - 50
deltachat-ios/View/InputBarAccessoryView/Protocols/InputItem.swift

@@ -1,50 +0,0 @@
-//
-//  InputItem.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Copyright © 2017-2019 Nathan Tannar. All rights reserved.
-//
-
-import UIKit
-
-/// InputItem is a protocol that links elements to the InputBarAccessoryView to make them reactive
-public protocol InputItem: AnyObject {
-    
-    /// A weak reference to the InputBarAccessoryView. Set when inserted into an InputStackView
-    var inputBarAccessoryView: InputBarAccessoryView? { get set }
-    
-    /// A reference to the InputStackView that the InputItem is contained in. Set when inserted into an InputStackView
-    var parentStackViewPosition: InputStackView.Position? { get set }
-    
-    /// A hook that is called when the InputTextView's text is changed
-    func textViewDidChangeAction(with textView: InputTextView)
-    
-    /// A hook that is called when the InputBarAccessoryView's InputTextView receieves a swipe gesture
-    func keyboardSwipeGestureAction(with gesture: UISwipeGestureRecognizer)
-    
-    /// A hook that is called when the InputTextView is resigned as the first responder
-    func keyboardEditingEndsAction()
-    
-    /// A hook that is called when the InputTextView is made the first responder
-    func keyboardEditingBeginsAction()
-}

+ 0 - 43
deltachat-ios/View/InputBarAccessoryView/Protocols/InputPlugin.swift

@@ -1,43 +0,0 @@
-//
-//  InputPlugin.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Copyright © 2017-2019 Nathan Tannar. All rights reserved.
-//
-
-import UIKit
-
-/// `InputPlugin` is a protocol that makes integrating plugins to the `InputBarAccessoryView` easy.
-public protocol InputPlugin: AnyObject {
-    
-    /// Should reload the state if the `InputPlugin`
-    func reloadData()
-    
-    /// Should remove any content that the `InputPlugin` is managing
-    func invalidate()
-    
-    /// Should handle the input of data types that an `InputPlugin` manages
-    ///
-    /// - Parameter object: The object to input
-    func handleInput(of object: AnyObject) -> Bool
-}

+ 0 - 185
deltachat-ios/View/InputBarAccessoryView/RxInputBarAccessoryView/RxInputBarAccessoryView.swift

@@ -1,185 +0,0 @@
-//
-//  RxInputBarAccessoryView.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 9/13/18.
-//
-
-import UIKit
-#if canImport(RxSwift) && canImport(RxCocoa)
-import RxSwift
-import RxCocoa
-
-final class RxInputBarAccessoryViewDelegate:
-    DelegateProxy<InputBarAccessoryView, InputBarAccessoryViewDelegate>,
-    DelegateProxyType,
-InputBarAccessoryViewDelegate {
-
-    let sendText = PublishSubject<String>()
-    let currentText = PublishSubject<String>()
-    let intrinsicContentSize = PublishSubject<CGSize>()
-    let swipeGesture = PublishSubject<UISwipeGestureRecognizer>()
-
-    func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) {
-        sendText.onNext(text)
-    }
-
-    func inputBar(_ inputBar: InputBarAccessoryView, textViewTextDidChangeTo text: String) {
-        currentText.onNext(text)
-    }
-
-    func inputBar(_ inputBar: InputBarAccessoryView, didChangeIntrinsicContentTo size: CGSize) {
-        intrinsicContentSize.onNext(size)
-    }
-
-    func inputBar(_ inputBar: InputBarAccessoryView, didSwipeTextViewWith gesture: UISwipeGestureRecognizer) {
-        swipeGesture.onNext(gesture)
-    }
-
-    static func registerKnownImplementations() {
-        register {
-            RxInputBarAccessoryViewDelegate(
-                parentObject: $0,
-                delegateProxy: RxInputBarAccessoryViewDelegate.self
-            )
-        }
-    }
-
-    static func currentDelegate(for object: InputBarAccessoryView) -> InputBarAccessoryViewDelegate? {
-        return object.delegate
-    }
-
-    static func setCurrentDelegate(_ delegate: InputBarAccessoryViewDelegate?, to object: InputBarAccessoryView) {
-        object.delegate = delegate
-    }
-}
-
-extension InputBarAccessoryView {
-    var rxDelegate: RxInputBarAccessoryViewDelegate {
-        return RxInputBarAccessoryViewDelegate.proxy(for: self)
-    }
-}
-
-extension Reactive where Base: InputBarAccessoryView {
-    public var isTranslucent: Binder<Bool> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.isTranslucent = newValue
-        }
-    }
-
-    public var shouldAutoUpdateMaxTextViewHeight: Binder<Bool> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.shouldAutoUpdateMaxTextViewHeight = newValue
-        }
-    }
-
-    public var maxTextViewHeight: Binder<CGFloat> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.maxTextViewHeight = newValue
-        }
-    }
-
-    public var shouldManageSendButtonEnabledState: Binder<Bool> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.shouldManageSendButtonEnabledState = newValue
-        }
-    }
-
-    public var leftStackViewItems: Binder<[InputItem]> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.setStackViewItems(newValue, forStack: .left, animated: false)
-        }
-    }
-
-    public var rightStackViewItems: Binder<[InputItem]> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.setStackViewItems(newValue, forStack: .right, animated: false)
-        }
-    }
-
-    public var topStackViewItems: Binder<[InputItem]> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.setStackViewItems(newValue, forStack: .top, animated: false)
-        }
-    }
-
-    public var bottomStackViewItems: Binder<[InputItem]> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.setStackViewItems(newValue, forStack: .bottom, animated: false)
-        }
-    }
-
-    public var leftStackViewWidthConstant: Binder<CGFloat> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.setLeftStackViewWidthConstant(to: newValue, animated: false)
-        }
-    }
-
-    public var rightStackViewWidthConstant: Binder<CGFloat> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.setRightStackViewWidthConstant(to: newValue, animated: false)
-        }
-    }
-
-    public var shouldForceMaxTextViewHeight: Binder<Bool> {
-        return Binder(base) { inputBar, newValue in
-            inputBar.setShouldForceMaxTextViewHeight(to: newValue, animated: false)
-        }
-    }
-}
-
-extension Reactive where Base: InputBarButtonItem {
-    public var size: Binder<CGSize?> {
-        return Binder(base) { item, newValue in
-            item.setSize(newValue, animated: false)
-        }
-    }
-
-    public var spacing: Binder<InputBarButtonItem.Spacing> {
-        return Binder(base) { item, newValue in
-            item.spacing = newValue
-        }
-    }
-}
-
-extension Reactive where Base: InputBarSendButton {
-    public var isAnimating: Binder<Bool> {
-        return Binder(base) { item, newValue in
-            if newValue {
-                item.startAnimating()
-            } else {
-                item.stopAnimating()
-            }
-        }
-    }
-}
-
-extension Reactive where Base: InputBarViewController {
-    public var isInputBarHidden: Binder<Bool> {
-        return Binder(base) { viewController, newValue in
-            viewController.isInputBarHidden = newValue
-        }
-    }
-}
-
-#endif

+ 0 - 24
deltachat-ios/View/InputBarAccessoryView/Supporting Files/Info.plist

@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>en</string>
-	<key>CFBundleExecutable</key>
-	<string>$(EXECUTABLE_NAME)</string>
-	<key>CFBundleIdentifier</key>
-	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>$(PRODUCT_NAME)</string>
-	<key>CFBundlePackageType</key>
-	<string>FMWK</string>
-	<key>CFBundleShortVersionString</key>
-	<string>4.2.1</string>
-	<key>CFBundleVersion</key>
-	<string>$(CURRENT_PROJECT_VERSION)</string>
-	<key>NSPrincipalClass</key>
-	<string></string>
-</dict>
-</plist>

+ 0 - 91
deltachat-ios/View/InputBarAccessoryView/Supporting Files/InputBarAccessoryView+Availability.swift

@@ -1,91 +0,0 @@
-//
-//  InputBarAccessoryView+Availability.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 2/12/17.
-//
-
-import UIKit
-
-@available(*, deprecated, message: "InputManager has been renamed to InputPlugin")
-public typealias InputManager = InputPlugin
-
-extension InputPlugin {
-    
-    @available(*, deprecated, message: "`handleInput(object:)` should return a `Bool` if handle was successful or now")
-    func handleInput(of object: AnyObject) {
-        _ = self.handleInput(of: object)
-    }
-}
-
-extension AutocompleteCompletion {
-    
-    // An optional string to display instead of `text`, for example emojis
-    @available(*, deprecated, message: "`displayText` should no longer be used, use `context: [String: Any]` instead")
-    public var displayText: String? {
-        return text
-    }
-}
-
-extension AutocompleteManager {
-    /// If the autocomplete matches should be made by casting the strings to lowercase.
-    /// Default value is `FALSE`
-    /// DEPRICATED; will always return `FALSE`
-    @available(*, deprecated, message: "`isCaseSensitive` was replaced in favour of a more customizable `filterBlock: (String) -> (Bool)`")
-    public var isCaseSensitive: Bool {
-        get { return false }
-        set {
-            if isCaseSensitive {
-                filterBlock = { session, completion in
-                    completion.text.contains(session.filter)
-                }
-            } else {
-                filterBlock = { session, completion in completion.text.lowercased().contains(session.filter.lowercased())
-                }
-            }
-        }
-    }
-}
-
-extension InputBarAccessoryView {
-
-    /**
-     The anchor constants used by the InputStackView
-
-     ````
-     V:|...-(padding.top)-(textViewPadding.top)-[InputTextView]-(textViewPadding.bottom)-[InputStackView.bottom]-...|
-
-     H:|...-[InputStackView.left]-(textViewPadding.left)-[InputTextView]-(textViewPadding.right)-[InputStackView.right]-...|
-     ````
-
-     */
-    @available(*, deprecated, message: "The `InputTextView` now resides in the `middleContentView` and thus this property has been renamed to `middleContentViewPadding`")
-    public var textViewPadding: UIEdgeInsets {
-        get {
-            return middleContentViewPadding
-        }
-        set {
-            middleContentViewPadding = newValue
-        }
-    }
-}

+ 0 - 19
deltachat-ios/View/InputBarAccessoryView/Supporting Files/InputBarAccessoryView-Bridging-Header.h

@@ -1,19 +0,0 @@
-//
-//  InputBarAccessoryView.h
-//  InputBarAccessoryView
-//
-//  Created by Nathan Tannar on 8/18/17.
-//  Copyright © 2017-2019 Nathan Tannar. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-//! Project version number for InputBarAccessoryView.
-FOUNDATION_EXPORT double InputBarAccessoryViewVersionNumber;
-
-//! Project version string for InputBarAccessoryView.
-FOUNDATION_EXPORT const unsigned char InputBarAccessoryViewVersionString[];
-
-// In this header, you should import all the public headers of your framework using statements like #import <InputBarAccessoryView/PublicHeader.h>
-
-

+ 0 - 88
deltachat-ios/View/InputBarAccessoryView/ViewControllers/InputBarViewController.swift

@@ -1,88 +0,0 @@
-//
-//  InputBarViewController.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 9/13/18.
-//
-
-import UIKit
-
-/// An simple `UIViewController` subclass that is ready to work
-/// with an `inputAccessoryView`
-open class InputBarViewController: UIViewController, InputBarAccessoryViewDelegate {
-
-    /// A powerful InputAccessoryView ideal for messaging applications
-    public let inputBar = InputBarAccessoryView()
-
-    /// A boolean value that when changed will update the `inputAccessoryView`
-    /// of the `InputBarViewController`. When set to `TRUE`, the
-    /// `inputAccessoryView` is set to `nil` and the `inputBar` slides off
-    /// the screen.
-    ///
-    /// The default value is FALSE
-    open var isInputBarHidden: Bool = false {
-        didSet {
-            isInputBarHiddenDidChange()
-        }
-    }
-
-    open override var inputAccessoryView: UIView? {
-        return isInputBarHidden ? nil : inputBar
-    }
-
-    open override var canBecomeFirstResponder: Bool {
-        return !isInputBarHidden
-    }
-
-    open override func viewDidLoad() {
-        super.viewDidLoad()
-        inputBar.delegate = self
-    }
-
-    /// Invoked when `isInputBarHidden` changes to become or
-    /// resign first responder
-    open func isInputBarHiddenDidChange() {
-        if isInputBarHidden, isFirstResponder {
-            resignFirstResponder()
-        } else if !isFirstResponder {
-            becomeFirstResponder()
-        }
-    }
-
-    @discardableResult
-    open override func resignFirstResponder() -> Bool {
-        inputBar.inputTextView.resignFirstResponder()
-        return super.resignFirstResponder()
-    }
-
-    // MARK: - InputBarAccessoryViewDelegate
-
-    open func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) { }
-
-    open func inputBar(_ inputBar: InputBarAccessoryView, textViewTextDidChangeTo text: String) { }
-
-    open func inputBar(_ inputBar: InputBarAccessoryView, didChangeIntrinsicContentTo size: CGSize) { }
-
-    open func inputBar(_ inputBar: InputBarAccessoryView, didSwipeTextViewWith gesture: UISwipeGestureRecognizer) { }
-}
-

+ 0 - 76
deltachat-ios/View/InputBarAccessoryView/Views/InputStackView.swift

@@ -1,76 +0,0 @@
-//
-//  InputStackView.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/6/17.
-//
-
-import UIKit
-
-/**
- A UIStackView that's intended for holding `InputItem`s
- 
- ## Important Notes ##
- 1. Default alignment is .fill
- 2. Default distribution is .fill
- 3. The distribution property needs to be based on its arranged subviews intrinsicContentSize so it is not recommended to change it
- */
-open class InputStackView: UIStackView {
-    
-    /// The stack view position in the InputBarAccessoryView
-    ///
-    /// - left: Left Stack View
-    /// - right: Bottom Stack View
-    /// - bottom: Left Stack View
-    /// - top: Top Stack View
-    public enum Position {
-        case left, right, bottom, top
-    }
-    
-    // MARK: Initialization
-    
-    convenience init(axis: NSLayoutConstraint.Axis, spacing: CGFloat) {
-        self.init(frame: .zero)
-        self.axis = axis
-        self.spacing = spacing
-    }
-    
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-    
-    required public init(coder: NSCoder) {
-        super.init(coder: coder)
-    }
-    
-    // MARK: - Setup
-    
-    /// Sets up the default properties
-    open func setup() {
-        translatesAutoresizingMaskIntoConstraints = false
-        distribution = .fill
-        alignment = .bottom
-    }
-    
-}

+ 0 - 401
deltachat-ios/View/InputBarAccessoryView/Views/InputTextView.swift

@@ -1,401 +0,0 @@
-//
-//  InputTextView.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 8/18/17.
-//
-
-import Foundation
-import UIKit
-
-/**
- A UITextView that has a UILabel embedded for placeholder text
- 
- ## Important Notes ##
- 1. Changing the font, textAlignment or textContainerInset automatically performs the same modifications to the placeholderLabel
- 2. Intended to be used in an `InputBarAccessoryView`
- 3. Default placeholder text is "Aa"
- 4. Will pass a pasted image it's `InputBarAccessoryView`'s `InputPlugin`s
- */
-open class InputTextView: UITextView {
-    
-    // MARK: - Properties
-    
-    open override var text: String! {
-        didSet {
-            postTextViewDidChangeNotification()
-        }
-    }
-    
-    open override var attributedText: NSAttributedString! {
-        didSet {
-            postTextViewDidChangeNotification()
-        }
-    }
-    
-    /// The images that are currently stored as NSTextAttachment's
-    open var images: [UIImage] {
-        return parseForAttachedImages()
-    }
-    
-    open var components: [Any] {
-        return parseForComponents()
-    }
-    
-    open var isImagePasteEnabled: Bool = true
-
-    /// A UILabel that holds the InputTextView's placeholder text
-    public let placeholderLabel: UILabel = {
-        let label = UILabel()
-        label.numberOfLines = 0
-        label.textColor = .lightGray
-        label.text = "Aa"
-        label.backgroundColor = .clear
-        label.translatesAutoresizingMaskIntoConstraints = false
-        return label
-    }()
-    
-    /// The placeholder text that appears when there is no text
-    open var placeholder: String? = "Aa" {
-        didSet {
-            placeholderLabel.text = placeholder
-        }
-    }
-    
-    /// The placeholderLabel's textColor
-    open var placeholderTextColor: UIColor? = .lightGray {
-        didSet {
-            placeholderLabel.textColor = placeholderTextColor
-        }
-    }
-    
-    /// The UIEdgeInsets the placeholderLabel has within the InputTextView
-    open var placeholderLabelInsets: UIEdgeInsets = UIEdgeInsets(top: 8, left: 4, bottom: 8, right: 4) {
-        didSet {
-            updateConstraintsForPlaceholderLabel()
-        }
-    }
-    
-    /// The font of the InputTextView. When set the placeholderLabel's font is also updated
-    open override var font: UIFont! {
-        didSet {
-            placeholderLabel.font = font
-        }
-    }
-    
-    /// The textAlignment of the InputTextView. When set the placeholderLabel's textAlignment is also updated
-    open override var textAlignment: NSTextAlignment {
-        didSet {
-            placeholderLabel.textAlignment = textAlignment
-        }
-    }
-    
-    /// The textContainerInset of the InputTextView. When set the placeholderLabelInsets is also updated
-    open override var textContainerInset: UIEdgeInsets {
-        didSet {
-            placeholderLabelInsets = textContainerInset
-        }
-    }
-    
-    open override var scrollIndicatorInsets: UIEdgeInsets {
-        didSet {
-            // When .zero a rendering issue can occur
-            if scrollIndicatorInsets == .zero {
-                scrollIndicatorInsets = UIEdgeInsets(top: .leastNonzeroMagnitude,
-                                                     left: .leastNonzeroMagnitude,
-                                                     bottom: .leastNonzeroMagnitude,
-                                                     right: .leastNonzeroMagnitude)
-            }
-        }
-    }
-    
-    /// A weak reference to the InputBarAccessoryView that the InputTextView is contained within
-    open weak var inputBarAccessoryView: InputBarAccessoryView?
-    
-    /// The constraints of the placeholderLabel
-    private var placeholderLabelConstraintSet: NSLayoutConstraintSet?
- 
-    // MARK: - Initializers
-    
-    public convenience init() {
-        self.init(frame: .zero)
-    }
-    
-    public override init(frame: CGRect, textContainer: NSTextContainer?) {
-        super.init(frame: frame, textContainer: textContainer)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    deinit {
-        NotificationCenter.default.removeObserver(self)
-    }
-    
-    // MARK: - Setup
-    
-    /// Sets up the default properties
-    open func setup() {
-        
-        backgroundColor = .clear
-        font = UIFont.preferredFont(forTextStyle: .body)
-        isScrollEnabled = false
-        scrollIndicatorInsets = UIEdgeInsets(top: .leastNonzeroMagnitude,
-                                             left: .leastNonzeroMagnitude,
-                                             bottom: .leastNonzeroMagnitude,
-                                             right: .leastNonzeroMagnitude)
-        setupPlaceholderLabel()
-        setupObservers()
-    }
-    
-    /// Adds the placeholderLabel to the view and sets up its initial constraints
-    private func setupPlaceholderLabel() {
-
-        addSubview(placeholderLabel)
-        placeholderLabelConstraintSet = NSLayoutConstraintSet(
-            top:     placeholderLabel.topAnchor.constraint(equalTo: topAnchor, constant: placeholderLabelInsets.top),
-            bottom:  placeholderLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -placeholderLabelInsets.bottom),
-            left:    placeholderLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: placeholderLabelInsets.left),
-            right:   placeholderLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -placeholderLabelInsets.right),
-            centerX: placeholderLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
-            centerY: placeholderLabel.centerYAnchor.constraint(equalTo: centerYAnchor)
-        )
-        placeholderLabelConstraintSet?.centerX?.priority = .defaultLow
-        placeholderLabelConstraintSet?.centerY?.priority = .defaultLow
-        placeholderLabelConstraintSet?.activate()
-    }
-    
-    /// Adds a notification for .UITextViewTextDidChange to detect when the placeholderLabel
-    /// should be hidden or shown
-    private func setupObservers() {
-        
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(InputTextView.redrawTextAttachments),
-                                               name: UIDevice.orientationDidChangeNotification, object: nil)
-        NotificationCenter.default.addObserver(self,
-                                               selector: #selector(InputTextView.textViewTextDidChange),
-                                               name: UITextView.textDidChangeNotification, object: nil)
-    }
-
-    /// Updates the placeholderLabels constraint constants to match the placeholderLabelInsets
-    private func updateConstraintsForPlaceholderLabel() {
-
-        placeholderLabelConstraintSet?.top?.constant = placeholderLabelInsets.top
-        placeholderLabelConstraintSet?.bottom?.constant = -placeholderLabelInsets.bottom
-        placeholderLabelConstraintSet?.left?.constant = placeholderLabelInsets.left
-        placeholderLabelConstraintSet?.right?.constant = -placeholderLabelInsets.right
-    }
-    
-    // MARK: - Notifications
-    
-    private func postTextViewDidChangeNotification() {
-        NotificationCenter.default.post(name: UITextView.textDidChangeNotification, object: self)
-    }
-    
-    @objc
-    private func textViewTextDidChange() {
-        let isPlaceholderHidden = !text.isEmpty
-        placeholderLabel.isHidden = isPlaceholderHidden
-        // Adjust constraints to prevent unambiguous content size
-        if isPlaceholderHidden {
-            placeholderLabelConstraintSet?.deactivate()
-        } else {
-            placeholderLabelConstraintSet?.activate()
-        }
-    }
-    
-    // MARK: - Image Paste Support
-    
-    open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
-        
-        if action == NSSelectorFromString("paste:") && UIPasteboard.general.image != nil {
-            return isImagePasteEnabled
-        }
-        return super.canPerformAction(action, withSender: sender)
-    }
-    
-    open override func paste(_ sender: Any?) {
-        
-        guard let image = UIPasteboard.general.image else {
-            return super.paste(sender)
-        }
-        if isImagePasteEnabled {
-            pasteImageInTextContainer(with: image)
-        } else {
-            for plugin in inputBarAccessoryView?.inputPlugins ?? [] {
-                if plugin.handleInput(of: image) {
-                    return
-                }
-            }
-        }
-    }
-    
-    /// Addes a new UIImage to the NSTextContainer as an NSTextAttachment
-    ///
-    /// - Parameter image: The image to add
-    private func pasteImageInTextContainer(with image: UIImage) {
-        
-        // Add the new image as an NSTextAttachment
-        let attributedImageString = NSAttributedString(attachment: textAttachment(using: image))
-        
-        let isEmpty = attributedText.length == 0
-        
-        // Add a new line character before the image, this is what iMessage does
-        let newAttributedStingComponent = isEmpty ? NSMutableAttributedString(string: "") : NSMutableAttributedString(string: "\n")
-        newAttributedStingComponent.append(attributedImageString)
-        
-        // Add a new line character after the image, this is what iMessage does
-        newAttributedStingComponent.append(NSAttributedString(string: "\n"))
-        
-        // The attributes that should be applied to the new NSAttributedString to match the current attributes
-        let attributes: [NSAttributedString.Key: Any] = [
-            NSAttributedString.Key.font: font ?? UIFont.preferredFont(forTextStyle: .body),
-            NSAttributedString.Key.foregroundColor: textColor ?? .black
-        ]
-        newAttributedStingComponent.addAttributes(attributes, range: NSRange(location: 0, length: newAttributedStingComponent.length))
-        
-        textStorage.beginEditing()
-        // Paste over selected text
-        textStorage.replaceCharacters(in: selectedRange, with: newAttributedStingComponent)
-        textStorage.endEditing()
-        
-        // Advance the range to the selected range plus the number of characters added
-        let location = selectedRange.location + (isEmpty ? 2 : 3)
-        selectedRange = NSRange(location: location, length: 0)
-        
-        // Broadcast a notification to recievers such as the MessageInputBar which will handle resizing
-        postTextViewDidChangeNotification()
-    }
-    
-    /// Returns an NSTextAttachment the provided image that will fit inside the NSTextContainer
-    ///
-    /// - Parameter image: The image to create an attachment with
-    /// - Returns: The formatted NSTextAttachment
-    private func textAttachment(using image: UIImage) -> NSTextAttachment {
-        
-        guard let cgImage = image.cgImage else { return NSTextAttachment() }
-        let scale = image.size.width / (frame.width - 2 * (textContainerInset.left + textContainerInset.right))
-        let textAttachment = NSTextAttachment()
-        textAttachment.image = UIImage(cgImage: cgImage, scale: scale, orientation: image.imageOrientation)
-        return textAttachment
-    }
-    
-    /// Returns all images that exist as NSTextAttachment's
-    ///
-    /// - Returns: An array of type UIImage
-    private func parseForAttachedImages() -> [UIImage] {
-        
-        var images = [UIImage]()
-        let range = NSRange(location: 0, length: attributedText.length)
-        attributedText.enumerateAttribute(.attachment, in: range, options: [], using: { value, range, _ -> Void in
-            
-            if let attachment = value as? NSTextAttachment {
-                if let image = attachment.image {
-                    images.append(image)
-                } else if let image = attachment.image(forBounds: attachment.bounds,
-                                                       textContainer: nil,
-                                                       characterIndex: range.location) {
-                    images.append(image)
-                }
-            }
-        })
-        return images
-    }
-    
-    /// Returns an array of components (either a String or UIImage) that makes up the textContainer in
-    /// the order that they were typed
-    ///
-    /// - Returns: An array of objects guaranteed to be of UIImage or String
-    private func parseForComponents() -> [Any] {
-        
-        var components = [Any]()
-        var attachments = [(NSRange, UIImage)]()
-        let length = attributedText.length
-        let range = NSRange(location: 0, length: length)
-        attributedText.enumerateAttribute(.attachment, in: range) { (object, range, _) in
-            if let attachment = object as? NSTextAttachment {
-                if let image = attachment.image {
-                    attachments.append((range, image))
-                } else if let image = attachment.image(forBounds: attachment.bounds,
-                                                       textContainer: nil,
-                                                       characterIndex: range.location) {
-                    attachments.append((range,image))
-                }
-            }
-        }
-        
-        var curLocation = 0
-        if attachments.isEmpty {
-            let text = attributedText.string.trimmingCharacters(in: .whitespacesAndNewlines)
-            if !text.isEmpty {
-                components.append(text)
-            }
-        }
-        else {
-            attachments.forEach { (attachment) in
-                let (range, image) = attachment
-                if curLocation < range.location {
-                    let textRange = NSMakeRange(curLocation, range.location - curLocation)
-                    let text = attributedText.attributedSubstring(from: textRange).string.trimmingCharacters(in: .whitespacesAndNewlines)
-                    if !text.isEmpty {
-                        components.append(text)
-                    }
-                }
-                
-                curLocation = range.location + range.length
-                components.append(image)
-            }
-            if curLocation < length - 1  {
-                let text = attributedText.attributedSubstring(from: NSMakeRange(curLocation, length - curLocation)).string.trimmingCharacters(in: .whitespacesAndNewlines)
-                if !text.isEmpty {
-                    components.append(text)
-                }
-            }
-        }
-        
-        return components
-    }
-    
-    /// Redraws the NSTextAttachments in the NSTextContainer to fit the current bounds
-    @objc
-    private func redrawTextAttachments() {
-        
-        guard !images.isEmpty else { return }
-        let range = NSRange(location: 0, length: attributedText.length)
-        attributedText.enumerateAttribute(.attachment, in: range, options: [], using: { value, _, _ -> Void in
-            if let attachment = value as? NSTextAttachment, let image = attachment.image {
-                
-                // Calculates a new width/height ratio to fit the image in the current frame
-                let newWidth = frame.width - 2 * (textContainerInset.left + textContainerInset.right)
-                let ratio = image.size.height / image.size.width
-                attachment.bounds.size = CGSize(width: newWidth, height: ratio * newWidth)
-            }
-        })
-        layoutManager.invalidateLayout(forCharacterRange: range, actualCharacterRange: nil)
-    }
-    
-}
-

+ 0 - 72
deltachat-ios/View/InputBarAccessoryView/Views/SeparatorLine.swift

@@ -1,72 +0,0 @@
-//
-//  SeparatorLine.swift
-//  InputBarAccessoryView
-//
-//  Copyright © 2017-2019 Nathan Tannar.
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in all
-//  copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-//  SOFTWARE.
-//
-//  Created by Nathan Tannar on 10/4/17.
-//
-
-import UIKit
-
-/**
- A UIView thats intrinsicContentSize is overrided so an exact height can be specified
- 
- ## Important Notes ##
- 1. Default height is 1.0
- 2. Default backgroundColor is UIColor.lightGray
- 3. Intended to be used in an `InputStackView`
- */
-open class SeparatorLine: UIView {
-    
-    // MARK: - Properties
-    
-    /// The height of the line
-    open var height: CGFloat = 1.0 {
-        didSet {
-            constraints.filter { $0.identifier == "height" }.forEach { $0.constant = height } // Assumes constraint was given an identifier
-            invalidateIntrinsicContentSize()
-        }
-    }
-    
-    open override var intrinsicContentSize: CGSize {
-        return CGSize(width: super.intrinsicContentSize.width, height: height)
-    }
-    
-    // MARK: - Initialization
-    
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-    
-    required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setup()
-    }
-    
-    /// Sets up the default properties
-    open func setup() {
-        backgroundColor = .lightGray
-        translatesAutoresizingMaskIntoConstraints = false
-        setContentHuggingPriority(.defaultHigh, for: .vertical)
-    }
-}

+ 0 - 0
deltachat-ios/InputBarAccessoryView → deltachat-ios/libraries/InputBarAccessoryView