Skip to content

Commit a28e8e3

Browse files
committed
Fix bel bel on nav
1 parent 3e1ff60 commit a28e8e3

File tree

8 files changed

+81
-58
lines changed

8 files changed

+81
-58
lines changed

apple/InlineMac/AppDelegate.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import UserNotifications
77

88
class AppDelegate: NSObject, NSApplicationDelegate {
99
let notifications = NotificationsManager()
10+
let navigation: NavigationModel = .shared
1011

1112
func applicationWillFinishLaunching(_ notification: Notification) {
1213
// Disable native tabbing
@@ -23,7 +24,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
2324
options.debug = false
2425
options.tracesSampleRate = 0.1
2526
}
26-
27+
2728
notifications.setup()
2829
}
2930

apple/InlineMac/InlineApp.swift

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ struct InlineApp: App {
99
@NSApplicationDelegateAdaptor private var appDelegate: AppDelegate
1010
@StateObject var viewModel = MainWindowViewModel()
1111
@StateObject var ws = WebSocketManager()
12-
@StateObject var navigation = NavigationModel()
12+
@StateObject var navigation: NavigationModel = .shared
1313
@StateObject var auth = Auth.shared
1414
@StateObject var overlay = OverlayManager()
1515

1616
@Environment(\.openWindow) var openWindow
17-
17+
1818
var body: some Scene {
1919
// Note(@mo): Using Window here messes up with our title bar handling upon window re-open after close
2020
WindowGroup("main") {
@@ -91,7 +91,6 @@ struct InlineApp: App {
9191
// Reset internal navigation
9292
navigation.reset()
9393

94-
9594
// Close Settings
9695
if let window = NSApplication.shared.keyWindow {
9796
window.close()

apple/InlineMac/Models/NavigationModel.swift

+28-29
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ private struct NavigationState: Codable {
3636
var spaceSelectionDict: [Int64: NavigationRoute]
3737
}
3838

39-
@MainActor
4039
class NavigationModel: ObservableObject {
4140
static let shared = NavigationModel()
42-
41+
4342
private let log = Log.scoped("Navigation", enableTracing: true)
4443

4544
@Published var homePath: [NavigationRoute] = []
@@ -53,13 +52,7 @@ class NavigationModel: ObservableObject {
5352
@Published private var spacePathDict: [Int64: [NavigationRoute]] = [:]
5453
@Published private var spaceSelectionDict: [Int64: NavigationRoute] = [:]
5554

56-
public var windowManager: MainWindowViewModel? {
57-
didSet {
58-
log.trace("windowManager set")
59-
// upon window creation
60-
prepareForCurrentRoute()
61-
}
62-
}
55+
public var windowManager: MainWindowViewModel?
6356

6457
var spacePath: Binding<[NavigationRoute]> {
6558
Binding(
@@ -73,10 +66,9 @@ class NavigationModel: ObservableObject {
7366
guard let self,
7467
let activeSpaceId
7568
else { return }
76-
Task { @MainActor in
77-
self.spacePathDict[activeSpaceId] = newValue
78-
self.windowManager?.setUpForInnerRoute(newValue.last ?? .spaceRoot)
79-
}
69+
70+
self.spacePathDict[activeSpaceId] = newValue
71+
self.setUpForRoute(newValue.last ?? .spaceRoot)
8072
}
8173
)
8274
}
@@ -93,10 +85,9 @@ class NavigationModel: ObservableObject {
9385
guard let self,
9486
let activeSpaceId
9587
else { return }
96-
Task { @MainActor in
97-
self.spaceSelectionDict[activeSpaceId] = newValue
98-
self.windowManager?.setUpForInnerRoute(newValue)
99-
}
88+
89+
self.spaceSelectionDict[activeSpaceId] = newValue
90+
self.setUpForRoute(newValue)
10091
}
10192
)
10293
}
@@ -114,44 +105,52 @@ class NavigationModel: ObservableObject {
114105
.sink { [weak self] newValue in
115106
guard let self, let spaceId = newValue else { return }
116107
guard let w = self.windowManager, w.topLevelRoute == .main else { return }
117-
self.windowManager?.setUpForInnerRoute(self.spaceSelectionDict[spaceId] ?? .spaceRoot)
108+
self.setUpForRoute(self.spaceSelectionDict[spaceId] ?? .spaceRoot)
118109
}
119110
.store(in: &cancellables)
120111

121112
$homePath.sink { [weak self] newValue in
122113
guard let self = self else { return }
123114
guard let w = self.windowManager, w.topLevelRoute == .main else { return }
124-
self.windowManager?.setUpForInnerRoute(newValue.last ?? self.homeSelection)
115+
self.setUpForRoute(newValue.last ?? self.homeSelection)
125116
}.store(in: &cancellables)
126117
}
127118

128119
private func prepareForCurrentRoute() {
129120
if let activeSpaceId {
130-
windowManager?.setUpForInnerRoute(spaceSelectionDict[activeSpaceId] ?? .spaceRoot)
121+
setUpForRoute(spaceSelectionDict[activeSpaceId] ?? .spaceRoot)
131122
} else {
132-
windowManager?.setUpForInnerRoute(homePath.last ?? homeSelection)
123+
setUpForRoute(homePath.last ?? homeSelection)
124+
}
125+
}
126+
127+
private func setUpForRoute(_ route: NavigationRoute) {
128+
guard let windowManager = windowManager else {
129+
log.error("Window manager not set up")
130+
return
133131
}
132+
windowManager.setUpForInnerRoute(route)
134133
}
135134

136135
// Used from sidebars
137136
func select(_ route: NavigationRoute) {
138137
if let activeSpaceId {
139138
spaceSelectionDict[activeSpaceId] = route
140-
windowManager?.setUpForInnerRoute(route)
139+
setUpForRoute(route)
141140
} else {
142141
homeSelection = route
143142
homePath.removeAll()
144-
windowManager?.setUpForInnerRoute(route)
143+
setUpForRoute(route)
145144
}
146145
}
147146

148147
func navigate(to route: NavigationRoute) {
149148
if let activeSpaceId {
150149
spacePathDict[activeSpaceId, default: []].append(route)
151-
windowManager?.setUpForInnerRoute(route)
150+
setUpForRoute(route)
152151
} else {
153152
homePath.append(route)
154-
windowManager?.setUpForInnerRoute(route)
153+
setUpForRoute(route)
155154
}
156155
}
157156

@@ -160,24 +159,24 @@ class NavigationModel: ObservableObject {
160159
// TODO: Load from persistence layer
161160
if spacePathDict[id] == nil {
162161
spacePathDict[id] = []
163-
windowManager?.setUpForInnerRoute(.spaceRoot)
162+
setUpForRoute(.spaceRoot)
164163
}
165164
}
166165

167166
func goHome() {
168167
activeSpaceId = nil
169168
// TODO: Load from persistence layer
170169
let currentHomeRoute = homePath.last ?? homeSelection
171-
windowManager?.setUpForInnerRoute(currentHomeRoute)
170+
setUpForRoute(currentHomeRoute)
172171
}
173172

174173
func navigateBack() {
175174
if let activeSpaceId {
176175
spacePathDict[activeSpaceId]?.removeLast()
177-
windowManager?.setUpForInnerRoute(spacePathDict[activeSpaceId]?.last ?? .spaceRoot)
176+
setUpForRoute(spacePathDict[activeSpaceId]?.last ?? .spaceRoot)
178177
} else {
179178
homePath.removeLast()
180-
windowManager?.setUpForInnerRoute(homePath.last ?? homeSelection)
179+
setUpForRoute(homePath.last ?? homeSelection)
181180
}
182181
}
183182

apple/InlineMac/Utils/LineHeight.swift

+19-18
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,52 @@
22
// https://github.com/krzyzanowskim/STTextView/blob/main/LICENSE.md
33

44
#if canImport(AppKit) && !targetEnvironment(macCatalyst)
5-
import AppKit
5+
import AppKit
66
#endif
77
#if canImport(UIKit)
8-
import UIKit
8+
import UIKit
99
#endif
1010

1111
func calculateDefaultLineHeight(for font: CTFont) -> CGFloat {
1212
/// Heavily inspired by WebKit
13-
13+
1414
let kLineHeightAdjustment: CGFloat = 0.15
15-
15+
1616
var ascent = CTFontGetAscent(font)
1717
var descent = CTFontGetDescent(font)
1818
var lineGap = CTFontGetLeading(font)
19-
19+
2020
let familyName = CTFontCopyFamilyName(font) as String
21-
21+
2222
if shouldUseAdjustment(familyName) {
2323
// Needs ascent adjustment
2424
ascent += round((ascent + descent) * kLineHeightAdjustment)
2525
}
26-
26+
2727
// Compute line spacing before the line metrics hacks are applied.
2828
var lineSpacing = round(ascent) + round(descent) + round(lineGap)
29-
29+
3030
// Hack Hiragino line metrics to allow room for marked text underlines.
3131
if descent < 3, lineGap >= 3, familyName.hasPrefix("Hiragino") == true {
3232
lineGap -= 3 - descent
3333
descent = 3
3434
}
35-
36-
#if os(iOS) || targetEnvironment(macCatalyst)
37-
let adjustment = shouldUseAdjustment(familyName) ? ceil(ascent + descent) * kLineHeightAdjustment : 0
38-
lineGap = ceil(lineGap)
39-
lineSpacing = ceil(ascent) + adjustment + ceil(descent) + lineGap
40-
ascent = ceil(ascent + adjustment)
41-
descent = ceil(descent)
42-
#endif
43-
35+
36+
#if os(iOS) || targetEnvironment(macCatalyst)
37+
let adjustment =
38+
shouldUseAdjustment(familyName) ? ceil(ascent + descent) * kLineHeightAdjustment : 0
39+
lineGap = ceil(lineGap)
40+
lineSpacing = ceil(ascent) + adjustment + ceil(descent) + lineGap
41+
ascent = ceil(ascent + adjustment)
42+
descent = ceil(descent)
43+
#endif
44+
4445
return lineSpacing
4546
}
4647

4748
private func shouldUseAdjustment(_ familyName: String) -> Bool {
4849
familyName.caseInsensitiveCompare("Times") == .orderedSame
4950
|| familyName.caseInsensitiveCompare("Helvetica") == .orderedSame
50-
|| familyName.caseInsensitiveCompare("Courier") == .orderedSame // macOS only
51+
|| familyName.caseInsensitiveCompare("Courier") == .orderedSame // macOS only
5152
|| familyName.caseInsensitiveCompare(".Helvetica NeueUI") == .orderedSame
5253
}

apple/InlineMac/Views/Chat/AppKit/MessageTableView.swift

+21
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class MessagesTableView: NSViewController {
8383
scroll.verticalScroller?.controlSize = .small // This makes it ultra-minimal
8484

8585
scroll.postsBoundsChangedNotifications = true
86+
scroll.automaticallyAdjustsContentInsets = false
8687

8788
return scroll
8889
}()
@@ -96,6 +97,23 @@ class MessagesTableView: NSViewController {
9697
super.viewDidLoad()
9798
setupScrollObserver()
9899
}
100+
101+
102+
// This fixes the issue with the toolbar messing up initial content insets on window open. Now we call it on did layout and it fixes the issue.
103+
private func updateScrollViewInsets() {
104+
guard let window = view.window else { return }
105+
106+
let windowFrame = window.frame
107+
let contentFrame = window.contentLayoutRect
108+
let toolbarHeight = windowFrame.height - contentFrame.height
109+
110+
scrollView.contentInsets = NSEdgeInsets(
111+
top: toolbarHeight,
112+
left: 0,
113+
bottom: 0,
114+
right: 0
115+
)
116+
}
99117

100118
private func setupViews() {
101119
view.addSubview(scrollView)
@@ -120,6 +138,8 @@ class MessagesTableView: NSViewController {
120138
private func scrollToBottom(animated: Bool) {
121139
guard messages.count > 0 else { return }
122140

141+
print("scrollTopInset \(scrollView.contentInsets.top)")
142+
123143
let lastRow = messages.count - 1
124144

125145
if animated {
@@ -363,6 +383,7 @@ class MessagesTableView: NSViewController {
363383

364384
override func viewDidLayout() {
365385
super.viewDidLayout()
386+
updateScrollViewInsets()
366387

367388
let newWidth = tableView.bounds.width
368389
// let newWidth = width

apple/InlineMac/Views/Chat/ChatView.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct ChatView: View {
3838
compose
3939
}
4040
// So the scroll bar goes under the toolbar
41+
// Note(@mo: this adds a bug on first frame toolbar doesn't have background and insets are messed up? so scroll fails initially)
4142
.ignoresSafeArea(.container, edges: .top)
4243
}
4344
.task {
@@ -60,7 +61,7 @@ struct ChatView: View {
6061
var body: some View {
6162
content
6263
// Hide default title. No way to achieve this without this for now
63-
.navigationTitle("")
64+
.navigationTitle(" ")
6465
.toolbar {
6566
ToolbarItem(placement: .navigation) {
6667
HStack {
@@ -100,6 +101,7 @@ struct ChatView: View {
100101
}
101102
}
102103
}
104+
.toolbarBackground(.visible, for: .windowToolbar)
103105
}
104106

105107
/// Fetch chat history

apple/InlineMac/Views/Main/MainView.swift

+3-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ struct MainView: View {
4040
self.setUpSidebarAutoCollapse()
4141
}
4242
.task {
43-
await requestNotifications();
43+
await requestNotifications()
4444
}
4545
// Disable auto collapse while user is modifying it to avoid jump
4646
.onChange(of: window.columnVisibility) { _ in
@@ -74,6 +74,7 @@ struct MainView: View {
7474
.navigationDestination(for: NavigationRoute.self) { route in
7575
renderSpaceRoute(for: route, spaceId: spaceId)
7676
}
77+
7778
} else {
7879
renderHomeRoute(for: navigation.homeSelection)
7980
// Note(@mo): without this .id, route would not update correctly
@@ -116,7 +117,7 @@ struct MainView: View {
116117
switch destination {
117118
case .chat(let peer):
118119
ChatView(peerId: peer)
119-
120+
120121
case .homeRoot:
121122
HomeRoot()
122123

apple/InlineMac/Views/Main/MainWindow.swift

+3-4
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ enum TopLevelRoute {
5959
case main
6060
}
6161

62-
@MainActor
6362
class MainWindowViewModel: ObservableObject {
6463
@Published var topLevelRoute: TopLevelRoute
6564
@Published var columnVisibility: NavigationSplitViewVisibility
@@ -88,9 +87,9 @@ class MainWindowViewModel: ObservableObject {
8887
let previousWindow = self.window
8988
self.window = window
9089

91-
// if previousWindow == window {
92-
// return
93-
// }
90+
if previousWindow == window {
91+
return
92+
}
9493
// if windowInitilized {
9594
// return
9695
// }

0 commit comments

Comments
 (0)