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

144
app.js
View file

@ -5420,6 +5420,7 @@ var $elm$browser$Browser$element = _Browser_element;
var $author$project$PhotoGroove$GotPhotos = function (a) {
return {$: 'GotPhotos', a: a};
};
var $elm$json$Json$Decode$decodeString = _Json_runOnString;
var $elm$http$Http$BadStatus_ = F2(
function (a, b) {
return {$: 'BadStatus_', a: a, b: b};
@ -5975,17 +5976,6 @@ var $elm$http$Http$expectStringResponse = F2(
$elm$core$Basics$identity,
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(
function (f, result) {
if (result.$ === 'Ok') {
@ -5997,6 +5987,17 @@ var $elm$core$Result$mapError = F2(
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(
function (toResult, response) {
switch (response.$) {
@ -6020,12 +6021,19 @@ var $elm$http$Http$resolve = F2(
toResult(body));
}
});
var $elm$http$Http$expectString = function (toMsg) {
var $elm$http$Http$expectJson = F2(
function (toMsg, decoder) {
return A2(
$elm$http$Http$expectStringResponse,
toMsg,
$elm$http$Http$resolve($elm$core$Result$Ok));
};
$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$Request = function (a) {
return {$: 'Request', a: a};
@ -6199,9 +6207,99 @@ var $elm$http$Http$get = function (r) {
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});
};
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(
{
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'
});
var $author$project$PhotoGroove$Large = {$: 'Large'};
@ -6219,9 +6317,6 @@ var $author$project$PhotoGroove$Loaded = F2(
function (a, b) {
return {$: 'Loaded', a: a, b: b};
});
var $author$project$PhotoGroove$Photo = function (url) {
return {url: url};
};
var $elm$random$Random$Generate = function (a) {
return {$: 'Generate', a: a};
};
@ -6500,17 +6595,14 @@ var $author$project$PhotoGroove$update = F2(
$elm$core$Platform$Cmd$none);
default:
if (msg.a.$ === 'Ok') {
var str = msg.a.a;
var _v3 = A2($elm$core$String$split, ',', str);
if (_v3.b) {
var urls = _v3;
var x = urls.a;
var photos = A2($elm$core$List$map, $author$project$PhotoGroove$Photo, urls);
if (msg.a.a.b) {
var photos = msg.a.a;
var firstPhoto = photos.a;
return _Utils_Tuple2(
_Utils_update(
model,
{
status: A2($author$project$PhotoGroove$Loaded, photos, x)
status: A2($author$project$PhotoGroove$Loaded, photos, firstPhoto.url)
}),
$elm$core$Platform$Cmd$none);
} else {
@ -6518,7 +6610,7 @@ var $author$project$PhotoGroove$update = F2(
_Utils_update(
model,
{
status: $author$project$PhotoGroove$Errored('No photos: ' + str)
status: $author$project$PhotoGroove$Errored('No photos!')
}),
$elm$core$Platform$Cmd$none);
}

View file

@ -6,16 +6,17 @@
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"NoRedInk/elm-json-decode-pipeline": "1.0.1",
"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/random": "1.0.0"
},
"indirect": {
"elm/bytes": "1.0.8",
"elm/file": "1.0.5",
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"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.Events exposing (onClick)
import Http
import Json.Decode as D exposing (Decoder)
import Json.Decode.Pipeline as D
import Random
@ -21,7 +23,18 @@ type alias Model =
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
@ -41,7 +54,7 @@ initialCommand : Cmd Message
initialCommand =
Http.get
{ url = "list"
, expect = Http.expectString GotPhotos
, expect = Http.expectJson GotPhotos (D.list photoDecoder)
}
@ -129,7 +142,7 @@ type Message
| ClickedSurpriseMe
| ClickedSize ThumbnailSize
| GotRandomPhoto Photo
| GotPhotos (Result Http.Error String)
| GotPhotos (Result Http.Error (List Photo))
update : Message -> Model -> ( Model, Cmd Message )
@ -160,17 +173,11 @@ update msg model =
GotRandomPhoto photo ->
( { model | status = selectUrl photo.url model.status }, Cmd.none )
GotPhotos (Ok str) ->
case String.split "," str of
(x :: _) as urls ->
let
photos =
List.map Photo urls
in
( { model | status = Loaded photos x }, Cmd.none )
GotPhotos (Ok ((firstPhoto :: _) as photos)) ->
( { model | status = Loaded photos firstPhoto.url }, Cmd.none )
[] ->
( { model | status = Errored ("No photos: " ++ str) }, Cmd.none )
GotPhotos (Ok []) ->
( { model | status = Errored "No photos!" }, Cmd.none )
GotPhotos (Err httpError) ->
( { model | status = Errored <| ("Failed to load photos: " ++ httpErrorToString httpError) }, Cmd.none )