add local storage example

This commit is contained in:
Ryan Haskell-Glatz 2021-04-24 15:41:49 -05:00
parent 2b2643da59
commit ae00cfcb29
9 changed files with 285 additions and 0 deletions

5
examples/03-local-storage/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.DS_Store
.elm-spa
elm-stuff
node_modules
dist

View File

@ -0,0 +1,28 @@
# my new project
> 🌳 built with [elm-spa](https://elm-spa.dev)
## dependencies
This project requires the latest LTS version of [Node.js](https://nodejs.org/)
```bash
npm install -g elm elm-spa
```
## running locally
```bash
elm-spa server # starts this app at http:/localhost:1234
```
### other commands
```bash
elm-spa add # add a new page to the application
elm-spa build # production build
elm-spa watch # runs build as you code (without the server)
```
## learn more
You can learn more at [elm-spa.dev](https://elm-spa.dev)

View File

@ -0,0 +1,27 @@
{
"type": "application",
"source-directories": [
"src",
".elm-spa/defaults",
".elm-spa/generated",
"../../src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/json": "1.1.3",
"elm/url": "1.0.0"
},
"indirect": {
"elm/time": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="/dist/elm.js"></script>
<script src="/main.js"></script>
</body>
</html>

View File

@ -0,0 +1,8 @@
const app = Elm.Main.init({
flags: JSON.parse(localStorage.getItem('storage'))
})
app.ports.save_.subscribe(storage => {
localStorage.setItem('storage', JSON.stringify(storage))
app.ports.load_.send(storage)
})

View File

@ -0,0 +1,82 @@
module Pages.Home_ exposing (Model, Msg, init, page, update, view)
import Gen.Params.Home_ exposing (Params)
import Html exposing (Html)
import Html.Events
import Page
import Ports
import Request
import Shared
import Storage exposing (Storage)
import View exposing (View)
page : Shared.Model -> Request.With Params -> Page.With Model Msg
page shared req =
Page.element
{ init = init
, update = update shared.storage
, view = view shared.storage
, subscriptions = subscriptions
}
-- INIT
type alias Model =
{}
init : ( Model, Cmd Msg )
init =
( {}, Cmd.none )
-- UPDATE
type Msg
= Increment
| Decrement
update : Storage -> Msg -> Model -> ( Model, Cmd Msg )
update storage msg model =
case msg of
Increment ->
( model
, Ports.save (Storage.increment storage)
)
Decrement ->
( model
, Ports.save (Storage.decrement storage)
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Storage -> Model -> View Msg
view storage model =
{ title = "Homepage"
, body =
[ Html.h1 [] [ Html.text "Local storage" ]
, Html.button [ Html.Events.onClick Increment ] [ Html.text "+" ]
, Html.p [] [ Html.text ("Count: " ++ String.fromInt storage.counter) ]
, Html.button [ Html.Events.onClick Decrement ] [ Html.text "-" ]
]
}

View File

@ -0,0 +1,20 @@
port module Ports exposing (load, save)
import Json.Decode as Json
import Storage exposing (Storage)
save : Storage -> Cmd msg
save =
Storage.save >> save_
load : (Storage -> msg) -> Sub msg
load fromStorage =
load_ (\json -> Storage.load json |> fromStorage)
port save_ : Json.Value -> Cmd msg
port load_ : (Json.Value -> msg) -> Sub msg

View File

@ -0,0 +1,45 @@
module Shared exposing
( Flags
, Model
, Msg
, init
, subscriptions
, update
)
import Json.Decode as Json
import Ports
import Request exposing (Request)
import Storage exposing (Storage)
type alias Flags =
Json.Value
type alias Model =
{ storage : Storage
}
init : Request -> Flags -> ( Model, Cmd Msg )
init _ flags =
( { storage = Storage.load flags }
, Cmd.none
)
type Msg
= StorageUpdated Storage
update : Request -> Msg -> Model -> ( Model, Cmd Msg )
update _ msg model =
case msg of
StorageUpdated storage ->
( { model | storage = storage }, Cmd.none )
subscriptions : Request -> Model -> Sub Msg
subscriptions _ _ =
Ports.load StorageUpdated

View File

@ -0,0 +1,59 @@
module Storage exposing
( Storage, save, load
, increment, decrement
)
{-|
@docs Storage, save, load
@docs increment, decrement
-}
import Json.Decode as Json
import Json.Encode as Encode
type alias Storage =
{ counter : Int
}
load : Json.Value -> Storage
load json =
json
|> Json.decodeValue decoder
|> Result.withDefault init
init : Storage
init =
{ counter = 0
}
decoder : Json.Decoder Storage
decoder =
Json.map Storage
(Json.field "counter" Json.int)
save : Storage -> Json.Value
save storage =
Encode.object
[ ( "counter", Encode.int storage.counter )
]
-- UPDATING STORAGE
increment : Storage -> Storage
increment storage =
{ storage | counter = storage.counter + 1 }
decrement : Storage -> Storage
decrement storage =
{ storage | counter = storage.counter - 1 }