mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
milestone: route one real action (copy text)
This commit is contained in:
parent
bb6722ea42
commit
0c4cae133b
5 changed files with 283 additions and 187 deletions
|
@ -419,8 +419,8 @@
|
|||
4C20B2B720CA0034001BAC90 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542DF51208B82E9007B4E76 /* ThreadViewModel.swift */; };
|
||||
4C20B2B920CA10DE001BAC90 /* ConversationSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */; };
|
||||
4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C4AEC4420EC343B0020E72B /* DismissableTextField.swift */; };
|
||||
4CB5F26720F6E1E2004D1B42 /* MessageActionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFF4C0920F55BBA005DA313 /* MessageActionsViewController.swift */; };
|
||||
4CC0B59C20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0B59B20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift */; };
|
||||
4CFF4C0B20F56104005DA313 /* MessageActionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFF4C0920F55BBA005DA313 /* MessageActionsViewController.swift */; };
|
||||
70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70377AAA1918450100CAF501 /* MobileCoreServices.framework */; };
|
||||
768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; };
|
||||
76C87F19181EFCE600C4ACAB /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; };
|
||||
|
@ -1691,6 +1691,7 @@
|
|||
452EC6DE205E9E30000E787C /* MediaGalleryViewController.swift */,
|
||||
45F32C1D205718B000A300D5 /* MediaPageViewController.swift */,
|
||||
454A84032059C787008B8C75 /* MediaTileViewController.swift */,
|
||||
4CFF4C0920F55BBA005DA313 /* MessageActionsViewController.swift */,
|
||||
34CA1C261F7156F300E51C51 /* MessageDetailViewController.swift */,
|
||||
34B3F84F1E8DF1700035BE1A /* NewContactThreadViewController.h */,
|
||||
34B3F8501E8DF1700035BE1A /* NewContactThreadViewController.m */,
|
||||
|
@ -1888,7 +1889,6 @@
|
|||
34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */,
|
||||
34D99C8A1F27B13B00D284D6 /* OWSViewController.h */,
|
||||
34D99C8B1F27B13B00D284D6 /* OWSViewController.m */,
|
||||
4CFF4C0920F55BBA005DA313 /* MessageActionsViewController.swift */,
|
||||
45A60E7220AC674100FB1ABF /* ReturnToCallViewController.swift */,
|
||||
);
|
||||
path = ViewControllers;
|
||||
|
@ -3129,7 +3129,6 @@
|
|||
344D6CEC20069E070042AF96 /* NewNonContactConversationViewController.m in Sources */,
|
||||
346129FB1FD5F31400532771 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */,
|
||||
344F248D2007CCD600CFB4F4 /* DisplayableText.swift in Sources */,
|
||||
4CFF4C0B20F56104005DA313 /* MessageActionsViewController.swift in Sources */,
|
||||
450998651FD8A34D00D89EB3 /* DeviceSleepManager.swift in Sources */,
|
||||
3466087220E550F400AFFE73 /* ConversationStyle.swift in Sources */,
|
||||
3478506B1FD9B78A007B8332 /* NoopCallMessageHandler.swift in Sources */,
|
||||
|
@ -3265,6 +3264,7 @@
|
|||
340FC8CD20518C77007AEB0F /* OWSBackupJob.m in Sources */,
|
||||
34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */,
|
||||
4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */,
|
||||
4CB5F26720F6E1E2004D1B42 /* MessageActionsViewController.swift in Sources */,
|
||||
451686AB1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift in Sources */,
|
||||
45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */,
|
||||
340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */,
|
||||
|
|
|
@ -22,13 +22,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@protocol ConversationViewCellDelegate <NSObject>
|
||||
|
||||
- (void)conversationCellDidLongpressText:(ConversationViewCell *)cell viewItem:(ConversationViewItem *)viewItem;
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didLongpressTextViewItem:(ConversationViewItem *)viewItem;
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didLongpressMediaViewItem:(ConversationViewItem *)viewItem;
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didLongpressQuoteViewItem:(ConversationViewItem *)viewItem;
|
||||
|
||||
- (void)didPanWithGestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer
|
||||
viewItem:(ConversationViewItem *)conversationItem;
|
||||
|
||||
- (void)showMetadataViewForViewItem:(ConversationViewItem *)conversationItem;
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didTapReplyForViewItem:(ConversationViewItem *)conversationItem;
|
||||
// MJK move these to MessageActionDelegate
|
||||
//- (void)showMetadataViewForViewItem:(ConversationViewItem *)conversationItem;
|
||||
//- (void)conversationCell:(ConversationViewCell *)cell didTapReplyForViewItem:(ConversationViewItem *)conversationItem;
|
||||
|
||||
#pragma mark - System Cell
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[self.sendFailureBadgeView removeFromSuperview];
|
||||
self.sendFailureBadgeView = nil;
|
||||
|
||||
[self hideMenuControllerIfNecessary];
|
||||
// [self hideMenuControllerIfNecessary];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
@ -395,9 +395,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
[self ensureMediaLoadState];
|
||||
|
||||
if (!isCellVisible) {
|
||||
[self hideMenuControllerIfNecessary];
|
||||
}
|
||||
// if (!isCellVisible) {
|
||||
// [self hideMenuControllerIfNecessary];
|
||||
// }
|
||||
}
|
||||
|
||||
#pragma mark - Gesture recognizers
|
||||
|
@ -448,17 +448,18 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
switch ([self.messageBubbleView gestureLocationForLocation:locationInMessageBubble]) {
|
||||
case OWSMessageGestureLocation_Default:
|
||||
case OWSMessageGestureLocation_OversizeText: {
|
||||
[self.delegate conversationCellDidLongpressText:self viewItem:self.viewItem];
|
||||
[self.delegate conversationCell:self didLongpressTextViewItem:self.viewItem];
|
||||
break;
|
||||
}
|
||||
case OWSMessageGestureLocation_Media: {
|
||||
CGPoint location = [sender locationInView:self];
|
||||
[self showMediaMenuController:location];
|
||||
[self.delegate conversationCell:self didLongpressMediaViewItem:self.viewItem];
|
||||
|
||||
break;
|
||||
}
|
||||
case OWSMessageGestureLocation_QuotedReply: {
|
||||
CGPoint location = [sender locationInView:self];
|
||||
[self showDefaultMenuController:location];
|
||||
[self.delegate conversationCell:self didLongpressQuoteViewItem:self.viewItem];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -471,135 +472,135 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[self.delegate didPanWithGestureRecognizer:panRecognizer viewItem:self.viewItem];
|
||||
}
|
||||
|
||||
#pragma mark - UIMenuController
|
||||
//#pragma mark - UIMenuController
|
||||
//
|
||||
//- (void)showTextMenuController:(CGPoint)fromLocation
|
||||
//{
|
||||
// [self showMenuController:fromLocation menuItems:self.viewItem.textMenuControllerItems];
|
||||
//}
|
||||
//
|
||||
//- (void)showMediaMenuController:(CGPoint)fromLocation
|
||||
//{
|
||||
// [self showMenuController:fromLocation menuItems:self.viewItem.mediaMenuControllerItems];
|
||||
//}
|
||||
//
|
||||
//- (void)showDefaultMenuController:(CGPoint)fromLocation
|
||||
//{
|
||||
// [self showMenuController:fromLocation menuItems:self.viewItem.defaultMenuControllerItems];
|
||||
//}
|
||||
//
|
||||
//- (void)showMenuController:(CGPoint)fromLocation menuItems:(NSArray *)menuItems
|
||||
//{
|
||||
// if (menuItems.count < 1) {
|
||||
// OWSFail(@"%@ No menu items to present.", self.logTag);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // We don't want taps on messages to hide the keyboard,
|
||||
// // so we only let messages become first responder
|
||||
// // while they are trying to present the menu controller.
|
||||
// self.isPresentingMenuController = YES;
|
||||
//
|
||||
// [self becomeFirstResponder];
|
||||
//
|
||||
// if ([UIMenuController sharedMenuController].isMenuVisible) {
|
||||
// [[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO];
|
||||
// }
|
||||
//
|
||||
// // We use custom action selectors so that we can control
|
||||
// // the ordering of the actions in the menu.
|
||||
// [UIMenuController sharedMenuController].menuItems = menuItems;
|
||||
// CGRect targetRect = CGRectMake(fromLocation.x, fromLocation.y, 1, 1);
|
||||
// [[UIMenuController sharedMenuController] setTargetRect:targetRect inView:self];
|
||||
// [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
|
||||
//}
|
||||
//
|
||||
//- (BOOL)canPerformAction:(SEL)action withSender:(nullable id)sender
|
||||
//{
|
||||
// return [self.viewItem canPerformAction:action];
|
||||
//}
|
||||
//
|
||||
//- (void)copyTextAction:(nullable id)sender
|
||||
//{
|
||||
// [self.viewItem copyTextAction];
|
||||
//}
|
||||
//
|
||||
//- (void)copyMediaAction:(nullable id)sender
|
||||
//{
|
||||
// [self.viewItem copyMediaAction];
|
||||
//}
|
||||
//
|
||||
//- (void)shareTextAction:(nullable id)sender
|
||||
//{
|
||||
// [self.viewItem shareTextAction];
|
||||
//}
|
||||
//
|
||||
//- (void)shareMediaAction:(nullable id)sender
|
||||
//{
|
||||
// [self.viewItem shareMediaAction];
|
||||
//}
|
||||
//
|
||||
//- (void)saveMediaAction:(nullable id)sender
|
||||
//{
|
||||
// [self.viewItem saveMediaAction];
|
||||
//}
|
||||
//
|
||||
//- (void)deleteAction:(nullable id)sender
|
||||
//{
|
||||
// [self.viewItem deleteAction];
|
||||
//}
|
||||
//
|
||||
//- (void)metadataAction:(nullable id)sender
|
||||
//{
|
||||
// OWSAssert([self.viewItem.interaction isKindOfClass:[TSMessage class]]);
|
||||
//
|
||||
// [self.delegate showMetadataViewForViewItem:self.viewItem];
|
||||
//}
|
||||
//
|
||||
//- (void)replyAction:(nullable id)sender
|
||||
//{
|
||||
// OWSAssert([self.viewItem.interaction isKindOfClass:[TSMessage class]]);
|
||||
//
|
||||
// [self.delegate conversationCell:self didTapReplyForViewItem:self.viewItem];
|
||||
//}
|
||||
|
||||
- (void)showTextMenuController:(CGPoint)fromLocation
|
||||
{
|
||||
[self showMenuController:fromLocation menuItems:self.viewItem.textMenuControllerItems];
|
||||
}
|
||||
|
||||
- (void)showMediaMenuController:(CGPoint)fromLocation
|
||||
{
|
||||
[self showMenuController:fromLocation menuItems:self.viewItem.mediaMenuControllerItems];
|
||||
}
|
||||
|
||||
- (void)showDefaultMenuController:(CGPoint)fromLocation
|
||||
{
|
||||
[self showMenuController:fromLocation menuItems:self.viewItem.defaultMenuControllerItems];
|
||||
}
|
||||
|
||||
- (void)showMenuController:(CGPoint)fromLocation menuItems:(NSArray *)menuItems
|
||||
{
|
||||
if (menuItems.count < 1) {
|
||||
OWSFail(@"%@ No menu items to present.", self.logTag);
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't want taps on messages to hide the keyboard,
|
||||
// so we only let messages become first responder
|
||||
// while they are trying to present the menu controller.
|
||||
self.isPresentingMenuController = YES;
|
||||
|
||||
[self becomeFirstResponder];
|
||||
|
||||
if ([UIMenuController sharedMenuController].isMenuVisible) {
|
||||
[[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO];
|
||||
}
|
||||
|
||||
// We use custom action selectors so that we can control
|
||||
// the ordering of the actions in the menu.
|
||||
[UIMenuController sharedMenuController].menuItems = menuItems;
|
||||
CGRect targetRect = CGRectMake(fromLocation.x, fromLocation.y, 1, 1);
|
||||
[[UIMenuController sharedMenuController] setTargetRect:targetRect inView:self];
|
||||
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
|
||||
}
|
||||
|
||||
- (BOOL)canPerformAction:(SEL)action withSender:(nullable id)sender
|
||||
{
|
||||
return [self.viewItem canPerformAction:action];
|
||||
}
|
||||
|
||||
- (void)copyTextAction:(nullable id)sender
|
||||
{
|
||||
[self.viewItem copyTextAction];
|
||||
}
|
||||
|
||||
- (void)copyMediaAction:(nullable id)sender
|
||||
{
|
||||
[self.viewItem copyMediaAction];
|
||||
}
|
||||
|
||||
- (void)shareTextAction:(nullable id)sender
|
||||
{
|
||||
[self.viewItem shareTextAction];
|
||||
}
|
||||
|
||||
- (void)shareMediaAction:(nullable id)sender
|
||||
{
|
||||
[self.viewItem shareMediaAction];
|
||||
}
|
||||
|
||||
- (void)saveMediaAction:(nullable id)sender
|
||||
{
|
||||
[self.viewItem saveMediaAction];
|
||||
}
|
||||
|
||||
- (void)deleteAction:(nullable id)sender
|
||||
{
|
||||
[self.viewItem deleteAction];
|
||||
}
|
||||
|
||||
- (void)metadataAction:(nullable id)sender
|
||||
{
|
||||
OWSAssert([self.viewItem.interaction isKindOfClass:[TSMessage class]]);
|
||||
|
||||
[self.delegate showMetadataViewForViewItem:self.viewItem];
|
||||
}
|
||||
|
||||
- (void)replyAction:(nullable id)sender
|
||||
{
|
||||
OWSAssert([self.viewItem.interaction isKindOfClass:[TSMessage class]]);
|
||||
|
||||
[self.delegate conversationCell:self didTapReplyForViewItem:self.viewItem];
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder
|
||||
{
|
||||
return self.isPresentingMenuController;
|
||||
}
|
||||
|
||||
- (void)didHideMenuController:(NSNotification *)notification
|
||||
{
|
||||
self.isPresentingMenuController = NO;
|
||||
}
|
||||
|
||||
- (void)setIsPresentingMenuController:(BOOL)isPresentingMenuController
|
||||
{
|
||||
if (_isPresentingMenuController == isPresentingMenuController) {
|
||||
return;
|
||||
}
|
||||
|
||||
_isPresentingMenuController = isPresentingMenuController;
|
||||
|
||||
if (isPresentingMenuController) {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(didHideMenuController:)
|
||||
name:UIMenuControllerDidHideMenuNotification
|
||||
object:nil];
|
||||
} else {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:UIMenuControllerDidHideMenuNotification
|
||||
object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)hideMenuControllerIfNecessary
|
||||
{
|
||||
if (self.isPresentingMenuController) {
|
||||
[[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO];
|
||||
}
|
||||
self.isPresentingMenuController = NO;
|
||||
}
|
||||
//- (BOOL)canBecomeFirstResponder
|
||||
//{
|
||||
// return self.isPresentingMenuController;
|
||||
//}
|
||||
//
|
||||
//- (void)didHideMenuController:(NSNotification *)notification
|
||||
//{
|
||||
// self.isPresentingMenuController = NO;
|
||||
//}
|
||||
//
|
||||
//- (void)setIsPresentingMenuController:(BOOL)isPresentingMenuController
|
||||
//{
|
||||
// if (_isPresentingMenuController == isPresentingMenuController) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// _isPresentingMenuController = isPresentingMenuController;
|
||||
//
|
||||
// if (isPresentingMenuController) {
|
||||
// [[NSNotificationCenter defaultCenter] addObserver:self
|
||||
// selector:@selector(didHideMenuController:)
|
||||
// name:UIMenuControllerDidHideMenuNotification
|
||||
// object:nil];
|
||||
// } else {
|
||||
// [[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
// name:UIMenuControllerDidHideMenuNotification
|
||||
// object:nil];
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//- (void)hideMenuControllerIfNecessary
|
||||
//{
|
||||
// if (self.isPresentingMenuController) {
|
||||
// [[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO];
|
||||
// }
|
||||
// self.isPresentingMenuController = NO;
|
||||
//}
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1990,7 +1990,17 @@ typedef enum : NSUInteger {
|
|||
|
||||
#pragma mark - ConversationViewCellDelegate
|
||||
|
||||
- (void)conversationCellDidLongpressText:(ConversationViewCell *)cell viewItem:(ConversationViewItem *)viewItem
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didLongpressMediaViewItem:(ConversationViewItem *)viewItem
|
||||
{
|
||||
DDLogDebug(@"%@ in %s TODO", self.logTag, __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didLongpressQuoteViewItem:(ConversationViewItem *)viewItem
|
||||
{
|
||||
DDLogDebug(@"%@ in %s TODO", self.logTag, __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didLongpressTextViewItem:(ConversationViewItem *)viewItem
|
||||
{
|
||||
// TODO Interpolate from 0->0.3 depending on distance to make visible.
|
||||
NSTimeInterval animationDuration = 0.3;
|
||||
|
@ -2003,8 +2013,10 @@ typedef enum : NSUInteger {
|
|||
}
|
||||
completion:^(BOOL finished) {
|
||||
// TODO pass in real actions
|
||||
|
||||
NSArray<MessageAction *> *messageActions = [viewItem textActionsWithDelegate:self];
|
||||
MessageActionsViewController *messageActionsViewController =
|
||||
[[MessageActionsViewController alloc] initWithFocusedView:cell actions:@[]];
|
||||
[[MessageActionsViewController alloc] initWithFocusedView:cell actions:messageActions];
|
||||
|
||||
messageActionsViewController.delegate = self;
|
||||
|
||||
|
|
|
@ -7,10 +7,85 @@ import Foundation
|
|||
@objc
|
||||
protocol MessageActionsDelegate: class {
|
||||
func messageActionsDidHide(_ messageActionsViewController: MessageActionsViewController)
|
||||
func messageActions(_ messageActionsViewController: MessageActionsViewController, showInfoForItem conversationViewItem: ConversationViewItem)
|
||||
func messageActions(_ messageActionsViewController: MessageActionsViewController, replyToItem conversationViewItem: ConversationViewItem)
|
||||
}
|
||||
|
||||
struct MessageActionBuilder {
|
||||
static func reply(conversationViewItem: ConversationViewItem, delegate: MessageActionsDelegate) -> MessageAction {
|
||||
return MessageAction(image: #imageLiteral(resourceName: "table_ic_verify"),
|
||||
title: NSLocalizedString("MESSAGE_ACTION_REPLY", comment: "Action sheet button title"),
|
||||
subtitle: nil,
|
||||
block: { (_) in
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
static func copyText(conversationViewItem: ConversationViewItem, delegate: MessageActionsDelegate) -> MessageAction {
|
||||
return MessageAction(image: #imageLiteral(resourceName: "generic-attachment-small"),
|
||||
title: NSLocalizedString("MESSAGE_ACTION_COPY_TEXT", comment: "Action sheet button title"),
|
||||
subtitle: nil,
|
||||
block: { (_) in
|
||||
conversationViewItem.copyTextAction()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
extension ConversationViewItem {
|
||||
|
||||
var deleteMessageAction: MessageAction {
|
||||
return MessageAction(image: #imageLiteral(resourceName: "message_status_failed_large"),
|
||||
title: NSLocalizedString("MESSAGE_ACTION_DELETE_MESSAGE", comment: "Action sheet button title"),
|
||||
subtitle: NSLocalizedString("MESSAGE_ACTION_DELETE_MESSAGE_SUBTITLE", comment: "Action sheet button subtitle"),
|
||||
block: { (action) in
|
||||
Logger.debug("\(self.logTag) in \(#function) action: \(action)")
|
||||
})
|
||||
}
|
||||
|
||||
var infoAction: MessageAction {
|
||||
return MessageAction(image: #imageLiteral(resourceName: "system_message_security"),
|
||||
title: NSLocalizedString("MESSAGE_ACTION_TITLE_INFO", comment: "Action sheet button title"),
|
||||
subtitle: nil,
|
||||
block: { (action) in
|
||||
Logger.debug("\(self.logTag) in \(#function) action: \(action)")
|
||||
})
|
||||
}
|
||||
|
||||
@objc
|
||||
func textActions(delegate: MessageActionsDelegate) -> [MessageAction] {
|
||||
var actions: [MessageAction] = []
|
||||
if self.hasBodyText {
|
||||
actions.append(MessageActionBuilder.copyText(conversationViewItem: self, delegate: delegate))
|
||||
}
|
||||
|
||||
return actions
|
||||
// switch self.messageCellType() {
|
||||
// case .unknown:
|
||||
// return actions
|
||||
// case .textMessage:
|
||||
// return [self.copyTextAction]
|
||||
// case .oversizeTextMessage:
|
||||
// return [self.copyTextAction]
|
||||
// case .stillImage:
|
||||
// return []
|
||||
// case .animatedImage:
|
||||
// return []
|
||||
// case .audio:
|
||||
// return []
|
||||
// case .video:
|
||||
// return []
|
||||
// case .genericAttachment:
|
||||
// return []
|
||||
// case .downloadingAttachment:
|
||||
// return []
|
||||
// case .contactShare:
|
||||
// return []
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
class MessageActionsViewController: UIViewController {
|
||||
class MessageActionsViewController: UIViewController, MessageActionSheetDelegate {
|
||||
|
||||
@objc
|
||||
weak var delegate: MessageActionsDelegate?
|
||||
|
@ -18,49 +93,14 @@ class MessageActionsViewController: UIViewController {
|
|||
private let focusedView: UIView
|
||||
private let actionSheetView: MessageActionSheetView
|
||||
|
||||
static let replyAction = MessageAction(block: { (action) in
|
||||
Logger.debug("\(logTag) in \(#function) action: \(action)")
|
||||
},
|
||||
image: #imageLiteral(resourceName: "table_ic_verify"),
|
||||
title: NSLocalizedString("MESSAGE_ACTION_REPLY", comment: "Action sheet button title"),
|
||||
subtitle: nil)
|
||||
|
||||
static let copyTextAction = MessageAction(block: { (action) in
|
||||
Logger.debug("\(logTag) in \(#function) action: \(action)")
|
||||
},
|
||||
image: #imageLiteral(resourceName: "generic-attachment-small"),
|
||||
title: NSLocalizedString("MESSAGE_ACTION_COPY_TEXT", comment: "Action sheet button title"),
|
||||
subtitle: nil)
|
||||
|
||||
static let deleteMessageAction = MessageAction(block: { (action) in
|
||||
Logger.debug("\(logTag) in \(#function) action: \(action)")
|
||||
},
|
||||
image: #imageLiteral(resourceName: "message_status_failed_large"),
|
||||
title: NSLocalizedString("MESSAGE_ACTION_DELETE_MESSAGE", comment: "Action sheet button title"),
|
||||
subtitle: NSLocalizedString("MESSAGE_ACTION_DELETE_MESSAGE_SUBTITLE", comment: "Action sheet button subtitle"))
|
||||
|
||||
static let infoAction = MessageAction(block: { (action) in
|
||||
Logger.debug("\(logTag) in \(#function) action: \(action)")
|
||||
},
|
||||
image: #imageLiteral(resourceName: "system_message_info"),
|
||||
title: NSLocalizedString("MESSAGE_ACTION_TITLE_INFO", comment: "Action sheet button title"),
|
||||
subtitle: nil)
|
||||
|
||||
static let testActions: [MessageAction] = [
|
||||
replyAction,
|
||||
copyTextAction,
|
||||
deleteMessageAction,
|
||||
infoAction
|
||||
]
|
||||
|
||||
@objc
|
||||
required init(focusedView: UIView, actions: [MessageAction]) {
|
||||
self.focusedView = focusedView
|
||||
|
||||
// FIXME
|
||||
self.actionSheetView = MessageActionSheetView(actions: MessageActionsViewController.testActions)
|
||||
|
||||
self.actionSheetView = MessageActionSheetView(actions: actions)
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
actionSheetView.delegate = self
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
|
@ -156,33 +196,49 @@ class MessageActionsViewController: UIViewController {
|
|||
self.delegate?.messageActionsDidHide(self)
|
||||
})
|
||||
}
|
||||
|
||||
// MARK: MessageActionSheetDelegate
|
||||
|
||||
func actionSheet(_ actionSheet: MessageActionSheetView, didCompleteAction action: MessageAction) {
|
||||
animateDismiss()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: ActionView
|
||||
|
||||
@objc
|
||||
class MessageAction: NSObject {
|
||||
public class MessageAction: NSObject {
|
||||
let block: (MessageAction) -> Void
|
||||
let image: UIImage
|
||||
let title: String
|
||||
let subtitle: String?
|
||||
|
||||
init(block: @escaping (MessageAction) -> Void, image: UIImage, title: String, subtitle: String?) {
|
||||
self.block = block
|
||||
public init(image: UIImage, title: String, subtitle: String?, block: @escaping (MessageAction) -> Void) {
|
||||
self.image = image
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
self.block = block
|
||||
}
|
||||
}
|
||||
|
||||
protocol MessageActionSheetDelegate: class {
|
||||
func actionSheet(_ actionSheet: MessageActionSheetView, didCompleteAction action: MessageAction)
|
||||
}
|
||||
|
||||
protocol MessageActionViewDelegate: class {
|
||||
func actionView(_ actionView: MessageActionView, didCompleteAction action: MessageAction)
|
||||
}
|
||||
|
||||
class MessageActionView: UIView {
|
||||
let action: MessageAction
|
||||
public weak var delegate: MessageActionViewDelegate?
|
||||
private let action: MessageAction
|
||||
|
||||
required init(action: MessageAction) {
|
||||
self.action = action
|
||||
|
||||
super.init(frame: CGRect.zero)
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
backgroundColor = .white
|
||||
|
||||
let imageView = UIImageView(image: action.image)
|
||||
|
@ -213,6 +269,21 @@ class MessageActionView: UIView {
|
|||
self.addSubview(contentRow)
|
||||
contentRow.autoPinToSuperviewMargins()
|
||||
contentRow.autoSetDimension(.height, toSize: 56, relation: .greaterThanOrEqual)
|
||||
|
||||
// TODO better mimic button
|
||||
// - style with touch down
|
||||
// - slide from one to the next
|
||||
// - accessability hints
|
||||
// - UIControl?
|
||||
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didPress))
|
||||
self.addGestureRecognizer(tapGesture)
|
||||
}
|
||||
|
||||
@objc
|
||||
func didPress(event: Any) {
|
||||
Logger.debug("\(logTag) in \(#function)")
|
||||
self.action.block(action)
|
||||
self.delegate?.actionView(self, didCompleteAction: action)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
|
@ -220,10 +291,11 @@ class MessageActionView: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
class MessageActionSheetView: UIView {
|
||||
class MessageActionSheetView: UIView, MessageActionViewDelegate {
|
||||
|
||||
private let actionStackView: UIStackView
|
||||
private var actions: [MessageAction]
|
||||
weak var delegate: MessageActionSheetDelegate?
|
||||
|
||||
override var bounds: CGRect {
|
||||
didSet {
|
||||
|
@ -258,10 +330,18 @@ class MessageActionSheetView: UIView {
|
|||
|
||||
public func addAction(_ action: MessageAction) {
|
||||
let actionView = MessageActionView(action: action)
|
||||
actionView.delegate = self
|
||||
actions.append(action)
|
||||
self.actionStackView.addArrangedSubview(actionView)
|
||||
}
|
||||
|
||||
// MARK: MessageActionViewDelegate
|
||||
|
||||
func actionView(_ actionView: MessageActionView, didCompleteAction action: MessageAction) {
|
||||
self.delegate?.actionSheet(self, didCompleteAction: action)
|
||||
}
|
||||
|
||||
// MARK:
|
||||
private func updateMask() {
|
||||
let cornerRadius: CGFloat = 16
|
||||
let path: UIBezierPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: cornerRadius, height: cornerRadius))
|
Loading…
Reference in a new issue