Merge branch 'dev' into conversation-swap-action

This commit is contained in:
Ryan Zhao 2023-03-06 16:13:27 +11:00
commit 1b744e9bc2
9 changed files with 76 additions and 21 deletions

View File

@ -6044,7 +6044,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 394;
CURRENT_PROJECT_VERSION = 395;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
@ -6117,7 +6117,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 394;
CURRENT_PROJECT_VERSION = 395;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = SUQ8J2PCT7;
ENABLE_NS_ASSERTIONS = NO;
@ -6183,7 +6183,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 394;
CURRENT_PROJECT_VERSION = 395;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
@ -6257,7 +6257,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 394;
CURRENT_PROJECT_VERSION = 395;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = SUQ8J2PCT7;
ENABLE_NS_ASSERTIONS = NO;
@ -7185,7 +7185,7 @@
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 394;
CURRENT_PROJECT_VERSION = 395;
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@ -7257,7 +7257,7 @@
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 394;
CURRENT_PROJECT_VERSION = 395;
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",

View File

@ -1604,6 +1604,23 @@ extension ConversationVC:
let thread: SessionThread = try SessionThread.fetchOne(db, id: threadId)
else { return }
if
let quote = try? interaction.quote.fetchOne(db),
let quotedAttachment = try? quote.attachment.fetchOne(db),
quotedAttachment.isVisualMedia,
quotedAttachment.downloadUrl == Attachment.nonMediaQuoteFileId,
let quotedInteraction = try? quote.originalInteraction.fetchOne(db)
{
let attachment = try? quotedInteraction.attachments.fetchAll(db).first
try quote.with(
attachmentId: attachment?.cloneAsQuoteThumbnail()?.inserted(db).id
).update(db)
}
// Remove message sending jobs for the same interaction in database
// Prevent the same message being sent twice
try Job.filter(Job.Columns.interactionId == interaction.id).deleteAll(db)
try MessageSender.send(
db,
interaction: interaction,

View File

@ -144,7 +144,7 @@ final class QuoteView: UIView {
.messageBubble_outgoingText :
.messageBubble_incomingText
)
case .draft: return .messageBubble_outgoingText
case .draft: return .textPrimary
}
}()
imageView.contentMode = .center
@ -156,10 +156,7 @@ final class QuoteView: UIView {
mainStackView.addArrangedSubview(imageView)
if (body ?? "").isEmpty {
body = (attachment.isImage ?
"Image" :
(isAudio ? "Audio" : "Document")
)
body = attachment.shortDescription
}
// Generate the thumbnail if needed
@ -223,10 +220,10 @@ final class QuoteView: UIView {
}
.defaulting(
to: attachment.map {
NSAttributedString(string: MIMETypeUtil.isAudio($0.contentType) ? "Audio" : "Document")
NSAttributedString(string: $0.shortDescription, attributes: [ .foregroundColor: textColor ])
}
)
.defaulting(to: NSAttributedString(string: "Document"))
.defaulting(to: NSAttributedString(string: "QUOTED_MESSAGE_NOT_FOUND".localized(), attributes: [ .foregroundColor: textColor ]))
}
// Label stack view

View File

