d
This commit is contained in:
16
src/Cord.Button.swift
Normal file
16
src/Cord.Button.swift
Normal file
@@ -0,0 +1,16 @@
|
||||
import Combine
|
||||
|
||||
extension Cord {
|
||||
final class Button: ObservableObject {
|
||||
let press = PassthroughSubject<Void, Never>()
|
||||
var subscriptions = [AnyCancellable]()
|
||||
|
||||
init(_ key: String) {
|
||||
Bus.send(
|
||||
key,
|
||||
press.eraseToAnyPublisher(),
|
||||
sub: &subscriptions
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/Cord.ReadOnly.swift
Normal file
20
src/Cord.ReadOnly.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
import Combine
|
||||
|
||||
extension Cord {
|
||||
final class ReadOnly<T>: ObservableObject {
|
||||
@Published var value: T
|
||||
var subscriptions = [AnyCancellable]()
|
||||
|
||||
init(
|
||||
_ key: String,
|
||||
_ defaultValue: T
|
||||
) {
|
||||
value = defaultValue
|
||||
Bus.receive(
|
||||
[key],
|
||||
{ [weak self] (_, v: T) in self?.value = v },
|
||||
sub: &subscriptions
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ extension Cord {
|
||||
) {
|
||||
Bus.send(
|
||||
textUI,
|
||||
$value.compactMap(onlyUIText).eraseToAnyPublisher(),
|
||||
$value.removeDuplicates().compactMap(onlyUIText).eraseToAnyPublisher(),
|
||||
sub: &subscriptions
|
||||
)
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@ enum MeetupId {
|
||||
case meetupIdTextUI
|
||||
}
|
||||
|
||||
static func onlyAllowJoin(_ s: String) -> Bool? {
|
||||
s.hasPrefix("123")
|
||||
}
|
||||
|
||||
static func onlyFormat(_ s: String) -> String? {
|
||||
let digits = s.components(separatedBy: NSCharacterSet.decimalDigits.inverted).reduce("") { $0 + $1 }
|
||||
var r = ""
|
||||
|
||||
19
src/V.swift
19
src/V.swift
@@ -1,27 +1,32 @@
|
||||
import SwiftUI
|
||||
|
||||
struct V: View {
|
||||
@StateObject var tf = Cord.TextField("text.app", "text.ui")
|
||||
@StateObject var vm = VM()
|
||||
@StateObject var isJoinAvailable = Cord.ReadOnly("joinAvailable", false)
|
||||
@StateObject var join = Cord.Button("join")
|
||||
@StateObject var textF = Cord.TextField("text.app", "text.ui")
|
||||
let test = Bus.Processor("text.ui", "joinAvailable", MeetupId.onlyAllowJoin)
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack {
|
||||
Text("Check text field:")
|
||||
Text("'\(tf.value)'")
|
||||
Text("'\(textF.value)'")
|
||||
.fontWeight(.bold)
|
||||
}
|
||||
|
||||
TextField("Binding-3", value: $tf.value, formatter: TextFieldValueOwner())
|
||||
TextField("Binding-3", value: $textF.value, formatter: TextFieldValueOwner())
|
||||
.padding(8)
|
||||
.border(Color.blue, width: 2)
|
||||
|
||||
Button(action: vm.join.send) {
|
||||
Button(action: join.press.send) {
|
||||
Text("Join")
|
||||
.padding(8)
|
||||
.border(vm.isJoinAvailable ? Color.green : Color.red, width: 4)
|
||||
.border(
|
||||
isJoinAvailable.value ? Color.green : Color.gray,
|
||||
width: isJoinAvailable.value ? 4 : 1
|
||||
)
|
||||
}
|
||||
|
||||
.disabled(!isJoinAvailable.value)
|
||||
}
|
||||
.frame(width: 320)
|
||||
.padding()
|
||||
|
||||
@@ -10,8 +10,7 @@ final class VM: ObservableObject {
|
||||
MeetupId.onlyFormat
|
||||
)
|
||||
*/
|
||||
var isJoinAvailable = true
|
||||
let join = PassthroughSubject<Void, Never>()
|
||||
var isJoinAvailable = false
|
||||
var subscriptions = [AnyCancellable]()
|
||||
|
||||
init() {
|
||||
|
||||
Reference in New Issue
Block a user