It's tricky because we're hopping from one first responder to another.
Specifically, from the CaptionView.textView, which shows the keyboard, to
making the AttachmentApprovalViewController first responder, which shows the
BottomToolbar message text field, so in short order, we're getting multiple
notifications.
User hit's "Done" with caption
- Point A - CaptionView is positioned at the top of the keyboard
- Hide keyboard (frame change details must be calculated by y offset, since willChanage notification doesn't "shrink" the keyboard frame, it just offsets it to be non-visible.
- Point B - caption view is positioned at the bottom of the screen, input accessory view not visible
- Show Keyboard (not actually showing the *keyboard* here, but rather the VC's input accessory view)
- Point C - caption view is positioned atop the input accessory view
We want to animated smoothly from A->C, skipping B. But how do we do that robustly? We could track something like "last known input accessory view height" and never present the captionView below that. But I'm worried it won't be very robust since the input accessory view can change height, e.g. text view grows with text content or dynamic text changes.
TODO
-[] caption field per photo, separate from album message
-[] caption field sticks to keyboard on becoming first responder
-[] swipe updates caption field (not album message)
-[] limit caption length to 240 chars
-[] add more asset
TODO picker
-[] Done becomes "next"
-[] shared navbar, album picker doesn't cover entire screen
-[] new selected checkmark asset
TODO
-[] caption field per photo, separate from album message
-[] caption field sticks to keyboard on becoming first responder
-[] swipe updates caption field (not album message)
-[] limit caption length to 240 chars
-[] add more asset
TODO picker
-[] Done becomes "next"
-[] shared navbar, album picker doesn't cover entire screen
-[] new selected checkmark asset
By not overriding the initializer for an OWSNavigationController subclass,
we can use the dynamic disaptch intialization chain.
The root difficulty here is that super.init(navBarClass:) wants to call
self.init(nibNam)
TODO
-[x] respect order of queue
-[x] replacements
-[x] those w/o completion handler
-[x] basic send+log operation persists
-[x] send+ui completion
-[x] share extension
-[x] update state jobs
-[x] App Lifecyle
-[x] settable
-[x] Mark as ready on startup
-[x] Fail appropriate jobs on startup
NICE TO HAVE
-[x] concurrent per senders
-[ ] longer retry (e.g. 24hrs)
-[ ] App Lifecyle
-[x] retry failed jobs on startup?
-[ ] reachability
DONE
-[x] basic passing test
-[x] datamodel
-[x] queue/classes
TODO
-[x] tap to select/deselect
-[x] initially selected
-[x] integrate into conversation settings
-[x] colorPickerDelegate
-[x] translate strings
-[] reorder colors
-[x] SheetView: add top handle
Nice to have:
-[] SheetView: interactively swipe/unswipe to dismiss?
-[] preview color in bubbles
-[ ] UI
-[ ] Conversation Settings
-[x] Show switch for group
-[ ] localize
-[ ] migrate existing localizations? (nice to have)
-[ ] can view conversation settings (but not edit them) in left group
-[ ] special block copy for groups
-[ ] special unblock copy for groups
-[ ] ConversationViewHelper
-[x] Track blocked groups
-[ ] HomeView
-[ ] ConversationView
-[ ] Any others?
-[ ] Rename? Extract BlockList cache?
-[ ] Block List
-[ ] Group Section
-[ ] Unblock group
-[ ] Interstitial interacting with blocked threads (e.g. thread picker)
-[ ] BlockListUIUtils w/ thread
-[x] Block
-[x] Unblock
-[ ] Replace usages where possible
-[x] block manager
-[ ] Sync
-[x] tentative protos
-[ ] confirm protos w/ team
-[x] send new protos
-[ ] Message Processing
-[ ] Drop messages from blocked groups
-[ ] UI
-[ ] Conversation Settings
-[x] Show switch for group
-[ ] localize
-[ ] migrate existing localizations? (nice to have)
-[ ] can view conversation settings (but not edit them) in left group
-[ ] special block copy for groups
-[ ] special unblock copy for groups
-[ ] Block List
-[ ] Group Section
-[ ] Unblock group
-[ ] Interstitial interacting with blocked threads (e.g. thread picker)
-[ ] BlockListUIUtils w/ thread
-[x] Block
-[x] Unblock
-[ ] Replace usages where possible
-[x] block manager
-[ ] Sync
-[x] tentative protos
-[ ] confirm protos w/ team
-[ ] send new protos
-[ ] Message Processing
-[ ] Drop messages from blocked groups