|
|
@@ -2,93 +2,25 @@ import Combine |
|
|
|
import SwiftUI |
|
|
|
|
|
|
|
final class VM: ObservableObject { |
|
|
|
/* |
|
|
|
@Published var text = "" |
|
|
|
let changeText = PassthroughSubject<String, Never>() |
|
|
|
|
|
|
|
@Published var t2 = "a:value" |
|
|
|
var bt2: Binding<String>! |
|
|
|
*/ |
|
|
|
|
|
|
|
@Published var t3 = "a:value" |
|
|
|
@Published var text = "a:" |
|
|
|
|
|
|
|
var subscriptions = Set<AnyCancellable>() |
|
|
|
|
|
|
|
init() { |
|
|
|
$t3 |
|
|
|
$text |
|
|
|
// Исключаем конфликты от UI и App путём игнорирования спама. |
|
|
|
.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main) |
|
|
|
.sink { v in |
|
|
|
/**/print("ИГР VM.init t3: '\(v)'") |
|
|
|
// Ignore repoting application initiated strings |
|
|
|
// Only report user initiated strings |
|
|
|
guard v.hasPrefix("u:") else { return } |
|
|
|
Bus.send(MeetupId.Keys.meetupIdTextUI.rawValue, String(v.dropFirst(2))) |
|
|
|
} |
|
|
|
// Нужны лишь значения от UI. |
|
|
|
.filter { $0.hasPrefix("u:") } |
|
|
|
// Убираем источник. |
|
|
|
.map { String($0.dropFirst(2)) } |
|
|
|
.sink { Bus.send(MeetupId.Keys.meetupIdTextUI.rawValue, $0) } |
|
|
|
.store(in: &subscriptions) |
|
|
|
|
|
|
|
Bus.receiveAsync( |
|
|
|
&subscriptions, |
|
|
|
[MeetupId.Keys.meetupIdTextApp.rawValue], |
|
|
|
{ [weak self] _, v in self?.applyFormattedValue(v) } |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
bt2 = Binding<String>( |
|
|
|
get: { [weak self] in |
|
|
|
String(self?.t2.dropFirst(2) ?? "") |
|
|
|
}, |
|
|
|
set: { [weak self] v in |
|
|
|
if v.hasPrefix("a:") { |
|
|
|
self?.t2 = v |
|
|
|
} else { |
|
|
|
self?.t2 = "u:\(v)" |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
|
$t2 |
|
|
|
.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main) |
|
|
|
.sink { v in |
|
|
|
/**/print("ИГР VM.init t2: '\(v)'") |
|
|
|
// Ignore repoting application initiated strings |
|
|
|
// Only report user initiated strings |
|
|
|
guard v.hasPrefix("u:") else { return } |
|
|
|
Bus.Service.singleton?.send(MeetupId.Keys.meetupIdTextUI.rawValue, String(v.dropFirst(2))) |
|
|
|
} |
|
|
|
.store(in: &subscriptions) |
|
|
|
|
|
|
|
Bus.receive( |
|
|
|
&subscriptions, |
|
|
|
[MeetupId.Keys.meetupIdTextApp.rawValue], |
|
|
|
{ [weak self] k, v in self?.handleAppValue(k, v) } |
|
|
|
{ [weak self] (_, v: String) in self?.text = "a:\(v)" } |
|
|
|
) |
|
|
|
|
|
|
|
// Интерпретируем текст с задержкой, потому что: |
|
|
|
// 1. смена @Published в ту же секунду игнорируется |
|
|
|
// полем ввода, т.е. нужна задержка |
|
|
|
// 2. ожидаем окончания ввода (спама), чтобы |
|
|
|
// обработать введённое без потерь из-за конфликта |
|
|
|
// старых данных и новых. |
|
|
|
$text |
|
|
|
.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main) |
|
|
|
.sink { [weak self] v in |
|
|
|
guard |
|
|
|
let out = MeetupId.shouldFormat(v), |
|
|
|
v != out |
|
|
|
else { |
|
|
|
return |
|
|
|
} |
|
|
|
/**/print("ИГР TFCVM.init changeT in/out: '\(v)'/'\(out)'") |
|
|
|
self?.text = out |
|
|
|
} |
|
|
|
.store(in: &subscriptions) |
|
|
|
*/ |
|
|
|
} |
|
|
|
|
|
|
|
func applyFormattedValue(_ value: String) { |
|
|
|
/**/print("ИГР VM.handleFV value: '\(value)'") |
|
|
|
t3 = "a:\(value)" |
|
|
|
} |
|
|
|
|
|
|
|
} |