Skip to content

Commit e373b14

Browse files
authored
Device hint when hovering a preview thumbnail (#27)
1 parent fdd6ff7 commit e373b14

1 file changed

Lines changed: 33 additions & 5 deletions

File tree

Snap-O/CaptureWindow/CapturePreviewStrip.swift

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ struct CapturePreviewStrip: View {
2323
}
2424
.padding(.horizontal, 24)
2525
.padding(.vertical, 16)
26-
.background(.ultraThinMaterial)
27-
.clipShape(RoundedRectangle(cornerRadius: 28, style: .continuous))
26+
.background(RoundedRectangle(cornerRadius: 28, style: .continuous).fill(.ultraThinMaterial))
2827
.shadow(color: Color.black.opacity(0.25), radius: 10, x: 0, y: 6)
2928
.padding(.horizontal, 24)
3029
.overlayPreferenceValue(PreviewSelectionBoundsKey.self) { anchor in
@@ -47,9 +46,11 @@ private struct CapturePreviewThumbnail: View {
4746
var dragItemProvider: () -> NSItemProvider
4847

4948
private let height: CGFloat = 80
49+
@StateObject private var imageLoader = ImageLoader()
50+
@State private var isHovered = false
5051

5152
var body: some View {
52-
ZStack {
53+
let preview = ZStack {
5354
thumbnail
5455
.frame(maxWidth: .infinity, maxHeight: .infinity)
5556
.background(Color.black.opacity(0.6))
@@ -60,13 +61,24 @@ private struct CapturePreviewThumbnail: View {
6061
.frame(width: targetWidth, height: height)
6162
.clipShape(RoundedRectangle(cornerRadius: 4, style: .continuous))
6263
.anchorPreference(key: PreviewSelectionBoundsKey.self, value: .bounds) { isSelected ? $0 : nil }
63-
.onDrag { dragItemProvider() }
64+
65+
return preview
66+
.onDrag { dragItemProvider() }
67+
.onHover { isHovered = $0 }
68+
.overlay(alignment: .bottom) {
69+
if isHovered {
70+
TextBubble(text: capture.device.displayTitle)
71+
.fixedSize(horizontal: true, vertical: true)
72+
.offset(y: 32)
73+
.allowsHitTesting(false)
74+
}
75+
}
6476
}
6577

6678
@ViewBuilder private var thumbnail: some View {
6779
switch capture.media {
6880
case .image(let url, _):
69-
if let image = NSImage(contentsOf: url) {
81+
if let image = imageLoader.image(url: url) {
7082
Image(nsImage: image)
7183
.resizable()
7284
.scaledToFill()
@@ -201,6 +213,22 @@ private struct VideoPreviewThumbnail: View {
201213
}
202214
}
203215

216+
private struct TextBubble: View {
217+
let text: String
218+
219+
var body: some View {
220+
Text(text)
221+
.multilineTextAlignment(.center)
222+
.font(.system(size: 13, weight: .medium))
223+
.padding(.horizontal, 14)
224+
.padding(.vertical, 6)
225+
.background(
226+
RoundedRectangle(cornerRadius: 16, style: .continuous)
227+
.fill(.ultraThinMaterial)
228+
)
229+
}
230+
}
231+
204232
final class VideoThumbnailCache {
205233
nonisolated(unsafe) static let shared = VideoThumbnailCache()
206234

0 commit comments

Comments
 (0)