Add long polling live updates.
This commit is contained in:
parent
0ceb1413ce
commit
70cf5273e9
10
src/Main.elm
10
src/Main.elm
|
@ -71,9 +71,13 @@ updateLoginResponse model r = case r of
|
||||||
Err e -> (model, Cmd.none)
|
Err e -> (model, Cmd.none)
|
||||||
|
|
||||||
updateSyncResponse : Model -> Result Http.Error SyncResponse -> (Model, Cmd Msg)
|
updateSyncResponse : Model -> Result Http.Error SyncResponse -> (Model, Cmd Msg)
|
||||||
updateSyncResponse model r = let sync = model.sync in case r of
|
updateSyncResponse model r =
|
||||||
Ok sr -> ({ model | sync = mergeSyncResponse model.sync sr }, Cmd.none)
|
let
|
||||||
_ -> (model, Cmd.none)
|
cmd = sync model.sync.nextBatch model.apiUrl <| Maybe.withDefault "" model.token
|
||||||
|
in
|
||||||
|
case r of
|
||||||
|
Ok sr -> ({ model | sync = mergeSyncResponse model.sync sr }, cmd)
|
||||||
|
_ -> (model, cmd)
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
subscriptions m = Sub.none
|
subscriptions m = Sub.none
|
||||||
|
|
|
@ -3,8 +3,8 @@ import Scylla.Model exposing (..)
|
||||||
import Scylla.Api exposing (..)
|
import Scylla.Api exposing (..)
|
||||||
import Scylla.Sync exposing (syncResponseDecoder)
|
import Scylla.Sync exposing (syncResponseDecoder)
|
||||||
import Scylla.Login exposing (loginResponseDecoder, Username, Password)
|
import Scylla.Login exposing (loginResponseDecoder, Username, Password)
|
||||||
import Json.Encode exposing (object, string)
|
import Json.Encode exposing (object, string, int)
|
||||||
import Http exposing (request, jsonBody, expectJson)
|
import Http exposing (request, emptyBody, jsonBody, expectJson)
|
||||||
|
|
||||||
fullUrl : ApiUrl -> ApiUrl
|
fullUrl : ApiUrl -> ApiUrl
|
||||||
fullUrl s = s ++ "/_matrix/client/r0"
|
fullUrl s = s ++ "/_matrix/client/r0"
|
||||||
|
@ -15,7 +15,18 @@ firstSync apiUrl token = request
|
||||||
{ method = "GET"
|
{ method = "GET"
|
||||||
, headers = authenticatedHeaders token
|
, headers = authenticatedHeaders token
|
||||||
, url = (fullUrl apiUrl) ++ "/sync"
|
, url = (fullUrl apiUrl) ++ "/sync"
|
||||||
, body = jsonBody <| object []
|
, body = emptyBody
|
||||||
|
, expect = expectJson ReceiveSyncResponse syncResponseDecoder
|
||||||
|
, timeout = Nothing
|
||||||
|
, tracker = Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
sync : String -> ApiUrl -> ApiToken -> Cmd Msg
|
||||||
|
sync nextBatch apiUrl token = request
|
||||||
|
{ method = "GET"
|
||||||
|
, headers = authenticatedHeaders token
|
||||||
|
, url = (fullUrl apiUrl) ++ "/sync" ++ "?since=" ++ (nextBatch) ++ "&timeout=10000"
|
||||||
|
, body = emptyBody
|
||||||
, expect = expectJson ReceiveSyncResponse syncResponseDecoder
|
, expect = expectJson ReceiveSyncResponse syncResponseDecoder
|
||||||
, timeout = Nothing
|
, timeout = Nothing
|
||||||
, tracker = Nothing
|
, tracker = Nothing
|
||||||
|
|
|
@ -3,6 +3,7 @@ import Scylla.Api exposing (..)
|
||||||
import Dict exposing (Dict)
|
import Dict exposing (Dict)
|
||||||
import Json.Decode as Decode exposing (Decoder, int, string, float, list, value, dict, bool, field)
|
import Json.Decode as Decode exposing (Decoder, int, string, float, list, value, dict, bool, field)
|
||||||
import Json.Decode.Pipeline exposing (required, optional)
|
import Json.Decode.Pipeline exposing (required, optional)
|
||||||
|
import Set exposing (Set)
|
||||||
|
|
||||||
-- Special Decoding
|
-- Special Decoding
|
||||||
decodeJust : Decoder a -> Decoder (Maybe a)
|
decodeJust : Decoder a -> Decoder (Maybe a)
|
||||||
|
@ -256,8 +257,95 @@ presenceDecoder =
|
||||||
|> maybeDecode "events" (list eventDecoder)
|
|> maybeDecode "events" (list eventDecoder)
|
||||||
|
|
||||||
-- Business Logic
|
-- Business Logic
|
||||||
|
uniqueByRecursive : (a -> comparable) -> List a -> Set comparable -> List a
|
||||||
|
uniqueByRecursive f l s = case l of
|
||||||
|
x::tail -> if Set.member (f x) s
|
||||||
|
then uniqueByRecursive f tail s
|
||||||
|
else x::uniqueByRecursive f tail (Set.insert (f x) s)
|
||||||
|
[] -> []
|
||||||
|
|
||||||
|
uniqueBy : (a -> comparable) -> List a -> List a
|
||||||
|
uniqueBy f l = uniqueByRecursive f l Set.empty
|
||||||
|
|
||||||
|
mergeMaybe : (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a
|
||||||
|
mergeMaybe f l r = case (l, r) of
|
||||||
|
(Just v1, Just v2) -> Just <| f v1 v2
|
||||||
|
(Just v, Nothing) -> Just v
|
||||||
|
(Nothing, Just v) -> Just v
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
|
mergeEvents : List Event -> List Event -> List Event
|
||||||
|
mergeEvents l1 l2 = l1 ++ l2
|
||||||
|
|
||||||
|
mergeStateEvents : List StateEvent -> List StateEvent -> List StateEvent
|
||||||
|
mergeStateEvents l1 l2 = l1 ++ l2
|
||||||
|
|
||||||
|
mergeRoomEvents : List RoomEvent -> List RoomEvent -> List RoomEvent
|
||||||
|
mergeRoomEvents l1 l2 = l1 ++ l2
|
||||||
|
|
||||||
|
mergeStrippedStates : List StrippedState -> List StrippedState -> List StrippedState
|
||||||
|
mergeStrippedStates l1 l2 = l1 ++ l2
|
||||||
|
|
||||||
|
mergeAccountData : AccountData -> AccountData -> AccountData
|
||||||
|
mergeAccountData a1 a2 = AccountData <| mergeMaybe mergeEvents a1.events a2.events
|
||||||
|
|
||||||
|
mergePresence : Presence -> Presence -> Presence
|
||||||
|
mergePresence p1 p2 = Presence <| mergeMaybe mergeEvents p1.events p2.events
|
||||||
|
|
||||||
|
mergeDicts : (b -> b -> b) -> Dict comparable b -> Dict comparable b -> Dict comparable b
|
||||||
|
mergeDicts f d1 d2 =
|
||||||
|
let
|
||||||
|
inOne = Dict.insert
|
||||||
|
inBoth k v1 v2 = Dict.insert k (f v1 v2)
|
||||||
|
in
|
||||||
|
Dict.merge inOne inBoth inOne d1 d2 (Dict.empty)
|
||||||
|
|
||||||
|
mergeState : State -> State -> State
|
||||||
|
mergeState s1 s2 = State <| mergeMaybe mergeStateEvents s1.events s2.events
|
||||||
|
|
||||||
|
mergeTimeline : Timeline -> Timeline -> Timeline
|
||||||
|
mergeTimeline t1 t2 = Timeline (mergeMaybe mergeRoomEvents t1.events t2.events) Nothing t2.prevBatch
|
||||||
|
|
||||||
|
mergeJoinedRoom : JoinedRoom -> JoinedRoom -> JoinedRoom
|
||||||
|
mergeJoinedRoom r1 r2 =
|
||||||
|
{ r2 | state = mergeMaybe mergeState r1.state r2.state
|
||||||
|
, timeline = mergeMaybe mergeTimeline r1.timeline r2.timeline
|
||||||
|
, accountData = mergeMaybe mergeAccountData r1.accountData r2.accountData
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeInviteState : InviteState -> InviteState -> InviteState
|
||||||
|
mergeInviteState i1 i2 = InviteState <| mergeMaybe mergeStrippedStates i1.events i2.events
|
||||||
|
|
||||||
|
mergeInvitedRoom : InvitedRoom -> InvitedRoom -> InvitedRoom
|
||||||
|
mergeInvitedRoom i1 i2 = InvitedRoom <| mergeMaybe mergeInviteState i1.inviteState i2.inviteState
|
||||||
|
|
||||||
|
mergeLeftRoom : LeftRoom -> LeftRoom -> LeftRoom
|
||||||
|
mergeLeftRoom l1 l2 = LeftRoom
|
||||||
|
(mergeMaybe mergeState l1.state l2.state)
|
||||||
|
(mergeMaybe mergeTimeline l1.timeline l2.timeline)
|
||||||
|
(mergeMaybe mergeAccountData l1.accountData l2.accountData)
|
||||||
|
|
||||||
|
mergeJoin : Dict String JoinedRoom -> Dict String JoinedRoom -> Dict String JoinedRoom
|
||||||
|
mergeJoin = mergeDicts mergeJoinedRoom
|
||||||
|
|
||||||
|
mergeInvite : Dict String InvitedRoom -> Dict String InvitedRoom -> Dict String InvitedRoom
|
||||||
|
mergeInvite = mergeDicts mergeInvitedRoom
|
||||||
|
|
||||||
|
mergeLeave : Dict String LeftRoom -> Dict String LeftRoom -> Dict String LeftRoom
|
||||||
|
mergeLeave = mergeDicts mergeLeftRoom
|
||||||
|
|
||||||
|
mergeRooms : Rooms -> Rooms -> Rooms
|
||||||
|
mergeRooms r1 r2 =
|
||||||
|
{ join = mergeMaybe mergeJoin r1.join r2.join
|
||||||
|
, invite = mergeMaybe mergeInvite r1.invite r2.invite
|
||||||
|
, leave = mergeMaybe mergeLeave r1.leave r2.leave
|
||||||
|
}
|
||||||
|
|
||||||
mergeSyncResponse : SyncResponse -> SyncResponse -> SyncResponse
|
mergeSyncResponse : SyncResponse -> SyncResponse -> SyncResponse
|
||||||
mergeSyncResponse l r = r
|
mergeSyncResponse l r =
|
||||||
|
{ r | rooms = mergeMaybe mergeRooms l.rooms r.rooms
|
||||||
|
, accountData = mergeMaybe mergeAccountData l.accountData r.accountData
|
||||||
|
}
|
||||||
|
|
||||||
roomName : JoinedRoom -> Maybe String
|
roomName : JoinedRoom -> Maybe String
|
||||||
roomName jr =
|
roomName jr =
|
||||||
|
|
Loading…
Reference in New Issue
Block a user