deleted message UI in conversation screen

This commit is contained in:
Ryan Zhao 2021-08-05 13:34:07 +10:00
parent ab492d5304
commit eaab6ee22d
8 changed files with 87 additions and 1 deletions

View File

@ -137,6 +137,7 @@
76C87F19181EFCE600C4ACAB /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; };
76EB054018170B33006006FC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB03C318170B33006006FC /* AppDelegate.m */; };
7B4C75CB26B37E0F0000AC89 /* UnsendRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4C75CA26B37E0F0000AC89 /* UnsendRequest.swift */; };
7B4C75CD26BB92060000AC89 /* DeletedMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4C75CC26BB92060000AC89 /* DeletedMessageView.swift */; };
7BC01A3E241F40AB00BC7C55 /* NotificationServiceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC01A3D241F40AB00BC7C55 /* NotificationServiceExtension.swift */; };
7BC01A42241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 7BC01A3B241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
7BDCFC08242186E700641C39 /* NotificationServiceExtensionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */; };
@ -1099,6 +1100,7 @@
76EB03C218170B33006006FC /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
76EB03C318170B33006006FC /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
7B4C75CA26B37E0F0000AC89 /* UnsendRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsendRequest.swift; sourceTree = "<group>"; };
7B4C75CC26BB92060000AC89 /* DeletedMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedMessageView.swift; sourceTree = "<group>"; };
7BC01A3B241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SessionNotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
7BC01A3D241F40AB00BC7C55 /* NotificationServiceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtension.swift; sourceTree = "<group>"; };
7BC01A3F241F40AB00BC7C55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -2089,6 +2091,7 @@
B849789525D4A2F500D0D0B3 /* LinkPreviewView.swift */,
B8D84EA225DF745A005A043E /* LinkPreviewState.swift */,
B8EB20EF2640F7F000773E52 /* OpenGroupInvitationView.swift */,
7B4C75CC26BB92060000AC89 /* DeletedMessageView.swift */,
);
path = "Content Views";
sourceTree = "<group>";
@ -4903,6 +4906,7 @@
B8D0A25025E3678700C1835E /* LinkDeviceVC.swift in Sources */,
3496957321A301A100DCFE74 /* OWSBackupJob.m in Sources */,
B894D0752339EDCF00B4D94D /* NukeDataModal.swift in Sources */,
7B4C75CD26BB92060000AC89 /* DeletedMessageView.swift in Sources */,
B897621C25D201F7004F83B2 /* ScrollToBottomButton.swift in Sources */,
346B66311F4E29B200E5122F /* CropScaleImageViewController.swift in Sources */,
45E5A6991F61E6DE001E4A8A /* MarqueeLabel.swift in Sources */,

View File

@ -15,6 +15,7 @@ typedef NS_ENUM(NSInteger, OWSMessageCellType) {
OWSMessageCellType_GenericAttachment,
OWSMessageCellType_MediaMessage,
OWSMessageCellType_OversizeTextDownloading,
OWSMessageCellType_DeletedMessage
};
NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);

View File

@ -470,6 +470,11 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
self.hasViewState = YES;
TSMessage *message = (TSMessage *)self.interaction;
if (message.isDeleted) {
self.messageCellType = OWSMessageCellType_DeletedMessage;
return;
}
// Check for quoted replies _before_ media album handling,
// since that logic may exit early.

View File

@ -0,0 +1,51 @@
final class DeletedMessageView : UIView {
private let viewItem: ConversationViewItem
private let textColor: UIColor
// MARK: Settings
private static let iconSize: CGFloat = 18
private static let iconImageViewSize: CGFloat = 30
// MARK: Lifecycle
init(viewItem: ConversationViewItem, textColor: UIColor) {
self.viewItem = viewItem
self.textColor = textColor
super.init(frame: CGRect.zero)
setUpViewHierarchy()
}
override init(frame: CGRect) {
preconditionFailure("Use init(viewItem:textColor:) instead.")
}
required init?(coder: NSCoder) {
preconditionFailure("Use init(viewItem:textColor:) instead.")
}
private func setUpViewHierarchy() {
// Image view
let iconSize = DeletedMessageView.iconSize
let icon = UIImage(named: "ic_trash")?.withTint(textColor)?.resizedImage(to: CGSize(width: iconSize, height: iconSize))
let imageView = UIImageView(image: icon)
imageView.contentMode = .center
let iconImageViewSize = DeletedMessageView.iconImageViewSize
imageView.set(.width, to: iconImageViewSize)
imageView.set(.height, to: iconImageViewSize)
// Body label
let titleLabel = UILabel()
titleLabel.lineBreakMode = .byTruncatingTail
titleLabel.text = "This message has been deleted."
titleLabel.textColor = textColor
titleLabel.font = .systemFont(ofSize: Values.smallFontSize)
// Stack view
let stackView = UIStackView(arrangedSubviews: [ imageView, titleLabel ])
stackView.axis = .horizontal
stackView.alignment = .center
stackView.isLayoutMarginsRelativeArrangement = true
stackView.layoutMargins = UIEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 6)
addSubview(stackView)
stackView.pin(to: self, withInset: Values.smallSpacing)
}
}

View File

@ -389,6 +389,10 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
snContentView.addSubview(documentView)
documentView.pin(to: snContentView)
}
case .deletedMessage:
let deletedMessageView = DeletedMessageView(viewItem: viewItem, textColor: bodyLabelTextColor)
snContentView.addSubview(deletedMessageView)
deletedMessageView.pin(to: snContentView)
default: return
}
}

View File

@ -39,6 +39,7 @@ extern const NSUInteger kOversizeTextMessageSizeThreshold;
@property (nonatomic, readonly, nullable) NSString *openGroupInvitationName;
@property (nonatomic, readonly, nullable) NSString *openGroupInvitationURL;
@property (nonatomic, nullable) NSString *serverHash;
@property (nonatomic) BOOL isDeleted;
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread NS_UNAVAILABLE;
@ -82,6 +83,8 @@ extern const NSUInteger kOversizeTextMessageSizeThreshold;
- (void)updateWithLinkPreview:(OWSLinkPreview *)linkPreview transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)updateForDeletionWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
@end
NS_ASSUME_NONNULL_END

View File

@ -86,6 +86,7 @@ const NSUInteger kOversizeTextMessageSizeThreshold = 2 * 1024;
_openGroupInvitationName = openGroupInvitationName;
_openGroupInvitationURL = openGroupInvitationURL;
_serverHash = serverHash;
_isDeleted = false;
return self;
}
@ -423,6 +424,23 @@ const NSUInteger kOversizeTextMessageSizeThreshold = 2 * 1024;
}];
}
- (void)updateForDeletionWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSMessage *message) {
[message setBody:nil];
[message setServerHash:nil];
for (NSString *attachmentId in message.attachmentIds) {
TSAttachment *_Nullable attachment =
[TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction];
if (attachment) {
[attachment removeWithTransaction:transaction];
}
}
[message setIsDeleted:true];
}];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -234,7 +234,7 @@ extension MessageReceiver {
if let serverHash = messageToDelete.serverHash {
SnodeAPI.deleteMessage(publicKey: author, serverHashes: [serverHash]).retainUntilComplete()
}
messageToDelete.remove(with: transaction)
messageToDelete.updateForDeletion(with: transaction)
}
}