Merge branch 'dev' into disappearing-message-redesign

pull/941/head
ryanzhao 2 years ago
commit 3da092019b

@ -1579,6 +1579,11 @@ extension ConversationVC:
case .typingIndicator, .dateHeader: break
case .textOnlyMessage:
if cellViewModel.body == nil, let linkPreview: LinkPreview = cellViewModel.linkPreview {
UIPasteboard.general.string = linkPreview.url
return
}
UIPasteboard.general.string = cellViewModel.body
case .audio, .genericAttachment, .mediaMessage:

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

@ -241,7 +241,24 @@ class ThreadSettingsViewModel: SessionTableViewModel<ThreadSettingsViewModel.Nav
),
accessibilityIdentifier: "\(ThreadSettingsViewModel.self).copy_thread_id",
onTap: {
UIPasteboard.general.string = threadId
switch threadVariant {
case .contact, .closedGroup:
UIPasteboard.general.string = threadId
case .openGroup:
guard
let server: String = threadViewModel.openGroupServer,
let roomToken: String = threadViewModel.openGroupRoomToken,
let publicKey: String = threadViewModel.openGroupPublicKey
else { return }
UIPasteboard.general.string = OpenGroup.urlFor(
server: server,
roomToken: roomToken,
publicKey: publicKey
)
}
self?.showToast(
text: "copied".localized(),
backgroundColor: .backgroundSecondary
@ -297,7 +314,10 @@ class ThreadSettingsViewModel: SessionTableViewModel<ThreadSettingsViewModel.Nav
with: "vc_conversation_settings_invite_button_title".localized(),
excluding: Set()
) { [weak self] selectedUsers in
self?.addUsersToOpenGoup(selectedUsers: selectedUsers)
self?.addUsersToOpenGoup(
threadViewModel: threadViewModel,
selectedUsers: selectedUsers
)
}
)
}
@ -558,13 +578,20 @@ class ThreadSettingsViewModel: SessionTableViewModel<ThreadSettingsViewModel.Nav
self.transitionToScreen(navController, transitionType: .present)
}
private func addUsersToOpenGoup(selectedUsers: Set<String>) {
let threadId: String = self.threadId
private func addUsersToOpenGoup(threadViewModel: SessionThreadViewModel, selectedUsers: Set<String>) {
guard
let name: String = threadViewModel.openGroupName,
let server: String = threadViewModel.openGroupServer,
let roomToken: String = threadViewModel.openGroupRoomToken,
let publicKey: String = threadViewModel.openGroupPublicKey
else { return }
dependencies.storage.writeAsync { db in
guard let openGroup: OpenGroup = try OpenGroup.fetchOne(db, id: threadId) else { return }
let urlString: String = "\(openGroup.server)/\(openGroup.roomToken)?public_key=\(openGroup.publicKey)"
let urlString: String = OpenGroup.urlFor(
server: server,
roomToken: roomToken,
publicKey: publicKey
)
try selectedUsers.forEach { userId in
let thread: SessionThread = try SessionThread.fetchOrCreate(db, id: userId, variant: .contact)
@ -572,7 +599,7 @@ class ThreadSettingsViewModel: SessionTableViewModel<ThreadSettingsViewModel.Nav
try LinkPreview(
url: urlString,
variant: .openGroupInvitation,
title: openGroup.name
title: name
)
.save(db)

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "پیام شما ارسال نشد.";
"INVALID_SESSION_ID_MESSAGE" = "لطفاً شناسه Session را مجدد بررسی کنید.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "لطفاً شناسه بازیابی را مجدد بررسی کنید.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "مدیا";
"DOCUMENT_TAB_TITLE" = "مدارک";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "شما در این مکالمه هیچ مدرکی ندارید.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -450,6 +450,7 @@
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
"QUOTED_MESSAGE_NOT_FOUND" = "Original message not found.";
"MEDIA_TAB_TITLE" = "Media";
"DOCUMENT_TAB_TITLE" = "Documents";
"DOCUMENT_TILES_EMPTY_DOCUMENT" = "You don't have any document in this conversation.";

@ -219,6 +219,10 @@ public extension OpenGroup {
// Always force the server to lowercase
return "\(server.lowercased()).\(roomToken)"
}
static func urlFor(server: String, roomToken: String, publicKey: String) -> String {
return "\(server)/\(roomToken)?public_key=\(publicKey)"
}
}
extension OpenGroup: CustomStringConvertible, CustomDebugStringConvertible {
@ -243,51 +247,3 @@ extension OpenGroup: CustomStringConvertible, CustomDebugStringConvertible {
].joined(separator: ", ")
}
}
// MARK: - Objective-C Support
// TODO: Remove this when possible
@objc(SMKOpenGroup)
public class SMKOpenGroup: NSObject {
@objc(inviteUsers:toOpenGroupFor:)
public static func invite(selectedUsers: Set<String>, openGroupThreadId: String) {
Storage.shared.write { db in
guard let openGroup: OpenGroup = try OpenGroup.fetchOne(db, id: openGroupThreadId) else { return }
let urlString: String = "\(openGroup.server)/\(openGroup.roomToken)?public_key=\(openGroup.publicKey)"
try selectedUsers.forEach { userId in
let thread: SessionThread = try SessionThread.fetchOrCreate(db, id: userId, variant: .contact)
try LinkPreview(
url: urlString,
variant: .openGroupInvitation,
title: openGroup.name
)
.save(db)
let interaction: Interaction = try Interaction(
threadId: thread.id,
authorId: userId,
variant: .standardOutgoing,
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000)),
expiresInSeconds: try? DisappearingMessagesConfiguration
.select(.durationSeconds)
.filter(id: userId)
.filter(DisappearingMessagesConfiguration.Columns.isEnabled == true)
.asRequest(of: TimeInterval.self)
.fetchOne(db),
linkPreviewUrl: urlString
)
.inserted(db)
try MessageSender.send(
db,
interaction: interaction,
in: thread
)
}
}
}
}

