203 lines
4.7 KiB
Swift
203 lines
4.7 KiB
Swift
import Foundation
|
|
|
|
enum ClipboardItemKind: Int {
|
|
case text = 0
|
|
case url
|
|
case image
|
|
case richText
|
|
case file
|
|
case unknown
|
|
case pdf
|
|
case audio
|
|
case color
|
|
|
|
var displayName: String {
|
|
switch self {
|
|
case .text: return "text"
|
|
case .url: return "link"
|
|
case .image: return "image"
|
|
case .richText: return "rich text"
|
|
case .file: return "file"
|
|
case .unknown: return "item"
|
|
case .pdf: return "PDF"
|
|
case .audio: return "audio"
|
|
case .color: return "color"
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ClipboardItemKind {
|
|
var canOpen: Bool {
|
|
switch self {
|
|
case .url, .file, .image, .pdf, .audio:
|
|
return true
|
|
case .text, .richText, .unknown, .color:
|
|
return false
|
|
}
|
|
}
|
|
|
|
var canReveal: Bool {
|
|
switch self {
|
|
case .file, .image, .pdf, .audio:
|
|
return true
|
|
case .text, .richText, .unknown, .url, .color:
|
|
return false
|
|
}
|
|
}
|
|
|
|
var hasManagedCacheReference: Bool {
|
|
switch self {
|
|
case .url, .image, .pdf, .audio, .richText:
|
|
return true
|
|
case .text, .file, .unknown, .color:
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
enum ClipboardSortMode: Int {
|
|
case mostRecent = 0
|
|
case mostUsed
|
|
case images
|
|
case links
|
|
case text
|
|
case pinned
|
|
case files
|
|
case audio
|
|
case colors
|
|
|
|
static let allCases: [ClipboardSortMode] = [.mostRecent, .mostUsed, .text, .links, .images, .colors, .audio, .files, .pinned]
|
|
|
|
var title: String {
|
|
switch self {
|
|
case .mostRecent: return "Most Recent"
|
|
case .mostUsed: return "Most Used"
|
|
case .images: return "Images"
|
|
case .links: return "Links"
|
|
case .text: return "Text"
|
|
case .pinned: return "Pinned"
|
|
case .files: return "Files"
|
|
case .audio: return "Audio"
|
|
case .colors: return "Colors"
|
|
}
|
|
}
|
|
}
|
|
|
|
enum ClipboardCollectionDefaults {
|
|
static let names = [
|
|
"Useful Links",
|
|
"Important Notes",
|
|
"Code Snippets",
|
|
"Read Later"
|
|
]
|
|
|
|
static func normalizedName(_ value: String?) -> String? {
|
|
guard let value else { return nil }
|
|
let name = value
|
|
.split { $0.isWhitespace }
|
|
.joined(separator: " ")
|
|
.clipboardTrimmed
|
|
guard !name.isEmpty else { return nil }
|
|
return String(name.prefix(40))
|
|
}
|
|
}
|
|
|
|
struct ClipboardItem {
|
|
var id: UUID
|
|
var kind: ClipboardItemKind
|
|
var displayText: String
|
|
var payload: String
|
|
var payloadHash: String
|
|
var createdAt: Date
|
|
var lastUsedAt: Date
|
|
var useCount: Int
|
|
var sourceApp: String?
|
|
var imagePath: String?
|
|
var thumbnailPath: String?
|
|
var isPinned: Bool
|
|
var sourceAppBundleId: String?
|
|
var ocrText: String?
|
|
var collectionName: String?
|
|
var customTitle: String?
|
|
|
|
var searchableText: String {
|
|
var text = kindLabel + " " + displayText.lowercased() + " " + payload.lowercased()
|
|
if let customTitle {
|
|
text += " " + customTitle.lowercased()
|
|
}
|
|
if let sourceApp {
|
|
text += " " + sourceApp.lowercased()
|
|
}
|
|
if let ocrText {
|
|
text += " " + ocrText.lowercased()
|
|
}
|
|
if let sourceAppBundleId {
|
|
text += " " + sourceAppBundleId.lowercased()
|
|
}
|
|
if let collectionName {
|
|
text += " " + collectionName.lowercased()
|
|
}
|
|
return text
|
|
}
|
|
|
|
private var kindLabel: String {
|
|
switch kind {
|
|
case .text: return "text"
|
|
case .url: return "link url"
|
|
case .image: return "image"
|
|
case .richText: return "richtext rtf"
|
|
case .file: return "file"
|
|
case .unknown: return "unknown"
|
|
case .pdf: return "pdf document"
|
|
case .audio: return "audio sound"
|
|
case .color: return "color swatch hex"
|
|
}
|
|
}
|
|
|
|
init(
|
|
id: UUID,
|
|
kind: ClipboardItemKind,
|
|
displayText: String,
|
|
payload: String,
|
|
payloadHash: String,
|
|
createdAt: Date,
|
|
lastUsedAt: Date,
|
|
useCount: Int,
|
|
sourceApp: String?,
|
|
imagePath: String?,
|
|
thumbnailPath: String?,
|
|
isPinned: Bool = false,
|
|
sourceAppBundleId: String? = nil,
|
|
ocrText: String? = nil,
|
|
collectionName: String? = nil,
|
|
customTitle: String? = nil
|
|
) {
|
|
self.id = id
|
|
self.kind = kind
|
|
self.displayText = displayText
|
|
self.payload = payload
|
|
self.payloadHash = payloadHash
|
|
self.createdAt = createdAt
|
|
self.lastUsedAt = lastUsedAt
|
|
self.useCount = useCount
|
|
self.sourceApp = sourceApp
|
|
self.imagePath = imagePath
|
|
self.thumbnailPath = thumbnailPath
|
|
self.isPinned = isPinned
|
|
self.sourceAppBundleId = sourceAppBundleId
|
|
self.ocrText = ocrText
|
|
self.collectionName = collectionName
|
|
self.customTitle = ClipboardItem.normalizedCustomTitle(customTitle)
|
|
}
|
|
|
|
static func normalizedCustomTitle(_ value: String?) -> String? {
|
|
guard let value else { return nil }
|
|
let title = value
|
|
.split { $0.isWhitespace }
|
|
.joined(separator: " ")
|
|
.clipboardTrimmed
|
|
guard !title.isEmpty else { return nil }
|
|
return String(title.prefix(80))
|
|
}
|
|
}
|