forked from shadowfacts/Tusker
Apply Mastodon poll limits in Compose view
This commit is contained in:
parent
32382c4783
commit
2d45fbbd91
|
@ -15,15 +15,17 @@ struct ComposeEmojiTextField: UIViewRepresentable {
|
|||
|
||||
@Binding var text: String
|
||||
let placeholder: String
|
||||
let maxLength: Int?
|
||||
let becomeFirstResponder: Binding<Bool>?
|
||||
let focusNextView: Binding<Bool>?
|
||||
private var didChange: ((String) -> Void)? = nil
|
||||
private var didEndEditing: (() -> Void)? = nil
|
||||
private var backgroundColor: UIColor? = nil
|
||||
|
||||
init(text: Binding<String>, placeholder: String, becomeFirstResponder: Binding<Bool>? = nil, focusNextView: Binding<Bool>? = nil) {
|
||||
init(text: Binding<String>, placeholder: String, maxLength: Int? = nil, becomeFirstResponder: Binding<Bool>? = nil, focusNextView: Binding<Bool>? = nil) {
|
||||
self._text = text
|
||||
self.placeholder = placeholder
|
||||
self.maxLength = maxLength
|
||||
self.becomeFirstResponder = becomeFirstResponder
|
||||
self.focusNextView = focusNextView
|
||||
self.didChange = nil
|
||||
|
@ -74,6 +76,7 @@ struct ComposeEmojiTextField: UIViewRepresentable {
|
|||
} else {
|
||||
uiView.text = text
|
||||
}
|
||||
context.coordinator.maxLength = maxLength
|
||||
context.coordinator.didChange = didChange
|
||||
context.coordinator.didEndEditing = didEndEditing
|
||||
context.coordinator.focusNextView = focusNextView
|
||||
|
@ -95,6 +98,7 @@ struct ComposeEmojiTextField: UIViewRepresentable {
|
|||
var text: Binding<String>!
|
||||
// break retained cycle through ComposeUIState.currentInput
|
||||
unowned var uiState: ComposeUIState!
|
||||
var maxLength: Int?
|
||||
var didChange: ((String) -> Void)?
|
||||
var didEndEditing: (() -> Void)?
|
||||
var focusNextView: Binding<Bool>?
|
||||
|
@ -114,6 +118,14 @@ struct ComposeEmojiTextField: UIViewRepresentable {
|
|||
focusNextView?.wrappedValue = true
|
||||
}
|
||||
|
||||
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
if let maxLength {
|
||||
return ((textField.text ?? "") as NSString).replacingCharacters(in: range, with: string).count <= maxLength
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
uiState.currentInput = self
|
||||
updateAutocompleteState(textField: textField)
|
||||
|
|
|
@ -20,6 +20,7 @@ struct ComposePollView: View {
|
|||
@ObservedObject var draft: Draft
|
||||
@ObservedObject var poll: Draft.Poll
|
||||
|
||||
@EnvironmentObject var mastodonController: MastodonController
|
||||
@Environment(\.colorScheme) var colorScheme: ColorScheme
|
||||
|
||||
@State private var duration: Duration
|
||||
|
@ -30,6 +31,14 @@ struct ComposePollView: View {
|
|||
|
||||
self._duration = State(initialValue: .fromTimeInterval(poll.duration) ?? .oneDay)
|
||||
}
|
||||
|
||||
private var canAddOption: Bool {
|
||||
if let pollConfig = mastodonController.instance?.pollsConfiguration {
|
||||
return poll.options.count < pollConfig.maxOptions
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
|
@ -67,9 +76,15 @@ struct ComposePollView: View {
|
|||
.frame(height: 44 * CGFloat(poll.options.count))
|
||||
|
||||
Button(action: self.addOption) {
|
||||
Label("Add Option", systemImage: "plus")
|
||||
Label {
|
||||
Text("Add Option")
|
||||
} icon: {
|
||||
Image(systemName: "plus")
|
||||
.foregroundColor(.accentColor)
|
||||
}
|
||||
}
|
||||
.buttonStyle(.borderless)
|
||||
.disabled(!canAddOption)
|
||||
|
||||
HStack {
|
||||
MenuPicker(selection: $poll.multiple, options: [
|
||||
|
@ -155,6 +170,8 @@ struct ComposePollOption: View {
|
|||
@ObservedObject var option: Draft.Poll.Option
|
||||
let optionIndex: Int
|
||||
|
||||
@EnvironmentObject private var mastodonController: MastodonController
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 4) {
|
||||
Checkbox(radiusFraction: poll.multiple ? 0.1 : 0.5, borderWidth: 2)
|
||||
|
@ -173,7 +190,7 @@ struct ComposePollOption: View {
|
|||
}
|
||||
|
||||
private var textField: some View {
|
||||
var field = ComposeEmojiTextField(text: $option.text, placeholder: "Option \(optionIndex + 1)")
|
||||
var field = ComposeEmojiTextField(text: $option.text, placeholder: "Option \(optionIndex + 1)", maxLength: mastodonController.instance?.pollsConfiguration?.maxCharactersPerOption)
|
||||
return field.backgroundColor(.systemBackground)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue