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:
Alexander Kobjolke 2023-12-12 09:43:51 +01:00
parent e47f1d0449
commit a4501d5cb5
4 changed files with 174 additions and 44 deletions

150
app.js
View file

@ -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);
} }

View file

@ -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
View file

@ -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"
}
]

View file

@ -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 )