import Foundation
import Photos
import ThreemaMacros
// MARK: - FileMessageProvider
/// Set of supported file message types
public enum FileMessageType {
/// An image (not animated)
case image(ImageMessage)
/// A sticker (not animated)
case sticker(StickerMessage)
/// An animated image
case animatedImage(ImageMessage)
/// An animated sticker
case animatedSticker(StickerMessage)
/// A video
case video(VideoMessage)
/// A voice message
case voice(VoiceMessage)
/// A file/document
case file(FileMessage)
/// Name of the belonging SFSymbol
public var symbolName: String {
switch self {
case .image, .sticker:
"photo.fill"
case .animatedImage, .animatedSticker:
"photo.artframe"
case .video:
// Own icon used because SFSymbols is reserved
"threema.video.fill"
case .voice:
"mic.fill"
case .file:
"doc.fill"
}
}
public var defaultInteractionSymbolName: String? {
switch self {
case .animatedImage, .animatedSticker, .video:
"play.fill"
case .image, .sticker, .voice, .file:
nil
}
}
/// Localized description of the type
public var localizedDescription: String {
switch self {
case .image:
#localize("file_message_image")
case .sticker, .animatedSticker:
#localize("file_message_sticker")
case .animatedImage:
#localize("file_message_animated_image")
case .video:
#localize("file_message_video")
case .voice:
#localize("file_message_voice")
case .file:
#localize("file_message_file")
}
}
}
/// This message can be represented as a `FileMessageType`
///
/// A definition for the abstraction interface of any message that contains blob data (e.g. `FileMessage`,
/// `ImageMessage`, ...)
public protocol FileMessageProvider: BlobData {
/// File message type representation of this object with a blob
var fileMessageType: FileMessageType { get }
// TODO: Remove after debugging
var thumbnailState: BlobState { get }
var dataState: BlobState { get }
}
// MARK: - CommonFileMessageMetadata
/// Common metadata of all `FileMessageType`s
public protocol CommonFileMessageMetadata: BlobData {
/// Blob display state of this message
var blobDisplayState: BlobDisplayState { get }
/// Blob file size
var dataBlobFileSize: Measurement<UnitInformationStorage> { get }
/// Caption of file message if it has any
var caption: String? { get }
/// When this message is displayed should it try to inline the date and state with the thumbnail?
var showDateAndStateInline: Bool { get }
/// Creates a new temporary URL to the blob data
///
/// Please remove the data if it is no longer needed.
func temporaryBlobDataURL() -> URL?
}
extension CommonFileMessageMetadata {
// We normally inline date and state if there is no caption
public var showDateAndStateInline: Bool {
caption == nil
}
}
// MARK: - ThumbnailDisplayMessage
/// General display message for message types that use a thumbnail
public protocol ThumbnailDisplayMessage: BaseMessageEntity & FileMessageProvider & CommonFileMessageMetadata {
/// Thumbnail representing this message
var thumbnailImage: UIImage? { get }
/// Aspect ratio of (thumbnail) image (heigh/width)
var heightToWidthAspectRatio: Double { get }
var assetResourceTypeForAutosave: PHAssetResourceType? { get }
/// Creates a `SaveMediaItem` that can be saved to photos using `AlbumManager`
/// - Parameter forAutosave: If the created item is used to auto save
/// - Returns: `SaveMediaItem` to be used in AlbumManager`
func createSaveMediaItem(forAutosave: Bool) -> AlbumManager.SaveMediaItem?
}
extension ThumbnailDisplayMessage {
public var readableFileName: String {
let uti = blobUTTypeIdentifier ?? ""
let mimeType = UTIConverter.mimeType(fromUTI: uti) ?? "application/octet-stream"
let ext = UTIConverter.preferredFileExtension(forMimeType: mimeType)
return "\(TargetManager.appName.replacingOccurrences(of: " ", with: "_"))_\(DateFormatter.getDateForExport(date)).\(ext ?? "")"
}
public func createSaveMediaItem() -> AlbumManager.SaveMediaItem? {
createSaveMediaItem(forAutosave: false)
}
}
// MARK: - ImageMessage
/// A blob message that is an image. The image might be animated.
public protocol ImageMessage: ThumbnailDisplayMessage { }
// MARK: - StickerMessage
/// A blob message that is a sticker. The sticker might be animated.
public protocol StickerMessage: ThumbnailDisplayMessage { }
// MARK: - VideoMessage
public protocol VideoMessage: ThumbnailDisplayMessage {
var durationTimeInterval: TimeInterval? { get }
}
// MARK: - VoiceMessage
public protocol VoiceMessage: BaseMessageEntity & FileMessageProvider & CommonFileMessageMetadata {
var durationTimeInterval: TimeInterval? { get }
var consumed: Date? { get }
}
// MARK: - FileMessage
public protocol FileMessage: BaseMessageEntity & FileMessageProvider & CommonFileMessageMetadata {
/// Name of file
var name: String { get }
/// File extension
var `extension`: String { get }
}
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland