Switch to json encoded meta data
Instead of parsing a comma separated list of photo urls, we retrieve a json array of meta data (url, title, size).
This commit is contained in:
parent
e47f1d0449
commit
a4501d5cb5
4 changed files with 174 additions and 44 deletions
150
app.js
150
app.js
|
|
@ -5420,6 +5420,7 @@ var $elm$browser$Browser$element = _Browser_element;
|
||||||
var $author$project$PhotoGroove$GotPhotos = function (a) {
|
var $author$project$PhotoGroove$GotPhotos = function (a) {
|
||||||
return {$: 'GotPhotos', a: a};
|
return {$: 'GotPhotos', a: a};
|
||||||
};
|
};
|
||||||
|
var $elm$json$Json$Decode$decodeString = _Json_runOnString;
|
||||||
var $elm$http$Http$BadStatus_ = F2(
|
var $elm$http$Http$BadStatus_ = F2(
|
||||||
function (a, b) {
|
function (a, b) {
|
||||||
return {$: 'BadStatus_', a: a, b: b};
|
return {$: 'BadStatus_', a: a, b: b};
|
||||||
|
|
@ -5975,17 +5976,6 @@ var $elm$http$Http$expectStringResponse = F2(
|
||||||
$elm$core$Basics$identity,
|
$elm$core$Basics$identity,
|
||||||
A2($elm$core$Basics$composeR, toResult, toMsg));
|
A2($elm$core$Basics$composeR, toResult, toMsg));
|
||||||
});
|
});
|
||||||
var $elm$http$Http$BadBody = function (a) {
|
|
||||||
return {$: 'BadBody', a: a};
|
|
||||||
};
|
|
||||||
var $elm$http$Http$BadStatus = function (a) {
|
|
||||||
return {$: 'BadStatus', a: a};
|
|
||||||
};
|
|
||||||
var $elm$http$Http$BadUrl = function (a) {
|
|
||||||
return {$: 'BadUrl', a: a};
|
|
||||||
};
|
|
||||||
var $elm$http$Http$NetworkError = {$: 'NetworkError'};
|
|
||||||
var $elm$http$Http$Timeout = {$: 'Timeout'};
|
|
||||||
var $elm$core$Result$mapError = F2(
|
var $elm$core$Result$mapError = F2(
|
||||||
function (f, result) {
|
function (f, result) {
|
||||||
if (result.$ === 'Ok') {
|
if (result.$ === 'Ok') {
|
||||||
|
|
@ -5997,6 +5987,17 @@ var $elm$core$Result$mapError = F2(
|
||||||
f(e));
|
f(e));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
var $elm$http$Http$BadBody = function (a) {
|
||||||
|
return {$: 'BadBody', a: a};
|
||||||
|
};
|
||||||
|
var $elm$http$Http$BadStatus = function (a) {
|
||||||
|
return {$: 'BadStatus', a: a};
|
||||||
|
};
|
||||||
|
var $elm$http$Http$BadUrl = function (a) {
|
||||||
|
return {$: 'BadUrl', a: a};
|
||||||
|
};
|
||||||
|
var $elm$http$Http$NetworkError = {$: 'NetworkError'};
|
||||||
|
var $elm$http$Http$Timeout = {$: 'Timeout'};
|
||||||
var $elm$http$Http$resolve = F2(
|
var $elm$http$Http$resolve = F2(
|
||||||
function (toResult, response) {
|
function (toResult, response) {
|
||||||
switch (response.$) {
|
switch (response.$) {
|
||||||
|
|
@ -6020,12 +6021,19 @@ var $elm$http$Http$resolve = F2(
|
||||||
toResult(body));
|
toResult(body));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var $elm$http$Http$expectString = function (toMsg) {
|
var $elm$http$Http$expectJson = F2(
|
||||||
return A2(
|
function (toMsg, decoder) {
|
||||||
$elm$http$Http$expectStringResponse,
|
return A2(
|
||||||
toMsg,
|
$elm$http$Http$expectStringResponse,
|
||||||
$elm$http$Http$resolve($elm$core$Result$Ok));
|
toMsg,
|
||||||
};
|
$elm$http$Http$resolve(
|
||||||
|
function (string) {
|
||||||
|
return A2(
|
||||||
|
$elm$core$Result$mapError,
|
||||||
|
$elm$json$Json$Decode$errorToString,
|
||||||
|
A2($elm$json$Json$Decode$decodeString, decoder, string));
|
||||||
|
}));
|
||||||
|
});
|
||||||
var $elm$http$Http$emptyBody = _Http_emptyBody;
|
var $elm$http$Http$emptyBody = _Http_emptyBody;
|
||||||
var $elm$http$Http$Request = function (a) {
|
var $elm$http$Http$Request = function (a) {
|
||||||
return {$: 'Request', a: a};
|
return {$: 'Request', a: a};
|
||||||
|
|
@ -6199,9 +6207,99 @@ var $elm$http$Http$get = function (r) {
|
||||||
return $elm$http$Http$request(
|
return $elm$http$Http$request(
|
||||||
{body: $elm$http$Http$emptyBody, expect: r.expect, headers: _List_Nil, method: 'GET', timeout: $elm$core$Maybe$Nothing, tracker: $elm$core$Maybe$Nothing, url: r.url});
|
{body: $elm$http$Http$emptyBody, expect: r.expect, headers: _List_Nil, method: 'GET', timeout: $elm$core$Maybe$Nothing, tracker: $elm$core$Maybe$Nothing, url: r.url});
|
||||||
};
|
};
|
||||||
|
var $elm$json$Json$Decode$list = _Json_decodeList;
|
||||||
|
var $author$project$PhotoGroove$Photo = F3(
|
||||||
|
function (url, size, title) {
|
||||||
|
return {size: size, title: title, url: url};
|
||||||
|
});
|
||||||
|
var $elm$json$Json$Decode$int = _Json_decodeInt;
|
||||||
|
var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom = $elm$json$Json$Decode$map2($elm$core$Basics$apR);
|
||||||
|
var $elm$json$Json$Decode$andThen = _Json_andThen;
|
||||||
|
var $elm$json$Json$Decode$field = _Json_decodeField;
|
||||||
|
var $elm$json$Json$Decode$at = F2(
|
||||||
|
function (fields, decoder) {
|
||||||
|
return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields);
|
||||||
|
});
|
||||||
|
var $elm$json$Json$Decode$decodeValue = _Json_run;
|
||||||
|
var $elm$json$Json$Decode$null = _Json_decodeNull;
|
||||||
|
var $elm$json$Json$Decode$oneOf = _Json_oneOf;
|
||||||
|
var $elm$json$Json$Decode$value = _Json_decodeValue;
|
||||||
|
var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder = F3(
|
||||||
|
function (path, valDecoder, fallback) {
|
||||||
|
var nullOr = function (decoder) {
|
||||||
|
return $elm$json$Json$Decode$oneOf(
|
||||||
|
_List_fromArray(
|
||||||
|
[
|
||||||
|
decoder,
|
||||||
|
$elm$json$Json$Decode$null(fallback)
|
||||||
|
]));
|
||||||
|
};
|
||||||
|
var handleResult = function (input) {
|
||||||
|
var _v0 = A2(
|
||||||
|
$elm$json$Json$Decode$decodeValue,
|
||||||
|
A2($elm$json$Json$Decode$at, path, $elm$json$Json$Decode$value),
|
||||||
|
input);
|
||||||
|
if (_v0.$ === 'Ok') {
|
||||||
|
var rawValue = _v0.a;
|
||||||
|
var _v1 = A2(
|
||||||
|
$elm$json$Json$Decode$decodeValue,
|
||||||
|
nullOr(valDecoder),
|
||||||
|
rawValue);
|
||||||
|
if (_v1.$ === 'Ok') {
|
||||||
|
var finalResult = _v1.a;
|
||||||
|
return $elm$json$Json$Decode$succeed(finalResult);
|
||||||
|
} else {
|
||||||
|
return A2(
|
||||||
|
$elm$json$Json$Decode$at,
|
||||||
|
path,
|
||||||
|
nullOr(valDecoder));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $elm$json$Json$Decode$succeed(fallback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return A2($elm$json$Json$Decode$andThen, handleResult, $elm$json$Json$Decode$value);
|
||||||
|
});
|
||||||
|
var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional = F4(
|
||||||
|
function (key, valDecoder, fallback, decoder) {
|
||||||
|
return A2(
|
||||||
|
$NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom,
|
||||||
|
A3(
|
||||||
|
$NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optionalDecoder,
|
||||||
|
_List_fromArray(
|
||||||
|
[key]),
|
||||||
|
valDecoder,
|
||||||
|
fallback),
|
||||||
|
decoder);
|
||||||
|
});
|
||||||
|
var $NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required = F3(
|
||||||
|
function (key, valDecoder, decoder) {
|
||||||
|
return A2(
|
||||||
|
$NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$custom,
|
||||||
|
A2($elm$json$Json$Decode$field, key, valDecoder),
|
||||||
|
decoder);
|
||||||
|
});
|
||||||
|
var $elm$json$Json$Decode$string = _Json_decodeString;
|
||||||
|
var $author$project$PhotoGroove$photoDecoder = A4(
|
||||||
|
$NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$optional,
|
||||||
|
'title',
|
||||||
|
$elm$json$Json$Decode$string,
|
||||||
|
'(untitled)',
|
||||||
|
A3(
|
||||||
|
$NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required,
|
||||||
|
'size',
|
||||||
|
$elm$json$Json$Decode$int,
|
||||||
|
A3(
|
||||||
|
$NoRedInk$elm_json_decode_pipeline$Json$Decode$Pipeline$required,
|
||||||
|
'url',
|
||||||
|
$elm$json$Json$Decode$string,
|
||||||
|
$elm$json$Json$Decode$succeed($author$project$PhotoGroove$Photo))));
|
||||||
var $author$project$PhotoGroove$initialCommand = $elm$http$Http$get(
|
var $author$project$PhotoGroove$initialCommand = $elm$http$Http$get(
|
||||||
{
|
{
|
||||||
expect: $elm$http$Http$expectString($author$project$PhotoGroove$GotPhotos),
|
expect: A2(
|
||||||
|
$elm$http$Http$expectJson,
|
||||||
|
$author$project$PhotoGroove$GotPhotos,
|
||||||
|
$elm$json$Json$Decode$list($author$project$PhotoGroove$photoDecoder)),
|
||||||
url: 'list'
|
url: 'list'
|
||||||
});
|
});
|
||||||
var $author$project$PhotoGroove$Large = {$: 'Large'};
|
var $author$project$PhotoGroove$Large = {$: 'Large'};
|
||||||
|
|
@ -6219,9 +6317,6 @@ var $author$project$PhotoGroove$Loaded = F2(
|
||||||
function (a, b) {
|
function (a, b) {
|
||||||
return {$: 'Loaded', a: a, b: b};
|
return {$: 'Loaded', a: a, b: b};
|
||||||
});
|
});
|
||||||
var $author$project$PhotoGroove$Photo = function (url) {
|
|
||||||
return {url: url};
|
|
||||||
};
|
|
||||||
var $elm$random$Random$Generate = function (a) {
|
var $elm$random$Random$Generate = function (a) {
|
||||||
return {$: 'Generate', a: a};
|
return {$: 'Generate', a: a};
|
||||||
};
|
};
|
||||||
|
|
@ -6500,17 +6595,14 @@ var $author$project$PhotoGroove$update = F2(
|
||||||
$elm$core$Platform$Cmd$none);
|
$elm$core$Platform$Cmd$none);
|
||||||
default:
|
default:
|
||||||
if (msg.a.$ === 'Ok') {
|
if (msg.a.$ === 'Ok') {
|
||||||
var str = msg.a.a;
|
if (msg.a.a.b) {
|
||||||
var _v3 = A2($elm$core$String$split, ',', str);
|
var photos = msg.a.a;
|
||||||
if (_v3.b) {
|
var firstPhoto = photos.a;
|
||||||
var urls = _v3;
|
|
||||||
var x = urls.a;
|
|
||||||
var photos = A2($elm$core$List$map, $author$project$PhotoGroove$Photo, urls);
|
|
||||||
return _Utils_Tuple2(
|
return _Utils_Tuple2(
|
||||||
_Utils_update(
|
_Utils_update(
|
||||||
model,
|
model,
|
||||||
{
|
{
|
||||||
status: A2($author$project$PhotoGroove$Loaded, photos, x)
|
status: A2($author$project$PhotoGroove$Loaded, photos, firstPhoto.url)
|
||||||
}),
|
}),
|
||||||
$elm$core$Platform$Cmd$none);
|
$elm$core$Platform$Cmd$none);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -6518,7 +6610,7 @@ var $author$project$PhotoGroove$update = F2(
|
||||||
_Utils_update(
|
_Utils_update(
|
||||||
model,
|
model,
|
||||||
{
|
{
|
||||||
status: $author$project$PhotoGroove$Errored('No photos: ' + str)
|
status: $author$project$PhotoGroove$Errored('No photos!')
|
||||||
}),
|
}),
|
||||||
$elm$core$Platform$Cmd$none);
|
$elm$core$Platform$Cmd$none);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
elm.json
3
elm.json
|
|
@ -6,16 +6,17 @@
|
||||||
"elm-version": "0.19.1",
|
"elm-version": "0.19.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"direct": {
|
"direct": {
|
||||||
|
"NoRedInk/elm-json-decode-pipeline": "1.0.1",
|
||||||
"elm/browser": "1.0.2",
|
"elm/browser": "1.0.2",
|
||||||
"elm/core": "1.0.5",
|
"elm/core": "1.0.5",
|
||||||
"elm/html": "1.0.0",
|
"elm/html": "1.0.0",
|
||||||
"elm/http": "2.0.0",
|
"elm/http": "2.0.0",
|
||||||
|
"elm/json": "1.1.3",
|
||||||
"elm/random": "1.0.0"
|
"elm/random": "1.0.0"
|
||||||
},
|
},
|
||||||
"indirect": {
|
"indirect": {
|
||||||
"elm/bytes": "1.0.8",
|
"elm/bytes": "1.0.8",
|
||||||
"elm/file": "1.0.5",
|
"elm/file": "1.0.5",
|
||||||
"elm/json": "1.1.3",
|
|
||||||
"elm/time": "1.0.0",
|
"elm/time": "1.0.0",
|
||||||
"elm/url": "1.0.0",
|
"elm/url": "1.0.0",
|
||||||
"elm/virtual-dom": "1.0.3"
|
"elm/virtual-dom": "1.0.3"
|
||||||
|
|
|
||||||
32
list
32
list
|
|
@ -1 +1,31 @@
|
||||||
1.jpeg,2.jpeg,3.jpeg,4.jpeg
|
[
|
||||||
|
{
|
||||||
|
"url": "1.jpeg",
|
||||||
|
"size": 36,
|
||||||
|
"title": "Beachside"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "2.jpeg",
|
||||||
|
"size": 19,
|
||||||
|
"title": "Epica, live at the Agora"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "3.jpeg",
|
||||||
|
"size": 41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "4.jpeg",
|
||||||
|
"size": 41,
|
||||||
|
"title": "City Museum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "5.jpeg",
|
||||||
|
"size": 25,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "6.jpeg",
|
||||||
|
"size": 37,
|
||||||
|
"title": "Boat in Glass"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import Html exposing (Html, button, div, h1, h3, img, input, label, text)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
import Http
|
import Http
|
||||||
|
import Json.Decode as D exposing (Decoder)
|
||||||
|
import Json.Decode.Pipeline as D
|
||||||
import Random
|
import Random
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,7 +23,18 @@ type alias Model =
|
||||||
|
|
||||||
|
|
||||||
type alias Photo =
|
type alias Photo =
|
||||||
{ url : String }
|
{ url : String
|
||||||
|
, size : Int
|
||||||
|
, title : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
photoDecoder : Decoder Photo
|
||||||
|
photoDecoder =
|
||||||
|
D.succeed Photo
|
||||||
|
|> D.required "url" D.string
|
||||||
|
|> D.required "size" D.int
|
||||||
|
|> D.optional "title" D.string "(untitled)"
|
||||||
|
|
||||||
|
|
||||||
type ThumbnailSize
|
type ThumbnailSize
|
||||||
|
|
@ -41,7 +54,7 @@ initialCommand : Cmd Message
|
||||||
initialCommand =
|
initialCommand =
|
||||||
Http.get
|
Http.get
|
||||||
{ url = "list"
|
{ url = "list"
|
||||||
, expect = Http.expectString GotPhotos
|
, expect = Http.expectJson GotPhotos (D.list photoDecoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -129,7 +142,7 @@ type Message
|
||||||
| ClickedSurpriseMe
|
| ClickedSurpriseMe
|
||||||
| ClickedSize ThumbnailSize
|
| ClickedSize ThumbnailSize
|
||||||
| GotRandomPhoto Photo
|
| GotRandomPhoto Photo
|
||||||
| GotPhotos (Result Http.Error String)
|
| GotPhotos (Result Http.Error (List Photo))
|
||||||
|
|
||||||
|
|
||||||
update : Message -> Model -> ( Model, Cmd Message )
|
update : Message -> Model -> ( Model, Cmd Message )
|
||||||
|
|
@ -160,17 +173,11 @@ update msg model =
|
||||||
GotRandomPhoto photo ->
|
GotRandomPhoto photo ->
|
||||||
( { model | status = selectUrl photo.url model.status }, Cmd.none )
|
( { model | status = selectUrl photo.url model.status }, Cmd.none )
|
||||||
|
|
||||||
GotPhotos (Ok str) ->
|
GotPhotos (Ok ((firstPhoto :: _) as photos)) ->
|
||||||
case String.split "," str of
|
( { model | status = Loaded photos firstPhoto.url }, Cmd.none )
|
||||||
(x :: _) as urls ->
|
|
||||||
let
|
|
||||||
photos =
|
|
||||||
List.map Photo urls
|
|
||||||
in
|
|
||||||
( { model | status = Loaded photos x }, Cmd.none )
|
|
||||||
|
|
||||||
[] ->
|
GotPhotos (Ok []) ->
|
||||||
( { model | status = Errored ("No photos: " ++ str) }, Cmd.none )
|
( { model | status = Errored "No photos!" }, Cmd.none )
|
||||||
|
|
||||||
GotPhotos (Err httpError) ->
|
GotPhotos (Err httpError) ->
|
||||||
( { model | status = Errored <| ("Failed to load photos: " ++ httpErrorToString httpError) }, Cmd.none )
|
( { model | status = Errored <| ("Failed to load photos: " ++ httpErrorToString httpError) }, Cmd.none )
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue