Add cookies demo
parent
cd3a16d6bd
commit
02c0a8d7f6
|
@ -0,0 +1,288 @@
|
||||||
|
module Demos.Cookie exposing (main)
|
||||||
|
|
||||||
|
import Browser
|
||||||
|
import Dict exposing (Dict)
|
||||||
|
import Html exposing (Html)
|
||||||
|
import Html.Attributes
|
||||||
|
import Html.Events
|
||||||
|
import Internal.Tools.Exceptions as X
|
||||||
|
import Json.Decode as D
|
||||||
|
import Json.Encode as E
|
||||||
|
import Matrix exposing (VaultUpdate)
|
||||||
|
import Matrix.Event
|
||||||
|
import Matrix.Room
|
||||||
|
import Task
|
||||||
|
import Time
|
||||||
|
import Url
|
||||||
|
|
||||||
|
|
||||||
|
main =
|
||||||
|
Browser.element { init = init, update = update, subscriptions = subscriptions, view = view }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- MODEL
|
||||||
|
|
||||||
|
|
||||||
|
type Msg
|
||||||
|
= Login { accessToken : String, baseUrl : String }
|
||||||
|
| SendEventToRoom String
|
||||||
|
| SyncVault
|
||||||
|
| VaultUpdate (Result X.Error Matrix.VaultUpdate)
|
||||||
|
| WriteAccessToken String
|
||||||
|
| WriteBaseUrl String
|
||||||
|
|
||||||
|
|
||||||
|
type Model
|
||||||
|
= LoginMenu { accessToken : String, baseUrl : String }
|
||||||
|
| CookieView Matrix.Vault
|
||||||
|
|
||||||
|
|
||||||
|
init : () -> ( Model, Cmd Msg )
|
||||||
|
init _ =
|
||||||
|
( LoginMenu { accessToken = "", baseUrl = "" }
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- UPDATE
|
||||||
|
|
||||||
|
|
||||||
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
|
update msg model =
|
||||||
|
case ( msg, model ) of
|
||||||
|
( Login data, _ ) ->
|
||||||
|
let
|
||||||
|
vault : Matrix.Vault
|
||||||
|
vault =
|
||||||
|
Matrix.fromAccessToken data
|
||||||
|
in
|
||||||
|
( CookieView vault, Matrix.sync vault |> Task.attempt VaultUpdate )
|
||||||
|
|
||||||
|
( VaultUpdate _, LoginMenu _ ) ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
( VaultUpdate u, CookieView vault ) ->
|
||||||
|
case u of
|
||||||
|
Ok vu ->
|
||||||
|
( vault
|
||||||
|
|> Matrix.updateWith vu
|
||||||
|
|> CookieView
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
|
Err _ ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
( SendEventToRoom _, LoginMenu _ ) ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
( SendEventToRoom roomId, CookieView vault ) ->
|
||||||
|
( model
|
||||||
|
, vault
|
||||||
|
|> Matrix.getRoomById roomId
|
||||||
|
|> Maybe.map
|
||||||
|
(Matrix.Room.sendOneEvent
|
||||||
|
{ content = E.object [ ( "body", E.string "I sent you a cookie! :)" ) ]
|
||||||
|
, eventType = "me.noordstar.demo_cookie"
|
||||||
|
, stateKey = Nothing
|
||||||
|
}
|
||||||
|
>> Task.attempt VaultUpdate
|
||||||
|
)
|
||||||
|
|> Maybe.withDefault Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
|
( SyncVault, LoginMenu _ ) ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
( SyncVault, CookieView vault ) ->
|
||||||
|
( model, Matrix.sync vault |> Task.attempt VaultUpdate )
|
||||||
|
|
||||||
|
( WriteAccessToken s, LoginMenu data ) ->
|
||||||
|
( LoginMenu { data | accessToken = s }, Cmd.none )
|
||||||
|
|
||||||
|
( WriteAccessToken _, _ ) ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
( WriteBaseUrl s, LoginMenu data ) ->
|
||||||
|
( LoginMenu { data | baseUrl = s }, Cmd.none )
|
||||||
|
|
||||||
|
( WriteBaseUrl _, _ ) ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- SUBSCRIPTIONS
|
||||||
|
|
||||||
|
|
||||||
|
subscriptions : Model -> Sub Msg
|
||||||
|
subscriptions model =
|
||||||
|
case model of
|
||||||
|
CookieView _ ->
|
||||||
|
Time.every 5000 (always SyncVault)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Sub.none
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- VIEW
|
||||||
|
|
||||||
|
|
||||||
|
cookies : List Matrix.Room.Room -> Dict String Int
|
||||||
|
cookies =
|
||||||
|
let
|
||||||
|
merge : Matrix.Room.Room -> Dict String Int -> Dict String Int
|
||||||
|
merge room d =
|
||||||
|
room
|
||||||
|
|> Matrix.Room.mostRecentEvents
|
||||||
|
|> List.filterMap
|
||||||
|
(\event ->
|
||||||
|
case Matrix.Event.contentType event of
|
||||||
|
"me.noordstar.demo_cookie" ->
|
||||||
|
Just (Matrix.Event.sender event)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Nothing
|
||||||
|
)
|
||||||
|
|> List.foldl
|
||||||
|
(\user users ->
|
||||||
|
case Dict.get user users of
|
||||||
|
Just i ->
|
||||||
|
Dict.insert user (i + 1) users
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Dict.insert user 1 users
|
||||||
|
)
|
||||||
|
d
|
||||||
|
in
|
||||||
|
List.foldl merge Dict.empty
|
||||||
|
|
||||||
|
|
||||||
|
view : Model -> Html Msg
|
||||||
|
view model =
|
||||||
|
case model of
|
||||||
|
LoginMenu ({ accessToken, baseUrl } as data) ->
|
||||||
|
[ Html.span [] [ Html.text "Homeserver URL:" ]
|
||||||
|
, Html.input
|
||||||
|
[ Html.Events.onInput WriteBaseUrl
|
||||||
|
, Html.Attributes.style "font-size" "20px"
|
||||||
|
, Html.Attributes.style "width" "80%"
|
||||||
|
]
|
||||||
|
[ Html.text baseUrl ]
|
||||||
|
, Html.span [] [ Html.text "Access token:" ]
|
||||||
|
, Html.input
|
||||||
|
[ Html.Events.onInput WriteAccessToken
|
||||||
|
, Html.Attributes.style "font-size" "20px"
|
||||||
|
, Html.Attributes.style "width" "80%"
|
||||||
|
]
|
||||||
|
[ Html.text accessToken ]
|
||||||
|
, case ( Url.fromString baseUrl, accessToken ) of
|
||||||
|
( _, "" ) ->
|
||||||
|
Html.div [ Html.Attributes.style "height" "30px" ] []
|
||||||
|
|
||||||
|
( Nothing, _ ) ->
|
||||||
|
Html.div [ Html.Attributes.style "height" "30px" ] []
|
||||||
|
|
||||||
|
( Just _, _ ) ->
|
||||||
|
Html.button
|
||||||
|
[ Html.Attributes.style "font-size" "20px"
|
||||||
|
, Html.Attributes.style "height" "30px"
|
||||||
|
, Html.Events.onClick (Login data)
|
||||||
|
]
|
||||||
|
[ Html.text "Access" ]
|
||||||
|
]
|
||||||
|
|> Html.div
|
||||||
|
[ Html.Attributes.style "display" "flex"
|
||||||
|
, Html.Attributes.style "flex-flow" "column nowrap"
|
||||||
|
, Html.Attributes.style "justify-content" "space-evenly"
|
||||||
|
, Html.Attributes.style "align-items" "center"
|
||||||
|
, Html.Attributes.style "font-size" "20px"
|
||||||
|
, Html.Attributes.style "height" "250px"
|
||||||
|
, Html.Attributes.style "background-color" "antiquewhite"
|
||||||
|
]
|
||||||
|
|
||||||
|
CookieView vault ->
|
||||||
|
case Matrix.getRooms vault of
|
||||||
|
[] ->
|
||||||
|
Html.text "Loading rooms..."
|
||||||
|
|> List.singleton
|
||||||
|
|> Html.div
|
||||||
|
[ Html.Attributes.style "display" "flex"
|
||||||
|
, Html.Attributes.style "flex-flow" "column nowrap"
|
||||||
|
, Html.Attributes.style "justify-content" "space-evenly"
|
||||||
|
, Html.Attributes.style "align-items" "center"
|
||||||
|
, Html.Attributes.style "font-size" "20px"
|
||||||
|
, Html.Attributes.style "background-color" "antiquewhite"
|
||||||
|
]
|
||||||
|
|
||||||
|
_ :: _ ->
|
||||||
|
[ vault
|
||||||
|
|> Matrix.getRooms
|
||||||
|
|> cookies
|
||||||
|
|> Debug.log "Cookies: "
|
||||||
|
|> Dict.toList
|
||||||
|
|> List.map
|
||||||
|
(\( user, amount ) ->
|
||||||
|
case amount of
|
||||||
|
0 ->
|
||||||
|
user ++ " didn't send you any cookies."
|
||||||
|
|
||||||
|
1 ->
|
||||||
|
user ++ " sent you a cookie! 🍪"
|
||||||
|
|
||||||
|
2 ->
|
||||||
|
user ++ " sent you 2 cookies! 🍪🍪"
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
user ++ " sent you " ++ String.fromInt amount ++ " cookies! 🍪🍪🍪"
|
||||||
|
)
|
||||||
|
|> List.map Html.text
|
||||||
|
|> List.map List.singleton
|
||||||
|
|> List.map (Html.p [])
|
||||||
|
|> Html.div []
|
||||||
|
, vault
|
||||||
|
|> Matrix.getRooms
|
||||||
|
|> List.map
|
||||||
|
(\room ->
|
||||||
|
let
|
||||||
|
roomName : String
|
||||||
|
roomName =
|
||||||
|
room
|
||||||
|
|> Matrix.Room.stateEvent { eventType = "m.room.name", stateKey = "" }
|
||||||
|
|> Maybe.andThen
|
||||||
|
(\event ->
|
||||||
|
case D.decodeValue (D.field "name" D.string) (Matrix.Event.content event) of
|
||||||
|
Ok title ->
|
||||||
|
Just title
|
||||||
|
|
||||||
|
Err _ ->
|
||||||
|
Nothing
|
||||||
|
)
|
||||||
|
|> Maybe.withDefault (Matrix.Room.roomId room)
|
||||||
|
in
|
||||||
|
[ Html.text roomName
|
||||||
|
, Html.text "Click here to send a cookie to everyone in this room!"
|
||||||
|
]
|
||||||
|
|> List.map List.singleton
|
||||||
|
|> List.map (Html.span [])
|
||||||
|
|> Html.span
|
||||||
|
[ Html.Events.onClick <| SendEventToRoom <| Matrix.Room.roomId room
|
||||||
|
, Html.Attributes.style "display" "flex"
|
||||||
|
, Html.Attributes.style "flex-flow" "column nowrap"
|
||||||
|
, Html.Attributes.style "justify-content" "space-evenly"
|
||||||
|
, Html.Attributes.style "margin" "20px"
|
||||||
|
, Html.Attributes.style "background-color" "beige"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|> Html.div []
|
||||||
|
]
|
||||||
|
|> Html.div
|
||||||
|
[ Html.Attributes.style "display" "flex"
|
||||||
|
, Html.Attributes.style "flex-flow" "column nowrap"
|
||||||
|
, Html.Attributes.style "justify-content" "space-evenly"
|
||||||
|
, Html.Attributes.style "align-items" "center"
|
||||||
|
, Html.Attributes.style "font-size" "20px"
|
||||||
|
, Html.Attributes.style "background-color" "antiquewhite"
|
||||||
|
]
|
File diff suppressed because one or more lines are too long
|
@ -119,6 +119,14 @@ withoutCredentials (Room { room }) =
|
||||||
room
|
room
|
||||||
|
|
||||||
|
|
||||||
|
{-| Get a given state event.
|
||||||
|
-}
|
||||||
|
getStateEvent : { eventType : String, stateKey : String } -> Room -> Maybe Event
|
||||||
|
getStateEvent data (Room { room, context }) =
|
||||||
|
Internal.getStateEvent data room
|
||||||
|
|> Maybe.map (Event.withCredentials context)
|
||||||
|
|
||||||
|
|
||||||
{-| Get older events from the Matrix API.
|
{-| Get older events from the Matrix API.
|
||||||
-}
|
-}
|
||||||
getOlderEvents : { limit : Maybe Int } -> Room -> Task X.Error VaultUpdate
|
getOlderEvents : { limit : Maybe Int } -> Room -> Task X.Error VaultUpdate
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
module Matrix.Room exposing
|
module Matrix.Room exposing
|
||||||
( Room, roomId, mostRecentEvents, findOlderEvents
|
( Room, roomId, mostRecentEvents, findOlderEvents
|
||||||
|
, stateEvent
|
||||||
, sendMessage, sendMessages, sendOneEvent, sendMultipleEvents
|
, sendMessage, sendMessages, sendOneEvent, sendMultipleEvents
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,6 +14,11 @@ A room represents a channel of communication within a Matrix home server.
|
||||||
@docs Room, roomId, mostRecentEvents, findOlderEvents
|
@docs Room, roomId, mostRecentEvents, findOlderEvents
|
||||||
|
|
||||||
|
|
||||||
|
# Exploring a room
|
||||||
|
|
||||||
|
@docs stateEvent
|
||||||
|
|
||||||
|
|
||||||
# Sending events
|
# Sending events
|
||||||
|
|
||||||
@docs sendMessage, sendMessages, sendOneEvent, sendMultipleEvents
|
@docs sendMessage, sendMessages, sendOneEvent, sendMultipleEvents
|
||||||
|
@ -49,6 +55,13 @@ mostRecentEvents =
|
||||||
Internal.mostRecentEvents
|
Internal.mostRecentEvents
|
||||||
|
|
||||||
|
|
||||||
|
{-| Get a state event in the room.
|
||||||
|
-}
|
||||||
|
stateEvent : { eventType : String, stateKey : String } -> Room -> Maybe Event.Event
|
||||||
|
stateEvent =
|
||||||
|
Internal.getStateEvent
|
||||||
|
|
||||||
|
|
||||||
{-| Get the Matrix room id of a room.
|
{-| Get the Matrix room id of a room.
|
||||||
-}
|
-}
|
||||||
roomId : Room -> String
|
roomId : Room -> String
|
||||||
|
|
Loading…
Reference in New Issue