mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Render the live location timeline item (#5209)
* created the data for the timeline item # Conflicts: # ElementX/Sources/Other/Logging/Tracing.swift # ElementX/Sources/Services/Authentication/AuthenticationService.swift # ElementX/Sources/Services/Authentication/LinkNewDeviceService.swift * Implemented the LLS timeline item * updated preview tests * pr and design suggestions * previewscrollview is debug only
This commit is contained in:
@@ -10,16 +10,10 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct LocationMarkerView: View {
|
||||
var userProfile: UserProfileProxy?
|
||||
var fillColor = Color.compound.bgCanvasDefault
|
||||
var strokeColor = Color.compound.iconSecondaryAlpha
|
||||
var dotColor = Color.compound.iconPrimary
|
||||
var kind: LocationMarkerKind
|
||||
@ScaledMetric var size: CGFloat = 42
|
||||
var mediaProvider: MediaProviderProtocol?
|
||||
|
||||
private let circleCenter = CGPoint(x: 21, y: 21) // in SVG space
|
||||
private let circleRadius: CGFloat = 6 // in SVG space
|
||||
|
||||
var body: some View {
|
||||
// Generated from the SVG
|
||||
Canvas { context, canvasSize in
|
||||
@@ -55,7 +49,7 @@ struct LocationMarkerView: View {
|
||||
p.closeSubpath()
|
||||
}
|
||||
|
||||
context.stroke(pinPath, with: .color(strokeColor), lineWidth: 2 * scaleX)
|
||||
context.stroke(pinPath, with: .color(externalStrokeColor), lineWidth: 2 * scaleX)
|
||||
context.fill(pinPath, with: .color(fillColor))
|
||||
|
||||
// Dot
|
||||
@@ -66,20 +60,20 @@ struct LocationMarkerView: View {
|
||||
context.fill(dotPath, with: .color(dotColor))
|
||||
|
||||
// Draw resolved symbol centered on the circle
|
||||
if userProfile != nil, let symbol = context.resolveSymbol(id: 0) {
|
||||
if kind.userProfile != nil, let symbol = context.resolveSymbol(id: 0) {
|
||||
let center = CGPoint(x: circleCenter.x * scaleX,
|
||||
y: circleCenter.y * scaleY)
|
||||
context.draw(symbol, at: center, anchor: .center)
|
||||
}
|
||||
} symbols: {
|
||||
if let userProfile {
|
||||
if let userProfile = kind.userProfile {
|
||||
LoadableAvatarImage(url: userProfile.avatarURL,
|
||||
name: userProfile.displayName,
|
||||
contentID: userProfile.userID,
|
||||
avatarSize: .user(on: .map),
|
||||
mediaProvider: mediaProvider)
|
||||
.overlay {
|
||||
Circle().inset(by: 0.5).stroke(strokeColor)
|
||||
Circle().inset(by: 0.5).stroke(internalStrokeColor)
|
||||
}
|
||||
.tag(0)
|
||||
}
|
||||
@@ -89,22 +83,77 @@ struct LocationMarkerView: View {
|
||||
dimensions[.bottom]
|
||||
}
|
||||
}
|
||||
|
||||
private let circleCenter = CGPoint(x: 21, y: 21) // in SVG space
|
||||
private let circleRadius: CGFloat = 6 // in SVG space
|
||||
|
||||
private var fillColor: Color {
|
||||
switch kind {
|
||||
case .pin, .staticUser:
|
||||
.compound.bgCanvasDefault
|
||||
case .liveUser:
|
||||
.compound.iconAccentPrimary
|
||||
case .placeholder:
|
||||
.compound.bgSubtleSecondary
|
||||
}
|
||||
}
|
||||
|
||||
private var externalStrokeColor: Color {
|
||||
switch kind {
|
||||
case .pin, .staticUser:
|
||||
.compound.iconSecondaryAlpha
|
||||
case .liveUser:
|
||||
.compound.iconAccentPrimary
|
||||
case .placeholder:
|
||||
.compound.iconDisabled
|
||||
}
|
||||
}
|
||||
|
||||
private var internalStrokeColor: Color {
|
||||
switch kind {
|
||||
case .pin, .staticUser:
|
||||
.compound.iconSecondaryAlpha
|
||||
case .liveUser:
|
||||
.compound.bgCanvasDefault
|
||||
case .placeholder:
|
||||
.compound.iconDisabled
|
||||
}
|
||||
}
|
||||
|
||||
private var dotColor: Color {
|
||||
switch kind {
|
||||
case .placeholder:
|
||||
.compound.iconDisabled
|
||||
default:
|
||||
.compound.iconPrimary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LocationMarkerView_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
VStack(spacing: 30) {
|
||||
LocationMarkerView()
|
||||
// Placeholder
|
||||
LocationMarkerView(kind: .placeholder)
|
||||
|
||||
LocationMarkerView()
|
||||
.colorScheme(.dark)
|
||||
// Pin (no user)
|
||||
LocationMarkerView(kind: .pin)
|
||||
|
||||
LocationMarkerView(userProfile: UserProfileProxy.mockDan,
|
||||
// Static user with avatar
|
||||
LocationMarkerView(kind: .staticUser(.mockDan),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
|
||||
LocationMarkerView(userProfile: UserProfileProxy.mockDan,
|
||||
// Static user without avatar
|
||||
LocationMarkerView(kind: .staticUser(.init(userID: "@someone:matrix.org",
|
||||
displayName: "Someone")))
|
||||
|
||||
// Live user with avatar
|
||||
LocationMarkerView(kind: .liveUser(.mockDan),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
.colorScheme(.dark)
|
||||
|
||||
// Live user without avatar
|
||||
LocationMarkerView(kind: .liveUser(.init(userID: "@someone:matrix.org",
|
||||
displayName: "Someone")))
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color(red: 0.9, green: 0.85, blue: 0.8))
|
||||
|
||||
Reference in New Issue
Block a user