Compare commits
	
		
			No commits in common. "996da079e2cd3b1ae7ef404d2e0687b1bcbb2552" and "3e7d12b6e4d970e17e271eed0fab68e86cddc9c8" have entirely different histories.
		
	
	
		
			996da079e2
			...
			3e7d12b6e4
		
	
		
@ -36,7 +36,6 @@ init flags url key =
 | 
			
		||||
            , errors = []
 | 
			
		||||
            , roomText = Dict.empty
 | 
			
		||||
            , transactionId = 0
 | 
			
		||||
            , userData = Dict.empty
 | 
			
		||||
            }
 | 
			
		||||
        cmd = case flags.token of
 | 
			
		||||
            Just _ -> Cmd.none
 | 
			
		||||
@ -59,9 +58,7 @@ update msg model = case msg of
 | 
			
		||||
    TryUrl urlRequest -> updateTryUrl model urlRequest
 | 
			
		||||
    ChangeRoute r -> ({ model | route = r }, Cmd.none)
 | 
			
		||||
    ReceiveLoginResponse r -> updateLoginResponse model r
 | 
			
		||||
    ReceiveFirstSyncResponse r -> updateSyncResponse model r False
 | 
			
		||||
    ReceiveSyncResponse r -> updateSyncResponse model r True
 | 
			
		||||
    ReceiveUserData s r -> (model, Cmd.none)
 | 
			
		||||
    ReceiveSyncResponse r -> updateSyncResponse model r
 | 
			
		||||
    ChangeRoomText r t -> ({ model | roomText = Dict.insert r t model.roomText}, Cmd.none)
 | 
			
		||||
    SendRoomText r -> updateSendRoomText model r
 | 
			
		||||
    SendRoomTextResponse r -> (model, Cmd.none)
 | 
			
		||||
@ -90,8 +87,8 @@ updateLoginResponse model r = case r of
 | 
			
		||||
        ] )
 | 
			
		||||
    Err e  -> (model, Cmd.none)
 | 
			
		||||
 | 
			
		||||
updateSyncResponse : Model -> Result Http.Error SyncResponse -> Bool -> (Model, Cmd Msg)
 | 
			
		||||
updateSyncResponse model r notify =
 | 
			
		||||
updateSyncResponse : Model -> Result Http.Error SyncResponse -> (Model, Cmd Msg)
 | 
			
		||||
updateSyncResponse model r =
 | 
			
		||||
    let
 | 
			
		||||
        token = Maybe.withDefault "" model.token
 | 
			
		||||
        nextBatch = Result.withDefault model.sync.nextBatch
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,6 @@ import Scylla.Model exposing (..)
 | 
			
		||||
import Scylla.Api exposing (..)
 | 
			
		||||
import Scylla.Sync exposing (syncResponseDecoder)
 | 
			
		||||
import Scylla.Login exposing (loginResponseDecoder, Username, Password)
 | 
			
		||||
import Scylla.UserData exposing (userDataDecoder, UserData)
 | 
			
		||||
import Json.Encode exposing (object, string, int)
 | 
			
		||||
import Http exposing (request, emptyBody, jsonBody, expectJson, expectWhatever)
 | 
			
		||||
 | 
			
		||||
@ -17,7 +16,7 @@ firstSync apiUrl token = request
 | 
			
		||||
    , headers = authenticatedHeaders token
 | 
			
		||||
    , url = (fullUrl apiUrl) ++ "/sync"
 | 
			
		||||
    , body = emptyBody
 | 
			
		||||
    , expect = expectJson ReceiveFirstSyncResponse syncResponseDecoder
 | 
			
		||||
    , expect = expectJson ReceiveSyncResponse syncResponseDecoder
 | 
			
		||||
    , timeout = Nothing
 | 
			
		||||
    , tracker = Nothing
 | 
			
		||||
    }
 | 
			
		||||
@ -67,14 +66,3 @@ login apiUrl username password = request
 | 
			
		||||
    , timeout = Nothing
 | 
			
		||||
    , tracker = Nothing
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
userData : ApiUrl -> ApiToken -> Username -> Cmd Msg
 | 
			
		||||
