merged branch. made elm-native-js into library

This commit is contained in:
hariroshan 2023-01-13 22:11:51 +05:30
parent 51037b1f08
commit bf0359196d
11 changed files with 380 additions and 14 deletions

View File

@ -1,11 +1,15 @@
@import '@nativescript/theme/css/core.css';
@import '@nativescript/theme/css/default.css';
/* ************************************* */
/* Flick.elm */
/* ************************************* */
/* Place any CSS rules you want to apply on both iOS and Android here.
This is where the vast majority of your CSS code goes. */
/* applied when device is in light mode */
.ns-light .bg-primary {
background-color: #fdfdfd;
}
@ -19,7 +23,9 @@ This is where the vast majority of your CSS code goes. */
color: #777;
}
/* applied when device is in dark mode */
.ns-dark .bg-primary {
background-color: #212121;
}
@ -32,3 +38,5 @@ This is where the vast majority of your CSS code goes. */
.ns-dark .text-secondary {
color: #ccc;
}
/* ************************************* */

43
app/_app-common.scss Normal file
View File

@ -0,0 +1,43 @@
@import '@nativescript/theme/core';
@import '@nativescript/theme/default';
@import '@nativescript/theme/scss/variables/blue';
// Place any CSS rules you want to apply on both iOS and Android here.
// This is where the vast majority of your CSS code goes.
// Font icon class
.fab {
font-family: 'Font Awesome 5 Brands', 'fa-brands-400';
font-weight: 400;
}
.fas {
font-family: 'Font Awesome 5 Free', 'fa-solid-900';
font-weight: 900;
}
.far {
font-family: 'Font Awesome 5 Free', 'fa-regular-400';
font-weight: 400;
}
// Custom styles
.cars-list {
&__item {
padding: 0 0 8 0;
@include colorize($background-color: background-alt-10);
&-content {
padding: 8 15 4 15;
border-bottom-width: 10;
border-bottom-color: #e4e4e4;
@include colorize($background-color: background);
}
&-name,
&-icon {
@include colorize($contrasted-color: complementary background 30% 0%);
}
}
}

8
app/app.android.scss Normal file
View File

@ -0,0 +1,8 @@
/* ************************************* */
/* Details.elm */
/* ************************************* */
// Import common styles
@import 'app-common';
// Place any CSS rules you want to apply only on android here

11
app/app.ios.scss Normal file
View File

@ -0,0 +1,11 @@
/* ************************************* */
/* Details.elm */
/* ************************************* */
// 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,10 +1,10 @@
import Elm from "./src/Main.elm";
import { start } from "elm-native-js"
import Elm from "./src/Details.elm";
import { start } from "../elm-native-js"
start(
{
elmModule: Elm,
elmModuleName: "Main",
elmModuleName: "Details",
initPorts: _elmPorts => { }
}
)

3
app/elm.d.ts vendored
View File

@ -1,3 +0,0 @@
declare module "*.elm" {
export const Elm: any;
}

BIN
app/fonts/fa-brands-400.ttf Normal file

Binary file not shown.

Binary file not shown.

BIN
app/fonts/fa-solid-900.ttf Normal file

Binary file not shown.

284
app/src/Details.elm Normal file
View File

