- SettingsView: ternary between .secondary (HierarchicalShapeStyle) and .red (Color) doesn't unify — both sides now explicit Color. - CollectionRowView: passing OutlineIconMapping.sfSymbolName as a bare function reference to flatMap loses its (inferred default) MainActor isolation; wrapping it in a closure keeps the call inside body's already-MainActor context. - NetworkMonitor: [weak self] was captured on NWPathMonitor's non-isolated pathUpdateHandler closure, which must cross into the inner @MainActor Task — moved the weak capture onto the Task closure itself instead, which is where it's actually used.
45 lines
1.6 KiB
Swift
45 lines
1.6 KiB
Swift
import SwiftUI
|
|
import OutlineKit
|
|
|
|
struct CollectionRowView: View {
|
|
let collection: OutlineCollection
|
|
|
|
var body: some View {
|
|
Label {
|
|
Text(collection.name)
|
|
} icon: {
|
|
if let emoji = collection.emojiIcon {
|
|
Text(emoji)
|
|
} else if let symbolName = collection.icon.flatMap({ OutlineIconMapping.sfSymbolName(for: $0) }) {
|
|
Image(systemName: symbolName)
|
|
.foregroundStyle(tintColor)
|
|
} else {
|
|
Image(systemName: "folder.fill")
|
|
.foregroundStyle(tintColor)
|
|
}
|
|
}
|
|
}
|
|
|
|
private var tintColor: Color {
|
|
collection.color.flatMap { Color(hex: $0) } ?? .accentColor
|
|
}
|
|
}
|
|
|
|
private extension OutlineCollection {
|
|
/// Outline's `icon` field holds either a literal emoji, or a string key
|
|
/// into Outline's own icon set (see OutlineIconMapping) — only the former
|
|
/// is renderable directly, the latter needs the lookup table.
|
|
var emojiIcon: String? {
|
|
// `isEmojiPresentation` misses symbol-class emoji that default to text
|
|
// presentation (e.g. some picked without a variation selector) — `isEmoji`
|
|
// is the broader, correct check for "this scalar can be an emoji at all".
|
|
// Plain ASCII digits/`#`/`*` also report `isEmoji == true` (they're valid
|
|
// keycap-sequence bases), so exclude the ASCII range to avoid treating a
|
|
// literal digit or punctuation icon name as an emoji.
|
|
guard let icon, icon.unicodeScalars.contains(where: { $0.properties.isEmoji && $0.value > 0x7F }) else {
|
|
return nil
|
|
}
|
|
return icon
|
|
}
|
|
}
|