import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput, onClick)
import Url exposing (percentEncode)
import Regex
import Dict
main =
Browser.element {
init = init,
view = view,
update = update,
subscriptions = \_ -> Sub.none
}
type Tab = TabJid | TabSMS | TabEmail | TabSIP
type alias Model = {
tab : Tab,
jabberId : String,
bifrost : Bifrost
}
init : () -> (Model, Cmd Msg)
init _ =
(Model TabJid "" ariaNet, Cmd.none)
type Msg = SetTab Tab | JabberID String | SMS String | Email String | SIP String | Gateway String
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
SetTab tab -> ({ model | tab = tab }, Cmd.none)
JabberID jid -> ({ model | jabberId = jid }, Cmd.none)
SMS tel -> ({ model | jabberId = telToJid tel }, Cmd.none)
Email email -> ({ model | jabberId = emailToJid email }, Cmd.none)
SIP sip -> ({ model | jabberId = sipToJid sip }, Cmd.none)
Gateway gw -> ({ model | bifrost = Maybe.withDefault ariaNet (Dict.get gw gateways) }, Cmd.none)
mkTab : Model -> Tab -> String -> Html Msg
mkTab model tab label =
let klass = if model.tab == tab then [class "current"] else []
in
li ([onClick (SetTab tab)] ++ klass)
[text label]
view : Model -> Html Msg
view model =
let matrixId = jidToMatrix model.bifrost model.jabberId
in
div [] [
select [title "Use Gateway", onInput Gateway] (List.map (\gateway ->
option [] [text gateway]
) (Dict.keys gateways)),
ul [class "tabs"] [
mkTab model TabJid "Jabber ID",
mkTab model TabSMS "SMS",
mkTab model TabEmail "Email",
mkTab model TabSIP "SIP"
],
case model.tab of
TabJid ->
input [
type_ "text",
placeholder "Jabber ID",
value model.jabberId,
onInput JabberID
] []
TabSMS ->
input [
type_ "tel",
placeholder "SMS",
onInput SMS
] []
TabEmail ->
input [
type_ "email",
placeholder "Email",
onInput Email
] []
TabSIP ->
input [
type_ "text",
placeholder "SIP",
onInput SIP
] [],
if matrixId /= "" then
a [class "mxid", target "_blank", href ("https://matrix.to/#/" ++ matrixId)] [text matrixId]
else
text ""
]
type alias Bifrost = {
domain : String,
prefix : String
}
gateways = Dict.fromList [("aria-net.org", ariaNet), ("matrix.org", matrixOrg)]
ariaNet = Bifrost "aria-net.org" "bifrost"
matrixOrg = Bifrost "matrix.org" "xmpp"
jidToMatrix : Bifrost -> String -> String
jidToMatrix gateway jid =
if jid == "" then
""
else
"@_" ++ gateway.prefix ++ "_" ++
String.replace "%" "=" (String.toLower (percentEncode jid)) ++
":" ++ gateway.domain
emailToJid : String -> String
emailToJid email =
if email == "" then
""
else
escapeJid email ++ "@smtp.cheogram.com"
sipToJid : String -> String
sipToJid sip =
if sip == "" then
""
else if String.startsWith "sip:" sip then
(escapeJid (String.dropLeft 4 sip)) ++ "@sip.cheogram.com"
else
(escapeJid sip) ++ "@sip.cheogram.com"
telToJid : String -> String
telToJid telish =
let digits = String.filter Char.isDigit telish
in
if String.startsWith "+" telish then
"+" ++ digits ++ "@cheogram.com"
else if String.startsWith "1" digits && String.length digits == 11 then
"+" ++ digits ++ "@cheogram.com"
else if String.length digits == 10 then
"+1" ++ digits ++ "@cheogram.com"
else
""
aRegex : String -> Regex.Regex
aRegex str = Maybe.withDefault Regex.never <| Regex.fromString str
escapeJid : String -> String
escapeJid str =
Regex.replace
(aRegex "[ \"&'/:<>@]")
(\match -> String.replace "%" "\\" (percentEncode match.match))
<|
Regex.replace
(aRegex "\\\\(20|22|26|27|2f|3a|3c|3e|40|5c)")
(\match -> "\\5c" ++ String.dropLeft 1 match.match)
str