@ -0,0 +1,284 @@
module Details exposing (..)
import Browser
import Json.Decode as D
import Json.Encode as E
import Native exposing (..)
import Native.Attributes as N
import Native.Event as Event
import Native.Frame as Frame
import Native.Layout as Layout
import Native.Page as Page
type alias Car =
{ class : String
, doors : Int
, hasAC : Bool
, id : String
, imageStoragePath : String
, imageUrl : String
, luggage : Int
, name : String
, price : Int
, seats : String
, transmission : String
}
decodeCar : D.Decoder Car
decodeCar =
D.map8 Car
(D.field "class" D.string)
(D.field "doors" D.int)
(D.field "hasAC" D.bool)
(D.field "id" D.string)
(D.field "imageStoragePath" D.string)
(D.field "imageUrl" D.string)
(D.field "luggage" D.int)
(D.field "name" D.string)
|> D.andThen
(\fx ->
D.map3 fx
(D.field "price" D.int)
(D.field "seats" D.string)
(D.field "transmission" D.string)
)
decodeResponse : D.Decoder (List Car)
decodeResponse =
D.field "cars" (D.keyValuePairs decodeCar)
|> D.map (List.map Tuple.second)
encodeCar : Car -> E.Value
encodeCar car =
[ ( "name", E.string car.name )
, ( "class", E.string car.class )
, ( "imageUrl", E.string car.imageUrl )
, ( "transmission", E.string car.transmission )
, ( "hasAC", E.bool car.hasAC )
, ( "price", E.int car.price )
]
|> E.object
encodeCars : List Car -> E.Value
encodeCars =
E.list encodeCar
response : List Car
response =
"""
{
"cars": {
"car1": {
"class": "Luxury",
"doors": 2,
"hasAC": true,
"id": "car1",
"imageStoragePath": "cars/BMW 5 Series.jpg",
"imageUrl": "https://firebasestorage.googleapis.com/v0/b/car-rental-b26b7.appspot.com/o/cars_public%2FBMW%205%20Series.jpg?alt=media&token=dec5a0bf-e3ca-45d2-8f2e-c7b8a25530b5",
"luggage": 3,
"name": "BMW 5 Series",
"price": 76,
"seats": "2",
"transmission": "Automatic"
},
"car2": {
"class": "Luxury",
"doors": 5,
"hasAC": false,
"id": "car2",
"imageStoragePath": "cars/Ford KA+.jpg",
"imageUrl": "https://firebasestorage.googleapis.com/v0/b/car-rental-b26b7.appspot.com/o/cars_public%2FFord%20KA%2B.jpg?alt=media&token=cf090183-ef5a-4c05-9f60-b0cbdfda7188",
"luggage": 3,
"name": "Ford KA",
"price": 44,
"seats": "4 + 1",
"transmission": "Automatic"
},
"car3": {
"class": "Mini",
"doors": 3,
"hasAC": true,
"id": "car3",
"imageStoragePath": "cars/Smart.jpg",
"imageUrl": "https://firebasestorage.googleapis.com/v0/b/car-rental-b26b7.appspot.com/o/cars_public%2FSmart.jpg?alt=media&token=6891aca9-4211-4545-834e-c934ed671961",
"luggage": 1,
"name": "Smart",
"price": 39,
"seats": "2",
"transmission": "Manual"
},
"car4": {
"class": "Standard",
"doors": 5,
"hasAC": true,
"id": "car4",
"imageStoragePath": "cars/Kia Sorento.jpg",
"imageUrl": "https://firebasestorage.googleapis.com/v0/b/car-rental-b26b7.appspot.com/o/cars_public%2FKia%20Sorento.jpg?alt=media&token=09ba5c41-5039-420f-b4fe-073dedb2ff1c",
"luggage": 2,
"name": "Kia Sorento",
"price": 45,
"seats": "4 + 1",
"transmission": "Manual"
},
"car5": {
"class": "Luxury",
"doors": 3,
"hasAC": true,
"id": "car5",
"imageStoragePath": "cars/Mazda MX-5.jpg",
"imageUrl": "https://firebasestorage.googleapis.com/v0/b/car-rental-b26b7.appspot.com/o/cars_public%2FMazda%20MX-5.jpg?alt=media&token=d27f2a97-2e09-431e-ad8c-d0e7723955ef",
"luggage": 2,
"name": "Mazda MX-5",
"price": 53,
"seats": "2",
"transmission": "Automatic"
},
"car6": {
"class": "Luxury",
"doors": 3,
"hasAC": false,
"id": "car6",
"imageStoragePath": "cars/Mercedes S-Class Cabriolet.jpg",
"imageUrl": "https://firebasestorage.googleapis.com/v0/b/car-rental-b26b7.appspot.com/o/cars_public%2FMercedes%20S-Class%20Cabriolet.jpg?alt=media&token=dc17f427-407c-45c5-b827-ed3e108e0034",
"luggage": 2,
"name": "Mercedes S-Class Cabriolet",
"price": 89,
"seats": "4",
"transmission": "Manual"
}
}
}
"""
|> D.decodeString decodeResponse
|> Result.toMaybe
|> Maybe.withDefault []
main : Program () Model Msg
main =
Browser.element
{ init = always init
, view = view
, update = update
, subscriptions = subscriptions
}
type NavPage
= HomePage
type alias Model =
{ rootFrame : Frame.Model NavPage
, cars : List Car
, encodedCars : E.Value
}
type Msg
= Back Bool
init : ( Model, Cmd Msg )
init =
( { rootFrame = Frame.init HomePage
, cars = response
, encodedCars =
encodeCars response
}
, Cmd.none
)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Back bool ->
( { model | rootFrame = Frame.back bool model.rootFrame }, Cmd.none )
carTemplate : Native Msg
carTemplate =
Layout.gridLayout
[ N.rows "*, *, *"
, N.columns "*, *"
, N.class "cars-list__item-content"
, N.iosSelectionStyle "0"
]
[ label [ N.text "{{ $value.name }}", N.class "font-weight-bold cars-list__item-name" ] []
, label [ N.col "1", N.horizontalAlignment "right" ]
[ formattedString []
[ span [ N.text "" ] []
, span [ N.text "{{ $value.price }}" ] []
, span [ N.text "/day" ] []
]
]
, Layout.stackLayout [ N.row "1", N.class "hr m-y-5", N.colSpan "2" ] []
, image [ N.row "2", N.src "{{ $value.imageUrl }}", N.stretch "aspectFill", N.height "120", N.class "m-r-20" ] []
, Layout.stackLayout [ N.row "2", N.col "1", N.verticalAlignment "center" ]
[ label [ N.class "p-b-10" ]
[ formattedString [ N.fontFamily "system" ]
[ span [ N.text (String.fromChar '\u{F1B9}' ++ " "), N.class "fas fa-car cars-list__item-icon" ] []
, span [ N.text "{{ $value.class }}" ] []
]
]
, label [ N.class "p-b-10" ]
[ formattedString [ N.fontFamily "system" ]
[ span [ N.text (String.fromChar '\u{F085}' ++ " "), N.class "fas fa-car cars-list__item-icon" ] []
, span [ N.text "{{ $value.transmission }}" ] []
, span [ N.text " Transmission" ] []
]
]
, label [ N.class "p-b-10" ]
[ formattedString [ N.fontFamily "system" ]
[ span [ N.text (String.fromChar '\u{F2DC}' ++ " "), N.class "fas fa-car cars-list__item-icon" ] []
, span [ N.text "{{ $value.hasAC ? 'Yes' : 'No' }}" ] []
]
]
]
]
-- Layout.stackLayout [ N.class "cars-list__item" ]
-- [
-- ]
homePage : Model -> Native Msg
homePage model =
Page.pageWithActionBar Back
[]
(actionBar []
[ label [ N.text "Browse", N.fontSize "18" ] []
]
)
(Layout.gridLayout []
[ listView
[ N.items model.encodedCars
, N.separatorColor "transparent"
, N.class "cars-list"
]
[ carTemplate ]
]
)
view : Model -> Native Msg
view model =
Frame.frame model.rootFrame
model
[ ( HomePage, homePage )
]
[]
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none