userData apiUrl token username = request
 | 
			
		||||
    { method = "GET"
 | 
			
		||||
    , headers = authenticatedHeaders token
 | 
			
		||||
    , url = (fullUrl apiUrl) ++ "/profile/" ++ username
 | 
			
		||||
    , body = emptyBody
 | 
			
		||||
    , expect = expectJson (ReceiveUserData username) userDataDecoder
 | 
			
		||||
    , timeout = Nothing
 | 
			
		||||
    , tracker = Nothing
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,6 @@ module Scylla.Model exposing (..)
 | 
			
		||||
import Scylla.Api exposing (..)
 | 
			
		||||
import Scylla.Sync exposing (SyncResponse, JoinedRoom)
 | 
			
		||||
import Scylla.Login exposing (LoginResponse, Username, Password)
 | 
			
		||||
import Scylla.UserData exposing (UserData)
 | 
			
		||||
import Scylla.Route exposing (Route)
 | 
			
		||||
import Browser.Navigation as Nav
 | 
			
		||||
import Dict exposing (Dict)
 | 
			
		||||
@ -21,7 +20,6 @@ type alias Model =
 | 
			
		||||
    , errors : List String
 | 
			
		||||
    , roomText : Dict String String
 | 
			
		||||
    , transactionId : Int
 | 
			
		||||
    , userData : Dict Username UserData
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
type Msg =
 | 
			
		||||
@ -34,8 +32,6 @@ type Msg =
 | 
			
		||||
    | ChangeRoomText String String -- Change to a room's input text
 | 
			
		||||
    | SendRoomText String -- Sends a message typed into a given room's input
 | 
			
		||||
    | SendRoomTextResponse (Result Http.Error ()) -- A send message response finished
 | 
			
		||||
    | ReceiveFirstSyncResponse (Result Http.Error SyncResponse) -- HTTP, Sync has finished
 | 
			
		||||
    | ReceiveSyncResponse (Result Http.Error SyncResponse) -- HTTP, Sync has finished
 | 
			
		||||
    | ReceiveLoginResponse (Result Http.Error LoginResponse) -- HTTP, Login has finished
 | 
			
		||||
    | ReceiveUserData Username (Result Http.Error UserData)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
port module Scylla.Notification exposing (..)
 | 
			
		||||
import Scylla.Model exposing (..)
 | 
			
		||||
import Json.Decode
 | 
			
		||||
 | 
			
		||||
type alias Notification =
 | 
			
		||||
    { name : String
 | 
			
		||||
    , text : String
 | 
			
		||||
    , room : String
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
port sendNotificationPort : Notification -> Cmd msg
 | 
			
		||||
port onNotificationClickPort : (Json.Decode.Value -> msg) -> Sub msg
 | 
			
		||||
port onNotificationClockPort : (Json.Decode.Value -> msg) -> Sub msg
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
module Scylla.Sync exposing (..)
 | 
			
		||||
import Scylla.Api exposing (..)
 | 
			
		||||
import Scylla.Notification exposing (..)
 | 
			
		||||
import Scylla.Login exposing (Username)
 | 
			
		||||
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)
 | 
			
		||||
@ -269,7 +267,6 @@ uniqueByRecursive f l s = case l of
 | 
			
		||||
uniqueBy : (a -> comparable) -> List a -> List a
 | 
			
		||||
uniqueBy f l = uniqueByRecursive f l Set.empty
 | 
			
		||||
 | 
			
		||||
-- Business Logic: Merging
 | 
			
		||||
mergeMaybe : (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a
 | 
			
		||||
mergeMaybe f l r = case (l, r) of
 | 
			
		||||
    (Just v1, Just v2) -> Just <| f v1 v2
 | 
			
		||||
@ -350,16 +347,6 @@ mergeSyncResponse l r =
 | 
			
		||||
    , accountData = mergeMaybe mergeAccountData l.accountData r.accountData
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
-- Business Logic: Names
 | 
			
		||||
senderName : String -> String
 | 
			
		||||
senderName s =
 | 
			
		||||
    let
 | 
			
		||||
        colonIndex = Maybe.withDefault -1 
 | 
			
		||||
            <| List.head
 | 
			
		||||
            <| String.indexes ":" s
 | 
			
		||||
    in
 | 
			
		||||
        String.slice 1 colonIndex s
 | 
			
		||||
 | 
			
		||||
roomName : JoinedRoom -> Maybe String
 | 
			
		||||
roomName jr = 
 | 
			
		||||
    let
 | 
			
		||||
@ -368,35 +355,3 @@ roomName jr =
 | 
			
		||||
        name e = Result.toMaybe <| Decode.decodeValue (field "name" string) e.content
 | 
			
		||||
    in
 | 
			
		||||
        Maybe.andThen name <| Maybe.andThen nameEvent <| Maybe.andThen .events <| state
 | 
			
		||||
 | 
			
		||||
-- Business Logic: Event Extraction
 | 
			
		||||
notificationEvent : SyncResponse -> Maybe (String, RoomEvent)
 | 
			
		||||
notificationEvent s =
 | 
			
		||||
    let
 | 
			
		||||
        applyPair k = List.map (\v -> (k, v))
 | 
			
		||||
    in
 | 
			
		||||
        List.head
 | 
			
		||||
        <| 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
 | 
			
		||||
roomsUsers : SyncResponse -> List Username
 | 
			
		||||
roomsUsers s =
 | 
			
		||||
    let
 | 
			
		||||
        users dict =
 | 
			
		||||
            List.map .sender
 | 
			
		||||
            <| (List.concatMap <| Maybe.withDefault [] << .events)
 | 
			
		||||
            <| (List.filterMap .timeline)
 | 
			
		||||
            <| Dict.values dict
 | 
			
		||||
        usersFor f = Maybe.withDefault [] <| Maybe.map users <| Maybe.andThen f s.rooms
 | 
			
		||||
        joinedUsers = usersFor .join
 | 
			
		||||
        leftUsers = usersFor .leave
 | 
			
		||||
    in
 | 
			
		||||
        leftUsers ++ joinedUsers
 | 
			
		||||
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
module Scylla.UserData exposing (..)
 | 
			
		||||
import Json.Decode as Decode exposing (Decoder, int, string, float, list, value, dict, bool, field)
 | 
			
		||||
import Json.Decode.Pipeline exposing (required, optional)
 | 
			
		||||
 | 
			
		||||
type alias UserData =
 | 
			
		||||
    { displayName : Maybe String
 | 
			
		||||
    , avatarUrl : Maybe String
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
userDataDecoder : Decoder UserData
 | 
			
		||||
userDataDecoder =
 | 
			
		||||
    Decode.succeed UserData
 | 
			
		||||
        |> optional "displayname" (Decode.map Just string) Nothing
 | 
			
		||||
        |> optional "avatar_url" (Decode.map Just string) Nothing
 | 
			
		||||
@ -19,6 +19,15 @@ stringColor s =
 | 
			
		||||
    in
 | 
			
		||||
        "hsl(" ++ hue ++ ", 82%, 71%)"
 | 
			
		||||
 | 
			
		||||
senderName : String -> String
 | 
			
		||||
senderName s =
 | 
			
		||||
    let
 | 
			
		||||
        colonIndex = Maybe.withDefault -1 
 | 
			
		||||
            <| List.head
 | 
			
		||||
            <| String.indexes ":" s
 | 
			
		||||
    in
 | 
			
		||||
        String.slice 1 colonIndex s
 | 
			
		||||
 | 
			
		||||
viewFull : Model -> List (Html Msg)
 | 
			
		||||
viewFull model = 
 | 
			
		||||
    let
 | 
			
		||||
 | 
			
		||||
@ -7,11 +7,6 @@ function setupNotificationPorts(app) {
 | 
			
		||||
        var options = {
 | 
			
		||||
            "body" : data.text
 | 
			
		||||
        }
 | 
			
		||||
        var n = new Notification(data.name, options)
 | 
			
		||||
        n.onclick = function() {
 | 
			
		||||
            app.ports.onNotificationClickPort.send({
 | 
			
		||||
                "room" : data.room
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        new Notification(data.name, options)
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user