@ -89,51 +89,7 @@ public extension Quote {
self.interactionId = interactionId
self.timestampMs = Int64(quoteProto.id)
self.authorId = quoteProto.author
// Prefer to generate the text snippet locally if available.
let quotedInteraction: Interaction? = try? thread
.interactions
.filter(Interaction.Columns.authorId == quoteProto.author)
.filter(Interaction.Columns.timestampMs == Double(quoteProto.id))
.fetchOne(db)
if let quotedInteraction: Interaction = quotedInteraction, quotedInteraction.body?.isEmpty == false {
self.body = quotedInteraction.body
}
else if let body: String = quoteProto.text, !body.isEmpty {
self.body = body
}
else {
self.body = nil
}
// We only use the first attachment
if let attachment = quoteProto.attachments.first(where: { $0.thumbnail != nil })?.thumbnail {
self.attachmentId = try quotedInteraction
.map { quotedInteraction -> Attachment? in
// If the quotedInteraction has an attachment then try clone it
if let attachment: Attachment = try? quotedInteraction.attachments.fetchOne(db) {
return attachment.cloneAsQuoteThumbnail()
}
// Otherwise if the quotedInteraction has a link preview, try clone that
return try? quotedInteraction.linkPreview
.fetchOne(db)?
.attachment
.fetchOne(db)?
.cloneAsQuoteThumbnail()
}
.defaulting(to: Attachment(proto: attachment))
.inserted(db)
.id
}
else {
self.attachmentId = nil
}
// Make sure the quote is valid before completing
if self.body == nil && self.attachmentId == nil {
return nil
}
self.body = nil
self.attachmentId = nil
}
}

