Last active
September 29, 2019 15:42
-
-
Save bradphelan/77f3fcb8e660783790c5610290cd8d97 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace XoaDotNet | |
open Avalonia.Controls | |
open Avalonia.Media | |
open Avalonia.FuncUI.Types | |
open Avalonia.FuncUI | |
open Avalonia.Layout | |
open FSharpx.Collections | |
open Bogus | |
[<AutoOpen>] | |
module Helpers = | |
let pvSet = PersistentVector.update | |
let pvGet = PersistentVector.nth | |
let pvAdd = PersistentVector.conj | |
type IndexedMessage<'Msg> = ( int*'Msg ) | |
module PersonModule = | |
type PersonState = { | |
name : string | |
age : int | |
} | |
let f = Faker() | |
let personGen() : PersonState = { | |
name = f.Name.FirstName() | |
age = f.Random.Number(10,99) | |
} | |
type PersonMsg = | |
| EditName of string | |
| EditAge of int | |
let update (msg:PersonMsg) (state:PersonState) : PersonState = | |
match msg with | |
| EditName name -> { state with name = name } | |
| EditAge age -> {state with age = age} | |
let updateNth (msg:PersonMsg) id state = | |
pvSet id (update msg (pvGet id state)) state | |
let view (state:PersonState) (dispatch) : View = | |
Views.uniformGrid [ | |
Attrs.columns 2 | |
Attrs.children [ | |
Views.textBox [ | |
Attrs.text state.name | |
Attrs.onKeyUp(fun sender args -> | |
dispatch (EditName (sender :?> TextBox).Text) | |
) | |
] | |
Views.textBox [ | |
Attrs.text (sprintf "%d" state.age) | |
Attrs.onKeyUp(fun sender args -> | |
dispatch (EditAge ((sender :?> TextBox).Text |> int)) | |
) | |
] | |
] | |
] | |
module PersonsModule = | |
type PersonsMsg = | |
| Update of IndexedMessage<PersonModule.PersonMsg> | |
| Delete of int | |
let update (personsMsg:PersonsMsg) state = | |
match personsMsg with | |
| Update (id, msg) -> pvSet id (PersonModule.update msg (pvGet id state)) state | |
| Delete id -> | |
state | |
|> Seq.indexed | |
|> Seq.where ( fun (_id,_)->id<>_id) | |
|> Seq.map (fun (_,p)->p) | |
|> PersistentVector.ofSeq | |
let view (state:PersonModule.PersonState PersistentVector) (dispatch) : View = | |
// Set up a dispatcher for a person at a specific id | |
let dispatchPerson id = (fun msg -> dispatch(Update(id,msg))) | |
Views.scrollViewer [ | |
Attrs.content ( | |
Views.stackPanel [ | |
Attrs.children [ | |
for (id,person) in state |> Seq.indexed do | |
yield Views.dockpanel [ | |
Attrs.children [ | |
Views.button [ | |
Attrs.content "X" | |
Attrs.onClick ( fun sender args -> dispatch (PersonsMsg.Delete id) ) | |
] | |
PersonModule.view person (dispatchPerson id) | |
] | |
] | |
] | |
] | |
) | |
] | |
module ParentView = | |
open Bogus | |
// The model holds data that you want to keep track of while the application is running | |
type ParentState = { | |
people : PersonModule.PersonState PersistentVector | |
} | |
let barConjGen state = | |
state |> PersistentVector.conj (PersonModule.personGen()) | |
//The initial state of of the application | |
let initialState = { | |
people = PersistentVector.empty | |
|> barConjGen | |
|> barConjGen | |
|> barConjGen | |
|> barConjGen | |
|> barConjGen | |
|> barConjGen | |
|> barConjGen | |
|> barConjGen | |
} | |
type ParentViewMsg = | |
| PersonsMsg of PersonsModule.PersonsMsg | |
| NewPerson | |
let update (msg: ParentViewMsg) (state: ParentState) : ParentState = | |
match msg with | |
| PersonsMsg msg -> { state with people = PersonsModule.update msg state.people } | |
| NewPerson -> { state with people = state.people |> barConjGen } | |
let view (state: ParentState) (dispatch): View = | |
Views.dockpanel[ | |
Attrs.children [ | |
Views.button [ | |
Attrs.dockPanel_dock Dock.Bottom | |
Attrs.content "new" | |
Attrs.onClick (fun sender args -> dispatch ParentViewMsg.NewPerson) | |
] | |
PersonsModule.view state.people (PersonsMsg >> dispatch) | |
] | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment