added goback

fixed issue with destroy
This commit is contained in:
hariroshan 2023-01-14 21:36:01 +05:30
parent 9e944207a9
commit 72b77bb345
14 changed files with 543 additions and 85 deletions

View File

@ -41,3 +41,54 @@
}
}
}
// Custom styles
.car-list {
&-even,
&-odd {
padding: 10 15;
margin: 0;
border-bottom-width: const(border-width);
@include colorize($border-color: background-alt-20);
}
&-odd {
@include colorize($background-color: background-alt-10, $color: secondary);
}
&__value {
width: 65;
text-align: right;
@include colorize($contrasted-color: complementary background 30% 10%);
}
TextField.placeholder-error {
@include colorize($placeholder-color: error);
}
Slider {
@include colorize($contrasted-background-color: complementary background 20% 0%,
$contrasted-color: complementary background 20% 0%);
}
}
.thumb {
background-size: cover;
background-repeat: no-repeat;
font-size: 25;
font-weight: bold;
&__add {
background-color: transparent;
border-radius: const(border-radius-sm);
border-width: const(border-width);
@include colorize($border-color: background-alt-20, $color: background-alt-20);
}
&__remove {
background-color: rgba(grey, 0.5);
@include colorize($color: background);
}
}

View File

@ -5,7 +5,3 @@
// Import common styles
@import 'app-common';
// Place any CSS rules you want to apply only on iOS here
.cars-list-content {
seperator-color: transparent
}

View File

@ -1,6 +1,7 @@
module Details exposing (..)
import Browser
import Http
import Json.Decode as D
import Json.Encode as E
import Native exposing (..)
@ -172,26 +173,32 @@ main =
type NavPage
= HomePage
| CarDetailsPage
| CarDetailsEditPage
type alias Model =
{ rootFrame : Frame.Model NavPage
, cars : List Car
, encodedCars : E.Value
, pickedCar : Maybe Car
}
type Msg
= Back Bool
= HandleFrameBack Bool
| GoBack
| NoOp
| ToCarDetailsPage Int
| ToCarDetailsEditPage
init : ( Model, Cmd Msg )
init =
( { rootFrame = Frame.init HomePage
, cars = response
, encodedCars =
encodeCars response
, encodedCars = encodeCars response
, pickedCar = Nothing
}
, Cmd.none
)
@ -203,8 +210,357 @@ update msg model =
NoOp ->
( model, Cmd.none )
Back bool ->
( { model | rootFrame = Frame.back bool model.rootFrame }, Cmd.none )
GoBack ->
( { model | rootFrame = Frame.goBack model.rootFrame }, Cmd.none )
HandleFrameBack bool ->
( { model | rootFrame = Frame.handleBack bool model.rootFrame }, Cmd.none )
ToCarDetailsEditPage ->
( { model
| rootFrame =
model.rootFrame
|> Frame.goTo CarDetailsEditPage
(Frame.defaultNavigationOptions
|> Frame.setAnimated True
|> Frame.setTransition
{ name = Just Frame.SlideTop
, duration = Just 200
, curve = Just Frame.Ease
}
|> Just
)
}
, Cmd.none
)
ToCarDetailsPage idx ->
( { model
| rootFrame =
model.rootFrame
|> Frame.goTo CarDetailsPage
(Frame.defaultNavigationOptions
|> Frame.setAnimated True
|> Frame.setTransition
{ name = Just Frame.FlipLeft
, duration = Just 300
, curve = Just Frame.Spring
}
|> Just
)
, pickedCar =
model.cars
|> List.foldl
(\cur (( curIdx, acc ) as result) ->
if acc /= Nothing then
result
else if curIdx == idx then
( idx, Just cur )
else
( curIdx + 1, acc )
)
( 0, Nothing )
|> Tuple.second
}
, Cmd.none
)
notFoundPage : Native Msg
notFoundPage =
Page.page HandleFrameBack
[]
(Layout.stackLayout []
[ Native.label [ N.text "Not found" ] []
]
)
carDetailEditView : Model -> Car -> Native Msg
carDetailEditView model car =
Page.pageWithActionBar HandleFrameBack
[]
(actionBar []
[ navigationButton [ N.visibility "collapsed" ] []
, label [ N.text "Edit Car Details", N.fontSize "18" ] []
, actionItem
[ N.text "Cancel"
, N.iosPosition "left"
, Event.onTap GoBack
]
[]
, actionItem
[ N.text "Done"
, N.iosPosition "right"
]
[]
]
)
(
-- scrollView [ N.class "car-list" ]
(Layout.flexboxLayout [ N.flexDirection "column" ]
[ label [ N.text "CAR MAKE", N.class "car-list-odd" ] []
, textField
[ N.text car.name
, N.hint "Car make field is required"
, N.class "car-list-even"
, Event.onTextChange (always NoOp)
]
[]
]
)
-- [
--
-- (
-- [
-- ,
-- ]
-- )
-- ]
-- , Layout.gridLayout
-- [ N.rows "*, 55, *"
-- , N.columns "*, auto"
-- , N.class "car-list-odd"
-- ]
-- [ label [ N.text "PRICE PER DAY" ] []
-- , label
-- [ N.col "1"
-- , N.horizontalAlignment "right"
-- , N.class "car-list__value"
-- ]
-- [ formattedString []
-- [ span [ N.text "€" ] []
-- , span [ N.text (String.fromInt car.price) ] []
-- ]
-- ]
-- , Layout.stackLayout
-- []
-- [ slider
-- [ N.row "1"
-- , N.colSpan "2"
-- , N.verticalAlignment "center"
-- , N.value (String.fromInt car.price)
-- ]
-- []
-- ]
-- , label
-- [ N.text "ADD OR REMOVE IMAGE"
-- , N.row "2"
-- , N.colSpan "2"
-- ]
-- []
-- ]
-- , Layout.stackLayout []
-- [ Layout.gridLayout
-- [ N.height "80"
-- , N.width "80"
-- , N.class "thumb"
-- , N.horizontalAlignment "left"
-- , N.backgroundImage car.imageUrl
-- , N.class "car-list-even"
-- -- , N.tap "onImageAddRemoveTap"
-- ]
-- [ Layout.gridLayout
-- [ N.class "thumb__add"
-- , N.visibility "collapsed"
-- -- , N.visibility "{{ car.imageUrl, car.imageUrl | visibilityValueConverter }}"
-- ]
-- [ label
-- [ N.text (String.fromChar '\u{F030}')
-- , N.class "fas"
-- , N.horizontalAlignment "center"
-- , N.verticalAlignment "center"
-- ]
-- []
-- ]
-- , Layout.gridLayout
-- [ N.class "thumb__remove"
-- , N.visibility "visible"
-- -- , N.visibility "{{ car.imageUrl, !car.imageUrl | visibilityValueConverter }}"
-- ]
-- [ label
-- [ N.text (String.fromChar '\u{F2ED}')
-- , N.class "far"
-- , N.horizontalAlignment "center"
-- , N.verticalAlignment "center"
-- ]
-- []
-- ]
-- ]
-- , label
-- [ N.visibility "collapsed"
-- -- N.visibility "{{ car.imageUrl, car.imageUrl | visibilityValueConverter }}"
-- , N.class "c-error"
-- , N.text "Image field is required"
-- ]
-- []
-- ]
-- , label [ N.text "CLASS", N.class "car-list-odd" ] []
-- , Layout.gridLayout
-- [ N.columns "*, auto"
-- -- , N.tap "onSelectorTap"
-- , N.class "car-list-even"
-- ]
-- [ label [ N.text car.class ] []
-- , label
-- [ N.text (String.fromChar '\u{F054}')
-- , N.class "fas"
-- , N.col "1"
-- , N.horizontalAlignment "center"
-- , N.verticalAlignment "center"
-- ]
-- []
-- ]
-- , label [ N.text "DOORS", N.class "car-list-odd" ] []
-- , Layout.gridLayout
-- [ N.columns "*, auto"
-- -- , N.tap "onSelectorTap"
-- , N.class "car-list-even"
-- ]
-- [ label [ N.text (String.fromInt car.doors) ] []
-- , label
-- [ N.text (String.fromChar '\u{F054}')
-- , N.class "fas"
-- , N.col "1"
-- , N.horizontalAlignment "center"
-- , N.verticalAlignment "center"
-- ]
-- []
-- ]
-- , label
-- [ N.text "SEATS"
-- , N.class "car-list-odd"
-- ]
-- []
-- , Layout.gridLayout
-- [ N.columns "*, auto"
-- -- , N.tap "onSelectorTap"
-- , N.class "car-list-even"
-- ]
-- [ label [ N.text car.seats ] []
-- , label
-- [ N.text (String.fromChar '\u{F054}')
-- , N.class "fas"
-- , N.col "1"
-- , N.horizontalAlignment "center"
-- , N.verticalAlignment "center"
-- ]
-- []
-- ]
-- , label
-- [ N.text "TRANSMISSION"
-- , N.class "car-list-odd"
-- ]
-- []
-- , Layout.gridLayout
-- [ N.columns "*, auto"
-- -- , N.tap "onSelectorTap"
-- , N.class "car-list-even"
-- ]
-- [ label [ N.text car.transmission ] []
-- , label
-- [ N.text (String.fromChar '\u{F054}')
-- , N.class "fas"
-- , N.col "1"
-- , N.horizontalAlignment "center"
-- , N.verticalAlignment "center"
-- ]
-- []
-- ]
-- , Layout.gridLayout
-- [ N.rows "*, 55"
-- , N.columns "*, auto"
-- , N.class "car-list-odd"
-- ]
-- [ label [ N.text "LUGGAGE" ] []
-- , label
-- [ N.col "1"
-- , N.horizontalAlignment "right"
-- , N.class "car-list__value"
-- ]
-- [ formattedString []
-- [ span [ N.text (String.fromInt car.luggage) ] []
-- , span [ N.text " Bag(s)" ] []
-- ]
-- ]
-- , slider
-- [ N.row "1"
-- , N.colSpan "2"
-- , N.minValue "0"
-- , N.maxValue "5"
-- , N.value (String.fromInt car.luggage)
-- ]
-- []
-- ]
)
carDetailsEditPage : Model -> Native Msg
carDetailsEditPage model =
case model.pickedCar of
Nothing ->
notFoundPage
Just car ->
carDetailEditView model car
carDetailView : Model -> Car -> Native Msg
carDetailView model car =
Page.pageWithActionBar HandleFrameBack
[]
(actionBar []
[ navigationButton [ N.androidSystemIcon "ic_menu_back" ] []
, label [ N.text car.name, N.fontSize "18" ] []
, actionItem
[ N.text "Edit"
, N.iosSystemIcon "2"
, N.iosPosition "right"
, N.androidPosition "right"
, Event.onTap ToCarDetailsEditPage
]
[]
]
)
(scrollView []
(Layout.gridLayout [ N.rows "auto, auto, auto" ]
[ image [ N.src car.imageUrl, N.class "m-b-15", N.stretch "aspectFill", N.height "200" ] []
, Layout.stackLayout [ N.row "1", N.class "hr m-y-15" ] []
, Layout.gridLayout [ N.row "2", N.rows "*, *, *, *, *, *", N.columns "auto, auto" ]
[ label [ N.text "Price", N.class "p-l-15 p-b-10 m-r-20" ] []
, label [ N.col "1", N.class "p-b-10" ]
[ formattedString []
[ span [ N.text "" ] []
, span [ N.text (String.fromInt car.price) ] []
, span [ N.text "/day" ] []
]
]
, label [ N.text "Class", N.row "1", N.class "p-l-15 p-b-10 m-r-20" ] []
, label [ N.text car.class, N.row "1", N.col "1", N.class "p-b-10" ] []
, label [ N.text "Doors", N.row "2", N.class "p-l-15 p-b-10 m-r-20" ] []
, label [ N.text (String.fromInt car.doors), N.row "2", N.col "1", N.class "p-b-10" ] []
, label [ N.text "Seats", N.row "3", N.class "p-l-15 p-b-10 m-r-20" ] []
, label [ N.text car.seats, N.row "3", N.col "1", N.class "p-b-10" ] []
, label [ N.text "Transmission", N.row "4", N.class "p-l-15 p-b-10 m-r-20" ] []
, label [ N.text car.transmission, N.row "4", N.col "1", N.class "p-b-10" ] []
, label [ N.text "Luggage", N.row "5", N.class "p-l-15 p-b-10 m-r-20" ] []
, label [ N.text (String.fromInt car.luggage), N.row "5", N.col "1", N.class "p-b-10" ] []
]
]
)
)
carDetailsPage : Model -> Native Msg
carDetailsPage model =
case model.pickedCar of
Nothing ->
notFoundPage
Just car ->
carDetailView model car
carTemplate : Native Msg
@ -250,7 +606,7 @@ carTemplate =
homePage : Model -> Native Msg
homePage model =
Page.pageWithActionBar Back
Page.pageWithActionBar HandleFrameBack
[]
(actionBar []
[ label [ N.text "Browse", N.fontSize "18" ] []
@ -261,14 +617,17 @@ homePage model =
[ N.items model.encodedCars
, N.separatorColor "transparent"
, N.class "cars-list"
, Event.onItemTap ToCarDetailsPage
, Event.onEventWith
"itemLoading"
[]
[ { keys = [ "ios", "selectionStyle" ]
, assignmentValue =
dangerousEvalExpression " UITableViewCellSelectionStyle.None "
}
]
{ methodCalls = []
, setters =
[ { keys = ( "ios", [ "selectionStyle" ] )
, assignmentValue =
dangerousEvalExpression " UITableViewCellSelectionStyle.None "
}
]
}
(D.succeed NoOp)
]
[ carTemplate ]
@ -281,6 +640,8 @@ view model =
Frame.frame model.rootFrame
model
[ ( HomePage, homePage )
, ( CarDetailsPage, carDetailsPage )
, ( CarDetailsEditPage, carDetailsEditPage )
]
[]

View File

@ -116,13 +116,13 @@ update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Back bool ->
( { model | rootFrame = Frame.back bool model.rootFrame }, Cmd.none )
( { model | rootFrame = Frame.handleBack bool model.rootFrame }, Cmd.none )
ToDetails idx ->
( { model
| rootFrame =
model.rootFrame
|> Frame.current DetailsPage
|> Frame.goTo DetailsPage
(Frame.defaultNavigationOptions
|> Frame.setAnimated True
|> Frame.setTransition
@ -319,41 +319,43 @@ detailsPage model =
[ Native.navigationButton [ NA.text "Back" ] []
]
)
(Layout.scrollView
(Native.scrollView
[]
[ Layout.stackLayout []
[ Native.image
[ NA.margin "0"
, NA.stretch "aspectFill"
, NA.src flick.image
(Layout.flexboxLayout []
[ Layout.stackLayout []
[ Native.image
[ NA.margin "0"
, NA.stretch "aspectFill"
, NA.src flick.image
]
[]
]
[]
, Layout.stackLayout [ NA.padding "10, 20" ]
(flick.details
|> List.map
(\detail ->
Layout.stackLayout []
[ Native.label
[ NA.marginTop "15"
, NA.fontSize "16"
, NA.fontWeight "700"
, NA.class "text-primary"
, NA.textWrap "true"
, NA.text detail.title
]
[]
, Native.label
[ NA.fontSize "14"
, NA.class "text-secondary"
, NA.textWrap "true"
, NA.text detail.body
]
[]
]
)
)
]
, Layout.stackLayout [ NA.padding "10, 20" ]
(flick.details
|> List.map
(\detail ->
Layout.stackLayout []
[ Native.label
[ NA.marginTop "15"
, NA.fontSize "16"
, NA.fontWeight "700"
, NA.class "text-primary"
, NA.textWrap "true"
, NA.text detail.title
]
[]
, Native.label
[ NA.fontSize "14"
, NA.class "text-secondary"
, NA.textWrap "true"
, NA.text detail.body
]
[]
]
)
)
]
)
)

View File

@ -269,13 +269,10 @@ module TabViewItem = {
let handler: Types.handler = buildHandler(
new,
Constants.tabViewItem,
Js.Nullable.return((. current: Types.htmlElement, _) => {
Js.Nullable.return((. current: Types.htmlElement, data: Types.nativeObject) => {
current.children
->Belt.Array.get(0)
->Helper.optionMap2(current.data->Js.Nullable.toOption, (
ch: Types.htmlElement,
data: Types.nativeObject,
) => {
->Belt.Option.map((ch: Types.htmlElement) => {
data->Types.setView(ch.data)
})
->ignore
@ -329,13 +326,9 @@ module ListView = {
@module("@nativescript/core") @new
external new: unit => Types.nativeObject = "ListView"
let itemsSetter = (current: Types.htmlElement, newItems) => {
current.data
->Js.Nullable.toOption
->Belt.Option.forEach(data => {
data->Types.setItems(newItems)
data->Types.refresh
})
let itemsSetter = (data: Types.nativeObject, newItems) => {
data->Types.setItems(newItems)
data->Types.refresh
}
)
let tagName = "ns-list-view"
@ -343,11 +336,9 @@ module ListView = {
let handler: Types.handler = buildHandler(
new,
Constants.listView,
Js.Nullable.return((. current: Types.htmlElement, _) => {
current.data->Js.Nullable.toOption->Belt.Option.forEach(ListPicker.setItems(current))
Types.definePropertyInHtml(. current, "items", {set: itemsSetter(current)})
Js.Nullable.return((. current: Types.htmlElement, data: Types.nativeObject) => {
ListPicker.setItems(current, data)
Types.definePropertyInHtml(. current, "items", {set: itemsSetter(data)})
Helper.addView(. current.parentElement, current)
}),
)

View File

@ -21,7 +21,19 @@ module Frame = {
init: (. ()) => new(),
observedAttributes: Constants.frameBase,
update: NativescriptCore.update,
render: Js.Nullable.null,
render: Js.Nullable.return((. current: Types.htmlElement, data: Types.nativeObject) => {
Types.definePropertyInHtml(.
current,
"popStack",
{
set: value => {
if value {
data->Types.goBack
}
},
},
)
}),
handlerKind: Types.Frame({
pageAdded: (. current: Types.htmlElement) => {
current.data

View File

@ -37,7 +37,14 @@ let rec update = (. nativeObject: Types.nativeObject, attr, newValue) => {
}
}
let dispose = (. nativeObject: Types.nativeObject) => nativeObject.destroyNode(.)
let dispose = (. nativeObject: Types.nativeObject) => {
if (
(Types.isIOS && !(nativeObject.ios->Js.Nullable.isNullable)) ||
(Types.isAndroid && !(nativeObject.android->Js.Nullable.isNullable))
) {
nativeObject.destroyNode(.)
}
}
let addEventListener = (. nativeObject: Types.nativeObject, event, callback) => {
nativeObject.on(. event, callback)

View File

@ -74,6 +74,11 @@ external bindExpression: (Obj.t, bindingOptions) => unit = "bind"
@send
external refresh: nativeObject => unit = "refresh"
@send
external goBack: nativeObject => unit = "goBack"
@val
external eval: string => 'a = "eval"

View File

@ -43,6 +43,9 @@ export const withCustomElements = (UIElement, handler) =>
}
disconnectedCallback() {
this.handler.dispose(this.data)
this.data = null
this.handler = null
this.enhancedCallbackRefs = {}
// console.log(`${this.tagName} disconnected`)
}
addEventListener(event, callback) {

View File

@ -90,9 +90,9 @@ progress =
buildElement "ns-progress"
scrollView : List (Attribute msg) -> List (Html msg) -> Html msg
scrollView =
buildElement "ns-scroll-view"
scrollView : List (Attribute msg) -> (Html msg) -> Html msg
scrollView attrs child =
buildElement "ns-scroll-view" attrs [ child ]
searchBar : List (Attribute msg) -> List (Html msg) -> Html msg
@ -168,3 +168,4 @@ listView =
placeholderView : List (Attribute msg) -> List (Html msg) -> Html msg
placeholderView =
buildElement "ns-placeholder"

View File

@ -85,18 +85,28 @@ on eventName =
Event.on eventName
{-| Setter keys require atleast one key.
-}
type alias Setter =
{ keys : List String, assignmentValue : String }
{ keys : ( String, List String )
, assignmentValue : String
}
encodeSetter : Setter -> E.Value
encodeSetter { keys, assignmentValue } =
[ ( "keys", E.list E.string keys )
[ ( "keys", E.list E.string (Tuple.first keys :: Tuple.second keys) )
, ( "value", E.string assignmentValue )
]
|> E.object
type alias EventOptions =
{ methodCalls : List String
, setters : List Setter
}
{-| Method values are kept under {custom: {[methodName]: value}}
For example:
@ -110,13 +120,13 @@ For example:
)
-}
onEventWith : String -> List String -> List Setter -> D.Decoder msg -> Attribute msg
onEventWith eventName methods setters =
onEventWith : String -> EventOptions -> D.Decoder msg -> Attribute msg
onEventWith eventName { methodCalls, setters } =
let
encodedValue : String
encodedValue =
[ ( "event", E.string eventName )
, ( "methods", E.list E.string methods )
, ( "methods", E.list E.string methodCalls )
, ( "setters", E.list encodeSetter setters )
]
|> E.object

View File

@ -4,6 +4,7 @@ module Native.Frame exposing
, TransitionName(..)
, defaultNavigationOptions
, frame
, goBack
, goTo
, handleBack
, init
@ -24,6 +25,7 @@ type alias Model page =
{ current : page
, history : List page
, encodedNavigationOptions : E.Value
, popStack : Bool
}
@ -219,6 +221,7 @@ frame model appModel pages attrs =
in
Html.node "ns-frame"
(property "navigationOptions" model.encodedNavigationOptions
:: property "popStack" (E.bool model.popStack)
:: attrs
)
history
@ -254,6 +257,7 @@ init currentPage =
{ current = currentPage
, history = []
, encodedNavigationOptions = E.null
, popStack = False
}
@ -268,13 +272,31 @@ handleBack isBackNavigation model =
model
cur :: rest ->
{ model | history = rest, current = cur }
{ model
| history = rest
, current = cur
, popStack = False
}
goBack : Model page -> Model page
goBack model =
{ model | popStack = True }
goTo : page -> Maybe NavigationOptions -> Model page -> Model page
goTo page maybeNavigationOptions model =
{ model
| history = model.current :: model.history
| history =
if
maybeNavigationOptions
|> Maybe.andThen .clearHistory
|> Maybe.withDefault False
then
[]
else
model.current :: model.history
, current = page
, encodedNavigationOptions =
maybeNavigationOptions

View File

@ -4,7 +4,6 @@ module Native.Layout exposing
, flexboxLayout
, gridLayout
, rootLayout
, scrollView
, stackLayout
, tabView
, wrapLayout
@ -53,11 +52,6 @@ flexboxLayout =
buildLayout "ns-flexbox-layout"
scrollView : List (Attribute msg) -> List (Html msg) -> Html msg
scrollView =
buildLayout "ns-scroll-view"
tabView : List (Attribute msg) -> List (Html msg) -> Html msg
tabView =
buildLayout "ns-tab-view"

View File

@ -10,10 +10,13 @@
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/http": "2.0.0",
"elm/json": "1.1.3",
"elm/time": "1.0.0"
},
"indirect": {
"elm/bytes": "1.0.8",
"elm/file": "1.0.5",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.3"
}