Merge branch 'dev' into conversation-swap-action
This commit is contained in:
commit
1b744e9bc2
|
@ -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)",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 (
|
||||
|
|
Loading…
Reference in New Issue