Add first (faulty) design of Timeline

pull/17/head
Bram van den Heuvel 2024-01-09 18:19:29 +01:00
parent 211f8f1df4
commit 81b0b1c166
1 changed files with 172 additions and 14 deletions

View File

@ -44,19 +44,67 @@ and maintain this room state.
-}
import Internal.Filter.Timeline as Filter exposing (Filter)
{-| The Timeline type represents the timeline state in a Matrix room.
-}
type Timeline
= Timeline
import Internal.Tools.Mashdict as Mashdict exposing (Mashdict)
import Internal.Tools.Iddict as Iddict exposing (Iddict)
import FastDict as Dict exposing (Dict)
import Set exposing (Set)
{-| A batch is a batch of events that is placed onto the Timeline. Functions
that require an insertion, generally require this data type.
-}
type Batch
= Batch
= StartOfTimeline
| BatchToken String
| BatchSlice Batch (List String) Filter String
{-| Internal batch that's being saved by the Timeline to track a list of events.
-}
type alias IBatch =
{ events : List String
, filter : Filter
, start : ITokenPTR
, end : ITokenPTR
}
{-| Pointer to an IBatch in the Timeline.
-}
type IBatchPTR = IBatchPTR Int
{-| Internal token value that's being stored by the Timeline.
If name is `Nothing`, it indicates the start of the timeline.
-}
type alias IToken =
{ name : Maybe String
, starts : Set Int -- This itoken starts the following batches
, ends : Set Int -- This itoken ends the following batches
, inFrontOf : Set Int -- This itoken is in front of the following tokens
, behind : Set Int -- This itoken is behind the following tokens
}
{-| Pointer to an IToken in the Timeline.
-}
type ITokenPTR = ITokenPTR String
{-| The Timeline type represents the timeline state in a Matrix room.
Following the description of the Matrix spec, a timeline contains the following
items:
- Events that indicate timeline events
- Batch values that can be used to paginate through the timeline
The topological shape of the timeline makes older API responses somewhat
unreliable - as a result,
-}
type Timeline
= Timeline
{ batches : Iddict IBatch
, mostRecentSync : ITokenPTR
, tokens : Mashdict IToken
}
{-| When syncing a Matrix room to its most recent state, add the most recent
@ -66,19 +114,52 @@ addSync : Batch -> Timeline -> Timeline
addSync _ timeline =
timeline
{-| Connect two tokens to each other, revealing their relative location.
-}
connectITokentoIToken : ITokenPTR -> ITokenPTR -> Timeline -> Timeline
connectITokentoIToken (ITokenPTR early) (ITokenPTR late) (Timeline tl) =
Timeline
{ tl
| tokens =
tl.tokens
|> Iddict.map early
(\data ->
{ data | behind = Set.insert late data.behind }
)
|> Iddict.map late
(\data ->
{ data | inFrontOf = Set.insert early data.inFrontOf }
)
}
{-| Create a new empty timeline.
-}
empty : Timeline
empty =
Timeline
case Iddict.singleton Nothing of
( key, iddict ) ->
Timeline
{ batches = Iddict.empty
, mostRecentSync = ITokenPTR key
, tokens = iddict
, tokenToPtr = Dict.empty
}
{-| Get an IBatch from the Timeline.
-}
getIBatch : IBatchPTR -> Timeline -> Maybe IBatch
getIBatch (IBatchPTR ptr) (Timeline { batches }) =
Iddict.get ptr batches
getITokenFromPTR : ITokenPTR -> Timeline -> Maybe IToken
getITokenFromPTR (ITokenPTR ptr) ( Timeline { tokens }) =
Iddict.get ptr tokens
{-| Turn a single token into a batch.
-}
fromToken : String -> Batch
fromToken _ =
Batch
fromToken token =
BatchToken token
{-| Turn a slice of events into a batch.
@ -88,15 +169,92 @@ connected until the start of the timeline.
-}
fromSlice : { start : Maybe String, events : List String, filter : Filter, end : String } -> Batch
fromSlice _ =
Batch
fromSlice data =
BatchSlice
( case data.start of
Just s ->
BatchToken s
Nothing ->
StartOfTimeline
)
data.events data.filter data.end
{-| Insert a batch anywhere else in the timeline.
-}
insert : Batch -> Timeline -> Timeline
insert _ timeline =
timeline
insert batch (Timeline tl) =
(Timeline tl)
-- {-| Insert a batch anywhere else in the timeline, and gain a ptr to its
-- location.
-- -}
-- insertBatch : Batch -> Timeline -> { start : ITokenPTR, end : ITokenPTR, tl : Timeline }
-- insertBatch batch (Timeline tl) =
-- case batch of
-- StartOfTimeline ->
-- case Iddict.insert Nothing tl.tokens of
-- ( key, iddict ) ->
-- { start = ITokenPTR key
-- , end = ITokenPTR key
-- , tl = Timeline { tl | tokens = iddict }
-- }
-- BatchToken token ->
-- -- TODO: Do not insert if it already exists
-- case Iddict.insert (Just token) tl.tokens of
-- ( key, iddict ) ->
-- { start = ITokenPTR key
-- , end = ITokenPTR key
-- , tl = Timeline
-- { tl
-- | tokens = iddict
-- , tokenToPtr =
-- Dict.insert token (ITokenPTR key) tl.tokenToPtr
-- }
-- }
-- BatchSlice prevBatch events filter end ->
-- -- Insert previous batch
-- case insertBatch prevBatch (Timeline tl) of
-- result ->
-- case result.tl of
-- (Timeline tl2) ->
-- { start = result.start
-- , end =
-- }
{-| Insert an internal batch into the timeline, and determine its result.
-}
insertIBatch : IBatch -> Timeline -> ( IBatchPTR, Timeline )
insertIBatch ibatch (Timeline tl) =
case Iddict.insert ibatch tl.batches of
( key, iddict ) ->
( IBatchPTR key, Timeline { tl | batches = iddict } )
insertIToken : IToken -> Timeline -> ( ITokenPTR, Timeline )
insertIToken itoken (Timeline tl) =
case Maybe.andThen (\n -> Dict.get n tl.tokenToPtr) itoken.name of
-- Already exists: merge
Just ((ITokenPTR ptr) as pointer) ->
( pointer
, Timeline
{ tl
| tokens =
Iddict.map ptr
(\data ->
{ name = data.name
,
}
)
}
)
-- Doesn't exist yet: insert!
Nothing ->
(ITokenPTR 0, Timeline tl)
{-| Under a given filter, find the most recent events.