Add event to get older events
parent
c32a62c242
commit
098b38170a
|
@ -7,6 +7,7 @@ import Hash
|
||||||
import Internal.Api.Chain as Chain
|
import Internal.Api.Chain as Chain
|
||||||
import Internal.Api.Credentials as Cred exposing (Credentials)
|
import Internal.Api.Credentials as Cred exposing (Credentials)
|
||||||
import Internal.Api.GetEvent.Main exposing (EventInput)
|
import Internal.Api.GetEvent.Main exposing (EventInput)
|
||||||
|
import Internal.Api.GetMessages.Main exposing (GetMessagesInput)
|
||||||
import Internal.Api.Invite.Main exposing (InviteInput)
|
import Internal.Api.Invite.Main exposing (InviteInput)
|
||||||
import Internal.Api.JoinRoomById.Main exposing (JoinRoomByIdInput)
|
import Internal.Api.JoinRoomById.Main exposing (JoinRoomByIdInput)
|
||||||
import Internal.Api.JoinedMembers.Main exposing (JoinedMembersInput)
|
import Internal.Api.JoinedMembers.Main exposing (JoinedMembersInput)
|
||||||
|
@ -35,6 +36,13 @@ getEvent { eventId, roomId } cred =
|
||||||
|> C.toTask
|
|> C.toTask
|
||||||
|
|
||||||
|
|
||||||
|
getMessages : GetMessagesInput -> Credentials -> FutureTask
|
||||||
|
getMessages data cred =
|
||||||
|
C.makeVBA cred
|
||||||
|
|> Chain.andThen (C.getMessages data)
|
||||||
|
|> C.toTask
|
||||||
|
|
||||||
|
|
||||||
invite : InviteInput -> Credentials -> FutureTask
|
invite : InviteInput -> Credentials -> FutureTask
|
||||||
invite data cred =
|
invite data cred =
|
||||||
C.makeVBA cred
|
C.makeVBA cred
|
||||||
|
|
|
@ -10,6 +10,7 @@ resend other events or forward them elsewhere.
|
||||||
import Internal.Api.Credentials exposing (Credentials)
|
import Internal.Api.Credentials exposing (Credentials)
|
||||||
import Internal.Api.GetEvent.Main as GetEvent
|
import Internal.Api.GetEvent.Main as GetEvent
|
||||||
import Internal.Api.GetEvent.V1.SpecObjects as GetEventSO
|
import Internal.Api.GetEvent.V1.SpecObjects as GetEventSO
|
||||||
|
import Internal.Api.GetMessages.V4.SpecObjects as GetMessagesSO
|
||||||
import Internal.Api.Sync.V2.SpecObjects as SyncSO
|
import Internal.Api.Sync.V2.SpecObjects as SyncSO
|
||||||
import Internal.Tools.Timestamp exposing (Timestamp)
|
import Internal.Tools.Timestamp exposing (Timestamp)
|
||||||
import Internal.Values.Event as Internal
|
import Internal.Values.Event as Internal
|
||||||
|
@ -62,6 +63,32 @@ initFromGetEvent output =
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| Create an internal event type from an API endpoint event object.
|
||||||
|
This function is placed in this file to respect file hierarchy and avoid circular imports.
|
||||||
|
-}
|
||||||
|
initFromGetMessages : GetMessagesSO.ClientEvent -> Internal.IEvent
|
||||||
|
initFromGetMessages output =
|
||||||
|
Internal.init
|
||||||
|
{ content = output.content
|
||||||
|
, eventId = output.eventId
|
||||||
|
, originServerTs = output.originServerTs
|
||||||
|
, roomId = output.roomId
|
||||||
|
, sender = output.sender
|
||||||
|
, stateKey = output.stateKey
|
||||||
|
, contentType = output.contentType
|
||||||
|
, unsigned =
|
||||||
|
output.unsigned
|
||||||
|
|> Maybe.map
|
||||||
|
(\(GetMessagesSO.UnsignedData data) ->
|
||||||
|
{ age = data.age
|
||||||
|
, prevContent = data.prevContent
|
||||||
|
, redactedBecause = Maybe.map initFromGetMessages data.redactedBecause
|
||||||
|
, transactionId = data.transactionId
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
{-| Create an internal event type from an API endpoint event object.
|
{-| Create an internal event type from an API endpoint event object.
|
||||||
This function is placed in this file to respect file hierarchy and avoid circular imports.
|
This function is placed in this file to respect file hierarchy and avoid circular imports.
|
||||||
-}
|
-}
|
||||||
|
|
|
@ -7,10 +7,11 @@ import Dict
|
||||||
import Internal.Api.Credentials exposing (Credentials)
|
import Internal.Api.Credentials exposing (Credentials)
|
||||||
import Internal.Api.Sync.V2.SpecObjects as Sync
|
import Internal.Api.Sync.V2.SpecObjects as Sync
|
||||||
import Internal.Api.Task as Api
|
import Internal.Api.Task as Api
|
||||||
import Internal.Api.VaultUpdate exposing (VaultUpdate)
|
import Internal.Api.VaultUpdate exposing (VaultUpdate(..))
|
||||||
import Internal.Event as Event exposing (Event)
|
import Internal.Event as Event exposing (Event)
|
||||||
import Internal.Tools.Exceptions as X
|
import Internal.Tools.Exceptions as X
|
||||||
import Internal.Tools.Hashdict as Hashdict
|
import Internal.Tools.Hashdict as Hashdict
|
||||||
|
import Internal.Tools.SpecEnums as Enums
|
||||||
import Internal.Values.Event as IEvent
|
import Internal.Values.Event as IEvent
|
||||||
import Internal.Values.Room as Internal
|
import Internal.Values.Room as Internal
|
||||||
import Internal.Values.StateManager as StateManager
|
import Internal.Values.StateManager as StateManager
|
||||||
|
@ -118,6 +119,26 @@ withoutCredentials (Room { room }) =
|
||||||
room
|
room
|
||||||
|
|
||||||
|
|
||||||
|
{-| Get older events from the Matrix API.
|
||||||
|
-}
|
||||||
|
getOlderEvents : { limit : Maybe Int } -> Room -> Task X.Error VaultUpdate
|
||||||
|
getOlderEvents { limit } (Room { context, room }) =
|
||||||
|
case Internal.latestGap room of
|
||||||
|
Nothing ->
|
||||||
|
Task.succeed (MultipleUpdates [])
|
||||||
|
|
||||||
|
Just { from, to } ->
|
||||||
|
Api.getMessages
|
||||||
|
{ direction = Enums.ReverseChronological
|
||||||
|
, filter = Nothing
|
||||||
|
, from = Just to
|
||||||
|
, limit = limit
|
||||||
|
, roomId = Internal.roomId room
|
||||||
|
, to = from
|
||||||
|
}
|
||||||
|
context
|
||||||
|
|
||||||
|
|
||||||
{-| Get the most recent events.
|
{-| Get the most recent events.
|
||||||
-}
|
-}
|
||||||
mostRecentEvents : Room -> List Event
|
mostRecentEvents : Room -> List Event
|
||||||
|
|
|
@ -59,11 +59,28 @@ getStateEvent data (IRoom room) =
|
||||||
|> StateManager.getStateEvent data
|
|> StateManager.getStateEvent data
|
||||||
|
|
||||||
|
|
||||||
{-| Get the room's id.
|
{-| Insert a chunk of events into a room.
|
||||||
-}
|
-}
|
||||||
roomId : IRoom -> String
|
insertEvents :
|
||||||
roomId (IRoom room) =
|
{ events : List IEvent
|
||||||
room.roomId
|
, nextBatch : String
|
||||||
|
, prevBatch : Maybe String
|
||||||
|
, stateDelta : Maybe StateManager
|
||||||
|
}
|
||||||
|
-> IRoom
|
||||||
|
-> IRoom
|
||||||
|
insertEvents data (IRoom ({ timeline } as room)) =
|
||||||
|
IRoom
|
||||||
|
{ room | timeline = Timeline.insertEvents data timeline }
|
||||||
|
|> List.foldl addEvent
|
||||||
|
|> (|>) data.events
|
||||||
|
|
||||||
|
|
||||||
|
{-| Get the latest gap.
|
||||||
|
-}
|
||||||
|
latestGap : IRoom -> Maybe { from : Maybe String, to : String }
|
||||||
|
latestGap (IRoom room) =
|
||||||
|
Timeline.latestGap room.timeline
|
||||||
|
|
||||||
|
|
||||||
{-| Get the most recent events.
|
{-| Get the most recent events.
|
||||||
|
@ -71,3 +88,10 @@ roomId (IRoom room) =
|
||||||
mostRecentEvents : IRoom -> List IEvent
|
mostRecentEvents : IRoom -> List IEvent
|
||||||
mostRecentEvents (IRoom room) =
|
mostRecentEvents (IRoom room) =
|
||||||
Timeline.mostRecentEvents room.timeline
|
Timeline.mostRecentEvents room.timeline
|
||||||
|
|
||||||
|
|
||||||
|
{-| Get the room's id.
|
||||||
|
-}
|
||||||
|
roomId : IRoom -> String
|
||||||
|
roomId (IRoom room) =
|
||||||
|
room.roomId
|
||||||
|
|
|
@ -92,63 +92,119 @@ newFromEvents { events, nextBatch, prevBatch, stateDelta } =
|
||||||
insertEvents :
|
insertEvents :
|
||||||
{ events : List IEvent
|
{ events : List IEvent
|
||||||
, nextBatch : String
|
, nextBatch : String
|
||||||
, prevBatch : String
|
, prevBatch : Maybe String
|
||||||
, stateDelta : Maybe StateManager
|
, stateDelta : Maybe StateManager
|
||||||
}
|
}
|
||||||
-> Timeline
|
-> Timeline
|
||||||
-> Timeline
|
-> Timeline
|
||||||
insertEvents ({ events, nextBatch, prevBatch, stateDelta } as data) (Timeline t) =
|
insertEvents ({ events, nextBatch, prevBatch, stateDelta } as data) (Timeline t) =
|
||||||
Timeline
|
Timeline
|
||||||
(if t.nextBatch == prevBatch then
|
(case prevBatch of
|
||||||
{ t
|
-- No prevbatch suggests the start of the timeline.
|
||||||
| events = t.events ++ events
|
-- This means that we must recurse until we've hit the bottom,
|
||||||
, nextBatch = nextBatch
|
-- and then mark the bottom of the timeline.
|
||||||
}
|
Nothing ->
|
||||||
|
case t.previous of
|
||||||
else if nextBatch == t.prevBatch then
|
Gap prevT ->
|
||||||
case t.previous of
|
|
||||||
Gap (Timeline prevT) ->
|
|
||||||
if prevT.nextBatch == prevBatch then
|
|
||||||
{ events = prevT.events ++ events ++ t.events
|
|
||||||
, nextBatch = t.nextBatch
|
|
||||||
, prevBatch = prevT.prevBatch
|
|
||||||
, stateAtStart = prevT.stateAtStart
|
|
||||||
, previous = prevT.previous
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{ t
|
{ t
|
||||||
| events = events ++ t.events
|
| previous =
|
||||||
, prevBatch = prevBatch
|
prevT
|
||||||
, stateAtStart =
|
|> insertEvents data
|
||||||
stateDelta
|
|> Gap
|
||||||
|> Maybe.withDefault StateManager.empty
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
{ t
|
if nextBatch == t.prevBatch then
|
||||||
| events = events ++ t.events
|
{ t | previous = StartOfTimeline, events = events ++ t.events, stateAtStart = StateManager.empty }
|
||||||
, prevBatch = prevBatch
|
|
||||||
, stateAtStart =
|
|
||||||
stateDelta
|
|
||||||
|> Maybe.withDefault StateManager.empty
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
case t.previous of
|
{ t | previous = Gap <| newFromEvents data }
|
||||||
Gap prevT ->
|
|
||||||
{ t
|
|
||||||
| previous =
|
|
||||||
prevT
|
|
||||||
|> insertEvents data
|
|
||||||
|> Gap
|
|
||||||
}
|
|
||||||
|
|
||||||
_ ->
|
-- If there is a prevbatch, it is not the start of the timeline
|
||||||
t
|
-- and could be located anywhere.
|
||||||
|
-- Starting at the front, look for a way to match it with the existing timeline.
|
||||||
|
Just p ->
|
||||||
|
-- Piece connects to the front of the timeline.
|
||||||
|
if t.nextBatch == p then
|
||||||
|
{ t
|
||||||
|
| events = t.events ++ events
|
||||||
|
, nextBatch = nextBatch
|
||||||
|
}
|
||||||
|
-- Piece connects to the back of the timeline.
|
||||||
|
|
||||||
|
else if nextBatch == t.prevBatch then
|
||||||
|
case t.previous of
|
||||||
|
Gap (Timeline prevT) ->
|
||||||
|
-- Piece also connects to the timeline in the back,
|
||||||
|
-- allowing the two timelines to merge.
|
||||||
|
if prevT.nextBatch == p then
|
||||||
|
{ events = prevT.events ++ events ++ t.events
|
||||||
|
, nextBatch = t.nextBatch
|
||||||
|
, prevBatch = prevT.prevBatch
|
||||||
|
, stateAtStart = prevT.stateAtStart
|
||||||
|
, previous = prevT.previous
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{ t
|
||||||
|
| events = events ++ t.events
|
||||||
|
, prevBatch = p
|
||||||
|
, stateAtStart =
|
||||||
|
stateDelta
|
||||||
|
|> Maybe.withDefault StateManager.empty
|
||||||
|
}
|
||||||
|
|
||||||
|
Endless _ ->
|
||||||
|
{ t
|
||||||
|
| events = events ++ t.events
|
||||||
|
, prevBatch = p
|
||||||
|
, stateAtStart =
|
||||||
|
stateDelta
|
||||||
|
|> Maybe.withDefault StateManager.empty
|
||||||
|
, previous = Endless p
|
||||||
|
}
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
{ t
|
||||||
|
| events = events ++ t.events
|
||||||
|
, prevBatch = p
|
||||||
|
, stateAtStart =
|
||||||
|
stateDelta
|
||||||
|
|> Maybe.withDefault StateManager.empty
|
||||||
|
}
|
||||||
|
-- Piece doesn't connect to this piece of the timeline.
|
||||||
|
-- Consequently, look for previous parts of the timeline to see if it connects.
|
||||||
|
|
||||||
|
else
|
||||||
|
case t.previous of
|
||||||
|
Gap prevT ->
|
||||||
|
{ t
|
||||||
|
| previous =
|
||||||
|
prevT
|
||||||
|
|> insertEvents data
|
||||||
|
|> Gap
|
||||||
|
}
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
t
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Get the width of the latest gap. This data is usually accessed when trying to get more messages.
|
||||||
|
-}
|
||||||
|
latestGap : Timeline -> Maybe { from : Maybe String, to : String }
|
||||||
|
latestGap (Timeline t) =
|
||||||
|
case t.previous of
|
||||||
|
StartOfTimeline ->
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
Endless prevBatch ->
|
||||||
|
Just { from = Nothing, to = prevBatch }
|
||||||
|
|
||||||
|
Gap (Timeline pt) ->
|
||||||
|
Just { from = Just pt.nextBatch, to = t.prevBatch }
|
||||||
|
|
||||||
|
|
||||||
{-| Get the longest uninterrupted length of most recent events.
|
{-| Get the longest uninterrupted length of most recent events.
|
||||||
-}
|
-}
|
||||||
localSize : Timeline -> Int
|
localSize : Timeline -> Int
|
||||||
|
|
|
@ -16,6 +16,7 @@ import Internal.Event as Event
|
||||||
import Internal.Invite as Invite
|
import Internal.Invite as Invite
|
||||||
import Internal.Room as Room
|
import Internal.Room as Room
|
||||||
import Internal.Tools.Exceptions as X
|
import Internal.Tools.Exceptions as X
|
||||||
|
import Internal.Tools.SpecEnums as Enums
|
||||||
import Internal.Values.Room as IRoom
|
import Internal.Values.Room as IRoom
|
||||||
import Internal.Values.RoomInvite exposing (IRoomInvite)
|
import Internal.Values.RoomInvite exposing (IRoomInvite)
|
||||||
import Internal.Values.StateManager as StateManager
|
import Internal.Values.StateManager as StateManager
|
||||||
|
@ -125,8 +126,62 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
||||||
vault
|
vault
|
||||||
|
|
||||||
-- TODO
|
-- TODO
|
||||||
GetMessages _ _ ->
|
GetMessages input output ->
|
||||||
vault
|
let
|
||||||
|
prevBatch : Maybe String
|
||||||
|
prevBatch =
|
||||||
|
case input.direction of
|
||||||
|
Enums.Chronological ->
|
||||||
|
Just output.start
|
||||||
|
|
||||||
|
Enums.ReverseChronological ->
|
||||||
|
case output.end of
|
||||||
|
Just end ->
|
||||||
|
Just end
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
input.to
|
||||||
|
|
||||||
|
nextBatch : Maybe String
|
||||||
|
nextBatch =
|
||||||
|
case input.direction of
|
||||||
|
Enums.Chronological ->
|
||||||
|
case output.end of
|
||||||
|
Just end ->
|
||||||
|
Just end
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
input.to
|
||||||
|
|
||||||
|
Enums.ReverseChronological ->
|
||||||
|
Just output.start
|
||||||
|
in
|
||||||
|
case ( getRoomById input.roomId vault, nextBatch ) of
|
||||||
|
( Just room, Just nb ) ->
|
||||||
|
room
|
||||||
|
|> Room.withoutCredentials
|
||||||
|
|> IRoom.insertEvents
|
||||||
|
{ events =
|
||||||
|
output.chunk
|
||||||
|
|> List.map Event.initFromGetMessages
|
||||||
|
|> (\x ->
|
||||||
|
case input.direction of
|
||||||
|
Enums.Chronological ->
|
||||||
|
x
|
||||||
|
|
||||||
|
Enums.ReverseChronological ->
|
||||||
|
List.reverse x
|
||||||
|
)
|
||||||
|
, prevBatch = prevBatch
|
||||||
|
, nextBatch = nb
|
||||||
|
, stateDelta = Just <| StateManager.fromEventList (List.map Event.initFromGetMessages output.state)
|
||||||
|
}
|
||||||
|
|> Internal.insertRoom
|
||||||
|
|> (|>) cred
|
||||||
|
|> (\v -> Vault { cred = v, context = context })
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
vault
|
||||||
|
|
||||||
-- TODO
|
-- TODO
|
||||||
InviteSent _ _ ->
|
InviteSent _ _ ->
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module Matrix.Room exposing
|
module Matrix.Room exposing
|
||||||
( Room, roomId, mostRecentEvents
|
( Room, roomId, mostRecentEvents, findOlderEvents
|
||||||
, sendMessage, sendMessages, sendOneEvent, sendMultipleEvents
|
, sendMessage, sendMessages, sendOneEvent, sendMultipleEvents
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ module Matrix.Room exposing
|
||||||
|
|
||||||
A room represents a channel of communication within a Matrix home server.
|
A room represents a channel of communication within a Matrix home server.
|
||||||
|
|
||||||
@docs Room, roomId, mostRecentEvents
|
@docs Room, roomId, mostRecentEvents, findOlderEvents
|
||||||
|
|
||||||
|
|
||||||
# Sending events
|
# Sending events
|
||||||
|
@ -35,6 +35,13 @@ type alias Room =
|
||||||
Internal.Room
|
Internal.Room
|
||||||
|
|
||||||
|
|
||||||
|
{-| If you want more events as part of the most recent events, you can run this task to get more.
|
||||||
|
-}
|
||||||
|
findOlderEvents : { limit : Maybe Int, room : Room } -> Task X.Error VaultUpdate
|
||||||
|
findOlderEvents { limit, room } =
|
||||||
|
Internal.getOlderEvents { limit = limit } room
|
||||||
|
|
||||||
|
|
||||||
{-| Get the most recent events from this room.
|
{-| Get the most recent events from this room.
|
||||||
-}
|
-}
|
||||||
mostRecentEvents : Room -> List Event.Event
|
mostRecentEvents : Room -> List Event.Event
|
||||||
|
|
Loading…
Reference in New Issue