2024-01-31 16:47:29 +01:00
|
|
|
//Made by Lumaa
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
struct NotificationRow: View {
|
2024-02-04 10:44:51 +01:00
|
|
|
@EnvironmentObject private var navigator: Navigator
|
2024-02-04 08:43:56 +01:00
|
|
|
|
2024-01-31 16:47:29 +01:00
|
|
|
var notif: Notification = .placeholder()
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
VStack {
|
|
|
|
HStack(spacing: 5) {
|
2024-02-04 08:43:56 +01:00
|
|
|
ProfilePicture(url: notif.account.avatar, size: 60)
|
2024-01-31 16:47:29 +01:00
|
|
|
.padding(.trailing)
|
|
|
|
.overlay(alignment: .bottomTrailing) {
|
|
|
|
notifIcon()
|
|
|
|
.offset(x: -5, y: 5)
|
|
|
|
}
|
2024-02-04 08:43:56 +01:00
|
|
|
.padding(.horizontal, 10)
|
|
|
|
.onTapGesture {
|
|
|
|
navigator.navigate(to: .account(acc: notif.account))
|
|
|
|
}
|
|
|
|
|
|
|
|
VStack(alignment: .leading) {
|
|
|
|
Text(localizedString())
|
|
|
|
.multilineTextAlignment(.leading)
|
|
|
|
.font(.subheadline)
|
|
|
|
.lineLimit(2)
|
|
|
|
|
|
|
|
if notif.status != nil {
|
|
|
|
TextEmoji(notif.status!.content, emojis: notif.status!.emojis)
|
|
|
|
.multilineTextAlignment(.leading)
|
|
|
|
.font(.caption)
|
|
|
|
.foregroundStyle(Color.gray)
|
|
|
|
.lineLimit(3, reservesSpace: true)
|
2024-02-08 08:33:20 +01:00
|
|
|
|
|
|
|
if notif.status!.mediaAttachments.count > 0 {
|
|
|
|
Label("activity.status.attachments-\(notif.status!.mediaAttachments.count)", systemImage: "photo.on.rectangle.angled")
|
|
|
|
.multilineTextAlignment(.leading)
|
|
|
|
.font(.caption)
|
|
|
|
.foregroundStyle(Color.gray)
|
|
|
|
.lineLimit(1, reservesSpace: false)
|
|
|
|
}
|
2024-02-04 08:43:56 +01:00
|
|
|
} else {
|
|
|
|
TextEmoji(notif.account.note, emojis: notif.account.emojis)
|
|
|
|
.multilineTextAlignment(.leading)
|
|
|
|
.font(.caption)
|
|
|
|
.foregroundStyle(Color.gray)
|
|
|
|
.lineLimit(3, reservesSpace: true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.contentShape(Rectangle())
|
|
|
|
.onTapGesture {
|
|
|
|
navigator.navigate(to: notif.status == nil ? .account(acc: notif.account) : .post(status: notif.status!))
|
|
|
|
}
|
2024-01-31 16:47:29 +01:00
|
|
|
}
|
|
|
|
.padding(.horizontal)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-04 08:43:56 +01:00
|
|
|
private func localizedString() -> LocalizedStringKey {
|
|
|
|
let nameStr = "@\(notif.account.username)"
|
2024-01-31 16:47:29 +01:00
|
|
|
switch (notif.supportedType) {
|
|
|
|
case .favourite:
|
2024-02-04 08:43:56 +01:00
|
|
|
return "activity.favorite.\(nameStr)"
|
2024-01-31 16:47:29 +01:00
|
|
|
case .follow:
|
2024-02-04 08:43:56 +01:00
|
|
|
return "activity.followed.\(nameStr)"
|
2024-01-31 16:47:29 +01:00
|
|
|
case .mention:
|
2024-02-04 08:43:56 +01:00
|
|
|
return "activity.mentionned.\(nameStr)"
|
2024-01-31 16:47:29 +01:00
|
|
|
case .reblog:
|
2024-02-04 08:43:56 +01:00
|
|
|
return "activity.reblogged.\(nameStr)"
|
2024-01-31 16:47:29 +01:00
|
|
|
case .status:
|
2024-02-04 08:43:56 +01:00
|
|
|
return "activity.status.\(nameStr)"
|
2024-01-31 16:47:29 +01:00
|
|
|
default:
|
2024-02-04 08:43:56 +01:00
|
|
|
return "activity.unknown" // follow requests & polls
|
2024-01-31 16:47:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private func notifColor() -> Color {
|
|
|
|
switch (notif.supportedType) {
|
|
|
|
case .favourite:
|
|
|
|
return Color.red
|
|
|
|
case .follow:
|
|
|
|
return Color.purple
|
|
|
|
case .mention:
|
|
|
|
return Color.blue
|
|
|
|
case .reblog:
|
2024-02-08 08:33:20 +01:00
|
|
|
return Color.orange
|
2024-01-31 16:47:29 +01:00
|
|
|
case .status:
|
|
|
|
return Color.yellow
|
|
|
|
default:
|
|
|
|
return Color.gray
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@ViewBuilder
|
|
|
|
private func notifIcon() -> some View {
|
2024-02-10 01:08:53 +01:00
|
|
|
let size: CGFloat = 60.0 / 4.0
|
2024-02-04 08:43:56 +01:00
|
|
|
|
2024-01-31 16:47:29 +01:00
|
|
|
ZStack {
|
|
|
|
switch (notif.supportedType) {
|
|
|
|
case .favourite:
|
|
|
|
Image(systemName: "heart.fill")
|
2024-02-10 01:08:53 +01:00
|
|
|
.resizable()
|
|
|
|
.scaledToFit()
|
|
|
|
.frame(width: size, height: size)
|
2024-01-31 16:47:29 +01:00
|
|
|
case .follow:
|
|
|
|
Image(systemName: "person.fill.badge.plus")
|
2024-02-10 01:08:53 +01:00
|
|
|
.resizable()
|
|
|
|
.scaledToFit()
|
|
|
|
.frame(width: size, height: size)
|
2024-01-31 16:47:29 +01:00
|
|
|
case .mention:
|
|
|
|
Image(systemName: "tag.fill")
|
2024-02-10 01:08:53 +01:00
|
|
|
.resizable()
|
|
|
|
.scaledToFit()
|
|
|
|
.frame(width: size, height: size)
|
2024-01-31 16:47:29 +01:00
|
|
|
case .reblog:
|
|
|
|
Image(systemName: "bolt.horizontal.fill")
|
2024-02-10 01:08:53 +01:00
|
|
|
.resizable()
|
|
|
|
.scaledToFit()
|
|
|
|
.frame(width: size, height: size)
|
2024-01-31 16:47:29 +01:00
|
|
|
case .status:
|
|
|
|
Image(systemName: "text.badge.plus")
|
2024-02-10 01:08:53 +01:00
|
|
|
.resizable()
|
|
|
|
.scaledToFit()
|
|
|
|
.frame(width: size, height: size)
|
2024-01-31 16:47:29 +01:00
|
|
|
default:
|
|
|
|
Image(systemName: "questionmark")
|
2024-02-10 01:08:53 +01:00
|
|
|
.resizable()
|
|
|
|
.scaledToFit()
|
|
|
|
.frame(width: size, height: size)
|
2024-01-31 16:47:29 +01:00
|
|
|
}
|
|
|
|
}
|
2024-02-04 08:43:56 +01:00
|
|
|
.frame(minWidth: 30)
|
|
|
|
.padding(7)
|
2024-01-31 16:47:29 +01:00
|
|
|
.background(notifColor())
|
|
|
|
.clipShape(.circle)
|
|
|
|
.overlay {
|
|
|
|
Circle()
|
|
|
|
.stroke(Color.appBackground, lineWidth: 3)
|
|
|
|
}
|
|
|
|
.fixedSize()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#Preview {
|
|
|
|
NotificationRow()
|
|
|
|
}
|