commit 9a70bcf280a1ca68505307bee3207e00c9e1e45f
parent 4f5c9b1bf7b6c2ea097cb3ff8ab30958ce53b33e
Author: William Casarin <jb55@jb55.com>
Date: Thu, 30 Jun 2022 07:15:11 -0700
tabs: add blue dot to home view
Changelog-Added: Add blue dot notification to home tab
Changelog-Fixed: Clicking tabs now clear blue dots immediately
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
3 files changed, 68 insertions(+), 47 deletions(-)
diff --git a/damus/ContentView.swift b/damus/ContentView.swift
@@ -174,7 +174,7 @@ struct ContentView: View {
.navigationViewStyle(.stack)
}
- TabBar(new_notifications: $home.new_notifications, selected: $selected_timeline, action: switch_timeline)
+ TabBar(new_events: $home.new_events, selected: $selected_timeline, action: switch_timeline)
}
.onAppear() {
self.connect()
@@ -305,9 +305,6 @@ struct ContentView: View {
return
}
- if (timeline != .notifications && self.selected_timeline == .notifications) || timeline == .notifications {
- home.new_notifications = false
- }
self.selected_timeline = timeline
NotificationCenter.default.post(name: .switched_timeline, object: timeline)
//self.selected_timeline = timeline
@@ -413,9 +410,10 @@ struct LastNotification {
let created_at: Int64
}
-func get_last_notified() -> LastNotification? {
- let last = UserDefaults.standard.string(forKey: "last_notification")
- let last_created = UserDefaults.standard.string(forKey: "last_notification_time")
+func get_last_event(_ timeline: Timeline) -> LastNotification? {
+ let str = timeline.rawValue
+ let last = UserDefaults.standard.string(forKey: "last_\(str)")
+ let last_created = UserDefaults.standard.string(forKey: "last_\(str)_time")
.flatMap { Int64($0) }
return last.flatMap { id in
@@ -425,9 +423,10 @@ func get_last_notified() -> LastNotification? {
}
}
-func save_last_notified(_ ev: NostrEvent) {
- UserDefaults.standard.set(ev.id, forKey: "last_notification")
- UserDefaults.standard.set(String(ev.created_at), forKey: "last_notification_time")
+func save_last_event(_ ev: NostrEvent, timeline: Timeline) {
+ let str = timeline.rawValue
+ UserDefaults.standard.set(ev.id, forKey: "last_\(str)")
+ UserDefaults.standard.set(String(ev.created_at), forKey: "last_\(str)_time")
}
diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift
@@ -7,6 +7,27 @@
import Foundation
+struct NewEventsBits {
+ let bits: Int
+
+ init() {
+ bits = 0
+ }
+
+ init (prev: NewEventsBits, setting: Timeline) {
+ self.bits = prev.bits | timeline_bit(setting)
+ }
+
+ init (prev: NewEventsBits, unsetting: Timeline) {
+ self.bits = prev.bits & ~timeline_bit(unsetting)
+ }
+
+ func is_set(_ timeline: Timeline) -> Bool {
+ let notification_bit = timeline_bit(timeline)
+ return (bits & notification_bit) == notification_bit
+ }
+
+}
class HomeModel: ObservableObject {
var damus_state: DamusState
@@ -18,9 +39,10 @@ class HomeModel: ObservableObject {
let home_subid = UUID().description
let contacts_subid = UUID().description
let notifications_subid = UUID().description
+ let dms_subid = UUID().description
let init_subid = UUID().description
- @Published var new_notifications: Bool = false
+ @Published var new_events: NewEventsBits = NewEventsBits()
@Published var notifications: [NostrEvent] = []
@Published var events: [NostrEvent] = []
@Published var loading: Bool = false
@@ -261,21 +283,28 @@ class HomeModel: ObservableObject {
return m[kind]
}
+ func handle_last_event(ev: NostrEvent, timeline: Timeline) {
+ let last_ev = get_last_event(timeline)
+
+ if last_ev == nil || last_ev!.created_at < ev.created_at {
+ save_last_event(ev, timeline: timeline)
+ new_events = NewEventsBits(prev: new_events, setting: timeline)
+ }
+ }
+
func handle_notification(ev: NostrEvent) {
if !insert_uniq_sorted_event(events: ¬ifications, new_ev: ev, cmp: { $0.created_at > $1.created_at }) {
return
}
- let last_notified = get_last_notified()
-
- if last_notified == nil || last_notified!.created_at < ev.created_at {
- save_last_notified(ev)
- new_notifications = true
- }
+ handle_last_event(ev: ev, timeline: .notifications)
}
func insert_home_event(_ ev: NostrEvent) -> Bool {
let ok = insert_uniq_sorted_event(events: &self.events, new_ev: ev, cmp: { $0.created_at > $1.created_at })
+ if ok {
+ handle_last_event(ev: ev, timeline: .home)
+ }
return ok
}
diff --git a/damus/Views/MainTabView.swift b/damus/Views/MainTabView.swift
@@ -17,30 +17,30 @@ enum Timeline: String, CustomStringConvertible {
}
}
-
-struct MainTabView: View {
- var body: some View {
- Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
- }
-}
-
-struct MainTabView_Previews: PreviewProvider {
- static var previews: some View {
- MainTabView()
+func timeline_bit(_ timeline: Timeline) -> Int {
+ switch timeline {
+ case .home: return 1 << 0
+ case .notifications: return 1 << 1
+ case .search: return 1 << 2
+ case .dms: return 1 << 3
}
}
-struct NotificationsTab: View {
- @Binding var new_notifications: Bool
+
+struct TabButton: View {
+ let timeline: Timeline
+ let img: String
+
@Binding var selected: Timeline?
+ @Binding var new_events: NewEventsBits
let action: (Timeline) -> ()
var body: some View {
ZStack(alignment: .center) {
- TabButton(timeline: .notifications, img: "bell", selected: $selected, action: action)
+ Tab
- if new_notifications {
+ if new_events.is_set(timeline) {
Circle()
.size(CGSize(width: 8, height: 8))
.frame(width: 10, height: 10, alignment: .topTrailing)
@@ -50,19 +50,12 @@ struct NotificationsTab: View {
}
}
}
-}
-
-
-struct TabButton: View {
- let timeline: Timeline
- let img: String
- @Binding var selected: Timeline?
-
- let action: (Timeline) -> ()
-
- var body: some View {
- Button(action: {action(timeline)}) {
+ var Tab: some View {
+ Button(action: {
+ action(timeline)
+ new_events = NewEventsBits(prev: new_events, unsetting: timeline)
+ }) {
Label("", systemImage: selected == timeline ? "\(img).fill" : img)
.contentShape(Rectangle())
.frame(maxWidth: .infinity, minHeight: 30.0)
@@ -73,7 +66,7 @@ struct TabButton: View {
struct TabBar: View {
- @Binding var new_notifications: Bool
+ @Binding var new_events: NewEventsBits
@Binding var selected: Timeline?
let action: (Timeline) -> ()
@@ -82,9 +75,9 @@ struct TabBar: View {
VStack {
Divider()
HStack {
- TabButton(timeline: .home, img: "house", selected: $selected, action: action)
- TabButton(timeline: .search, img: "magnifyingglass.circle", selected: $selected, action: action)
- NotificationsTab(new_notifications: $new_notifications, selected: $selected, action: action)
+ TabButton(timeline: .home, img: "house", selected: $selected, new_events: $new_events, action: action)
+ TabButton(timeline: .search, img: "magnifyingglass.circle", selected: $selected, new_events: $new_events, action: action)
+ TabButton(timeline: .notifications, img: "bell", selected: $selected, new_events: $new_events, action: action)
}
}
}