View File

@ -1,4 +1,4 @@
module Main exposing (main)
module Flick exposing (main)
import Browser
import Html exposing (Html)
@ -8,10 +8,8 @@ import Native
import Native.Attributes as NA
import Native.Event as Event
import Native.Frame as Frame
import Native.Layout as Layout exposing (rootLayout)
import Native.Layout as Layout
import Native.Page as Page
import Process
import Task
type alias Flick =
@ -109,6 +107,9 @@ init =
)
type Msg
= ToDetails Int
| Back Bool
@ -122,7 +123,18 @@ update msg model =
ToDetails idx ->
( { model
| rootFrame = Frame.current DetailsPage model.rootFrame
| rootFrame =
model.rootFrame
|> Frame.current DetailsPage
(Frame.defaultNavigationOptions
|> Frame.setAnimated True
|> Frame.setTransition
{ name = Just Frame.FlipLeft
, duration = Just 200
, curve = Just Frame.Spring
}
|> Just
)
, picked =
model.flick
|> List.foldl
@ -277,7 +289,8 @@ flickTemplate =
homePage : Model -> Html Msg
homePage model =
Page.pageWithActionBar [ Event.on "navigatedTo" (D.field "isBackNavigation" D.bool |> D.map Back) ]
Page.pageWithActionBar Back
[]
(Native.actionBar [ NA.title "Elm Native Flix" ] [])
(Layout.stackLayout [ NA.height "100%" ]
[ Native.listView
@ -295,14 +308,16 @@ detailsPage : Model -> Html Msg
detailsPage model =
case model.picked of
Nothing ->
Page.page []
Page.page Back
[]
(Layout.stackLayout []
[ Native.label [ NA.text "Not found" ] []
]
)
Just flick ->
Page.pageWithActionBar [ Event.on "navigatedTo" (D.field "isBackNavigation" D.bool |> D.map Back) ]
Page.pageWithActionBar Back
[ Event.on "navigatedTo" (D.field "isBackNavigation" D.bool |> D.map Back) ]
(Native.actionBar [ NA.title flick.title ]
[ Native.navigationButton [ NA.text "Back" ] []
]