Skip to content

Commit 2d1e695

Browse files
Рустам ОйтовРустам Ойтов
authored andcommitted
Added new page navigation input
1 parent 92b045e commit 2d1e695

File tree

4 files changed

+56
-98
lines changed

4 files changed

+56
-98
lines changed

Modules/Sources/ForumFeature/ForumFeature.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ public struct ForumFeature: Reducer, Sendable {
6161
case subforumRedirectTapped(URL)
6262
case subforumTapped(id: Int, name: String)
6363
case announcementTapped(id: Int, name: String)
64-
case hideKeyboard
6564

6665
case contextOptionMenu(ForumOptionContextMenuAction)
6766
case contextTopicMenu(ForumTopicContextMenuAction, Int)
@@ -132,9 +131,6 @@ public struct ForumFeature: Reducer, Sendable {
132131
case .subforumRedirectTapped:
133132
return .none
134133

135-
case .hideKeyboard:
136-
return .send(.pageNavigation(.setFocus(focusState: false)))
137-
138134
case .contextOptionMenu(let action):
139135
switch action {
140136
// TODO: sort, to bookmarks

Modules/Sources/ForumFeature/ForumScreen.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ public struct ForumScreen: View {
6161
.toolbar {
6262
OptionsMenu()
6363
}
64-
.onTapGesture {
65-
store.send(.hideKeyboard)
66-
}
6764
.onAppear {
6865
store.send(.onAppear)
6966
}

Modules/Sources/PageNavigationFeature/PageNavigationFeature.swift

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ public struct PageNavigationFeature: Reducer, Sendable {
2626

2727
@ObservableState
2828
public struct State: Equatable {
29+
public enum Field: Sendable { case page }
30+
2931
@Shared(.appSettings) var appSettings: AppSettings
3032

3133
let type: PageNavigationType
32-
public var pageText: String = "1"
33-
public var textWidth: CGFloat = 30
34+
public var page: String = "1"
3435
public var count: Int = 0
3536
public var offset: Int = 0
3637
var perPage: Int
37-
public var isFocused: Bool = false
38+
public var focus: Field?
3839
public var shouldShow: Bool {
3940
return count > perPage
4041
}
@@ -73,9 +74,8 @@ public struct PageNavigationFeature: Reducer, Sendable {
7374
case nextPageTapped
7475
case lastPageTapped
7576
case doneButtonTapped
76-
case updateWidth(geometry: GeometryProxy)
77-
case updatePageText(value: String)
78-
case setFocus(focusState: Bool)
77+
case updatePage(newValue: String)
78+
case goToPage(newPage: Int)
7979

8080
case update(count: Int, offset: Int?)
8181
case offsetChanged(to: Int)
@@ -92,40 +92,37 @@ public struct PageNavigationFeature: Reducer, Sendable {
9292
return .none
9393

9494
case .doneButtonTapped:
95-
if state.pageText.isEmpty {
96-
state.offset = 0
97-
state.pageText = "1"
95+
state.focus = nil
96+
let newPage: Int
97+
if let currentPage = Int(state.page) {
98+
newPage = currentPage
9899
} else {
99-
let currentPage = Int(state.pageText) ?? 1
100-
state.offset = (currentPage - 1) * state.perPage
100+
newPage = 0
101+
state.page = "1"
101102
}
102-
103-
case .setFocus(let focusState):
104-
state.isFocused = focusState
105-
return .none
106-
107-
case .updateWidth(let geometry):
108-
let newWidth = max(30, geometry.size.width + 15)
109-
if newWidth != state.textWidth {
110-
state.textWidth = newWidth
103+
guard newPage != state.currentPage else {
104+
return .none
111105
}
112-
return .none
106+
return .send(.goToPage(newPage: newPage))
107+
108+
case .goToPage(let newPage):
109+
state.offset = (newPage - 1) * state.perPage
113110

114-
case .updatePageText(let newValue):
115-
state.pageText = newValue
111+
case .updatePage(let newValue):
112+
state.page = newValue
116113
return .none
117114

118115
case .firstPageTapped:
119116
state.offset = 0
120-
state.pageText = "1"
117+
state.page = "1"
121118

122119
case .previousPageTapped:
123120
state.offset -= state.perPage
124-
state.pageText = "\(state.currentPage)"
121+
state.page = "\(state.currentPage)"
125122

126123
case .nextPageTapped:
127124
state.offset += state.perPage
128-
state.pageText = "\(state.currentPage)"
125+
state.page = "\(state.currentPage)"
129126

130127
case .lastPageTapped:
131128
let targetOffset = state.count - (state.count % state.perPage)
@@ -134,7 +131,7 @@ public struct PageNavigationFeature: Reducer, Sendable {
134131
} else {
135132
state.offset = targetOffset
136133
}
137-
state.pageText = "\(state.currentPage)"
134+
state.page = "\(state.currentPage)"
138135

139136
case let .update(count: count, offset: offset):
140137
state.count = count

Modules/Sources/PageNavigationFeature/PageNavigationView.swift

Lines changed: 32 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ public struct PageNavigation: View {
1717
// MARK: - Properties
1818

1919
@Perception.Bindable public var store: StoreOf<PageNavigationFeature>
20-
@FocusState var isFocused: Bool
20+
@FocusState private var focus: PageNavigationFeature.State.Field?
2121

2222
// MARK: - Init
2323

2424
public init(store: StoreOf<PageNavigationFeature>) {
2525
self.store = store
26-
self.isFocused = store.isFocused
2726
}
2827

2928
// MARK: - Body
@@ -74,74 +73,43 @@ public struct PageNavigation: View {
7473
.disabled(store.currentPage + 1 > store.totalPages)
7574
}
7675
.overlay {
77-
// Button {
78-
// print("tapped page nav")
79-
// } label: {
80-
// Text(String("\(store.currentPage) / \(store.totalPages)"))
81-
// .font(.subheadline)
82-
// .foregroundStyle(Color(.Labels.secondary))
83-
// .padding(.vertical, 6)
84-
// .padding(.horizontal, 12)
85-
// .background(
86-
// RoundedRectangle(cornerRadius: 8)
87-
// .foregroundStyle(Color(.Background.teritary))
88-
// )
89-
// .contentTransition(.numericText())
90-
// }
91-
HStack {
92-
ZStack {
93-
Text("\(store.currentPage)")
94-
.font(.subheadline)
95-
.padding(.leading, 6)
96-
.background(GeometryReader { geometry in
97-
Color.clear
98-
.onAppear {
99-
store.send(.updateWidth(geometry: geometry))
100-
}
101-
.onChange(of: store.pageText) { _ in
102-
store.send(.updateWidth(geometry: geometry))
103-
}
104-
})
105-
.hidden()
106-
107-
TextField("", text: $store.pageText)
108-
.frame(width: store.textWidth, alignment: .leading)
109-
.focused($isFocused)
110-
.keyboardType(.numberPad)
111-
.multilineTextAlignment(.trailing)
112-
.animation(.easeInOut(duration: 0.2), value: store.textWidth)
113-
.onChange(of: store.pageText) { newValue in
114-
let filtered = newValue.filter { $0.isNumber }
115-
if let intValue = Int(filtered), intValue > store.totalPages {
116-
store.send(.updatePageText(value: "\(store.totalPages)"))
117-
}
118-
else {
119-
store.send(.updatePageText(value: filtered))
120-
}
121-
}
122-
.toolbar {
123-
ToolbarItemGroup(placement: .keyboard) {
124-
Spacer()
125-
126-
Button("Готово") {
127-
store.send(.setFocus(focusState: false))
128-
store.send(.doneButtonTapped)
129-
}
76+
HStack(spacing: 8) {
77+
TextField("", text: $store.page)
78+
.font(.subheadline)
79+
.fixedSize()
80+
.focused($focus, equals: PageNavigationFeature.State.Field.page)
81+
.keyboardType(.numberPad)
82+
.onChange(of: store.page) { newValue in
83+
let filtered = newValue.filter { $0.isNumber }
84+
if let intValue = Int(filtered), intValue > store.totalPages {
85+
store.send(.updatePage(newValue: "\(store.totalPages)"))
86+
} else { }
87+
}
88+
.toolbar {
89+
ToolbarItemGroup(placement: .keyboard) {
90+
Spacer()
91+
92+
Button("Готово") {
93+
store.send(.doneButtonTapped)
13094
}
13195
}
132-
}
96+
}
13397

134-
Text("/ \(store.totalPages)")
98+
Text("/")
99+
.font(.subheadline)
100+
101+
Text("\(store.totalPages)")
135102
.font(.subheadline)
136-
.padding(.trailing, 12)
137-
.onTapGesture {
138-
store.send(.setFocus(focusState: true))
139-
}
140103
}
104+
.padding(.vertical, 6)
105+
.padding(.horizontal, 12)
106+
.background(
107+
RoundedRectangle(cornerRadius: 8)
108+
.foregroundStyle(Color(.Background.teritary))
109+
)
110+
.contentTransition(.numericText())
141111
}
142-
.onChange(of: store.isFocused) { newValue in
143-
isFocused = newValue
144-
}
112+
.bind($store.focus, to: $focus)
145113
.listRowSeparator(.hidden)
146114
.animation(.default, value: store.currentPage)
147115
.frame(maxWidth: .infinity, maxHeight: 32)

0 commit comments

Comments
 (0)