Split Sync file into sub-modules
This commit is contained in:
parent
ccfd2fe76b
commit
595e28853e
|
@ -2,6 +2,7 @@ import Browser exposing (application, UrlRequest(..))
|
|||
import Browser.Navigation as Nav
|
||||
import Browser.Dom exposing (Viewport, setViewportOf)
|
||||
import Scylla.Sync exposing (..)
|
||||
import Scylla.Sync.Events exposing (toMessageEvent, getType, getSender, getUnsigned)
|
||||
import Scylla.Messages exposing (..)
|
||||
import Scylla.Login exposing (..)
|
||||
import Scylla.Api exposing (..)
|
||||
|
@ -182,7 +183,7 @@ updateHistoryResponse m r hr =
|
|||
userDataCmd h = newUsersCmd m
|
||||
<| newUsers m
|
||||
<| uniqueBy identity
|
||||
<| List.map .sender
|
||||
<| List.map getSender
|
||||
<| h.chunk
|
||||
in
|
||||
case hr of
|
||||
|
@ -253,7 +254,7 @@ updateChangeRoute m r =
|
|||
joinedRoom = case r of
|
||||
Room rid -> Maybe.andThen (Dict.get rid) <| Maybe.andThen .join <| m.sync.rooms
|
||||
_ -> Nothing
|
||||
lastMessage = Maybe.andThen (findLastEvent (((==) "m.room.message") << .type_)) <| Maybe.andThen .events <| Maybe.andThen .timeline joinedRoom
|
||||
lastMessage = Maybe.andThen (findLastEvent (((==) "m.room.message") << .type_)) <| Maybe.map (List.filterMap toMessageEvent) <| Maybe.andThen .events <| Maybe.andThen .timeline joinedRoom
|
||||
readMarkerCmd = case (r, lastMessage) of
|
||||
(Room rid, Just re) -> setReadMarkers m.apiUrl (Maybe.withDefault "" m.token) rid re.eventId <| Just re.eventId
|
||||
_ -> Cmd.none
|
||||
|
@ -331,6 +332,7 @@ updateSyncResponse model r notify =
|
|||
roomMessages sr = case room of
|
||||
Just rid -> List.filter (((==) "m.room.message") << .type_)
|
||||
<| Maybe.withDefault []
|
||||
<| Maybe.map (List.filterMap (toMessageEvent))
|
||||
<| Maybe.andThen .events
|
||||
<| Maybe.andThen .timeline
|
||||
<| Maybe.andThen (Dict.get rid)
|
||||
|
@ -345,7 +347,7 @@ updateSyncResponse model r notify =
|
|||
(Just rid, Just re) -> setReadMarkers model.apiUrl token rid re.eventId <| Just re.eventId
|
||||
_ -> Cmd.none
|
||||
receivedEvents sr = List.map Just <| allTimelineEventIds sr
|
||||
receivedTransactions sr = List.filterMap (Maybe.andThen .transactionId << .unsigned)
|
||||
receivedTransactions sr = List.filterMap (Maybe.andThen .transactionId << getUnsigned)
|
||||
<| allTimelineEvents sr
|
||||
sending sr = Dict.filter (\tid (rid, { body, id }) -> not <| List.member (String.fromInt tid) <| receivedTransactions sr) model.sending
|
||||
newSync sr = mergeSyncResponse model.sync sr
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
module Scylla.AccountData exposing (..)
|
||||
import Scylla.Sync exposing (SyncResponse, AccountData, JoinedRoom, roomAccountData)
|
||||
import Scylla.Sync exposing (SyncResponse, roomAccountData)
|
||||
import Scylla.Sync.AccountData exposing (AccountData)
|
||||
import Scylla.Sync.Rooms exposing (JoinedRoom)
|
||||
import Json.Decode as Decode
|
||||
import Json.Encode as Encode
|
||||
import Dict exposing (Dict)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module Scylla.Messages exposing (..)
|
||||
import Scylla.Sync exposing (RoomEvent)
|
||||
import Scylla.Sync.Events exposing (RoomEvent, MessageEvent, toMessageEvent)
|
||||
import Scylla.Login exposing (Username)
|
||||
import Scylla.Route exposing (RoomId)
|
||||
import Dict exposing (Dict)
|
||||
|
@ -13,7 +13,7 @@ type alias SendingMessage =
|
|||
|
||||
type Message
|
||||
= Sending SendingMessage
|
||||
| Received RoomEvent
|
||||
| Received MessageEvent
|
||||
|
||||
messageUsername : Username -> Message -> Username
|
||||
messageUsername u msg = case msg of
|
||||
|
@ -38,7 +38,8 @@ mergeMessages du xs =
|
|||
|
||||
receivedMessagesRoom : List RoomEvent -> List Message
|
||||
receivedMessagesRoom es = List.map Received
|
||||
<| List.filter (\e -> e.type_ == "m.room.message") es
|
||||
<| List.filter (\e -> e.type_ == "m.room.message")
|
||||
<| List.filterMap toMessageEvent es
|
||||
|
||||
sendingMessagesRoom : RoomId -> Dict Int (RoomId, SendingMessage) -> List Message
|
||||
sendingMessagesRoom rid ms = List.map (\(tid, (_, sm)) -> Sending sm)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
module Scylla.Model exposing (..)
|
||||
import Scylla.Api exposing (..)
|
||||
import Scylla.Sync exposing (SyncResponse, HistoryResponse, JoinedRoom, senderName, roomName, roomJoinedUsers, findFirst, AccountData)
|
||||
import Scylla.Sync exposing (SyncResponse, HistoryResponse, senderName, roomName, roomJoinedUsers, findFirst)
|
||||
import Scylla.Sync.Rooms exposing (JoinedRoom)
|
||||
import Scylla.Sync.AccountData exposing (AccountData)
|
||||
import Scylla.AccountData exposing (directMessagesDecoder)
|
||||
import Scylla.Login exposing (LoginResponse, Username, Password)
|
||||
import Scylla.UserData exposing (UserData)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
port module Scylla.Notification exposing (..)
|
||||
import Scylla.Sync exposing (SyncResponse, RoomEvent, joinedRoomsTimelineEvents)
|
||||
import Scylla.Sync exposing (SyncResponse, joinedRoomsTimelineEvents)
|
||||
import Scylla.Sync.Events exposing (RoomEvent, MessageEvent, toMessageEvent)
|
||||
import Scylla.AccountData exposing (..)
|
||||
import Json.Decode as Decode exposing (string, field)
|
||||
import Dict
|
||||
|
@ -13,17 +14,18 @@ type alias Notification =
|
|||
port sendNotificationPort : Notification -> Cmd msg
|
||||
port onNotificationClickPort : (String -> msg) -> Sub msg
|
||||
|
||||
notificationText : RoomEvent -> String
|
||||
notificationText : MessageEvent -> String
|
||||
notificationText re = case (Decode.decodeValue (field "msgtype" string) re.content) of
|
||||
Ok "m.text" -> Result.withDefault "" <| (Decode.decodeValue (field "body" string) re.content)
|
||||
_ -> ""
|
||||
|
||||
joinedRoomNotificationEvents : SyncResponse -> List (String, RoomEvent)
|
||||
joinedRoomNotificationEvents : SyncResponse -> List (String, MessageEvent)
|
||||
joinedRoomNotificationEvents s =
|
||||
let
|
||||
applyPair k = List.map (\v -> (k, v))
|
||||
in
|
||||
List.sortBy (\(k, v) -> v.originServerTs)
|
||||
<| List.filterMap (\(k, e) -> Maybe.map (\me -> (k, me)) <| toMessageEvent e)
|
||||
<| Dict.foldl (\k v a -> a ++ applyPair k v) []
|
||||
<| joinedRoomsTimelineEvents s
|
||||
|
||||
|
|
|
@ -2,223 +2,15 @@ module Scylla.Sync exposing (..)
|
|||
import Scylla.Api exposing (..)
|
||||
import Scylla.Login exposing (Username)
|
||||
import Scylla.Route exposing (RoomId)
|
||||
import Scylla.Sync.DecodeTools exposing (maybeDecode)
|
||||
import Scylla.Sync.Events exposing (..)
|
||||
import Scylla.Sync.Rooms exposing (..)
|
||||
import Scylla.Sync.AccountData exposing (..)
|
||||
import Dict exposing (Dict)
|
||||
import Json.Decode as Decode exposing (Decoder, int, string, float, list, value, dict, bool, field)
|
||||
import Json.Decode.Pipeline exposing (required, optional)
|
||||
import Set exposing (Set)
|
||||
|
||||
-- Special Decoding
|
||||
decodeJust : Decoder a -> Decoder (Maybe a)
|
||||
decodeJust = Decode.map Just
|
||||
|
||||
maybeDecode : String -> Decoder a -> Decoder (Maybe a -> b) -> Decoder b
|
||||
maybeDecode s d = optional s (decodeJust d) Nothing
|
||||
|
||||
-- General Events
|
||||
type alias Event =
|
||||
{ content : Decode.Value
|
||||
, type_ : String
|
||||
}
|
||||
|
||||
eventDecoder : Decoder Event
|
||||
eventDecoder =
|
||||
Decode.succeed Event
|
||||
|> required "content" value
|
||||
|> required "type" string
|
||||
|
||||
type alias EventContent = Decode.Value
|
||||
|
||||
eventContentDecoder : Decoder EventContent
|
||||
eventContentDecoder = Decode.value
|
||||
|
||||
-- Unsigned Data
|
||||
type alias UnsignedData =
|
||||
{ age : Maybe Int
|
||||
, redactedBecause : Maybe Event
|
||||
, transactionId : Maybe String
|
||||
}
|
||||
|
||||
unsignedDataDecoder : Decoder UnsignedData
|
||||
unsignedDataDecoder =
|
||||
Decode.succeed UnsignedData
|
||||
|> maybeDecode "age" int
|
||||
|> maybeDecode "redacted_because" eventDecoder
|
||||
|> maybeDecode "transaction_id" string
|
||||
|
||||
-- State
|
||||
type alias State =
|
||||
{ events : Maybe (List StateEvent)
|
||||
}
|
||||
|
||||
stateDecoder : Decoder State
|
||||
stateDecoder =
|
||||
Decode.succeed State
|
||||
|> maybeDecode "events" (list stateEventDecoder)
|
||||
|
||||
type alias StateEvent =
|
||||
{ content : Decode.Value
|
||||
, type_ : String
|
||||
, eventId : String
|
||||
, sender : String
|
||||
, originServerTs : Int
|
||||
, unsigned : Maybe UnsignedData
|
||||
, prevContent : Maybe EventContent
|
||||
, stateKey : String
|
||||
}
|
||||
|
||||
stateEventDecoder : Decoder StateEvent
|
||||
stateEventDecoder =
|
||||
Decode.succeed StateEvent
|
||||
|> required "content" value
|
||||
|> required "type" string
|
||||
|> required "event_id" string
|
||||
|> required "sender" string
|
||||
|> required "origin_server_ts" int
|
||||
|> maybeDecode "unsigned" unsignedDataDecoder
|
||||
|> maybeDecode "prev_content" eventContentDecoder
|
||||
|> required "state_key" string
|
||||
|
||||
-- Rooms
|
||||
type alias Rooms =
|
||||
{ join : Maybe (Dict String JoinedRoom)
|
||||
, invite : Maybe (Dict String InvitedRoom)
|
||||
, leave : Maybe (Dict String LeftRoom)
|
||||
}
|
||||
|
||||
roomsDecoder : Decoder Rooms
|
||||
roomsDecoder =
|
||||
Decode.succeed Rooms
|
||||
|> maybeDecode "join" (dict joinedRoomDecoder)
|
||||
|> maybeDecode "invite" (dict invitedRoomDecoder)
|
||||
|> maybeDecode "leave" (dict leftRoomDecoder)
|
||||
|
||||
type alias JoinedRoom =
|
||||
{ state : Maybe State
|
||||
, timeline : Maybe Timeline
|
||||
, ephemeral : Maybe Ephemeral
|
||||
, accountData : Maybe AccountData
|
||||
, unreadNotifications : Maybe UnreadNotificationCounts
|
||||
}
|
||||
|
||||
joinedRoomDecoder : Decoder JoinedRoom
|
||||
joinedRoomDecoder =
|
||||
Decode.succeed JoinedRoom
|
||||
|> maybeDecode "state" stateDecoder
|
||||
|> maybeDecode "timeline" timelineDecoder
|
||||
|> maybeDecode "ephemeral" ephemeralDecoder
|
||||
|> maybeDecode "account_data" accountDataDecoder
|
||||
|> maybeDecode "unread_notifications" unreadNotificationCountsDecoder
|
||||
|
||||
|
||||
-- Joined Room Data
|
||||
type alias Timeline =
|
||||
{ events : Maybe (List RoomEvent)
|
||||
, limited : Maybe Bool
|
||||
, prevBatch : Maybe String
|
||||
}
|
||||
|
||||
timelineDecoder =
|
||||
Decode.succeed Timeline
|
||||
|> maybeDecode "events" (list roomEventDecoder)
|
||||
|> maybeDecode "limited" bool
|
||||
|> maybeDecode "prev_batch" string
|
||||
|
||||
type alias RoomEvent =
|
||||
{ content : Decode.Value
|
||||
, type_ : String
|
||||
, eventId : String
|
||||
, sender : String
|
||||
, originServerTs : Int
|
||||
, unsigned : Maybe UnsignedData
|
||||
}
|
||||
|
||||
roomEventDecoder : Decoder RoomEvent
|
||||
roomEventDecoder =
|
||||
Decode.succeed RoomEvent
|
||||
|> required "content" value
|
||||
|> required "type" string
|
||||
|> required "event_id" string
|
||||
|> required "sender" string
|
||||
|> required "origin_server_ts" int
|
||||
|> maybeDecode "unsigned" unsignedDataDecoder
|
||||
|
||||
type alias Ephemeral =
|
||||
{ events : Maybe (List Event)
|
||||
}
|
||||
|
||||
ephemeralDecoder : Decoder Ephemeral
|
||||
ephemeralDecoder =
|
||||
Decode.succeed Ephemeral
|
||||
|> maybeDecode "events" (list eventDecoder)
|
||||
|
||||
type alias AccountData =
|
||||
{ events : Maybe (List Event)
|
||||
}
|
||||
|
||||
accountDataDecoder : Decoder AccountData
|
||||
accountDataDecoder =
|
||||
Decode.succeed AccountData
|
||||
|> maybeDecode "events" (list eventDecoder)
|
||||
|
||||
type alias UnreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
unreadNotificationCountsDecoder : Decoder UnreadNotificationCounts
|
||||
unreadNotificationCountsDecoder =
|
||||
Decode.succeed UnreadNotificationCounts
|
||||
|> maybeDecode "highlight_count" int
|
||||
|> maybeDecode "notification_count" int
|
||||
|
||||
-- Invited Room Data
|
||||
type alias InvitedRoom =
|
||||
{ inviteState : Maybe InviteState
|
||||
}
|
||||
|
||||
invitedRoomDecoder : Decoder InvitedRoom
|
||||
invitedRoomDecoder =
|
||||
Decode.succeed InvitedRoom
|
||||
|> maybeDecode "invite_state" inviteStateDecoder
|
||||
|
||||
type alias InviteState =
|
||||
{ events : Maybe (List StrippedState)
|
||||
}
|
||||
|
||||
inviteStateDecoder : Decoder InviteState
|
||||
inviteStateDecoder =
|
||||
Decode.succeed InviteState
|
||||
|> maybeDecode "events" (list strippedStateDecoder)
|
||||
|
||||
type alias StrippedState =
|
||||
{ content : EventContent
|
||||
, stateKey : String
|
||||
, type_ : String
|
||||
, sender : String
|
||||
}
|
||||
|
||||
strippedStateDecoder : Decoder StrippedState
|
||||
strippedStateDecoder =
|
||||
Decode.succeed StrippedState
|
||||
|> required "content" eventContentDecoder
|
||||
|> required "state_key" string
|
||||
|> required "type" string
|
||||
|> required "sender" string
|
||||
|
||||
-- Left Room Data
|
||||
type alias LeftRoom =
|
||||
{ state : Maybe State
|
||||
, timeline : Maybe Timeline
|
||||
, accountData : Maybe AccountData
|
||||
}
|
||||
|
||||
leftRoomDecoder : Decoder LeftRoom
|
||||
leftRoomDecoder =
|
||||
Decode.succeed LeftRoom
|
||||
|> maybeDecode "state" stateDecoder
|
||||
|> maybeDecode "timeline" timelineDecoder
|
||||
|> maybeDecode "account_data" accountDataDecoder
|
||||
|
||||
-- General Sync Response
|
||||
type alias SyncResponse =
|
||||
{ nextBatch : String
|
||||
|
@ -315,9 +107,9 @@ mergeStateEvents : List StateEvent -> List StateEvent -> List StateEvent
|
|||
mergeStateEvents l1 l2 = uniqueBy .eventId <| l1 ++ l2
|
||||
|
||||
mergeRoomEvents : List RoomEvent -> List RoomEvent -> List RoomEvent
|
||||
mergeRoomEvents l1 l2 = uniqueBy .eventId <| l1 ++ l2
|
||||
mergeRoomEvents l1 l2 = uniqueBy getEventId <| l1 ++ l2
|
||||
|
||||
mergeStrippedStates : List StrippedState -> List StrippedState -> List StrippedState
|
||||
mergeStrippedStates : List StrippedStateEvent -> List StrippedStateEvent -> List StrippedStateEvent
|
||||
mergeStrippedStates l1 l2 = l1 ++ l2
|
||||
|
||||
mergeAccountData : AccountData -> AccountData -> AccountData
|
||||
|
@ -445,17 +237,7 @@ allRoomStateEvents jr =
|
|||
let
|
||||
stateEvents = Maybe.withDefault [] <| Maybe.andThen .events jr.state
|
||||
timelineEvents = Maybe.withDefault [] <| Maybe.andThen .events jr.timeline
|
||||
roomToStateEvent re =
|
||||
{ content = re.content
|
||||
, type_ = re.type_
|
||||
, eventId = re.eventId
|
||||
, sender = re.sender
|
||||
, originServerTs = re.originServerTs
|
||||
, unsigned = re.unsigned
|
||||
, prevContent = Nothing
|
||||
, stateKey = ""
|
||||
}
|
||||
allStateEvents = uniqueBy .eventId (stateEvents ++ (List.map roomToStateEvent timelineEvents))
|
||||
allStateEvents = uniqueBy .eventId (stateEvents ++ (List.filterMap toStateEvent timelineEvents))
|
||||
in
|
||||
allStateEvents
|
||||
|
||||
|
@ -465,7 +247,7 @@ allRoomDictTimelineEvents dict = List.concatMap (Maybe.withDefault [] << .events
|
|||
<| Dict.values dict
|
||||
|
||||
allTimelineEventIds : SyncResponse -> List String
|
||||
allTimelineEventIds s = List.map .eventId <| allTimelineEvents s
|
||||
allTimelineEventIds s = List.map getEventId <| allTimelineEvents s
|
||||
|
||||
allTimelineEvents : SyncResponse -> List RoomEvent
|
||||
allTimelineEvents s =
|
||||
|
@ -476,7 +258,7 @@ allTimelineEvents s =
|
|||
joinedEvents = eventsFor .join
|
||||
leftEvents = eventsFor .leave
|
||||
in
|
||||
uniqueBy .eventId <| leftEvents ++ joinedEvents
|
||||
leftEvents ++ joinedEvents
|
||||
|
||||
joinedRoomsTimelineEvents : SyncResponse -> Dict String (List RoomEvent)
|
||||
joinedRoomsTimelineEvents s =
|
||||
|
@ -534,7 +316,7 @@ roomTypingUsers jr = Maybe.withDefault []
|
|||
|
||||
-- Business Logic: Users
|
||||
allUsers : SyncResponse -> List Username
|
||||
allUsers s = uniqueBy (\u -> u) <| List.map .sender <| allTimelineEvents s
|
||||
allUsers s = uniqueBy (\u -> u) <| List.map getSender <| allTimelineEvents s
|
||||
|
||||
roomJoinedUsers : JoinedRoom -> List Username
|
||||
roomJoinedUsers r =
|
||||
|
|
14
src/Scylla/Sync/AccountData.elm
Normal file
14
src/Scylla/Sync/AccountData.elm
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Scylla.Sync.AccountData exposing (..)
|
||||
import Scylla.Sync.DecodeTools exposing (maybeDecode)
|
||||
import Scylla.Sync.Events exposing (Event, eventDecoder)
|
||||
import Json.Decode as Decode exposing (Decoder, list)
|
||||
|
||||
type alias AccountData =
|
||||
{ events : Maybe (List Event)
|
||||
}
|
||||
|
||||
accountDataDecoder : Decoder AccountData
|
||||
accountDataDecoder =
|
||||
Decode.succeed AccountData
|
||||
|> maybeDecode "events" (list eventDecoder)
|
||||
|
9
src/Scylla/Sync/DecodeTools.elm
Normal file
9
src/Scylla/Sync/DecodeTools.elm
Normal file
|
@ -0,0 +1,9 @@
|
|||
module Scylla.Sync.DecodeTools exposing (..)
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
import Json.Decode.Pipeline exposing (optional)
|
||||
|
||||
decodeJust : Decoder a -> Decoder (Maybe a)
|
||||
decodeJust = Decode.map Just
|
||||
|
||||
maybeDecode : String -> Decoder a -> Decoder (Maybe a -> b) -> Decoder b
|
||||
maybeDecode s d = optional s (decodeJust d) Nothing
|
143
src/Scylla/Sync/Events.elm
Normal file
143
src/Scylla/Sync/Events.elm
Normal file
|
@ -0,0 +1,143 @@
|
|||
module Scylla.Sync.Events exposing (..)
|
||||
import Scylla.Sync.DecodeTools exposing (maybeDecode)
|
||||
import Json.Decode as Decode exposing (Decoder, int, string, value, oneOf)
|
||||
import Json.Decode.Pipeline exposing (required)
|
||||
|
||||
type alias UnsignedData =
|
||||
{ age : Maybe Int
|
||||
, redactedBecause : Maybe Event
|
||||
, transactionId : Maybe String
|
||||
}
|
||||
|
||||
unsignedDataDecoder : Decoder UnsignedData
|
||||
unsignedDataDecoder =
|
||||
Decode.succeed UnsignedData
|
||||
|> maybeDecode "age" int
|
||||
|> maybeDecode "redacted_because" eventDecoder
|
||||
|> maybeDecode "transaction_id" string
|
||||
|
||||
type alias EventContent = Decode.Value
|
||||
|
||||
eventContentDecoder : Decoder EventContent
|
||||
eventContentDecoder = Decode.value
|
||||
|
||||
type alias Event =
|
||||
{ content : Decode.Value
|
||||
, type_ : String
|
||||
}
|
||||
|
||||
eventDecoder : Decoder Event
|
||||
eventDecoder =
|
||||
Decode.succeed Event
|
||||
|> required "content" value
|
||||
|> required "type" string
|
||||
|
||||
type RoomEvent
|
||||
= StateRoomEvent StateEvent
|
||||
| MessageRoomEvent MessageEvent
|
||||
|
||||
roomEventDecoder : Decoder RoomEvent
|
||||
roomEventDecoder = oneOf
|
||||
[ Decode.map MessageRoomEvent messageEventDecoder
|
||||
, Decode.map StateRoomEvent stateEventDecoder
|
||||
]
|
||||
|
||||
type alias MessageEvent =
|
||||
{ content : EventContent
|
||||
, type_ : String
|
||||
, eventId : String
|
||||
, sender : String
|
||||
, originServerTs : Int
|
||||
, unsigned : Maybe UnsignedData
|
||||
}
|
||||
|
||||
messageEventDecoder : Decoder MessageEvent
|
||||
messageEventDecoder =
|
||||
Decode.succeed MessageEvent
|
||||
|> required "content" value
|
||||
|> required "type" string
|
||||
|> required "event_id" string
|
||||
|> required "sender" string
|
||||
|> required "origin_server_ts" int
|
||||
|> maybeDecode "unsigned" unsignedDataDecoder
|
||||
|
||||
type alias StateEvent =
|
||||
{ content : EventContent
|
||||
, type_ : String
|
||||
, eventId : String
|
||||
, sender : String
|
||||
, originServerTs : Int
|
||||
, unsigned : Maybe UnsignedData
|
||||
, prevContent : Maybe EventContent
|
||||
, stateKey : String
|
||||
}
|
||||
|
||||
stateEventDecoder : Decoder StateEvent
|
||||
stateEventDecoder =
|
||||
Decode.succeed StateEvent
|
||||
|> required "content" value
|
||||
|> required "type" string
|
||||
|> required "event_id" string
|
||||
|> required "sender" string
|
||||
|> required "origin_server_ts" int
|
||||
|> maybeDecode "unsigned" unsignedDataDecoder
|
||||
|> maybeDecode "prev_content" eventContentDecoder
|
||||
|> required "state_key" string
|
||||
|
||||
type alias StrippedStateEvent =
|
||||
{ content : EventContent
|
||||
, stateKey : String
|
||||
, type_ : String
|
||||
, sender : String
|
||||
}
|
||||
|
||||
strippedStateEventDecoder : Decoder StrippedStateEvent
|
||||
strippedStateEventDecoder =
|
||||
Decode.succeed StrippedStateEvent
|
||||
|> required "content" eventContentDecoder
|
||||
|> required "state_key" string
|
||||
|> required "type" string
|
||||
|> required "sender" string
|
||||
|
||||
-- Operations on Room Events
|
||||
getUnsigned : RoomEvent -> Maybe UnsignedData
|
||||
getUnsigned re =
|
||||
case re of
|
||||
StateRoomEvent e -> e.unsigned
|
||||
MessageRoomEvent e -> e.unsigned
|
||||
|
||||
getEventId : RoomEvent -> String
|
||||
getEventId re =
|
||||
case re of
|
||||
StateRoomEvent e -> e.eventId
|
||||
MessageRoomEvent e -> e.eventId
|
||||
|
||||
getSender : RoomEvent -> String
|
||||
getSender re =
|
||||
case re of
|
||||
StateRoomEvent e -> e.sender
|
||||
MessageRoomEvent e -> e.sender
|
||||
|
||||
getType : RoomEvent -> String
|
||||
getType re =
|
||||
case re of
|
||||
StateRoomEvent e -> e.type_
|
||||
MessageRoomEvent e -> e.type_
|
||||
|
||||
toStateEvent : RoomEvent -> Maybe StateEvent
|
||||
toStateEvent re =
|
||||
case re of
|
||||
StateRoomEvent e -> Just e
|
||||
_ -> Nothing
|
||||
|
||||
toMessageEvent : RoomEvent -> Maybe MessageEvent
|
||||
toMessageEvent re =
|
||||
case re of
|
||||
MessageRoomEvent e -> Just e
|
||||
_ -> Nothing
|
||||
|
||||
toEvent : RoomEvent -> Event
|
||||
toEvent re =
|
||||
case re of
|
||||
StateRoomEvent e -> { content = e.content, type_ = e.type_ }
|
||||
MessageRoomEvent e -> { content = e.content, type_ = e.type_ }
|
109
src/Scylla/Sync/Rooms.elm
Normal file
109
src/Scylla/Sync/Rooms.elm
Normal file
|
@ -0,0 +1,109 @@
|
|||
module Scylla.Sync.Rooms exposing (..)
|
||||
import Scylla.Sync.DecodeTools exposing (maybeDecode)
|
||||
import Scylla.Sync.Events exposing (Event, RoomEvent, StateEvent, StrippedStateEvent, stateEventDecoder, strippedStateEventDecoder, roomEventDecoder, eventDecoder)
|
||||
import Scylla.Sync.AccountData exposing (AccountData, accountDataDecoder)
|
||||
import Json.Decode as Decode exposing (Decoder, int, string, dict, list, bool)
|
||||
import Json.Decode.Pipeline exposing (required)
|
||||
import Dict exposing (Dict)
|
||||
|
||||
type alias Rooms =
|
||||
{ join : Maybe (Dict String JoinedRoom)
|
||||
, invite : Maybe (Dict String InvitedRoom)
|
||||
, leave : Maybe (Dict String LeftRoom)
|
||||
}
|
||||
|
||||
roomsDecoder : Decoder Rooms
|
||||
roomsDecoder =
|
||||
Decode.succeed Rooms
|
||||
|> maybeDecode "join" (dict joinedRoomDecoder)
|
||||
|> maybeDecode "invite" (dict invitedRoomDecoder)
|
||||
|> maybeDecode "leave" (dict leftRoomDecoder)
|
||||
|
||||
type alias JoinedRoom =
|
||||
{ state : Maybe State
|
||||
, timeline : Maybe Timeline
|
||||
, ephemeral : Maybe Ephemeral
|
||||
, accountData : Maybe AccountData
|
||||
, unreadNotifications : Maybe UnreadNotificationCounts
|
||||
}
|
||||
|
||||
joinedRoomDecoder : Decoder JoinedRoom
|
||||
joinedRoomDecoder =
|
||||
Decode.succeed JoinedRoom
|
||||
|> maybeDecode "state" stateDecoder
|
||||
|> maybeDecode "timeline" timelineDecoder
|
||||
|> maybeDecode "ephemeral" ephemeralDecoder
|
||||
|> maybeDecode "account_data" accountDataDecoder
|
||||
|> maybeDecode "unread_notifications" unreadNotificationCountsDecoder
|
||||
|
||||
type alias InvitedRoom =
|
||||
{ inviteState : Maybe InviteState
|
||||
}
|
||||
|
||||
invitedRoomDecoder : Decoder InvitedRoom
|
||||
invitedRoomDecoder =
|
||||
Decode.succeed InvitedRoom
|
||||
|> maybeDecode "invite_state" inviteStateDecoder
|
||||
|
||||
type alias LeftRoom =
|
||||
{ state : Maybe State
|
||||
, timeline : Maybe Timeline
|
||||
, accountData : Maybe AccountData
|
||||
}
|
||||
|
||||
leftRoomDecoder : Decoder LeftRoom
|
||||
leftRoomDecoder =
|
||||
Decode.succeed LeftRoom
|
||||
|> maybeDecode "state" stateDecoder
|
||||
|> maybeDecode "timeline" timelineDecoder
|
||||
|> maybeDecode "account_data" accountDataDecoder
|
||||
|
||||
type alias State =
|
||||
{ events : Maybe (List StateEvent)
|
||||
}
|
||||
|
||||
stateDecoder : Decoder State
|
||||
stateDecoder =
|
||||
Decode.succeed State
|
||||
|> maybeDecode "events" (list stateEventDecoder)
|
||||
|
||||
type alias InviteState =
|
||||
{ events : Maybe (List StrippedStateEvent)
|
||||
}
|
||||
|
||||
inviteStateDecoder : Decoder InviteState
|
||||
inviteStateDecoder =
|
||||
Decode.succeed InviteState
|
||||
|> maybeDecode "events" (list strippedStateEventDecoder)
|
||||
|
||||
type alias Timeline =
|
||||
{ events : Maybe (List RoomEvent)
|
||||
, limited : Maybe Bool
|
||||
, prevBatch : Maybe String
|
||||
}
|
||||
|
||||
timelineDecoder =
|
||||
Decode.succeed Timeline
|
||||
|> maybeDecode "events" (list roomEventDecoder)
|
||||
|> maybeDecode "limited" bool
|
||||
|> maybeDecode "prev_batch" string
|
||||
|
||||
type alias Ephemeral =
|
||||
{ events : Maybe (List Event)
|
||||
}
|
||||
|
||||
ephemeralDecoder : Decoder Ephemeral
|
||||
ephemeralDecoder =
|
||||
Decode.succeed Ephemeral
|
||||
|> maybeDecode "events" (list eventDecoder)
|
||||
|
||||
type alias UnreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
unreadNotificationCountsDecoder : Decoder UnreadNotificationCounts
|
||||
unreadNotificationCountsDecoder =
|
||||
Decode.succeed UnreadNotificationCounts
|
||||
|> maybeDecode "highlight_count" int
|
||||
|> maybeDecode "notification_count" int
|
|
@ -1,6 +1,8 @@
|
|||
module Scylla.Views exposing (..)
|
||||
import Scylla.Model exposing (..)
|
||||
import Scylla.Sync exposing (..)
|
||||
import Scylla.Sync.Events exposing (..)
|
||||
import Scylla.Sync.Rooms exposing (..)
|
||||
import Scylla.Route exposing (..)
|
||||
import Scylla.Fnv as Fnv
|
||||
import Scylla.Messages exposing (..)
|
||||
|
@ -250,7 +252,7 @@ sendingMessageView : SendingMessage -> Html Msg
|
|||
sendingMessageView msg = case msg.body of
|
||||
TextMessage t -> span [ class "sending"] [ text t ]
|
||||
|
||||
roomEventView : Dict String UserData -> ApiUrl -> RoomEvent -> Maybe (Html Msg)
|
||||
roomEventView : Dict String UserData -> ApiUrl -> MessageEvent -> Maybe (Html Msg)
|
||||
roomEventView ud apiUrl re =
|
||||
let
|
||||
msgtype = Decode.decodeValue (Decode.field "msgtype" Decode.string) re.content
|
||||
|
@ -264,13 +266,13 @@ roomEventView ud apiUrl re =
|
|||
Ok "m.video" -> roomEventVideoView apiUrl re
|
||||
_ -> Nothing
|
||||
|
||||
roomEventFormattedContent : RoomEvent -> Maybe (List (Html Msg))
|
||||
roomEventFormattedContent : MessageEvent -> Maybe (List (Html Msg))
|
||||
roomEventFormattedContent re = Maybe.map Html.Parser.Util.toVirtualDom
|
||||
<| Maybe.andThen (Result.toMaybe << Html.Parser.run )
|
||||
<| Result.toMaybe
|
||||
<| Decode.decodeValue (Decode.field "formatted_body" Decode.string) re.content
|
||||
|
||||
roomEventContent : (List (Html Msg) -> Html Msg) -> RoomEvent -> Maybe (Html Msg)
|
||||
roomEventContent : (List (Html Msg) -> Html Msg) -> MessageEvent -> Maybe (Html Msg)
|
||||
roomEventContent f re =
|
||||
let
|
||||
body = Decode.decodeValue (Decode.field "body" Decode.string) re.content
|
||||
|
@ -280,20 +282,20 @@ roomEventContent f re =
|
|||
Just c -> Just <| f c
|
||||
Nothing -> Maybe.map (f << List.singleton << text) <| Result.toMaybe body
|
||||
|
||||
roomEventEmoteView : Dict String UserData -> RoomEvent -> Maybe (Html Msg)
|
||||
roomEventEmoteView : Dict String UserData -> MessageEvent -> Maybe (Html Msg)
|
||||
roomEventEmoteView ud re =
|
||||
let
|
||||
emoteText = "* " ++ displayName ud re.sender ++ " "
|
||||
in
|
||||
roomEventContent (\cs -> span [] (text emoteText :: cs)) re
|
||||
|
||||
roomEventNoticeView : RoomEvent -> Maybe (Html Msg)
|
||||
roomEventNoticeView : MessageEvent -> Maybe (Html Msg)
|
||||
roomEventNoticeView = roomEventContent (span [ class "message-notice" ])
|
||||
|
||||
roomEventTextView : RoomEvent -> Maybe (Html Msg)
|
||||
roomEventTextView : MessageEvent -> Maybe (Html Msg)
|
||||
roomEventTextView = roomEventContent (span [])
|
||||
|
||||
roomEventImageView : ApiUrl -> RoomEvent -> Maybe (Html Msg)
|
||||
roomEventImageView : ApiUrl -> MessageEvent -> Maybe (Html Msg)
|
||||
roomEventImageView apiUrl re =
|
||||
let
|
||||
body = Decode.decodeValue (Decode.field "url" Decode.string) re.content
|
||||
|
@ -302,7 +304,7 @@ roomEventImageView apiUrl re =
|
|||
<| Maybe.map (contentRepositoryDownloadUrl apiUrl)
|
||||
<| Result.toMaybe body
|
||||
|
||||
roomEventFileView : ApiUrl -> RoomEvent -> Maybe (Html Msg)
|
||||
roomEventFileView : ApiUrl -> MessageEvent -> Maybe (Html Msg)
|
||||
roomEventFileView apiUrl re =
|
||||
let
|
||||
decoder = Decode.map2 (\l r -> (l, r)) (Decode.field "url" Decode.string) (Decode.field "body" Decode.string)
|
||||
|
@ -312,7 +314,7 @@ roomEventFileView apiUrl re =
|
|||
<| Maybe.map (\(url, name) -> (contentRepositoryDownloadUrl apiUrl url, name))
|
||||
<| Result.toMaybe fileData
|
||||
|
||||
roomEventVideoView : ApiUrl -> RoomEvent -> Maybe (Html Msg)
|
||||
roomEventVideoView : ApiUrl -> MessageEvent -> Maybe (Html Msg)
|
||||
roomEventVideoView apiUrl re =
|
||||
let
|
||||
decoder = Decode.map2 (\l r -> (l, r))
|
||||
|
|
Loading…
Reference in New Issue
Block a user