Remove CurrentValueSubject as protocol requirement (#807)

* Add CurrentValuePublisher

* Refactor to use CurrentValuePublisher

* Add comment
This commit is contained in:
Alfonso Grillo 2023-04-18 12:52:08 +02:00 committed by GitHub
parent 44def2277f
commit 9fe69acd20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 17 deletions

View File

@ -0,0 +1,45 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Combine
/// A wrapper of CurrentValueSubject.
/// The purpose of this type is to remove the possibility to send new values on the underlying subject.
struct CurrentValuePublisher<Output, Failure: Error>: Publisher {
private let subject: CurrentValueSubject<Output, Failure>
init(_ subject: CurrentValueSubject<Output, Failure>) {
self.subject = subject
}
init(_ value: Output) {
self.init(CurrentValueSubject(value))
}
func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input {
subject.receive(subscriber: subscriber)
}
var value: Output {
subject.value
}
}
extension CurrentValueSubject {
func asCurrentValuePublisher() -> CurrentValuePublisher<Output, Failure> {
.init(self)
}
}

View File

@ -23,9 +23,9 @@ enum MockRoomSummaryProviderState {
}
class MockRoomSummaryProvider: RoomSummaryProviderProtocol {
let roomListPublisher: CurrentValueSubject<[RoomSummary], Never>
let statePublisher: CurrentValueSubject<RoomSummaryProviderState, Never>
let countPublisher: CurrentValueSubject<UInt, Never>
let roomListPublisher: CurrentValuePublisher<[RoomSummary], Never>
let statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never>
let countPublisher: CurrentValuePublisher<UInt, Never>
convenience init() {
self.init(state: .loading)

View File

@ -25,13 +25,25 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
private var cancellables = Set<AnyCancellable>()
let roomListPublisher = CurrentValueSubject<[RoomSummary], Never>([])
let statePublisher = CurrentValueSubject<RoomSummaryProviderState, Never>(.notLoaded)
let countPublisher = CurrentValueSubject<UInt, Never>(0)
private let roomListSubject = CurrentValueSubject<[RoomSummary], Never>([])
private let stateSubject = CurrentValueSubject<RoomSummaryProviderState, Never>(.notLoaded)
private let countSubject = CurrentValueSubject<UInt, Never>(0)
var roomListPublisher: CurrentValuePublisher<[RoomSummary], Never> {
roomListSubject.asCurrentValuePublisher()
}
var statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never> {
stateSubject.asCurrentValuePublisher()
}
var countPublisher: CurrentValuePublisher<UInt, Never> {
countSubject.asCurrentValuePublisher()
}
private var rooms: [RoomSummary] = [] {
didSet {
roomListPublisher.send(rooms)
roomListSubject.send(rooms)
}
}
@ -44,15 +56,15 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
buildSummaryForRoomListEntry(roomListEntry)
}
roomListPublisher.send(rooms) // didSet not called from initialisers
roomListSubject.send(rooms) // didSet not called from initialisers
slidingSyncViewProxy.statePublisher
.map(RoomSummaryProviderState.init)
.subscribe(statePublisher)
.subscribe(stateSubject)
.store(in: &cancellables)
slidingSyncViewProxy.countPublisher
.subscribe(countPublisher)
.subscribe(countSubject)
.store(in: &cancellables)
slidingSyncViewProxy.diffPublisher

View File

@ -53,13 +53,13 @@ enum RoomSummary: CustomStringConvertible {
protocol RoomSummaryProviderProtocol {
/// Publishes the currently available room summaries
var roomListPublisher: CurrentValueSubject<[RoomSummary], Never> { get }
var roomListPublisher: CurrentValuePublisher<[RoomSummary], Never> { get }
/// Publishes the current state the summary provider is finding itself in
var statePublisher: CurrentValueSubject<RoomSummaryProviderState, Never> { get }
var statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never> { get }
/// Publishes the total number of rooms
var countPublisher: CurrentValueSubject<UInt, Never> { get }
var countPublisher: CurrentValuePublisher<UInt, Never> { get }
func updateVisibleRange(_ range: Range<Int>, timelineLimit: UInt)
}

View File

@ -17,7 +17,7 @@
import Combine
struct MockRoomTimelineProvider: RoomTimelineProviderProtocol {
var itemsPublisher = CurrentValueSubject<[TimelineItemProxy], Never>([])
var itemsPublisher = CurrentValuePublisher<[TimelineItemProxy], Never>([])
private var itemProxies = [TimelineItemProxy]()
}

View File

@ -31,11 +31,15 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
private var cancellables = Set<AnyCancellable>()
private let serialDispatchQueue: DispatchQueue
let itemsPublisher = CurrentValueSubject<[TimelineItemProxy], Never>([])
private let itemsSubject = CurrentValueSubject<[TimelineItemProxy], Never>([])
var itemsPublisher: CurrentValuePublisher<[TimelineItemProxy], Never> {
itemsSubject.asCurrentValuePublisher()
}
private var itemProxies: [TimelineItemProxy] {
didSet {
itemsPublisher.send(itemProxies)
itemsSubject.send(itemProxies)
}
}

View File

@ -18,5 +18,5 @@ import Combine
import Foundation
protocol RoomTimelineProviderProtocol {
var itemsPublisher: CurrentValueSubject<[TimelineItemProxy], Never> { get }
var itemsPublisher: CurrentValuePublisher<[TimelineItemProxy], Never> { get }
}