added dialogs

This commit is contained in:
hariroshan 2023-02-26 16:51:44 +05:30
parent 0cfbddf9af
commit f454da12b5
10 changed files with 587 additions and 4 deletions

View File

@ -6,6 +6,7 @@ import Json.Decode as D
import Json.Encode as E
import Native exposing (..)
import Native.Attributes as N exposing (bindAttributeWithExpression, dangerousEvalExpression)
import Native.Dialogs as Dialogs
import Native.Event as Event
import Native.Frame as Frame
import Native.Layout as Layout
@ -91,6 +92,14 @@ init =
, isSaving = False
}
, Cmd.none
-- Process.sleep 5000
-- |> Task.andThen
-- (\_ ->
-- Dialogs.defaultAlertOption "Something terrible has happened"
-- |> Dialogs.setOkButtonText "Okay"
-- |> Dialogs.alert
-- )
-- |> Task.attempt (Result.toMaybe >> always NoOp)
)

View File

@ -10,6 +10,7 @@
"postinstall": "rescript"
},
"dependencies": {
"elm-taskport": "^2.0.1",
"happy-dom": "^6.0.4",
"rescript": "^10.0.1",
"vm-shim": "^0.0.6"

View File

@ -10,6 +10,7 @@ type rec context = {
flags: Js.Nullable.t<Obj.t>,
isIOS: bool,
isAndroid: bool,
taskportInit: unit => unit,
initPorts: Js.Nullable.t<Obj.t => unit>,
withCustomElements: (. Obj.t, Types.handler) => Obj.t,
elements: array<Types.customElement>,
@ -64,6 +65,7 @@ let start: config => unit = config => {
isAndroid: Types.isAndroid,
elm: config.elmModule,
elements: Native.allElements,
taskportInit: Taskport.register,
withCustomElements: CustomElement.withCustomElements,
run: () =>
NativescriptCore.Application.run({
@ -75,12 +77,12 @@ let start: config => unit = config => {
let elmRoot = "elm-root"
let elmInitScript = `
taskportInit()
const el = elm().${config.elmModuleName}.init({
node: document.getElementById('${elmRoot}'),
flags: flags
})
if(initPorts !== undefined || initPorts !== null)
initPorts(el.ports)
if(initPorts != null) initPorts(el.ports)
`
let html = `<html><head><title>App</title></head><body><div id='${elmRoot}'></div></body></html>`

View File

@ -62,6 +62,70 @@ module Application = {
external run: config => unit = "run"
}
module Dialogs = {
type alertOptions = {
title: string,
message: string,
okButtonText: string,
cancelable: bool,
}
type actionOptions = {
title: string,
message: string,
cancelButtonText: string,
actions: array<string>,
cancelable: bool,
}
type confirmOptions = {
title: string,
message: string,
okButtonText: string,
cancelButtonText: string,
neutralButtonText: string,
}
type loginOptions = {
title: string,
message: string,
okButtonText: string,
cancelButtonText: string,
neutralButtonText: string,
userNameHint: string,
passwordHint: string,
userName: string,
password: string,
}
type promptOptions = {
title: string,
message: string,
cancelButtonText: string,
cancelable: bool,
okButtonText: string,
neutralButtonText: string,
defaultText: string,
inputType: string,
capitalizationType: string,
}
@module("@nativescript/core") @scope("Dialogs")
external alert: (. alertOptions) => Js.Promise.t<unit> = "alert"
@module("@nativescript/core") @scope("Dialogs")
external action: (. actionOptions) => Js.Promise.t<string> = "action"
@module("@nativescript/core") @scope("Dialogs")
external confirm: (. confirmOptions) => Js.Promise.t<bool> = "confirm"
@module("@nativescript/core") @scope("Dialogs")
external login: (. loginOptions) => Js.Promise.t<bool> = "login"
@module("@nativescript/core") @scope("Dialogs")
external prompt: (. promptOptions) => Js.Promise.t<bool> = "prompt"
}
%%private(
let processAttrAndValue = (attr, value) => {
if attr == "ios" || attr == "android" {

View File

@ -0,0 +1,41 @@
type namespace
%%private(
let namespace = "hariroshan/elm-native"
let version = "v1"
@module("elm-taskport")
external install: (. unit) => unit = "install"
@module("elm-taskport")
external createNamespace: (. string, string) => namespace = "createNamespace"
@send
external register: (namespace, string, 'a => 'b) => unit = "register"
)
install(.)
let register = () => {
open NativescriptCore
let ns = createNamespace(. namespace, version)
ns->register("DialogsAlert", (options: Dialogs.alertOptions) => {
Dialogs.alert(. options)
})
ns->register("DialogsAction", (options: Dialogs.actionOptions) => {
Dialogs.action(. options)
})
ns->register("DialogsConfirm", (options: Dialogs.confirmOptions) => {
Dialogs.confirm(. options)
})
ns->register("DialogsLogin", (options: Dialogs.loginOptions) => {
Dialogs.login(. options)
})
ns->register("DialogsPrompt", (options: Dialogs.promptOptions) => {
Dialogs.prompt(. options)
})
}

View File

@ -96,6 +96,11 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
elm-taskport@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/elm-taskport/-/elm-taskport-2.0.1.tgz#abaf091db79971b8354ddc2652c6c0c7abd91b5b"
integrity sha512-8UgIjzmGuoU6Wt6VC0tkJnzvc5xHL5yH7GdN+/QNxaaA3ckoyveCtV0QJqNCRa42bpyR1JhOwLSApwf2Id5xZg==
form-data@^2.2.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"

View File

@ -16,7 +16,8 @@
"dependencies": {
"elm/core": "1.0.0 <= v < 2.0.0",
"elm/html": "1.0.0 <= v < 2.0.0",
"elm/json": "1.1.3 <= v < 2.0.0"
"elm/json": "1.1.3 <= v < 2.0.0",
"lobanov/elm-taskport": "2.0.1 <= v < 3.0.0"
},
"test-dependencies": {}
}

View File

@ -0,0 +1,399 @@
module Native.Dialogs exposing
( Action
, Alert
, action
, alert
, confirm
, defaultActionOption
, defaultAlertOption
, defaultConfirmOption
, defaultLoginOption
, login
, prompt
, setAndroidOnlyCancelable
, setCancelButtonText
, setCapitalizationType
, setDefaultText
, setInputType
, setNeutralButtonText
, setOkButtonText
, setPassword
, setPasswordHint
, setTitle
, setUserName
, setUserNameHint, defaultPromptOption
)
import Json.Decode as D
import Json.Encode as E
import Native.Types exposing (CapitalizationType(..), InputType(..), capitalizationToString, inputTypeToString)
import TaskPort exposing (FunctionName, QualifiedName, Task, callNS, inNamespace)
type alias Alert =
{ title : Maybe String
, message : String
, okButtonText : Maybe String
, androidOnlyCancelable : Maybe Bool
}
type alias Action =
{ title : Maybe String
, message : String
, cancelButtonText : String
, actions : List String
, androidOnlyCancelable : Maybe Bool
}
type alias Confirm =
{ title : Maybe String
, message : String
, androidOnlyCancelable : Maybe Bool
, okButtonText : Maybe String
, neutralButtonText : Maybe String
, cancelButtonText : Maybe String
}
type alias Login =
{ title : Maybe String
, message : String
, okButtonText : Maybe String
, cancelButtonText : Maybe String
, neutralButtonText : Maybe String
, userNameHint : Maybe String
, passwordHint : Maybe String
, userName : Maybe String
, password : Maybe String
}
type alias LoginResult =
{ username : String
, password : String
, result : Bool
}
type alias Prompt =
{ title : Maybe String
, message : String
, okButtonText : Maybe String
, cancelButtonText : Maybe String
, neutralButtonText : Maybe String
, defaultText : Maybe String
, capitalizationType : Maybe CapitalizationType
, inputType : Maybe InputType
}
type alias PromptResult =
{ text : String
, result : Bool
}
defaultAlertOption : String -> Alert
defaultAlertOption message =
{ title = Nothing
, message = message
, okButtonText = Nothing
, androidOnlyCancelable = Nothing
}
defaultActionOption : String -> List String -> String -> Action
defaultActionOption message actions cancelButtonText =
{ title = Nothing
, message = message
, cancelButtonText = cancelButtonText
, actions = actions
, androidOnlyCancelable = Nothing
}
defaultConfirmOption : String -> Confirm
defaultConfirmOption message =
{ title = Nothing
, message = message
, androidOnlyCancelable = Nothing
, okButtonText = Nothing
, neutralButtonText = Nothing
, cancelButtonText = Nothing
}
defaultLoginOption : String -> Login
defaultLoginOption message =
{ title = Nothing
, message = message
, okButtonText = Nothing
, cancelButtonText = Nothing
, neutralButtonText = Nothing
, userNameHint = Nothing
, passwordHint = Nothing
, userName = Nothing
, password = Nothing
}
defaultPromptOption : String -> Prompt
defaultPromptOption message =
{ title = Nothing
, message = message
, okButtonText = Nothing
, cancelButtonText = Nothing
, neutralButtonText = Nothing
, defaultText = Nothing
, capitalizationType = Nothing
, inputType = Nothing
}
setTitle : String -> { a | title : Maybe String } -> { a | title : Maybe String }
setTitle title record =
{ record | title = Just title }
setOkButtonText : String -> { a | okButtonText : Maybe String } -> { a | okButtonText : Maybe String }
setOkButtonText okButtonText record =
{ record | okButtonText = Just okButtonText }
setCancelButtonText : String -> { a | cancelButtonText : Maybe String } -> { a | cancelButtonText : Maybe String }
setCancelButtonText cancelButtonText record =
{ record | cancelButtonText = Just cancelButtonText }
setNeutralButtonText : String -> { a | neutralButtonText : Maybe String } -> { a | neutralButtonText : Maybe String }
setNeutralButtonText neutralButtonText record =
{ record | neutralButtonText = Just neutralButtonText }
setDefaultText : String -> { a | defaultText : Maybe String } -> { a | defaultText : Maybe String }
setDefaultText defaultText record =
{ record | defaultText = Just defaultText }
setCapitalizationType : String -> { a | capitalizationType : Maybe String } -> { a | capitalizationType : Maybe String }
setCapitalizationType capitalizationType record =
{ record | capitalizationType = Just capitalizationType }
setInputType : String -> { a | inputType : Maybe String } -> { a | inputType : Maybe String }
setInputType inputType record =
{ record | inputType = Just inputType }
setUserNameHint : String -> { a | userNameHint : Maybe String } -> { a | userNameHint : Maybe String }
setUserNameHint userNameHint record =
{ record | userNameHint = Just userNameHint }
setUserName : String -> { a | userName : Maybe String } -> { a | userName : Maybe String }
setUserName userName record =
{ record | userName = Just userName }
setPasswordHint : String -> { a | passwordHint : Maybe String } -> { a | passwordHint : Maybe String }
setPasswordHint passwordHint record =
{ record | passwordHint = Just passwordHint }
setPassword : String -> { a | password : Maybe String } -> { a | password : Maybe String }
setPassword password record =
{ record | password = Just password }
setAndroidOnlyCancelable : Bool -> { a | androidOnlyCancelable : Maybe Bool } -> { a | androidOnlyCancelable : Maybe Bool }
setAndroidOnlyCancelable androidOnlyCancelable record =
{ record | androidOnlyCancelable = Just androidOnlyCancelable }
encodeCancelable : Bool -> ( String, E.Value )
encodeCancelable bool =
( "cancelable", E.bool bool )
encodeTitle : String -> ( String, E.Value )
encodeTitle title =
( "cancelable", E.string title )
encodeMessage : String -> ( String, E.Value )
encodeMessage message =
( "message", E.string message )
encodeOkButtonText : String -> ( String, E.Value )
encodeOkButtonText text =
( "okButtonText", E.string text )
encodeCancelButtonText : String -> ( String, E.Value )
encodeCancelButtonText text =
( "cancelButtonText", E.string text )
encodeNeutralButtonText : String -> ( String, E.Value )
encodeNeutralButtonText text =
( "neutralButtonText", E.string text )
encodeActions : List String -> ( String, E.Value )
encodeActions actions =
( "actions", E.list E.string actions )
filterMaybeEncode : List (Maybe ( String, E.Value )) -> E.Value
filterMaybeEncode =
List.filterMap identity
>> E.object
encodeAlert : Alert -> E.Value
encodeAlert alertOptions =
[ alertOptions.title |> Maybe.map encodeTitle
, Just (encodeMessage alertOptions.message)
, alertOptions.okButtonText |> Maybe.map encodeOkButtonText
, alertOptions.androidOnlyCancelable |> Maybe.map encodeCancelable
]
|> filterMaybeEncode
encodeAction : Action -> E.Value
encodeAction actionOptions =
[ actionOptions.title |> Maybe.map encodeTitle
, actionOptions.message |> encodeMessage |> Just
, actionOptions.actions |> encodeActions |> Just
, actionOptions.cancelButtonText |> encodeCancelButtonText |> Just
, actionOptions.androidOnlyCancelable |> Maybe.map encodeCancelable
]
|> filterMaybeEncode
encodeConfirm : Confirm -> E.Value
encodeConfirm confirmOptions =
[ confirmOptions.title |> Maybe.map encodeTitle
, Just (encodeMessage confirmOptions.message)
, confirmOptions.androidOnlyCancelable |> Maybe.map encodeCancelable
, confirmOptions.okButtonText |> Maybe.map encodeOkButtonText
, confirmOptions.neutralButtonText |> Maybe.map encodeNeutralButtonText
, confirmOptions.cancelButtonText |> Maybe.map encodeCancelButtonText
]
|> filterMaybeEncode
encodeLogin : Login -> E.Value
encodeLogin loginOptions =
[ loginOptions.title |> Maybe.map encodeTitle
, Just (encodeMessage loginOptions.message)
, loginOptions.okButtonText |> Maybe.map encodeOkButtonText
, loginOptions.cancelButtonText |> Maybe.map encodeCancelButtonText
, loginOptions.neutralButtonText |> Maybe.map encodeNeutralButtonText
, loginOptions.userNameHint |> Maybe.map (encodeStringWith "userNameHint")
, loginOptions.passwordHint |> Maybe.map (encodeStringWith "passwordHint")
, loginOptions.userName |> Maybe.map (encodeStringWith "userName")
, loginOptions.password |> Maybe.map (encodeStringWith "password")
]
|> filterMaybeEncode
decodeLoginResult : D.Decoder LoginResult
decodeLoginResult =
D.map3 LoginResult
(D.field "username" D.string)
(D.field "password" D.string)
(D.field "result" D.bool)
encodeCapitalizationType : CapitalizationType -> ( String, E.Value )
encodeCapitalizationType cap =
( "capitalizationType"
, E.string <| capitalizationToString cap
)
encodeInputType : InputType -> ( String, E.Value )
encodeInputType input =
( "inputType"
, E.string <| inputTypeToString input
)
encodeStringWith : String -> String -> ( String, E.Value )
encodeStringWith label value =
( label, E.string value )
encodePrompt : Prompt -> E.Value
encodePrompt promptOptions =
[ promptOptions.title |> Maybe.map encodeTitle
, Just (encodeMessage promptOptions.message)
, promptOptions.okButtonText |> Maybe.map encodeOkButtonText
, promptOptions.cancelButtonText |> Maybe.map encodeCancelButtonText
, promptOptions.neutralButtonText |> Maybe.map encodeNeutralButtonText
, promptOptions.capitalizationType |> Maybe.map encodeCapitalizationType
, promptOptions.inputType |> Maybe.map encodeInputType
, promptOptions.defaultText |> Maybe.map (encodeStringWith "defaultText")
]
|> filterMaybeEncode
decodePromptResult : D.Decoder PromptResult
decodePromptResult =
D.map2 PromptResult
(D.field "text" D.string)
(D.field "result" D.bool)
taskportNamespace : FunctionName -> QualifiedName
taskportNamespace =
inNamespace "hariroshan/elm-native" "v1"
alert : Alert -> Task ()
alert =
callNS
{ function = "DialogsAlert" |> taskportNamespace
, valueDecoder = D.succeed ()
, argsEncoder = encodeAlert
}
action : Action -> Task String
action =
callNS
{ function = "DialogsAction" |> taskportNamespace
, valueDecoder = D.string
, argsEncoder = encodeAction
}
confirm : Confirm -> Task Bool
confirm =
callNS
{ function = "DialogsConfirm" |> taskportNamespace
, valueDecoder = D.bool
, argsEncoder = encodeConfirm
}
login : Login -> Task LoginResult
login =
callNS
{ function = "DialogsLogin" |> taskportNamespace
, valueDecoder = decodeLoginResult
, argsEncoder = encodeLogin
}
prompt : Prompt -> Task PromptResult
prompt =
callNS
{ function = "DialogsPrompt" |> taskportNamespace
, valueDecoder = decodePromptResult
, argsEncoder = encodePrompt
}

View File

@ -0,0 +1,60 @@
module Native.Types exposing
( CapitalizationType(..)
, InputType(..)
, capitalizationToString
, inputTypeToString
)
type CapitalizationType
= Sentences
| None
| All
| Words
type InputType
= Text
| Password
| Email
| Number
| Decimal
| Phone
inputTypeToString : InputType -> String
inputTypeToString input =
case input of
Text ->
"text"
Password ->
"password"
Email ->
"email"
Number ->
"number"
Decimal ->
"decimal"
Phone ->
"phone"
capitalizationToString : CapitalizationType -> String
capitalizationToString cap =
case cap of
Sentences ->
"sentences"
None ->
"none"
All ->
"all"
Words ->
"words"

View File

@ -12,7 +12,8 @@
"elm/html": "1.0.0",
"elm/http": "2.0.0",
"elm/json": "1.1.3",
"elm/time": "1.0.0"
"elm/time": "1.0.0",
"lobanov/elm-taskport": "2.0.1"
},
"indirect": {
"elm/bytes": "1.0.8",