Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions MC1/Resources/Generated/L10n.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1069,8 +1069,10 @@ public enum L10n {
public static let info = L10n.tr("Contacts", "contacts.detail.info", fallback: "Info")
/// Location: ContactDetailView.swift - Purpose: Join room button
public static let joinRoom = L10n.tr("Contacts", "contacts.detail.joinRoom", fallback: "Join Room")
/// Location: ContactDetailView.swift - Purpose: Last advert label
public static let lastAdvert = L10n.tr("Contacts", "contacts.detail.lastAdvert", fallback: "Last Advert")
/// Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp)
public static let lastAdvert = L10n.tr("Contacts", "contacts.detail.lastAdvert", fallback: "Node Time Sent")
/// Location: ContactDetailView.swift - Purpose: Last heard label (when we received the node's advertisement)
public static let lastHeard = L10n.tr("Contacts", "contacts.detail.lastHeard", fallback: "Last Heard")
/// Location: ContactDetailView.swift - Purpose: Location section header
public static let location = L10n.tr("Contacts", "contacts.detail.location", fallback: "Location")
/// Location: ContactDetailView.swift - Purpose: Management button
Expand Down Expand Up @@ -2075,8 +2077,10 @@ public enum L10n {
}
/// Location: MapView.swift ContactDetailSheet - Purpose: Path length value for single hop
public static let hopSingular = L10n.tr("Map", "map.detail.hopSingular", fallback: "1 hop")
/// Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp
public static let lastAdvert = L10n.tr("Map", "map.detail.lastAdvert", fallback: "Last Advert")
/// Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp
public static let lastAdvert = L10n.tr("Map", "map.detail.lastAdvert", fallback: "Node Time Sent")
/// Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node
public static let lastHeard = L10n.tr("Map", "map.detail.lastHeard", fallback: "Last Heard")
/// Location: MapView.swift ContactDetailSheet - Purpose: Label for latitude coordinate
public static let latitude = L10n.tr("Map", "map.detail.latitude", fallback: "Latitude")
/// Location: MapView.swift ContactDetailSheet - Purpose: Label for longitude coordinate
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/de.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "Name";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "Letzte Ankündigung";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "Knotenzeitstempel";

/* Location: ContactDetailView.swift - Purpose: Last heard label */
"contacts.detail.lastHeard" = "Zuletzt gehört";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "Ungelesene Nachrichten";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/de.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "Favorit";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "Letzte Ankündigung";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "Knotenzeitstempel";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "Zuletzt gehört";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "Standort";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/en.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "Name";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "Last Advert";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "Node Time Sent";

/* Location: ContactDetailView.swift - Purpose: Last heard label (when we received the node's advertisement) */
"contacts.detail.lastHeard" = "Last Heard";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "Unread Messages";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/en.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "Favorite";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "Last Advert";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "Node Time Sent";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "Last Heard";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "Location";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/es.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "Nombre";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "Último anuncio";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "Hora envío nodo";

/* Location: ContactDetailView.swift - Purpose: Last heard label */
"contacts.detail.lastHeard" = "Última recepción";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "Mensajes sin leer";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/es.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "Favorito";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "Último anuncio";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "Hora envío nodo";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "Última recepción";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "Ubicación";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/fr.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "Nom";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "Dernière annonce";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "Heure envoi nœud";

/* Location: ContactDetailView.swift - Purpose: Last heard label */
"contacts.detail.lastHeard" = "Dernier contact";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "Messages non lus";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/fr.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "Favori";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "Dernière annonce";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "Heure envoi nœud";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "Dernier contact";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "Position";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/nl.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "Naam";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "Laatste advertentie";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "Tijdstip node verzonden";

/* Location: ContactDetailView.swift - Purpose: Last heard label */
"contacts.detail.lastHeard" = "Laatst gehoord";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "Ongelezen berichten";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/nl.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "Favoriet";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "Laatste advertentie";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "Tijdstip node verzonden";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "Laatst gehoord";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "Locatie";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/pl.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "Nazwa";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "Ostatnie ogłoszenie";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "Czas wysłania węzła";

/* Location: ContactDetailView.swift - Purpose: Last heard label */
"contacts.detail.lastHeard" = "Ostatnio odebrano";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "Nieprzeczytane wiadomości";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/pl.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "Ulubiony";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "Ostatnie ogłoszenie";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "Czas wysłania węzła";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "Ostatnio odebrano";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "Lokalizacja";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/ru.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "Имя";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "Последнее объявление";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "Время отправки узла";

/* Location: ContactDetailView.swift - Purpose: Last heard label */
"contacts.detail.lastHeard" = "Последний приём";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "Непрочитанные сообщения";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/ru.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "В избранном";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "Последний сигнал";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "Время отправки узла";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "Последний приём";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "Местоположение";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/uk.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "Ім'я";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "Останнє оголошення";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "Час відправки вузла";

/* Location: ContactDetailView.swift - Purpose: Last heard label */
"contacts.detail.lastHeard" = "Останній прийом";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "Непрочитані повідомлення";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/uk.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "Обраний";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "Останнє оголошення";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "Час відправки вузла";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "Останній прийом";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "Місцезнаходження";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/zh-Hans.lproj/Contacts.strings
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@
/* Location: ContactDetailView.swift - Purpose: Name label */
"contacts.detail.name" = "名称";

/* Location: ContactDetailView.swift - Purpose: Last advert label */
"contacts.detail.lastAdvert" = "最近广播";
/* Location: ContactDetailView.swift - Purpose: Node time sent label (device-reported timestamp) */
"contacts.detail.lastAdvert" = "节点发送时间";

/* Location: ContactDetailView.swift - Purpose: Last heard label */
"contacts.detail.lastHeard" = "最近收到";

/* Location: ContactDetailView.swift - Purpose: Unread messages label */
"contacts.detail.unreadMessages" = "未读消息";
Expand Down
7 changes: 5 additions & 2 deletions MC1/Resources/Localization/zh-Hans.lproj/Map.strings
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
/* Location: MapView.swift ContactDetailSheet - Purpose: Value showing contact is favorited */
"map.detail.favorite" = "收藏";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for last advertisement timestamp */
"map.detail.lastAdvert" = "最后广播";
/* Location: MapView.swift ContactDetailSheet - Purpose: Label for node-reported timestamp */
"map.detail.lastAdvert" = "节点发送时间";

/* Location: MapView.swift ContactDetailSheet - Purpose: Label for when we last heard the node */
"map.detail.lastHeard" = "最近收到";

/* Location: MapView.swift ContactDetailSheet - Purpose: Section header for location coordinates */
"map.detail.section.location" = "位置";
Expand Down
16 changes: 15 additions & 1 deletion MC1/Views/Contacts/ContactDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,13 @@ struct ContactDetailView: View {
let latencyMs = Int(elapsed / .milliseconds(1))

pingResult = .success(latencyMs: latencyMs, snrThere: snrThere, snrBack: snrBack)

// Ping response confirms the node is alive
try? await appState.services?.dataStore.updateContactLastHeard(
contactID: currentContact.id,
timestamp: UInt32(Date().timeIntervalSince1970)
)
Comment on lines +446 to +449

let announcement = L10n.Contacts.Contacts.Detail.pingSuccessAnnouncement(latencyMs)
AccessibilityNotification.Announcement(announcement).post()
} catch {
Expand Down Expand Up @@ -758,7 +765,7 @@ private struct ContactInfoSection: View {
.foregroundStyle(.secondary)
}

// Last advert
// Node time sent (device-reported timestamp)
if currentContact.lastAdvertTimestamp > 0 {
HStack {
Text(L10n.Contacts.Contacts.Detail.lastAdvert)
Expand All @@ -767,6 +774,13 @@ private struct ContactInfoSection: View {
}
}

// Last heard (when we actually received the advertisement)
HStack {
Text(L10n.Contacts.Contacts.Detail.lastHeard)
Spacer()
ConversationTimestamp(date: Date(timeIntervalSince1970: TimeInterval(currentContact.effectiveLastHeard)), font: .body)
Comment on lines +778 to +781
}

// Unread count
if currentContact.unreadCount > 0 {
HStack {
Expand Down
2 changes: 1 addition & 1 deletion MC1/Views/Contacts/ContactRowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct ContactRowView: View {
.accessibilityLabel(L10n.Contacts.Contacts.Row.favorite)
}

RelativeTimestampText(timestamp: contact.lastModified)
RelativeTimestampText(timestamp: contact.effectiveLastHeard)
}

HStack(spacing: 8) {
Expand Down
2 changes: 1 addition & 1 deletion MC1/Views/Contacts/ContactsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ final class ContactsViewModel {
) -> [ContactDTO] {
switch order {
case .lastHeard:
return contacts.sorted { $0.lastModified > $1.lastModified }
return contacts.sorted { $0.effectiveLastHeard > $1.effectiveLastHeard }
case .name:
return contacts.sorted {
$0.displayName.localizedCompare($1.displayName) == .orderedAscending
Expand Down
4 changes: 4 additions & 0 deletions MC1/Views/Map/ContactDetailSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ struct ContactDetailSheet: View {
ConversationTimestamp(date: Date(timeIntervalSince1970: TimeInterval(contact.lastAdvertTimestamp)), font: .body)
}
}

LabeledContent(L10n.Map.Map.Detail.lastHeard) {
ConversationTimestamp(date: Date(timeIntervalSince1970: TimeInterval(contact.effectiveLastHeard)), font: .body)
Comment on lines +65 to +66
}
}

// Location section
Expand Down
Loading
Loading