@@ -8,6 +8,7 @@ open Android.Widget
88open FSharp.Control .Reactive
99open ImmutableCollections
1010open React
11+ open React.Android
1112open React.Android .Views
1213open System
1314open System.Reactive .Disposables
@@ -17,7 +18,7 @@ open System.Runtime.CompilerServices
1718type IListViewProps =
1819 inherit IViewGroupProps
1920
20- type ListViewProps =
21+ type ListViewProps =
2122 {
2223 // View Props
2324 accessibilityLiveRegion: int
@@ -164,93 +165,107 @@ type ListViewComponentProps = {
164165 props: IListViewProps
165166 children: IImmutableMap < int , ReactElement >
166167}
167- (*
168+
168169[<CompilationRepresentation( CompilationRepresentationFlags.ModuleSuffix) >]
169170module ListView =
170171 [<Sealed>]
171- type ReactListAdapter (createNativeView: string (* view name *) -> obj (* initialProps *) -> IReactNativeView<View>,
172- emptyViewProvider: unit -> View) =
172+ type ReactListAdapter ( children : IObservable < IImmutableMap < int , ReactDOMNode >>,
173+ createNativeView: string (* view name *) -> obj (* initialProps *) -> IReactView< View>,
174+ onError: Exception -> unit) as this =
173175 inherit BaseAdapter()
174176
175177 let updateNativeView = ReactView.updateNativeView createNativeView
176178
177- let reactViewCache = new ConditionalWeakTable<View, ReactView<View>>()
179+ let childrenSubject =
180+ new BehaviorSubject< IImmutableVector< int * ReactNativeDOMNode>>( ImmutableVector.empty ())
178181
179- let onSetDomChildren = new Subject<seq<ReactDOMNode>>()
180- let state = new BehaviorSubject<IImmutableVector<Option<ReactNativeDOMNode>>>(ImmutableVector.empty ())
182+ let childrenSubscription =
183+ childrenSubject
184+ |> Observable.iter ( ignore >> this.NotifyDataSetChanged)
185+ |> Observable.subscribeWithError ignore onError
181186
182- let stateSubscription =
183- onSetDomChildren
184- |> Observable.map (
185- Seq.map (fun dom -> ReactDom.observe dom)
186- >> Observable.combineLatestSeq
187- >> Observable.map ImmutableVector.create
187+ let children =
188+ children
189+ |> Observable.flatmap (
190+ Seq.map (
191+ fun ( key , dom ) ->
192+ ReactDom.observe dom |> Observable.map ( fun nativeDomNode -> ( key , nativeDomNode ))
188193 )
189- |> Observable.flatmap (fun obs -> obs)
190- |> Observable.subscribeObserver state
194+ >> Observable.combineLatestSeq
195+ >> Observable.map (
196+ Seq.filter ( fun ( key , node ) -> node |> Option.isSome)
197+ >> Seq.map ( fun ( key , node ) -> ( key, node |> Option.get))
198+ >> ImmutableVector.create
199+ )
200+ )
201+ |> Observable.observeOn Scheduler.mainLoopScheduler
202+ |> Observable.subscribeObserver childrenSubject
203+
204+ let reactViewCache = new ConditionalWeakTable< View, IReactView< View>>()
205+
206+ override this.Count = childrenSubject.Value.Count
191207
192- override this.Count = state.Value.Count
208+ override this.GetItem position = null
193209
194210 override this.GetItemId position =
195- state .Value.Item position |> hash |> int64
211+ childrenSubject .Value.Item position |> ( fun ( key , _ ) -> key ) |> int64
196212
197213 override this.GetView ( position : int , convertView : View , parent : ViewGroup ) =
198- let nativeDomNode = state.Value.Item position
199-
200- let reactView =
201- match (reactViewCache.TryGetValue(convertView), nativeDomNode) with
202- | ((true, reactView), Some domNode) -> reactView |> updateNativeView domNode |> Some
203- | (_ , Some domNode) -> ReactViewNone |> updateNativeView domNode |> Some
204- | _ -> None
205-
214+ let ( key , nativeDomNode ) = childrenSubject.Value.Item position
215+
216+ let reactView =
217+ match reactViewCache.TryGetValue( convertView) with
218+ | ( true , reactView) -> updateNativeView ( Some reactView) ( Some nativeDomNode)
219+ | _ -> updateNativeView None ( Some nativeDomNode)
220+
206221 match reactView with
207222 | Some reactView ->
208223 reactViewCache.Remove reactView.View |> ignore
209- reactViewCache.Add (reactView.View, ReactNativeView reactView)
224+ reactViewCache.Add ( reactView.View, reactView)
210225 reactView.View
211- | _ when convertView.Id = -8 -> convertView
212- | _ ->
213- let emptyView = emptyViewProvider ()
214- emptyView.Id <- -8
215- emptyView
226+ | _ -> failwith " Something went wrong"
216227
217228 override this.HasStableIds = true
218229
219- member this.SetDomChildren children =
220- children
221- |> ImmutableMap.values
222- |> onSetDomChildren.OnNext
223-
224230 interface IListAdapter with
225231 member this.AreAllItemsEnabled () = true
226232 member this.IsEnabled index = true
227233
234+ interface IDisposable with
235+ member this.Dispose () =
236+ childrenSubscription.Dispose ()
237+
228238 let private name = typeof< ListView>. FullName
229239
230240 let private listViewAdapterCache =
231- new ConditionalWeakTable<ListView, IImmutableMap<string, ReactView <View>>>()
241+ new ConditionalWeakTable< ListView, IImmutableMap< string, IReactView < View>>>()
232242
233243 let setProps ( onError : Exception -> unit ) ( view : View ) ( props : IListViewProps ) =
234244 let view = ( view :?> ListView)
235245 ViewGroup.setProps onError view props
236246
237247 let private createView ( context : Context ): AndroidViewCreator =
238- let viewGroupProvider () = new ListView (context) :> View
248+ let createView
249+ ( onError : Exception -> unit )
250+ ( createView : string (* view name *) -> obj (* initialProps *) -> IReactView < View >) =
251+
252+ let view = new ListView ( context)
253+ let setChildrenSubject = new Subject< IImmutableMap< int, ReactDOMNode>>()
254+
255+ let adapter = new ReactListAdapter ( setChildrenSubject, createView, onError)
256+ view.Adapter <- adapter
239257
240- let createView onError updateWith initialProps =
241- let onDispose () = ()
242- let setChildren view children =
243- Disposable.Empty
244-
245- ReactView.createView name viewGroupProvider (setProps onError) setChildren onDispose initialProps
258+ let onDispose () =
259+ setChildrenSubject.OnCompleted()
260+ ()
261+
262+ ReactView.createView name ( view :> View) ( setProps onError view) setChildrenSubject.OnNext onDispose
246263
247264 createView
248265
249266 let viewProvider = ( name, createView)
250-
251- let internal reactComponent = ReactComponent.makeLazy (fun (props: ListViewComponentProps) -> ReactNativeElement {
267+ let internal reactComponent ( props : ListViewComponentProps ) = ReactNativeElement {
252268 Name = name
253269 Props = props.props
254270 Children = props.children
255- })
256- *)
271+ }
0 commit comments