@ -545,7 +545,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate {
let quoteView: QuoteView = QuoteView(
for: .regular,
authorId: quote.authorId,
quotedText: quote.body ?? "QUOTED_MESSAGE_NOT_FOUND".localized(),
quotedText: quote.body,
threadVariant: cellViewModel.threadVariant,
currentUserPublicKey: cellViewModel.currentUserPublicKey,
currentUserBlindedPublicKey: cellViewModel.currentUserBlindedPublicKey,

View File

@ -206,6 +206,10 @@ class ThreadSettingsViewModel: SessionTableViewModel<ThreadSettingsViewModel.Nav
threadVariant == .closedGroup &&
threadViewModel.currentUserIsClosedGroupMember == true
)
let currentUserIsClosedGroupAdmin: Bool = (
threadVariant == .closedGroup &&
threadViewModel.currentUserIsClosedGroupAdmin == true
)
return [
SectionModel(
@ -391,7 +395,7 @@ class ThreadSettingsViewModel: SessionTableViewModel<ThreadSettingsViewModel.Nav
accessibilityLabel: "Leave group",
confirmationInfo: ConfirmationModal.Info(
title: "CONFIRM_LEAVE_GROUP_TITLE".localized(),
explanation: (currentUserIsClosedGroupMember ?
explanation: (currentUserIsClosedGroupAdmin ?
"Because you are the creator of this group it will be deleted for everyone. This cannot be undone." :
"CONFIRM_LEAVE_GROUP_DESCRIPTION".localized()
),

View File

@ -787,6 +787,13 @@ extension Attachment {
public var isText: Bool { MIMETypeUtil.isText(contentType) }
public var isMicrosoftDoc: Bool { MIMETypeUtil.isMicrosoftDoc(contentType) }
public var shortDescription: String {
if isImage { return "Image" }
if isAudio { return "Audio" }
if isVideo { return "Video" }
return "Document"
}
public func readDataFromFile() throws -> Data? {
guard let filePath: String = self.originalFilePath else {
return nil

View File

@ -76,6 +76,26 @@ public struct Quote: Codable, Equatable, Hashable, FetchableRecord, PersistableR
}
}
// MARK: - Mutation
public extension Quote {
func with(
interactionId: Int64? = nil,
authorId: String? = nil,
timestampMs: Int64? = nil,
body: String? = nil,
attachmentId: String? = nil
) -> Quote {
return Quote(
interactionId: interactionId ?? self.interactionId,
authorId: authorId ?? self.authorId,
timestampMs: timestampMs ?? self.timestampMs,
body: body ?? self.body,
attachmentId: attachmentId ?? self.attachmentId
)
}
}
// MARK: - Protobuf
public extension Quote {

View File

@ -420,7 +420,7 @@ extension MessageReceiver {
// Delete the members to remove
try GroupMember
.filter(GroupMember.Columns.groupId == id)
.filter(updatedMemberIds.contains(GroupMember.Columns.profileId))
.filter(membersToRemove.map{ $0.profileId }.contains(GroupMember.Columns.profileId))
.deleteAll(db)
if didAdminLeave || sender == userPublicKey {

View File

@ -825,6 +825,10 @@ public extension SessionThreadViewModel {
let profileIdColumnLiteral: SQL = SQL(stringLiteral: Profile.Columns.id.name)
let groupMemberProfileIdColumnLiteral: SQL = SQL(stringLiteral: GroupMember.Columns.profileId.name)
let groupMemberRoleColumnLiteral: SQL = SQL(stringLiteral: GroupMember.Columns.role.name)
let groupMemberGroupIdColumnLiteral: SQL = SQL(stringLiteral: GroupMember.Columns.groupId.name)
/// **Note:** The `numColumnsBeforeProfiles` value **MUST** match the number of fields before
/// the `ViewModel.contactProfileKey` entry below otherwise the query will fail to
/// parse and might throw
@ -851,7 +855,8 @@ public extension SessionThreadViewModel {
\(ViewModel.closedGroupProfileBackFallbackKey).*,
\(closedGroup[.name]) AS \(ViewModel.closedGroupNameKey),
(\(groupMember[.profileId]) IS NOT NULL) AS \(ViewModel.currentUserIsClosedGroupMemberKey),
(\(ViewModel.currentUserIsClosedGroupMemberKey).profileId IS NOT NULL) AS \(ViewModel.currentUserIsClosedGroupMemberKey),
(\(ViewModel.currentUserIsClosedGroupAdminKey).profileId IS NOT NULL) AS \(ViewModel.currentUserIsClosedGroupAdminKey),
\(openGroup[.name]) AS \(ViewModel.openGroupNameKey),
\(openGroup[.server]) AS \(ViewModel.openGroupServerKey),
\(openGroup[.roomToken]) AS \(ViewModel.openGroupRoomTokenKey),
@ -865,10 +870,15 @@ public extension SessionThreadViewModel {
LEFT JOIN \(Profile.self) AS \(ViewModel.contactProfileKey) ON \(ViewModel.contactProfileKey).\(profileIdColumnLiteral) = \(thread[.id])
LEFT JOIN \(OpenGroup.self) ON \(openGroup[.threadId]) = \(thread[.id])
LEFT JOIN \(ClosedGroup.self) ON \(closedGroup[.threadId]) = \(thread[.id])
LEFT JOIN \(GroupMember.self) ON (
\(SQL("\(groupMember[.role]) = \(GroupMember.Role.standard)")) AND
\(groupMember[.groupId]) = \(closedGroup[.threadId]) AND
\(SQL("\(groupMember[.profileId]) = \(userPublicKey)"))
LEFT JOIN \(GroupMember.self) AS \(ViewModel.currentUserIsClosedGroupMemberKey) ON (
\(SQL("\(ViewModel.currentUserIsClosedGroupMemberKey).\(groupMemberRoleColumnLiteral) != \(GroupMember.Role.zombie)")) AND
\(ViewModel.currentUserIsClosedGroupMemberKey).\(groupMemberGroupIdColumnLiteral) = \(closedGroup[.threadId]) AND
\(SQL("\(ViewModel.currentUserIsClosedGroupMemberKey).\(groupMemberProfileIdColumnLiteral) = \(userPublicKey)"))
)
LEFT JOIN \(GroupMember.self) AS \(ViewModel.currentUserIsClosedGroupAdminKey) ON (
\(SQL("\(ViewModel.currentUserIsClosedGroupAdminKey).\(groupMemberRoleColumnLiteral) = \(GroupMember.Role.admin)")) AND
\(ViewModel.currentUserIsClosedGroupAdminKey).\(groupMemberGroupIdColumnLiteral) = \(closedGroup[.threadId]) AND
\(SQL("\(ViewModel.currentUserIsClosedGroupAdminKey).\(groupMemberProfileIdColumnLiteral) = \(userPublicKey)"))
)
LEFT JOIN \(Profile.self) AS \(ViewModel.closedGroupProfileFrontKey) ON (