Add new filter + VaultResult type
parent
4777de5b67
commit
4b92d9ea20
|
@ -0,0 +1,384 @@
|
||||||
|
module Internal.Tools.Filters.Filter exposing (..)
|
||||||
|
|
||||||
|
import Internal.Tools.Filters.SpecObjects as SO
|
||||||
|
import Internal.Tools.Filters.SimpleFilter as SF exposing (SimpleFilter)
|
||||||
|
import Internal.Tools.SpecEnums as Enums
|
||||||
|
|
||||||
|
{-| Event filters tell the API what events to look for,
|
||||||
|
but specifically for events that are unrelated to any room.
|
||||||
|
-}
|
||||||
|
type EventFilter
|
||||||
|
= EventFilter
|
||||||
|
{ limit : Maybe Int
|
||||||
|
, senders : SimpleFilter String
|
||||||
|
, types : SimpleFilter String
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| The final type dictates how everything else behaves.
|
||||||
|
-}
|
||||||
|
type Filter =
|
||||||
|
Filter
|
||||||
|
{ accountData : EventFilter
|
||||||
|
, presence : EventFilter
|
||||||
|
, room : RoomFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| RoomFilter types tell the API what is considered relevant in a room,
|
||||||
|
and which rooms to include.
|
||||||
|
-}
|
||||||
|
type RoomFilter
|
||||||
|
= RoomFilter
|
||||||
|
{ accountData : RoomEventFilter
|
||||||
|
, ephemeral : RoomEventFilter
|
||||||
|
, rooms : SimpleFilter String
|
||||||
|
, timeline : RoomEventFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| RoomEventFilter types tell the API what events to look for,
|
||||||
|
and what ones to ignore.
|
||||||
|
-}
|
||||||
|
type RoomEventFilter
|
||||||
|
= RoomEventFilter
|
||||||
|
{ lazyLoadMembers : Bool
|
||||||
|
, limit : Maybe Int
|
||||||
|
, rooms : SimpleFilter String
|
||||||
|
, senders : SimpleFilter String
|
||||||
|
, types : SimpleFilter String
|
||||||
|
}
|
||||||
|
|
||||||
|
allEvents : EventFilter
|
||||||
|
allEvents =
|
||||||
|
EventFilter
|
||||||
|
{ limit = Nothing
|
||||||
|
, senders = SF.all
|
||||||
|
, types = SF.all
|
||||||
|
}
|
||||||
|
|
||||||
|
allFilters : Filter
|
||||||
|
allFilters =
|
||||||
|
Filter
|
||||||
|
{ accountData = allEvents
|
||||||
|
, presence = allEvents
|
||||||
|
, room = allRooms
|
||||||
|
}
|
||||||
|
|
||||||
|
allRooms : RoomFilter
|
||||||
|
allRooms =
|
||||||
|
RoomFilter
|
||||||
|
{ accountData = allRoomEvents
|
||||||
|
, ephemeral = allRoomEvents
|
||||||
|
, rooms = SF.all
|
||||||
|
, timeline = allRoomEvents
|
||||||
|
}
|
||||||
|
|
||||||
|
allRoomEvents : RoomEventFilter
|
||||||
|
allRoomEvents =
|
||||||
|
RoomEventFilter
|
||||||
|
{ lazyLoadMembers = False
|
||||||
|
, limit = Nothing
|
||||||
|
, rooms = SF.all
|
||||||
|
, senders = SF.all
|
||||||
|
, types = SF.all
|
||||||
|
}
|
||||||
|
|
||||||
|
decodeEventFilter : SO.EventFilter -> EventFilter
|
||||||
|
decodeEventFilter data =
|
||||||
|
EventFilter
|
||||||
|
{ limit = data.limit
|
||||||
|
, senders = SF.toSimpleFilter data.senders data.notSenders
|
||||||
|
, types = SF.toSimpleFilter data.types data.notTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
decodeFilter : SO.Filter -> Filter
|
||||||
|
decodeFilter data =
|
||||||
|
Filter
|
||||||
|
{ accountData =
|
||||||
|
data.accountData
|
||||||
|
|> Maybe.map decodeEventFilter
|
||||||
|
|> Maybe.withDefault allEvents
|
||||||
|
, presence =
|
||||||
|
data.presence
|
||||||
|
|> Maybe.map decodeEventFilter
|
||||||
|
|> Maybe.withDefault allEvents
|
||||||
|
, room =
|
||||||
|
data.room
|
||||||
|
|> Maybe.map decodeRoomFilter
|
||||||
|
|> Maybe.withDefault allRooms
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Decode a RoomFilter from a spec-compliant format.
|
||||||
|
-}
|
||||||
|
decodeRoomFilter : SO.RoomFilter -> RoomFilter
|
||||||
|
decodeRoomFilter data =
|
||||||
|
let
|
||||||
|
decodeREF : Maybe SO.RoomEventFilter -> RoomEventFilter
|
||||||
|
decodeREF =
|
||||||
|
Maybe.map decodeRoomEventFilter >> Maybe.withDefault allRoomEvents
|
||||||
|
in
|
||||||
|
RoomFilter
|
||||||
|
{ accountData = decodeREF data.accountData
|
||||||
|
, ephemeral = decodeREF data.ephemeral
|
||||||
|
, rooms = SF.toSimpleFilter data.rooms data.notRooms
|
||||||
|
, timeline = decodeREF data.timeline
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Decode a RoomEventFilter from a spec-compliant format.
|
||||||
|
-}
|
||||||
|
decodeRoomEventFilter : SO.RoomEventFilter -> RoomEventFilter
|
||||||
|
decodeRoomEventFilter data =
|
||||||
|
RoomEventFilter
|
||||||
|
{ lazyLoadMembers = data.lazyLoadMembers
|
||||||
|
, limit = data.limit
|
||||||
|
, rooms = SF.toSimpleFilter data.rooms data.notRooms
|
||||||
|
, senders = SF.toSimpleFilter data.senders data.notSenders
|
||||||
|
, types = SF.toSimpleFilter data.types data.notTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Encode an EventFilter into a spec-compliant format.
|
||||||
|
-}
|
||||||
|
encodeEventFilter : EventFilter -> SO.EventFilter
|
||||||
|
encodeEventFilter (EventFilter data) =
|
||||||
|
{ limit = data.limit
|
||||||
|
, notSenders = SF.toExclude data.senders
|
||||||
|
, notTypes = SF.toExclude data.types
|
||||||
|
, senders = SF.toInclude data.senders
|
||||||
|
, types = SF.toInclude data.types
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Encode a Filter into a spec-compliant format.
|
||||||
|
-}
|
||||||
|
encodeFilter : Filter -> SO.Filter
|
||||||
|
encodeFilter (Filter data) =
|
||||||
|
{ accountData = Just <| encodeEventFilter data.accountData
|
||||||
|
, eventFields = Nothing
|
||||||
|
, eventFormat = Enums.Client
|
||||||
|
, presence = Just <| encodeEventFilter data.presence
|
||||||
|
, room = Just <| encodeRoomFilter data.room
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Encode a RoomFilter into a spec-compliant format.
|
||||||
|
-}
|
||||||
|
encodeRoomFilter : RoomFilter -> SO.RoomFilter
|
||||||
|
encodeRoomFilter (RoomFilter data) =
|
||||||
|
{ accountData = Just <| encodeRoomEventFilter data.accountData
|
||||||
|
, ephemeral = Just <| encodeRoomEventFilter data.ephemeral
|
||||||
|
, includeLeave = False
|
||||||
|
, notRooms = SF.toExclude data.rooms
|
||||||
|
, rooms = SF.toInclude data.rooms
|
||||||
|
, state = Just <| encodeRoomEventFilter data.timeline
|
||||||
|
, timeline = Just <| encodeRoomEventFilter data.timeline
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Encode a RoomEventFilter into a spec-compliant format.
|
||||||
|
-}
|
||||||
|
encodeRoomEventFilter : RoomEventFilter -> SO.RoomEventFilter
|
||||||
|
encodeRoomEventFilter (RoomEventFilter data) =
|
||||||
|
{ containsUrl = Nothing
|
||||||
|
, includeRedundantMembers = False
|
||||||
|
, lazyLoadMembers = data.lazyLoadMembers
|
||||||
|
, limit = data.limit
|
||||||
|
, notRooms = SF.toExclude data.rooms
|
||||||
|
, notSenders = SF.toExclude data.senders
|
||||||
|
, notTypes = SF.toExclude data.types
|
||||||
|
, rooms = SF.toInclude data.rooms
|
||||||
|
, senders = SF.toInclude data.senders
|
||||||
|
, types = SF.toInclude data.types
|
||||||
|
, unreadThreadNotifications = True
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Flatten a filter.
|
||||||
|
-}
|
||||||
|
flattenFilter : Filter -> List (SimpleFilter String)
|
||||||
|
flattenFilter (Filter f) =
|
||||||
|
List.concat
|
||||||
|
[ flattenEventFilter f.accountData
|
||||||
|
, flattenEventFilter f.presence
|
||||||
|
, flattenRoomFilter f.room
|
||||||
|
]
|
||||||
|
|
||||||
|
{-| Flatten a EventFilter.
|
||||||
|
-}
|
||||||
|
flattenEventFilter : EventFilter -> List (SimpleFilter String)
|
||||||
|
flattenEventFilter (EventFilter f) = [ f.senders, f.types ]
|
||||||
|
|
||||||
|
{-| Flatten a RoomFilter.
|
||||||
|
-}
|
||||||
|
flattenRoomFilter : RoomFilter -> List (SimpleFilter String)
|
||||||
|
flattenRoomFilter (RoomFilter f) =
|
||||||
|
[ f.accountData, f.ephemeral, f.timeline ]
|
||||||
|
|> List.map flattenRoomEventFilter
|
||||||
|
|> List.concat
|
||||||
|
|> (::) f.rooms
|
||||||
|
|
||||||
|
{-| Flatten a RoomEventFilter.
|
||||||
|
-}
|
||||||
|
flattenRoomEventFilter : RoomEventFilter -> List (SimpleFilter String)
|
||||||
|
flattenRoomEventFilter (RoomEventFilter f) = [ f.rooms, f.senders, f.types ]
|
||||||
|
|
||||||
|
{-| Get an intersection of a Filter.
|
||||||
|
-}
|
||||||
|
intersectFilter : Filter -> Filter -> Filter
|
||||||
|
intersectFilter (Filter f1) (Filter f2) =
|
||||||
|
Filter
|
||||||
|
{ accountData = intersectEventFilter f1.accountData f2.accountData
|
||||||
|
, presence = intersectEventFilter f1.presence f2.presence
|
||||||
|
, room = intersectRoomFilter f1.room f2.room
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Get an intersection of a EventFilter.
|
||||||
|
-}
|
||||||
|
intersectEventFilter : EventFilter -> EventFilter -> EventFilter
|
||||||
|
intersectEventFilter (EventFilter f1) (EventFilter f2) =
|
||||||
|
EventFilter
|
||||||
|
{ limit =
|
||||||
|
case (f1.limit, f2.limit) of
|
||||||
|
(Just l1, Just l2) ->
|
||||||
|
Just (max l1 l2)
|
||||||
|
|
||||||
|
(Just _, Nothing) ->
|
||||||
|
f1.limit
|
||||||
|
|
||||||
|
(Nothing, Just _) ->
|
||||||
|
f2.limit
|
||||||
|
|
||||||
|
(Nothing, Nothing) ->
|
||||||
|
Nothing
|
||||||
|
, senders = SF.intersect f1.senders f2.senders
|
||||||
|
, types = SF.intersect f1.types f2.types
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Get an intersection of a RoomFilter.
|
||||||
|
-}
|
||||||
|
intersectRoomFilter : RoomFilter -> RoomFilter -> RoomFilter
|
||||||
|
intersectRoomFilter (RoomFilter f1) (RoomFilter f2) =
|
||||||
|
RoomFilter
|
||||||
|
{ accountData = intersectRoomEventFilter f1.accountData f2.accountData
|
||||||
|
, ephemeral = intersectRoomEventFilter f1.ephemeral f2.ephemeral
|
||||||
|
, rooms = SF.intersect f1.rooms f2.rooms
|
||||||
|
, timeline = intersectRoomEventFilter f1.timeline f2.timeline
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Get an intersection of a RoomEventFilter.
|
||||||
|
-}
|
||||||
|
intersectRoomEventFilter : RoomEventFilter -> RoomEventFilter -> RoomEventFilter
|
||||||
|
intersectRoomEventFilter (RoomEventFilter f1) (RoomEventFilter f2) =
|
||||||
|
RoomEventFilter
|
||||||
|
{ lazyLoadMembers = f1.lazyLoadMembers && f2.lazyLoadMembers
|
||||||
|
, limit =
|
||||||
|
case (f1.limit, f2.limit) of
|
||||||
|
(Just l1, Just l2) ->
|
||||||
|
Just (max l1 l2)
|
||||||
|
|
||||||
|
(Just _, Nothing) ->
|
||||||
|
f1.limit
|
||||||
|
|
||||||
|
(Nothing, Just _) ->
|
||||||
|
f2.limit
|
||||||
|
|
||||||
|
(Nothing, Nothing) ->
|
||||||
|
Nothing
|
||||||
|
, rooms = SF.intersect f1.rooms f2.rooms
|
||||||
|
, senders = SF.intersect f1.senders f2.senders
|
||||||
|
, types = SF.intersect f1.types f2.types
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Check whether a filter is a subset of another filter.
|
||||||
|
-}
|
||||||
|
isSubSet : Filter -> Filter -> Bool
|
||||||
|
isSubSet f1 f2 =
|
||||||
|
let
|
||||||
|
isSame : List (SimpleFilter String) -> List (SimpleFilter String) -> Bool
|
||||||
|
isSame l1 l2 =
|
||||||
|
case (l1, l2) of
|
||||||
|
(h1 :: t1, h2 :: t2) ->
|
||||||
|
SF.subset h1 h2 && isSame t1 t2
|
||||||
|
([], []) ->
|
||||||
|
True
|
||||||
|
_ ->
|
||||||
|
False
|
||||||
|
in
|
||||||
|
isSame (flattenFilter f1) (flattenFilter f2)
|
||||||
|
|
||||||
|
lazyLoadMembers : Bool -> RoomEventFilter -> RoomEventFilter
|
||||||
|
lazyLoadMembers b (RoomEventFilter data) =
|
||||||
|
RoomEventFilter { data | lazyLoadMembers = b }
|
||||||
|
|
||||||
|
{-| Determine a limit for the amount of events. If no limit is given, the homeserver decides this limit for itself.
|
||||||
|
-}
|
||||||
|
setEventLimit : Maybe Int -> RoomEventFilter -> RoomEventFilter
|
||||||
|
setEventLimit i (RoomEventFilter data) =
|
||||||
|
RoomEventFilter { data | limit = i }
|
||||||
|
|
||||||
|
{-| Include a specific event type.
|
||||||
|
-}
|
||||||
|
withEventType : String -> RoomEventFilter -> RoomEventFilter
|
||||||
|
withEventType x (RoomEventFilter ({ types } as data)) =
|
||||||
|
RoomEventFilter { data | types = SF.with x types }
|
||||||
|
|
||||||
|
{-| Include all event types that haven't been explicitly mentioned.
|
||||||
|
-}
|
||||||
|
withOtherEventTypes : RoomEventFilter -> RoomEventFilter
|
||||||
|
withOtherEventTypes (RoomEventFilter ({ types } as data)) =
|
||||||
|
RoomEventFilter { data | types = SF.withOthers types }
|
||||||
|
|
||||||
|
{-| Include all rooms that haven't been explicitly mentioned.
|
||||||
|
-}
|
||||||
|
withOtherRooms : RoomEventFilter -> RoomEventFilter
|
||||||
|
withOtherRooms (RoomEventFilter ({ rooms } as data)) =
|
||||||
|
RoomEventFilter { data | rooms = SF.withOthers rooms }
|
||||||
|
|
||||||
|
{-| Include all senders that haven't been explicitly mentioned.
|
||||||
|
-}
|
||||||
|
withOtherSenders : RoomEventFilter -> RoomEventFilter
|
||||||
|
withOtherSenders (RoomEventFilter ({ senders } as data)) =
|
||||||
|
RoomEventFilter { data | senders = SF.withOthers senders }
|
||||||
|
|
||||||
|
{-| Include a specific room.
|
||||||
|
-}
|
||||||
|
withRoom : String -> RoomEventFilter -> RoomEventFilter
|
||||||
|
withRoom x (RoomEventFilter ({ rooms } as data)) =
|
||||||
|
RoomEventFilter { data | rooms = SF.with x rooms }
|
||||||
|
|
||||||
|
{-| Include a specific sender.
|
||||||
|
-}
|
||||||
|
withSender : String -> RoomEventFilter -> RoomEventFilter
|
||||||
|
withSender x (RoomEventFilter ({ senders } as data)) =
|
||||||
|
RoomEventFilter { data | senders = SF.with x senders }
|
||||||
|
|
||||||
|
{-| Ignore a specific event type.
|
||||||
|
-}
|
||||||
|
withoutEventType : String -> RoomEventFilter -> RoomEventFilter
|
||||||
|
withoutEventType x (RoomEventFilter ({ types } as data)) =
|
||||||
|
RoomEventFilter { data | types = SF.without x types }
|
||||||
|
|
||||||
|
{-| Ignore all rooms that haven't been explicitly mentioned.
|
||||||
|
-}
|
||||||
|
withoutOtherEventTypes : RoomEventFilter -> RoomEventFilter
|
||||||
|
withoutOtherEventTypes (RoomEventFilter ({ types } as data)) =
|
||||||
|
RoomEventFilter { data | types = SF.withoutOthers types }
|
||||||
|
|
||||||
|
{-| Ignore all rooms that haven't been explicitly mentioned.
|
||||||
|
-}
|
||||||
|
withoutOtherRooms : RoomEventFilter -> RoomEventFilter
|
||||||
|
withoutOtherRooms (RoomEventFilter ({ rooms } as data)) =
|
||||||
|
RoomEventFilter { data | rooms = SF.withoutOthers rooms }
|
||||||
|
|
||||||
|
{-| Ignore all senders that haven't been explicitly mentioned.
|
||||||
|
-}
|
||||||
|
withoutOtherSenders : RoomEventFilter -> RoomEventFilter
|
||||||
|
withoutOtherSenders (RoomEventFilter ({ senders } as data)) =
|
||||||
|
RoomEventFilter { data | senders = SF.withoutOthers senders }
|
||||||
|
|
||||||
|
{-| Ignore a specific room.
|
||||||
|
-}
|
||||||
|
withoutRoom : String -> RoomEventFilter -> RoomEventFilter
|
||||||
|
withoutRoom x (RoomEventFilter ({ rooms } as data)) =
|
||||||
|
RoomEventFilter { data | rooms = SF.without x rooms }
|
||||||
|
|
||||||
|
{-| Ignore a specific sender.
|
||||||
|
-}
|
||||||
|
withoutSender : String -> RoomEventFilter -> RoomEventFilter
|
||||||
|
withoutSender x (RoomEventFilter ({ senders } as data)) =
|
||||||
|
RoomEventFilter { data | senders = SF.without x senders }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
module Internal.Tools.Filters.Main exposing (..)
|
||||||
|
{-| This module contains the main functions used to get, manipulate and change
|
||||||
|
filters according to their needs.
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Internal.Tools.Filters.Filter as F
|
||||||
|
import Internal.Tools.Filters.SimpleFilter as SF
|
||||||
|
|
||||||
|
type alias Filter = F.Filter
|
||||||
|
|
||||||
|
type alias SimpleFilter = SF.SimpleFilter String
|
||||||
|
|
||||||
|
{-| Filter that adds all occurrences by default, but leaves a few ones out.
|
||||||
|
|
||||||
|
When provided with an empty list, the filter allows all types.
|
||||||
|
-}
|
||||||
|
allExcept : List String -> SimpleFilter
|
||||||
|
allExcept =
|
||||||
|
List.foldl SF.without SF.all
|
||||||
|
|
||||||
|
{-| Filter that removes everything by default, but leaves a few ones in.
|
||||||
|
|
||||||
|
When provided with an empty list, the filter allows nothing.
|
||||||
|
-}
|
||||||
|
only : List String -> SimpleFilter
|
||||||
|
only =
|
||||||
|
List.foldl SF.with SF.none
|
||||||
|
|
||||||
|
fromSimpleFilter :
|
||||||
|
{ accountDataTypes : SimpleFilter
|
||||||
|
, presence : { limit : Maybe Int, senders : SimpleFilter, types : SimpleFilter }
|
||||||
|
, ephemeral : { limit : Maybe Int, senders : SimpleFilter, types : SimpleFilter }
|
||||||
|
, roomIds : SimpleFilter
|
||||||
|
, lazyLoadMembers : Bool
|
||||||
|
, roomEvents : { limit : Maybe Int, senders : SimpleFilter, types : SimpleFilter }
|
||||||
|
} -> Filter
|
||||||
|
fromSimpleFilter data =
|
||||||
|
F.Filter
|
||||||
|
{ accountData =
|
||||||
|
F.EventFilter
|
||||||
|
{ limit = Nothing
|
||||||
|
, senders = SF.all
|
||||||
|
, types = data.accountDataTypes
|
||||||
|
}
|
||||||
|
, presence =
|
||||||
|
F.EventFilter
|
||||||
|
{ limit = data.presence.limit
|
||||||
|
, senders = data.presence.senders
|
||||||
|
, types = data.presence.types
|
||||||
|
}
|
||||||
|
, room =
|
||||||
|
F.RoomFilter
|
||||||
|
{ accountData =
|
||||||
|
F.RoomEventFilter
|
||||||
|
{ lazyLoadMembers = data.lazyLoadMembers
|
||||||
|
, limit = Nothing
|
||||||
|
, rooms = data.roomIds
|
||||||
|
, senders = SF.all
|
||||||
|
, types = data.accountDataTypes
|
||||||
|
}
|
||||||
|
, ephemeral =
|
||||||
|
F.RoomEventFilter
|
||||||
|
{ lazyLoadMembers = data.lazyLoadMembers
|
||||||
|
, limit = data.ephemeral.limit
|
||||||
|
, rooms = data.roomIds
|
||||||
|
, senders = data.ephemeral.senders
|
||||||
|
, types = data.ephemeral.types
|
||||||
|
}
|
||||||
|
, rooms = data.roomIds
|
||||||
|
, timeline =
|
||||||
|
F.RoomEventFilter
|
||||||
|
{ lazyLoadMembers = data.lazyLoadMembers
|
||||||
|
, limit = data.roomEvents.limit
|
||||||
|
, rooms = data.roomIds
|
||||||
|
, senders = data.roomEvents.senders
|
||||||
|
, types = data.roomEvents.types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Get the intersection of two filters.
|
||||||
|
-}
|
||||||
|
intersect : Filter -> Filter -> Filter
|
||||||
|
intersect =
|
||||||
|
F.intersectFilter
|
|
@ -0,0 +1,172 @@
|
||||||
|
module Internal.Tools.Filters.SimpleFilter exposing (..)
|
||||||
|
{-| The SimpleFilter tracks values that should or should not be monitored.
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Dict exposing (Dict)
|
||||||
|
|
||||||
|
{-| SimpleFilter type that tracks items to include or exclude.
|
||||||
|
-}
|
||||||
|
type alias SimpleFilter a =
|
||||||
|
{ specificOnes : Dict a Bool
|
||||||
|
, includeOthers : Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
all : SimpleFilter a
|
||||||
|
all =
|
||||||
|
{ specificOnes = Dict.empty
|
||||||
|
, includeOthers = True
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Use filter ones that are only available in the first filter.
|
||||||
|
-}
|
||||||
|
diff : SimpleFilter comparable -> SimpleFilter comparable -> SimpleFilter comparable
|
||||||
|
diff f1 f2 =
|
||||||
|
{ specificOnes =
|
||||||
|
Dict.merge
|
||||||
|
(\k v1 -> Dict.insert k (v1 && not f2.includeOthers))
|
||||||
|
(\k v1 v2 -> Dict.insert k (v1 && not v2))
|
||||||
|
(\k v2 -> Dict.insert k (f1.includeOthers && not v2))
|
||||||
|
f1.specificOnes
|
||||||
|
f2.specificOnes
|
||||||
|
Dict.empty
|
||||||
|
, includeOthers = f1.includeOthers && not f2.includeOthers
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Form a filter that only shows the values that two filters have in common.
|
||||||
|
-}
|
||||||
|
intersect : SimpleFilter comparable -> SimpleFilter comparable -> SimpleFilter comparable
|
||||||
|
intersect f1 f2 =
|
||||||
|
{ specificOnes =
|
||||||
|
Dict.merge
|
||||||
|
(\key v1 -> Dict.insert key (v1 && f2.includeOthers))
|
||||||
|
(\key v1 v2 -> Dict.insert key (v1 && v2))
|
||||||
|
(\key v2 -> Dict.insert key (f1.includeOthers && v2))
|
||||||
|
f1.specificOnes
|
||||||
|
f2.specificOnes
|
||||||
|
Dict.empty
|
||||||
|
, includeOthers = f1.includeOthers && f2.includeOthers
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Start with a filter that includes none.
|
||||||
|
-}
|
||||||
|
none : SimpleFilter a
|
||||||
|
none =
|
||||||
|
{ specificOnes = Dict.empty
|
||||||
|
, includeOthers = False
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Check whether a SimpleFilter is a subset of another filter.
|
||||||
|
-}
|
||||||
|
subset : SimpleFilter comparable -> SimpleFilter comparable -> Bool
|
||||||
|
subset small large =
|
||||||
|
if small.includeOthers && not large.includeOthers then
|
||||||
|
False
|
||||||
|
else
|
||||||
|
-- All elements of small are in large
|
||||||
|
Dict.merge
|
||||||
|
(\_ s ->
|
||||||
|
if s && not large.includeOthers then
|
||||||
|
always False
|
||||||
|
else
|
||||||
|
identity
|
||||||
|
)
|
||||||
|
(\_ s l ->
|
||||||
|
if s && not l then
|
||||||
|
always False
|
||||||
|
else
|
||||||
|
identity
|
||||||
|
)
|
||||||
|
(\_ l ->
|
||||||
|
if small.includeOthers && not l then
|
||||||
|
always False
|
||||||
|
else
|
||||||
|
identity
|
||||||
|
)
|
||||||
|
small.specificOnes
|
||||||
|
large.specificOnes
|
||||||
|
True
|
||||||
|
|
||||||
|
{-| Encode a SimpleFilter into a list of items to exclude.
|
||||||
|
-}
|
||||||
|
toExclude : SimpleFilter comparable -> Maybe (List comparable)
|
||||||
|
toExclude f =
|
||||||
|
f.specificOnes
|
||||||
|
|> Dict.filter (always not)
|
||||||
|
|> Dict.keys
|
||||||
|
|> Just
|
||||||
|
|
||||||
|
{-| Encode a SimpleFilter into a list of items to include.
|
||||||
|
-}
|
||||||
|
toInclude : SimpleFilter comparable -> Maybe (List comparable)
|
||||||
|
toInclude f =
|
||||||
|
if f.includeOthers then
|
||||||
|
Nothing
|
||||||
|
else
|
||||||
|
f.specificOnes
|
||||||
|
|> Dict.filter (always identity)
|
||||||
|
|> Dict.keys
|
||||||
|
|> Just
|
||||||
|
|
||||||
|
{-| Create a SimpleFilter out of two optionally present lists.
|
||||||
|
-}
|
||||||
|
toSimpleFilter : Maybe (List comparable) -> Maybe (List comparable) -> SimpleFilter comparable
|
||||||
|
toSimpleFilter these notThese =
|
||||||
|
let
|
||||||
|
no : List comparable
|
||||||
|
no = Maybe.withDefault [] notThese
|
||||||
|
in
|
||||||
|
case these of
|
||||||
|
Just yes ->
|
||||||
|
{ specificOnes =
|
||||||
|
Dict.union
|
||||||
|
(Dict.fromList ( List.map (\x -> Tuple.pair x False) no ))
|
||||||
|
(Dict.fromList ( List.map (\x -> Tuple.pair x True) yes ))
|
||||||
|
, includeOthers = False
|
||||||
|
}
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
{ specificOnes =
|
||||||
|
no
|
||||||
|
|> List.map (\x -> Tuple.pair x False)
|
||||||
|
|> Dict.fromList
|
||||||
|
, includeOthers = True
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Form a filter that includes values if it is included in either filters.
|
||||||
|
-}
|
||||||
|
union : SimpleFilter comparable -> SimpleFilter comparable -> SimpleFilter comparable
|
||||||
|
union f1 f2 =
|
||||||
|
{ specificOnes =
|
||||||
|
Dict.merge
|
||||||
|
(\key v1 -> Dict.insert key (v1 || f2.includeOthers))
|
||||||
|
(\key v1 v2 -> Dict.insert key (v1 || v2))
|
||||||
|
(\key v2 -> Dict.insert key (f1.includeOthers || v2))
|
||||||
|
f1.specificOnes
|
||||||
|
f2.specificOnes
|
||||||
|
Dict.empty
|
||||||
|
, includeOthers = f1.includeOthers && f2.includeOthers
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| Add a value that should be included.
|
||||||
|
-}
|
||||||
|
with : comparable -> SimpleFilter comparable -> SimpleFilter comparable
|
||||||
|
with x f =
|
||||||
|
{ f | specificOnes = Dict.insert x True f.specificOnes }
|
||||||
|
|
||||||
|
{-| Include all values that haven't been mentioned.
|
||||||
|
-}
|
||||||
|
withOthers : SimpleFilter comparable -> SimpleFilter comparable
|
||||||
|
withOthers f =
|
||||||
|
{ f | includeOthers = True }
|
||||||
|
|
||||||
|
{-| Add a value that should be ignored.
|
||||||
|
-}
|
||||||
|
without : comparable -> SimpleFilter comparable -> SimpleFilter comparable
|
||||||
|
without x f =
|
||||||
|
{ f | specificOnes = Dict.insert x False f.specificOnes }
|
||||||
|
|
||||||
|
{-| Ignore all values that haven't been mentioned.
|
||||||
|
-}
|
||||||
|
withoutOthers : SimpleFilter comparable -> SimpleFilter comparable
|
||||||
|
withoutOthers f =
|
||||||
|
{ f | includeOthers = False }
|
|
@ -0,0 +1,246 @@
|
||||||
|
module Internal.Tools.Filters.SpecObjects exposing
|
||||||
|
( EventFilter
|
||||||
|
, Filter
|
||||||
|
, RoomEventFilter
|
||||||
|
, RoomFilter
|
||||||
|
, StateFilter
|
||||||
|
, encodeEventFilter
|
||||||
|
, encodeFilter
|
||||||
|
, encodeRoomEventFilter
|
||||||
|
, encodeRoomFilter
|
||||||
|
, encodeStateFilter
|
||||||
|
, eventFilterDecoder
|
||||||
|
, filterDecoder
|
||||||
|
, roomEventFilterDecoder
|
||||||
|
, roomFilterDecoder
|
||||||
|
, stateFilterDecoder
|
||||||
|
)
|
||||||
|
|
||||||
|
{-| Automatically generated 'SpecObjects'
|
||||||
|
|
||||||
|
Last generated at Unix time 1681915222
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Internal.Tools.DecodeExtra as D exposing (opField, opFieldWithDefault)
|
||||||
|
import Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||||
|
import Internal.Tools.SpecEnums as Enums
|
||||||
|
import Json.Decode as D
|
||||||
|
import Json.Encode as E
|
||||||
|
|
||||||
|
|
||||||
|
{-| Filter that describes which events to include/exclude.
|
||||||
|
-}
|
||||||
|
type alias EventFilter =
|
||||||
|
{ limit : Maybe Int
|
||||||
|
, notSenders : Maybe (List String)
|
||||||
|
, notTypes : Maybe (List String)
|
||||||
|
, senders : Maybe (List String)
|
||||||
|
, types : Maybe (List String)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
encodeEventFilter : EventFilter -> E.Value
|
||||||
|
encodeEventFilter data =
|
||||||
|
maybeObject
|
||||||
|
[ ( "limit", Maybe.map E.int data.limit )
|
||||||
|
, ( "not_senders", Maybe.map (E.list E.string) data.notSenders )
|
||||||
|
, ( "not_types", Maybe.map (E.list E.string) data.notTypes )
|
||||||
|
, ( "senders", Maybe.map (E.list E.string) data.senders )
|
||||||
|
, ( "types", Maybe.map (E.list E.string) data.types )
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
eventFilterDecoder : D.Decoder EventFilter
|
||||||
|
eventFilterDecoder =
|
||||||
|
D.map5
|
||||||
|
(\a b c d e ->
|
||||||
|
{ limit = a, notSenders = b, notTypes = c, senders = d, types = e }
|
||||||
|
)
|
||||||
|
(opField "limit" D.int)
|
||||||
|
(opField "not_senders" (D.list D.string))
|
||||||
|
(opField "not_types" (D.list D.string))
|
||||||
|
(opField "senders" (D.list D.string))
|
||||||
|
(opField "types" (D.list D.string))
|
||||||
|
|
||||||
|
|
||||||
|
{-| Main filter for filtering results
|
||||||
|
-}
|
||||||
|
type alias Filter =
|
||||||
|
{ accountData : Maybe EventFilter
|
||||||
|
, eventFields : Maybe (List String)
|
||||||
|
, eventFormat : Enums.EventFormat
|
||||||
|
, presence : Maybe EventFilter
|
||||||
|
, room : Maybe RoomFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
encodeFilter : Filter -> E.Value
|
||||||
|
encodeFilter data =
|
||||||
|
maybeObject
|
||||||
|
[ ( "account_data", Maybe.map encodeEventFilter data.accountData )
|
||||||
|
, ( "event_fields", Maybe.map (E.list E.string) data.eventFields )
|
||||||
|
, ( "event_format", Just <| Enums.encodeEventFormat data.eventFormat )
|
||||||
|
, ( "presence", Maybe.map encodeEventFilter data.presence )
|
||||||
|
, ( "room", Maybe.map encodeRoomFilter data.room )
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
filterDecoder : D.Decoder Filter
|
||||||
|
filterDecoder =
|
||||||
|
D.map5
|
||||||
|
(\a b c d e ->
|
||||||
|
{ accountData = a, eventFields = b, eventFormat = c, presence = d, room = e }
|
||||||
|
)
|
||||||
|
(opField "account_data" eventFilterDecoder)
|
||||||
|
(opField "event_fields" (D.list D.string))
|
||||||
|
(opFieldWithDefault "event_format" Enums.Client Enums.eventFormatDecoder)
|
||||||
|
(opField "presence" eventFilterDecoder)
|
||||||
|
(opField "room" roomFilterDecoder)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Filter that describes which events to include/exclude in a Matrix room.
|
||||||
|
-}
|
||||||
|
type alias RoomEventFilter =
|
||||||
|
{ containsUrl : Maybe Bool
|
||||||
|
, includeRedundantMembers : Bool
|
||||||
|
, lazyLoadMembers : Bool
|
||||||
|
, limit : Maybe Int
|
||||||
|
, notRooms : Maybe (List String)
|
||||||
|
, notSenders : Maybe (List String)
|
||||||
|
, notTypes : Maybe (List String)
|
||||||
|
, rooms : Maybe (List String)
|
||||||
|
, senders : Maybe (List String)
|
||||||
|
, types : Maybe (List String)
|
||||||
|
, unreadThreadNotifications : Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
encodeRoomEventFilter : RoomEventFilter -> E.Value
|
||||||
|
encodeRoomEventFilter data =
|
||||||
|
maybeObject
|
||||||
|
[ ( "contains_url", Maybe.map E.bool data.containsUrl )
|
||||||
|
, ( "include_redundant_members", Just <| E.bool data.includeRedundantMembers )
|
||||||
|
, ( "lazy_load_members", Just <| E.bool data.lazyLoadMembers )
|
||||||
|
, ( "limit", Maybe.map E.int data.limit )
|
||||||
|
, ( "not_rooms", Maybe.map (E.list E.string) data.notRooms )
|
||||||
|
, ( "not_senders", Maybe.map (E.list E.string) data.notSenders )
|
||||||
|
, ( "not_types", Maybe.map (E.list E.string) data.notTypes )
|
||||||
|
, ( "rooms", Maybe.map (E.list E.string) data.rooms )
|
||||||
|
, ( "senders", Maybe.map (E.list E.string) data.senders )
|
||||||
|
, ( "types", Maybe.map (E.list E.string) data.types )
|
||||||
|
, ( "unread_thread_notifications", Just <| E.bool data.unreadThreadNotifications )
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
roomEventFilterDecoder : D.Decoder RoomEventFilter
|
||||||
|
roomEventFilterDecoder =
|
||||||
|
D.map11
|
||||||
|
(\a b c d e f g h i j k ->
|
||||||
|
{ containsUrl = a, includeRedundantMembers = b, lazyLoadMembers = c, limit = d, notRooms = e, notSenders = f, notTypes = g, rooms = h, senders = i, types = j, unreadThreadNotifications = k }
|
||||||
|
)
|
||||||
|
(opField "contains_url" D.bool)
|
||||||
|
(opFieldWithDefault "include_redundant_members" False D.bool)
|
||||||
|
(opFieldWithDefault "lazy_load_members" False D.bool)
|
||||||
|
(opField "limit" D.int)
|
||||||
|
(opField "not_rooms" (D.list D.string))
|
||||||
|
(opField "not_senders" (D.list D.string))
|
||||||
|
(opField "not_types" (D.list D.string))
|
||||||
|
(opField "rooms" (D.list D.string))
|
||||||
|
(opField "senders" (D.list D.string))
|
||||||
|
(opField "types" (D.list D.string))
|
||||||
|
(opFieldWithDefault "unread_thread_notifications" False D.bool)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Filter that describes what should and shouldn't be included for rooms.
|
||||||
|
-}
|
||||||
|
type alias RoomFilter =
|
||||||
|
{ accountData : Maybe RoomEventFilter
|
||||||
|
, ephemeral : Maybe RoomEventFilter
|
||||||
|
, includeLeave : Bool
|
||||||
|
, notRooms : Maybe (List String)
|
||||||
|
, rooms : Maybe (List String)
|
||||||
|
, state : Maybe StateFilter
|
||||||
|
, timeline : Maybe RoomEventFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
encodeRoomFilter : RoomFilter -> E.Value
|
||||||
|
encodeRoomFilter data =
|
||||||
|
maybeObject
|
||||||
|
[ ( "account_data", Maybe.map encodeRoomEventFilter data.accountData )
|
||||||
|
, ( "ephemeral", Maybe.map encodeRoomEventFilter data.ephemeral )
|
||||||
|
, ( "include_leave", Just <| E.bool data.includeLeave )
|
||||||
|
, ( "not_rooms", Maybe.map (E.list E.string) data.notRooms )
|
||||||
|
, ( "rooms", Maybe.map (E.list E.string) data.rooms )
|
||||||
|
, ( "state", Maybe.map encodeStateFilter data.state )
|
||||||
|
, ( "timeline", Maybe.map encodeRoomEventFilter data.timeline )
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
roomFilterDecoder : D.Decoder RoomFilter
|
||||||
|
roomFilterDecoder =
|
||||||
|
D.map7
|
||||||
|
(\a b c d e f g ->
|
||||||
|
{ accountData = a, ephemeral = b, includeLeave = c, notRooms = d, rooms = e, state = f, timeline = g }
|
||||||
|
)
|
||||||
|
(opField "account_data" roomEventFilterDecoder)
|
||||||
|
(opField "ephemeral" roomEventFilterDecoder)
|
||||||
|
(opFieldWithDefault "include_leave" False D.bool)
|
||||||
|
(opField "not_rooms" (D.list D.string))
|
||||||
|
(opField "rooms" (D.list D.string))
|
||||||
|
(opField "state" stateFilterDecoder)
|
||||||
|
(opField "timeline" roomEventFilterDecoder)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Filter that describes which events to include/exclude in a Matrix room.
|
||||||
|
-}
|
||||||
|
type alias StateFilter =
|
||||||
|
{ containsUrl : Maybe Bool
|
||||||
|
, includeRedundantMembers : Bool
|
||||||
|
, lazyLoadMembers : Bool
|
||||||
|
, limit : Maybe Int
|
||||||
|
, notRooms : Maybe (List String)
|
||||||
|
, notSenders : Maybe (List String)
|
||||||
|
, notTypes : Maybe (List String)
|
||||||
|
, rooms : Maybe (List String)
|
||||||
|
, senders : Maybe (List String)
|
||||||
|
, types : Maybe (List String)
|
||||||
|
, unreadThreadNotifications : Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
encodeStateFilter : StateFilter -> E.Value
|
||||||
|
encodeStateFilter data =
|
||||||
|
maybeObject
|
||||||
|
[ ( "contains_url", Maybe.map E.bool data.containsUrl )
|
||||||
|
, ( "include_redundant_members", Just <| E.bool data.includeRedundantMembers )
|
||||||
|
, ( "lazy_load_members", Just <| E.bool data.lazyLoadMembers )
|
||||||
|
, ( "limit", Maybe.map E.int data.limit )
|
||||||
|
, ( "not_rooms", Maybe.map (E.list E.string) data.notRooms )
|
||||||
|
, ( "not_senders", Maybe.map (E.list E.string) data.notSenders )
|
||||||
|
, ( "not_types", Maybe.map (E.list E.string) data.notTypes )
|
||||||
|
, ( "rooms", Maybe.map (E.list E.string) data.rooms )
|
||||||
|
, ( "senders", Maybe.map (E.list E.string) data.senders )
|
||||||
|
, ( "types", Maybe.map (E.list E.string) data.types )
|
||||||
|
, ( "unread_thread_notifications", Just <| E.bool data.unreadThreadNotifications )
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
stateFilterDecoder : D.Decoder StateFilter
|
||||||
|
stateFilterDecoder =
|
||||||
|
D.map11
|
||||||
|
(\a b c d e f g h i j k ->
|
||||||
|
{ containsUrl = a, includeRedundantMembers = b, lazyLoadMembers = c, limit = d, notRooms = e, notSenders = f, notTypes = g, rooms = h, senders = i, types = j, unreadThreadNotifications = k }
|
||||||
|
)
|
||||||
|
(opField "contains_url" D.bool)
|
||||||
|
(opFieldWithDefault "include_redundant_members" False D.bool)
|
||||||
|
(opFieldWithDefault "lazy_load_members" False D.bool)
|
||||||
|
(opField "limit" D.int)
|
||||||
|
(opField "not_rooms" (D.list D.string))
|
||||||
|
(opField "not_senders" (D.list D.string))
|
||||||
|
(opField "not_types" (D.list D.string))
|
||||||
|
(opField "rooms" (D.list D.string))
|
||||||
|
(opField "senders" (D.list D.string))
|
||||||
|
(opField "types" (D.list D.string))
|
||||||
|
(opFieldWithDefault "unread_thread_notifications" False D.bool)
|
|
@ -0,0 +1,135 @@
|
||||||
|
version: v1
|
||||||
|
name: SpecObjects
|
||||||
|
objects:
|
||||||
|
Filter:
|
||||||
|
description: Main filter for filtering results
|
||||||
|
fields:
|
||||||
|
account_data:
|
||||||
|
type: EventFilter
|
||||||
|
required: false
|
||||||
|
event_fields:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
event_format:
|
||||||
|
type: Enums.EventFormat
|
||||||
|
default: Enums.Client
|
||||||
|
presence:
|
||||||
|
type: EventFilter
|
||||||
|
required: false
|
||||||
|
room:
|
||||||
|
type: RoomFilter
|
||||||
|
required: false
|
||||||
|
EventFilter:
|
||||||
|
description: Filter that describes which events to include/exclude.
|
||||||
|
fields:
|
||||||
|
limit:
|
||||||
|
type: int
|
||||||
|
required: false
|
||||||
|
not_senders:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
not_types:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
senders:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
types:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
RoomFilter:
|
||||||
|
description: Filter that describes what should and shouldn't be included for rooms.
|
||||||
|
fields:
|
||||||
|
account_data:
|
||||||
|
type: RoomEventFilter
|
||||||
|
required: false
|
||||||
|
ephemeral:
|
||||||
|
type: RoomEventFilter
|
||||||
|
required: false
|
||||||
|
include_leave:
|
||||||
|
type: bool
|
||||||
|
default: 'False'
|
||||||
|
not_rooms:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
rooms:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
state:
|
||||||
|
type: StateFilter
|
||||||
|
required: false
|
||||||
|
timeline:
|
||||||
|
type: RoomEventFilter
|
||||||
|
required: false
|
||||||
|
RoomEventFilter:
|
||||||
|
description: Filter that describes which events to include/exclude in a Matrix room.
|
||||||
|
fields:
|
||||||
|
contains_url:
|
||||||
|
type: bool
|
||||||
|
required: false
|
||||||
|
include_redundant_members:
|
||||||
|
type: bool
|
||||||
|
default: 'False'
|
||||||
|
lazy_load_members:
|
||||||
|
type: bool
|
||||||
|
default: 'False'
|
||||||
|
limit:
|
||||||
|
type: int
|
||||||
|
required: false
|
||||||
|
not_rooms:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
not_senders:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
not_types:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
rooms:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
senders:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
types:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
unread_thread_notifications:
|
||||||
|
type: bool
|
||||||
|
default: 'False'
|
||||||
|
StateFilter:
|
||||||
|
description: Filter that describes which events to include/exclude in a Matrix room.
|
||||||
|
fields:
|
||||||
|
contains_url:
|
||||||
|
type: bool
|
||||||
|
required: false
|
||||||
|
include_redundant_members:
|
||||||
|
type: bool
|
||||||
|
default: 'False'
|
||||||
|
lazy_load_members:
|
||||||
|
type: bool
|
||||||
|
default: 'False'
|
||||||
|
limit:
|
||||||
|
type: int
|
||||||
|
required: false
|
||||||
|
not_rooms:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
not_senders:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
not_types:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
rooms:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
senders:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
types:
|
||||||
|
type: '[string]'
|
||||||
|
required: false
|
||||||
|
unread_thread_notifications:
|
||||||
|
type: bool
|
||||||
|
default: 'False'
|
|
@ -0,0 +1,14 @@
|
||||||
|
module Internal.Tools.VaultResult exposing (..)
|
||||||
|
|
||||||
|
import Internal.Tools.Exceptions as X
|
||||||
|
import Task exposing (Task)
|
||||||
|
|
||||||
|
|
||||||
|
type Info b a
|
||||||
|
= Info a
|
||||||
|
| NoInfo
|
||||||
|
| InfoFailed { status : LoadingError, retry : Task X.Error b }
|
||||||
|
|
||||||
|
|
||||||
|
type LoadingError
|
||||||
|
= NeverRequested
|
Loading…
Reference in New Issue