Skip to content

Commit fcc946e

Browse files
committed
Add username validation to note editor
1 parent 9eede65 commit fcc946e

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

FurAffinity/Notes/NoteEditor.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ struct NoteEditor: View {
1919
@FocusState private var textEditorHasFocus: Bool
2020
@State private var actionInProgress: ReplyEditorAction?
2121
@State private var avatarUrl: URL?
22+
// Should not be needed but looks like
23+
// https://www.hackingwithswift.com/forums/100-days-of-swiftui/unusual-behavior-when-trying-to-change-the-style-of-the-text-in-a-swiftui-textfield/28414
24+
// is not solved…
25+
@State private var isUsernameValid = false
2226

2327
var canCancel: Bool { actionInProgress == nil }
2428
var canSubmit: Bool {
@@ -70,13 +74,17 @@ struct NoteEditor: View {
7074
TextField("static user name", text: $reply.destinationUser)
7175
.textInputAutocapitalization(.never)
7276
.autocorrectionDisabled()
73-
.foregroundStyle(.primary)
77+
.foregroundStyle(isUsernameValid ? Color.primary : Color.red)
7478
.onReceive(
7579
reply.$destinationUser
7680
.debounce(for: 1.0, scheduler: RunLoop.main)
7781
) { user in
82+
guard reply.isUsernameValid else { return }
7883
avatarUrl = FAURLs.avatarUrl(for: user)
7984
}
85+
.onChange(of: reply.isUsernameValid) { _, newValue in
86+
isUsernameValid = newValue
87+
}
8088
}
8189
.focused($destinationUserHasFocus)
8290
.foregroundStyle(.secondary)

FurAffinity/Notes/NoteReplying.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,22 @@ import SwiftUI
99
import FAKit
1010

1111
final class NoteReply: ObservableObject, ReplyStorage {
12+
static let allowedCharset = CharacterSet
13+
.lowercaseLetters
14+
.union(.decimalDigits)
15+
.union(.init(charactersIn: "^~`"))
16+
1217
var isValidForSubmission: Bool {
13-
!destinationUser.isEmpty && !subject.isEmpty && !text.isEmpty
18+
isUsernameValid && !subject.isEmpty && !text.isEmpty
19+
}
20+
21+
var isUsernameValid: Bool {
22+
guard !destinationUser.isEmpty else {
23+
return false
24+
}
25+
26+
let actualCharset = CharacterSet(charactersIn: destinationUser)
27+
return Self.allowedCharset.isSuperset(of: actualCharset)
1428
}
1529

1630
func reset() {

0 commit comments

Comments
 (0)