Fixed a couple of minor outgoing quote bugs
Added a nicer mechanism for using table aliases Fixed a bug where the quote preview view close button could overlap the content Fixed a bug where an outgoing quote wouldn't show it's thumbnail in some cases Fixed a bug where quoting a link preview wouldn't show the link preview attachment
This commit is contained in:
parent
968f50f2fc
commit
42853a08c9
|
@ -635,6 +635,7 @@
|
|||
FD52090928B59411006098F6 /* ScreenLockUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD52090828B59411006098F6 /* ScreenLockUI.swift */; };
|
||||
FD52090B28B59BB4006098F6 /* ScreenLockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD52090A28B59BB4006098F6 /* ScreenLockViewController.swift */; };
|
||||
FD559DF52A7368CB00C7C62A /* DispatchQueue+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD559DF42A7368CB00C7C62A /* DispatchQueue+Utilities.swift */; };
|
||||
FD5931A72A8DA5DA0040147D /* SQLInterpolation+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD5931A62A8DA5DA0040147D /* SQLInterpolation+Utilities.swift */; };
|
||||
FD5C72F7284F0E560029977D /* MessageReceiver+ReadReceipts.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD5C72F6284F0E560029977D /* MessageReceiver+ReadReceipts.swift */; };
|
||||
FD5C72F9284F0E880029977D /* MessageReceiver+TypingIndicators.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD5C72F8284F0E880029977D /* MessageReceiver+TypingIndicators.swift */; };
|
||||
FD5C72FB284F0EA10029977D /* MessageReceiver+DataExtractionNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD5C72FA284F0EA10029977D /* MessageReceiver+DataExtractionNotification.swift */; };
|
||||
|
@ -1755,6 +1756,7 @@
|
|||
FD52090828B59411006098F6 /* ScreenLockUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenLockUI.swift; sourceTree = "<group>"; };
|
||||
FD52090A28B59BB4006098F6 /* ScreenLockViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenLockViewController.swift; sourceTree = "<group>"; };
|
||||
FD559DF42A7368CB00C7C62A /* DispatchQueue+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+Utilities.swift"; sourceTree = "<group>"; };
|
||||
FD5931A62A8DA5DA0040147D /* SQLInterpolation+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SQLInterpolation+Utilities.swift"; sourceTree = "<group>"; };
|
||||
FD5C72F6284F0E560029977D /* MessageReceiver+ReadReceipts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+ReadReceipts.swift"; sourceTree = "<group>"; };
|
||||
FD5C72F8284F0E880029977D /* MessageReceiver+TypingIndicators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+TypingIndicators.swift"; sourceTree = "<group>"; };
|
||||
FD5C72FA284F0EA10029977D /* MessageReceiver+DataExtractionNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+DataExtractionNotification.swift"; sourceTree = "<group>"; };
|
||||
|
@ -3693,6 +3695,7 @@
|
|||
FDDF074329C3E3D000E5E8B5 /* FetchRequest+Utilities.swift */,
|
||||
FDF2220E281B55E6000A4995 /* QueryInterfaceRequest+Utilities.swift */,
|
||||
FD1A94FA2900D1C2000D73D3 /* PersistableRecord+Utilities.swift */,
|
||||
FD5931A62A8DA5DA0040147D /* SQLInterpolation+Utilities.swift */,
|
||||
);
|
||||
path = Utilities;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5666,6 +5669,7 @@
|
|||
C32C5DD2256DD9E5003C73A2 /* LRUCache.swift in Sources */,
|
||||
FD71160228C8255900B47552 /* UIControl+Combine.swift in Sources */,
|
||||
FDFBB74B2A1EFF4900CA7350 /* Bencode.swift in Sources */,
|
||||
FD5931A72A8DA5DA0040147D /* SQLInterpolation+Utilities.swift in Sources */,
|
||||
FD9004152818B46300ABAAF6 /* JobRunner.swift in Sources */,
|
||||
FDF8487929405906007DCAE5 /* HTTPQueryParam.swift in Sources */,
|
||||
FD17D7CA27F546D900122BE0 /* _001_InitialSetupMigration.swift in Sources */,
|
||||
|
|
|
@ -156,7 +156,7 @@ final class QuoteView: UIView {
|
|||
if attachment.isVisualMedia {
|
||||
attachment.thumbnail(
|
||||
size: .small,
|
||||
success: { image, _ in
|
||||
success: { [imageView] image, _ in
|
||||
guard Thread.isMainThread else {
|
||||
DispatchQueue.main.async {
|
||||
imageView.image = image
|
||||
|
@ -234,8 +234,6 @@ final class QuoteView: UIView {
|
|||
}
|
||||
|
||||
// Label stack view
|
||||
let bodyLabelSize = bodyLabel.systemLayoutSizeFitting(availableSpace)
|
||||
|
||||
let isCurrentUser: Bool = [
|
||||
currentUserPublicKey,
|
||||
currentUserBlinded15PublicKey,
|
||||
|
@ -288,9 +286,8 @@ final class QuoteView: UIView {
|
|||
cancelButton.set(.height, to: cancelButtonSize)
|
||||
cancelButton.addTarget(self, action: #selector(cancel), for: UIControl.Event.touchUpInside)
|
||||
|
||||
addSubview(cancelButton)
|
||||
mainStackView.addArrangedSubview(cancelButton)
|
||||
cancelButton.center(.vertical, in: self)
|
||||
cancelButton.pin(.right, to: .right, of: self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -522,7 +522,7 @@ extension Attachment {
|
|||
\(interaction[.id]) = \(interactionAttachment[.interactionId]) OR
|
||||
(
|
||||
\(interaction[.linkPreviewUrl]) = \(linkPreview[.url]) AND
|
||||
\(Interaction.linkPreviewFilterLiteral)
|
||||
\(Interaction.linkPreviewFilterLiteral())
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -568,7 +568,7 @@ extension Attachment {
|
|||
\(interaction[.id]) = \(interactionAttachment[.interactionId]) OR
|
||||
(
|
||||
\(interaction[.linkPreviewUrl]) = \(linkPreview[.url]) AND
|
||||
\(Interaction.linkPreviewFilterLiteral)
|
||||
\(Interaction.linkPreviewFilterLiteral())
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -29,13 +29,14 @@ public struct Interaction: Codable, Identifiable, Equatable, FetchableRecord, Mu
|
|||
/// Whenever using this `linkPreview` association make sure to filter the result using
|
||||
/// `.filter(literal: Interaction.linkPreviewFilterLiteral)` to ensure the correct LinkPreview is returned
|
||||
public static let linkPreview = hasOne(LinkPreview.self, using: LinkPreview.interactionForeignKey)
|
||||
public static var linkPreviewFilterLiteral: SQL = {
|
||||
let interaction: TypedTableAlias<Interaction> = TypedTableAlias()
|
||||
let linkPreview: TypedTableAlias<LinkPreview> = TypedTableAlias()
|
||||
public static func linkPreviewFilterLiteral(
|
||||
interaction: TypedTableAlias<Interaction> = TypedTableAlias(),
|
||||
linkPreview: TypedTableAlias<LinkPreview> = TypedTableAlias()
|
||||
) -> SQL {
|
||||
let halfResolution: Double = LinkPreview.timstampResolution
|
||||
|
||||
return "(\(interaction[.timestampMs]) BETWEEN (\(linkPreview[.timestamp]) - \(halfResolution)) * 1000 AND (\(linkPreview[.timestamp]) + \(halfResolution)) * 1000)"
|
||||
}()
|
||||
}
|
||||
public static let recipientStates = hasMany(RecipientState.self, using: RecipientState.interactionForeignKey)
|
||||
|
||||
public typealias Columns = CodingKeys
|
||||
|
|
|
@ -143,7 +143,7 @@ public enum GarbageCollectionJob: JobExecutor {
|
|||
FROM \(LinkPreview.self)
|
||||
LEFT JOIN \(Interaction.self) ON (
|
||||
\(interaction[.linkPreviewUrl]) = \(linkPreview[.url]) AND
|
||||
\(Interaction.linkPreviewFilterLiteral)
|
||||
\(Interaction.linkPreviewFilterLiteral())
|
||||
)
|
||||
WHERE \(interaction[.id]) IS NULL
|
||||
)
|
||||
|
|
|
@ -777,10 +777,11 @@ public extension MessageViewModel {
|
|||
let disappearingMessagesConfig: TypedTableAlias<DisappearingMessagesConfiguration> = TypedTableAlias()
|
||||
let profile: TypedTableAlias<Profile> = TypedTableAlias()
|
||||
let quote: TypedTableAlias<Quote> = TypedTableAlias()
|
||||
let quoteInteraction: TypedTableAlias<Interaction> = TypedTableAlias(name: "quoteInteraction")
|
||||
let quoteLinkPreview: TypedTableAlias<LinkPreview> = TypedTableAlias(name: "quoteLinkPreview")
|
||||
let linkPreview: TypedTableAlias<LinkPreview> = TypedTableAlias()
|
||||
|
||||
let threadProfile: SQL = SQL(stringLiteral: "threadProfile")
|
||||
let quoteInteraction: SQL = SQL(stringLiteral: "quoteInteraction")
|
||||
let quoteInteractionAttachment: SQL = SQL(stringLiteral: "quoteInteractionAttachment")
|
||||
let readReceipt: SQL = SQL(stringLiteral: "readReceipt")
|
||||
let idColumn: SQL = SQL(stringLiteral: Interaction.Columns.id.name)
|
||||
|
@ -845,7 +846,7 @@ public extension MessageViewModel {
|
|||
\(quote[.interactionId]),
|
||||
\(quote[.authorId]),
|
||||
\(quote[.timestampMs]),
|
||||
\(quoteInteraction).\(interactionBodyColumn) AS \(quoteBodyColumn),
|
||||
\(quoteInteraction[.body]),
|
||||
\(quoteInteractionAttachment).\(interactionAttachmentAttachmentIdColumn) AS \(quoteAttachmentIdColumn),
|
||||
\(ViewModel.quoteAttachmentKey).*,
|
||||
\(ViewModel.linkPreviewKey).*,
|
||||
|
@ -873,12 +874,12 @@ public extension MessageViewModel {
|
|||
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 \(Interaction.self) AS \(quoteInteraction) ON (
|
||||
\(quoteInteraction).\(timestampMsColumn) = \(quote[.timestampMs]) AND (
|
||||
\(quoteInteraction).\(authorIdColumn) = \(quote[.authorId]) OR (
|
||||
LEFT JOIN \(quoteInteraction) ON (
|
||||
\(quoteInteraction[.timestampMs]) = \(quote[.timestampMs]) AND (
|
||||
\(quoteInteraction[.authorId]) = \(quote[.authorId]) OR (
|
||||
-- A users outgoing message is stored in some cases using their standard id
|
||||
-- but the quote will use their blinded id so handle that case
|
||||
\(quoteInteraction).\(authorIdColumn) = \(userPublicKey) AND
|
||||
\(quoteInteraction[.authorId]) = \(userPublicKey) AND
|
||||
(
|
||||
\(quote[.authorId]) = \(blinded15PublicKey ?? "''") OR
|
||||
\(quote[.authorId]) = \(blinded25PublicKey ?? "''")
|
||||
|
@ -887,14 +888,25 @@ public extension MessageViewModel {
|
|||
)
|
||||
)
|
||||
LEFT JOIN \(InteractionAttachment.self) AS \(quoteInteractionAttachment) ON (
|
||||
\(quoteInteractionAttachment).\(interactionAttachmentInteractionIdColumn) = \(quoteInteraction).\(idColumn) AND
|
||||
\(quoteInteractionAttachment).\(interactionAttachmentInteractionIdColumn) = \(quoteInteraction[.id]) AND
|
||||
\(quoteInteractionAttachment).\(interactionAttachmentAlbumIndexColumn) = 0
|
||||
)
|
||||
LEFT JOIN \(Attachment.self) AS \(ViewModel.quoteAttachmentKey) ON \(ViewModel.quoteAttachmentKey).\(attachmentIdColumn) = \(quoteInteractionAttachment).\(interactionAttachmentAttachmentIdColumn)
|
||||
LEFT JOIN \(quoteLinkPreview) ON (
|
||||
\(quoteLinkPreview[.url]) = \(quoteInteraction[.linkPreviewUrl]) AND
|
||||
\(Interaction.linkPreviewFilterLiteral(
|
||||
interaction: quoteInteraction,
|
||||
linkPreview: quoteLinkPreview
|
||||
))
|
||||
)
|
||||
LEFT JOIN \(Attachment.self) AS \(ViewModel.quoteAttachmentKey) ON (
|
||||
\(ViewModel.quoteAttachmentKey).\(attachmentIdColumn) = \(quoteInteractionAttachment).\(interactionAttachmentAttachmentIdColumn) OR
|
||||
\(ViewModel.quoteAttachmentKey).\(attachmentIdColumn) = \(quoteLinkPreview[.attachmentId]) OR
|
||||
\(ViewModel.quoteAttachmentKey).\(attachmentIdColumn) = \(quote[.attachmentId])
|
||||
)
|
||||
|
||||
LEFT JOIN \(LinkPreview.self) ON (
|
||||
\(linkPreview[.url]) = \(interaction[.linkPreviewUrl]) AND
|
||||
\(Interaction.linkPreviewFilterLiteral)
|
||||
\(Interaction.linkPreviewFilterLiteral())
|
||||
)
|
||||
LEFT JOIN \(Attachment.self) AS \(ViewModel.linkPreviewAttachmentKey) ON \(ViewModel.linkPreviewAttachmentKey).\(attachmentIdColumn) = \(linkPreview[.attachmentId])
|
||||
LEFT JOIN \(RecipientState.self) ON (
|
||||
|
|
|
@ -712,7 +712,7 @@ public extension SessionThreadViewModel {
|
|||
)
|
||||
LEFT JOIN \(LinkPreview.self) ON (
|
||||
\(linkPreview[.url]) = \(interaction[.linkPreviewUrl]) AND
|
||||
\(Interaction.linkPreviewFilterLiteral) AND
|
||||
\(Interaction.linkPreviewFilterLiteral()) AND
|
||||
\(SQL("\(linkPreview[.variant]) = \(LinkPreview.Variant.openGroupInvitation)"))
|
||||
)
|
||||
LEFT JOIN \(InteractionAttachment.self) AS \(firstInteractionAttachmentLiteral) ON (
|
||||
|
|
|
@ -4,9 +4,15 @@ import Foundation
|
|||
import GRDB
|
||||
|
||||
public class TypedTableAlias<T> where T: TableRecord, T: ColumnExpressible {
|
||||
public let alias: TableAlias = TableAlias(name: T.databaseTableName)
|
||||
internal let name: String
|
||||
internal let tableName: String
|
||||
public let alias: TableAlias
|
||||
|
||||
public init() {}
|
||||
public init(name: String = T.databaseTableName) {
|
||||
self.name = name
|
||||
self.tableName = T.databaseTableName
|
||||
self.alias = TableAlias(name: name)
|
||||
}
|
||||
|
||||
public subscript(_ column: T.Columns) -> SQLExpression {
|
||||
return alias[column.name]
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
|
||||
public extension SQLInterpolation {
|
||||
/// Appends the table name of the record type.
|
||||
///
|
||||
/// // SELECT * FROM player
|
||||
/// let player: TypedTableAlias<T> = TypedTableAlias()
|
||||
/// let request: SQLRequest<Player> = "SELECT * FROM \(player)"
|
||||
@_disfavoredOverload
|
||||
mutating func appendInterpolation<T>(_ typedTableAlias: TypedTableAlias<T>) {
|
||||
let name: String = typedTableAlias.name
|
||||
let tableName: String = typedTableAlias.tableName
|
||||
|
||||
guard name != tableName else { return appendLiteral(tableName.quotedDatabaseIdentifier) }
|
||||
|
||||
appendLiteral("\(tableName.quotedDatabaseIdentifier) AS \(name.quotedDatabaseIdentifier)")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue