Compare commits

..

2 Commits

Author SHA1 Message Date
1d3b0febde Refactor some code. 2018-12-23 21:29:48 -08:00
70d6eba427 Add basic notification priority filtering. 2018-12-23 21:17:03 -08:00
4 changed files with 66 additions and 47 deletions

View File

@ -284,7 +284,7 @@ updateSyncResponse model r notify =
notification sr = findFirstBy
(\(s, e) -> e.originServerTs)
(\(s, e) -> e.sender /= model.loginUsername)
<| notificationEvents sr
<| joinedRoomNotificationEvents sr
notificationCmd sr = if notify
then Maybe.withDefault Cmd.none
<| Maybe.map (\(s, e) -> sendNotificationPort

View File

@ -1,6 +1,7 @@
module Scylla.AccountData exposing (..)
import Scylla.Sync exposing (AccountData, JoinedRoom, roomAccountData)
import Scylla.Sync exposing (SyncResponse, AccountData, JoinedRoom, roomAccountData)
import Json.Decode as Decode
import Dict
type NotificationSetting = Normal | MentionsOnly | None
@ -20,3 +21,10 @@ roomNotificationSetting jr = Maybe.withDefault Normal
<| Maybe.andThen Result.toMaybe
<| Maybe.map (Decode.decodeValue notificationSettingDecoder)
<| roomAccountData jr "com.danilafe.scylla.notifications"
roomIdNotificationSetting : SyncResponse -> String -> NotificationSetting
roomIdNotificationSetting sr s = Maybe.withDefault Normal
<| Maybe.map roomNotificationSetting
<| Maybe.andThen (Dict.get s)
<| Maybe.andThen .join sr.rooms

View File

@ -1,5 +1,8 @@
port module Scylla.Notification exposing (..)
import Json.Decode
import Scylla.Sync exposing (SyncResponse, RoomEvent, joinedRoomsTimelineEvents)
import Scylla.AccountData exposing (..)
import Json.Decode as Decode exposing (string, field)
import Dict
type alias Notification =
{ name : String
@ -9,3 +12,25 @@ type alias Notification =
port sendNotificationPort : Notification -> Cmd msg
port onNotificationClickPort : (String -> msg) -> Sub msg
producesNotification : NotificationSetting -> RoomEvent -> Bool
producesNotification ns re = case ns of
Normal -> True
_ -> False
notificationText : RoomEvent -> 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 s =
let
applyPair k = List.map (\v -> (k, v))
in
List.sortBy (\(k, v) -> v.originServerTs)
<| Dict.foldl (\k v a -> a ++ applyPair k v) []
<| Dict.map (\k v -> List.filter (producesNotification (roomIdNotificationSetting s k)) v)
<| joinedRoomsTimelineEvents s

View File

@ -1,6 +1,5 @@
module Scylla.Sync exposing (..)
import Scylla.Api exposing (..)
import Scylla.Notification exposing (..)
import Scylla.Login exposing (Username)
import Scylla.Route exposing (RoomId)
import Dict exposing (Dict)
@ -273,7 +272,7 @@ historyResponseDecoder =
|> required "end" string
|> required "chunk" (list roomEventDecoder)
-- Business Logic
-- Business Logic: Helper Functions
uniqueByRecursive : (a -> comparable) -> List a -> Set comparable -> List a
uniqueByRecursive f l s = case l of
x::tail -> if Set.member (f x) s
@ -433,8 +432,9 @@ senderName s =
in
String.slice 1 colonIndex s
roomStateEvents : JoinedRoom -> List StateEvent
roomStateEvents jr =
-- Business Logic: Events
allRoomStateEvents : JoinedRoom -> List StateEvent
allRoomStateEvents jr =
let
stateEvents = Maybe.withDefault [] <| Maybe.andThen .events jr.state
timelineEvents = Maybe.withDefault [] <| Maybe.andThen .events jr.timeline
@ -452,6 +452,29 @@ roomStateEvents jr =
in
allStateEvents
allRoomDictTimelineEvents : Dict String { a | timeline : Maybe Timeline } -> List RoomEvent
allRoomDictTimelineEvents dict = List.concatMap (Maybe.withDefault [] << .events)
<| List.filterMap .timeline
<| Dict.values dict
allTimelineEvents : SyncResponse -> List RoomEvent
allTimelineEvents s =
let
eventsFor f = Maybe.withDefault []
<| Maybe.map allRoomDictTimelineEvents
<| Maybe.andThen f s.rooms
joinedEvents = eventsFor .join
leftEvents = eventsFor .leave
in
uniqueBy .eventId <| leftEvents ++ joinedEvents
joinedRoomsTimelineEvents : SyncResponse -> Dict String (List RoomEvent)
joinedRoomsTimelineEvents s =
Maybe.withDefault Dict.empty
<| Maybe.map (Dict.map (\k v -> Maybe.withDefault [] <| Maybe.andThen .events v.timeline))
<| Maybe.andThen .join s.rooms
-- Business Logic: Room Info
roomAccountData : JoinedRoom -> String -> Maybe Decode.Value
roomAccountData jr et =
Maybe.map .content
@ -462,32 +485,10 @@ roomName : JoinedRoom -> Maybe String
roomName jr =
let
name c = Result.toMaybe <| Decode.decodeValue (field "name" string) c
nameEvent = findLastEvent (((==) "m.room.name") << .type_) <| roomStateEvents jr
nameEvent = findLastEvent (((==) "m.room.name") << .type_) <| allRoomStateEvents jr
in
Maybe.andThen (name << .content) nameEvent
-- Business Logic: Event Extraction
notificationText : RoomEvent -> String
notificationText re = case (Decode.decodeValue (field "msgtype" string) re.content) of
Ok "m.text" -> Result.withDefault "" <| (Decode.decodeValue (field "body" string) re.content)
_ -> ""
notificationEvents : SyncResponse -> List (String, RoomEvent)
notificationEvents s =
let
applyPair k = List.map (\v -> (k, v))
in
List.sortBy (\(k, v) -> v.originServerTs)
<| Dict.foldl (\k v a -> a ++ applyPair k v) []
<| joinedRoomsEvents s
joinedRoomsEvents : SyncResponse -> Dict String (List RoomEvent)
joinedRoomsEvents s =
Maybe.withDefault Dict.empty
<| Maybe.map (Dict.map (\k v -> Maybe.withDefault [] <| Maybe.andThen .events v.timeline))
<| Maybe.andThen .join s.rooms
-- Business Logic: User Extraction
roomTypingUsers : JoinedRoom -> List Username
roomTypingUsers jr = Maybe.withDefault []
<| Maybe.andThen (Result.toMaybe << Decode.decodeValue (Decode.field "user_ids" (list string)))
@ -495,21 +496,6 @@ roomTypingUsers jr = Maybe.withDefault []
<| Maybe.andThen (findLast (((==) "m.typing") << .type_))
<| Maybe.andThen .events jr.ephemeral
allRoomDictEvents : Dict String { a | timeline : Maybe Timeline } -> List RoomEvent
allRoomDictEvents dict = List.concatMap (Maybe.withDefault [] << .events)
<| List.filterMap .timeline
<| Dict.values dict
allEvents : SyncResponse -> List RoomEvent
allEvents s =
let
eventsFor f = Maybe.withDefault []
<| Maybe.map allRoomDictEvents
<| Maybe.andThen f s.rooms
joinedEvents = eventsFor .join
leftEvents = eventsFor .leave
in
uniqueBy .eventId <| leftEvents ++ joinedEvents
-- Business Logic: Users
allUsers : SyncResponse -> List Username
allUsers s = uniqueBy (\u -> u) <| List.map .sender <| allEvents s
allUsers s = uniqueBy (\u -> u) <| List.map .sender <| allTimelineEvents s