@ -42,7 +42,13 @@ extension ConfigurationMessage {
.filter(OpenGroup.Columns.roomToken != "")
.filter(OpenGroup.Columns.isActive)
.fetchAll(db)
.map { "\($0.server)/\($0.roomToken)?public_key=\($0.publicKey)" }
.map { openGroup in
OpenGroup.urlFor(
server: openGroup.server,
roomToken: openGroup.roomToken,
publicKey: openGroup.publicKey
)
}
.asSet()
let contacts: Set<CMContact> = try Contact
.filter(Contact.Columns.id != currentUserProfile.id)

@ -633,6 +633,7 @@ public extension MessageViewModel {
let disappearingMessagesConfig: TypedTableAlias<DisappearingMessagesConfiguration> = TypedTableAlias()
let profile: TypedTableAlias<Profile> = TypedTableAlias()
let quote: TypedTableAlias<Quote> = TypedTableAlias()
let interactionAttachment: TypedTableAlias<InteractionAttachment> = TypedTableAlias()
let linkPreview: TypedTableAlias<LinkPreview> = TypedTableAlias()
let threadProfileTableLiteral: SQL = SQL(stringLiteral: "threadProfile")
@ -708,7 +709,19 @@ public extension MessageViewModel {
LEFT JOIN \(DisappearingMessagesConfiguration.self) ON \(disappearingMessagesConfig[.threadId]) = \(interaction[.threadId])
LEFT JOIN \(OpenGroup.self) ON \(openGroup[.threadId]) = \(interaction[.threadId])
LEFT JOIN \(Profile.self) ON \(profile[.id]) = \(interaction[.authorId])
LEFT JOIN \(Quote.self) ON \(quote[.interactionId]) = \(interaction[.id])
LEFT JOIN (
SELECT \(quote[.interactionId]),
\(quote[.authorId]),
\(quote[.timestampMs]),
\(interaction[.body]) AS \(Quote.Columns.body),
\(interactionAttachment[.attachmentId]) AS \(Quote.Columns.attachmentId)
FROM \(Quote.self)
LEFT JOIN \(Interaction.self) ON (
\(quote[.authorId]) = \(interaction[.authorId]) AND
\(quote[.timestampMs]) = \(interaction[.timestampMs])
)
LEFT JOIN \(InteractionAttachment.self) ON \(interaction[.id]) = \(interactionAttachment[.interactionId])
) AS \(ViewModel.quoteKey) ON \(quote[.interactionId]) = \(interaction[.id])
LEFT JOIN \(Attachment.self) AS \(ViewModel.quoteAttachmentKey) ON \(ViewModel.quoteAttachmentKey).\(attachmentIdColumnLiteral) = \(quote[.attachmentId])
LEFT JOIN \(LinkPreview.self) ON (
\(linkPreview[.url]) = \(interaction[.linkPreviewUrl]) AND

@ -44,6 +44,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat
public static let openGroupNameKey: SQL = SQL(stringLiteral: CodingKeys.openGroupName.stringValue)
public static let openGroupServerKey: SQL = SQL(stringLiteral: CodingKeys.openGroupServer.stringValue)
public static let openGroupRoomTokenKey: SQL = SQL(stringLiteral: CodingKeys.openGroupRoomToken.stringValue)
public static let openGroupPublicKeyKey: SQL = SQL(stringLiteral: CodingKeys.openGroupPublicKey.stringValue)
public static let openGroupProfilePictureDataKey: SQL = SQL(stringLiteral: CodingKeys.openGroupProfilePictureData.stringValue)
public static let openGroupUserCountKey: SQL = SQL(stringLiteral: CodingKeys.openGroupUserCount.stringValue)
public static let openGroupPermissionsKey: SQL = SQL(stringLiteral: CodingKeys.openGroupPermissions.stringValue)
@ -121,6 +122,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat
public let openGroupName: String?
public let openGroupServer: String?
public let openGroupRoomToken: String?
public let openGroupPublicKey: String?
public let openGroupProfilePictureData: Data?
private let openGroupUserCount: Int?
private let openGroupPermissions: OpenGroup.Permissions?
@ -281,6 +283,7 @@ public extension SessionThreadViewModel {
self.openGroupName = nil
self.openGroupServer = nil
self.openGroupRoomToken = nil
self.openGroupPublicKey = nil
self.openGroupProfilePictureData = nil
self.openGroupUserCount = nil
self.openGroupPermissions = nil
@ -342,6 +345,7 @@ public extension SessionThreadViewModel {
openGroupName: self.openGroupName,
openGroupServer: self.openGroupServer,
openGroupRoomToken: self.openGroupRoomToken,
openGroupPublicKey: self.openGroupPublicKey,
openGroupProfilePictureData: self.openGroupProfilePictureData,
openGroupUserCount: self.openGroupUserCount,
openGroupPermissions: self.openGroupPermissions,
@ -396,6 +400,7 @@ public extension SessionThreadViewModel {
openGroupName: self.openGroupName,
openGroupServer: self.openGroupServer,
openGroupRoomToken: self.openGroupRoomToken,
openGroupPublicKey: self.openGroupPublicKey,
openGroupProfilePictureData: self.openGroupProfilePictureData,
openGroupUserCount: self.openGroupUserCount,
openGroupPermissions: self.openGroupPermissions,
@ -765,6 +770,7 @@ public extension SessionThreadViewModel {
\(openGroup[.name]) AS \(ViewModel.openGroupNameKey),
\(openGroup[.server]) AS \(ViewModel.openGroupServerKey),
\(openGroup[.roomToken]) AS \(ViewModel.openGroupRoomTokenKey),
\(openGroup[.publicKey]) AS \(ViewModel.openGroupPublicKeyKey),
\(openGroup[.userCount]) AS \(ViewModel.openGroupUserCountKey),
\(openGroup[.permissions]) AS \(ViewModel.openGroupPermissionsKey),
@ -862,6 +868,9 @@ public extension SessionThreadViewModel {
\(closedGroup[.name]) AS \(ViewModel.closedGroupNameKey),
(\(groupMember[.profileId]) IS NOT NULL) AS \(ViewModel.currentUserIsClosedGroupMemberKey),
\(openGroup[.name]) AS \(ViewModel.openGroupNameKey),
\(openGroup[.server]) AS \(ViewModel.openGroupServerKey),
\(openGroup[.roomToken]) AS \(ViewModel.openGroupRoomTokenKey),
\(openGroup[.publicKey]) AS \(ViewModel.openGroupPublicKeyKey),
\(openGroup[.imageData]) AS \(ViewModel.openGroupProfilePictureDataKey),
\(SQL("\(userPublicKey)")) AS \(ViewModel.currentUserPublicKeyKey)

@ -79,6 +79,32 @@ class OpenGroupSpec: QuickSpec {
.to(equal("OpenGroup(server: \"server\", roomToken: \"room\", id: \"server.room\", publicKey: \"1234\", isActive: true, name: \"name\", roomDescription: null, imageId: null, userCount: 0, infoUpdates: 0, sequenceNumber: 0, inboxLatestMessageId: 0, outboxLatestMessageId: 0, pollFailureCount: 0, permissions: ---)"))
}
}
context("when generating an id") {
it("generates correctly") {
expect(OpenGroup.idFor(roomToken: "room", server: "server")).to(equal("server.room"))
}
it("converts the server to lowercase") {
expect(OpenGroup.idFor(roomToken: "room", server: "SeRVeR")).to(equal("server.room"))
}
it("maintains the casing of the roomToken") {
expect(OpenGroup.idFor(roomToken: "RoOM", server: "server")).to(equal("server.RoOM"))
}
}
context("when generating a url") {
it("generates the url correctly") {
expect(OpenGroup.urlFor(server: "server", roomToken: "room", publicKey: "key"))
.to(equal("server/room?public_key=key"))
}
it("maintains the casing provided") {
expect(OpenGroup.urlFor(server: "SeRVer", roomToken: "RoOM", publicKey: "KEy"))
.to(equal("SeRVer/RoOM?public_key=KEy"))
}
}
}
}
}

@ -32,6 +32,8 @@ public extension Database {
}
func interrupt() {
guard sqliteConnection != nil else { return }
sqlite3_interrupt(sqliteConnection)
}
}

Loading…
Cancel
Save