From fe10054e44440cbfbca6814aabbe6a4261d4e608 Mon Sep 17 00:00:00 2001 From: Alexander Kobjolke Date: Mon, 11 Dec 2023 11:30:30 +0100 Subject: [PATCH] Implement chapter 3: random picture selection --- app.js | 653 ++++++++++++++++++++++++++++++++++++-------- elm.json | 3 +- src/PhotoGroove.elm | 96 ++++++- 3 files changed, 622 insertions(+), 130 deletions(-) diff --git a/app.js b/app.js index 6ca7614..90517b5 100644 --- a/app.js +++ b/app.js @@ -80,6 +80,87 @@ function A9(fun, a, b, c, d, e, f, g, h, i) { console.warn('Compiled in DEV mode. Follow the advice at https://elm-lang.org/0.19.1/optimize for better performance and smaller assets.'); +var _List_Nil_UNUSED = { $: 0 }; +var _List_Nil = { $: '[]' }; + +function _List_Cons_UNUSED(hd, tl) { return { $: 1, a: hd, b: tl }; } +function _List_Cons(hd, tl) { return { $: '::', a: hd, b: tl }; } + + +var _List_cons = F2(_List_Cons); + +function _List_fromArray(arr) +{ + var out = _List_Nil; + for (var i = arr.length; i--; ) + { + out = _List_Cons(arr[i], out); + } + return out; +} + +function _List_toArray(xs) +{ + for (var out = []; xs.b; xs = xs.b) // WHILE_CONS + { + out.push(xs.a); + } + return out; +} + +var _List_map2 = F3(function(f, xs, ys) +{ + for (var arr = []; xs.b && ys.b; xs = xs.b, ys = ys.b) // WHILE_CONSES + { + arr.push(A2(f, xs.a, ys.a)); + } + return _List_fromArray(arr); +}); + +var _List_map3 = F4(function(f, xs, ys, zs) +{ + for (var arr = []; xs.b && ys.b && zs.b; xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES + { + arr.push(A3(f, xs.a, ys.a, zs.a)); + } + return _List_fromArray(arr); +}); + +var _List_map4 = F5(function(f, ws, xs, ys, zs) +{ + for (var arr = []; ws.b && xs.b && ys.b && zs.b; ws = ws.b, xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES + { + arr.push(A4(f, ws.a, xs.a, ys.a, zs.a)); + } + return _List_fromArray(arr); +}); + +var _List_map5 = F6(function(f, vs, ws, xs, ys, zs) +{ + for (var arr = []; vs.b && ws.b && xs.b && ys.b && zs.b; vs = vs.b, ws = ws.b, xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES + { + arr.push(A5(f, vs.a, ws.a, xs.a, ys.a, zs.a)); + } + return _List_fromArray(arr); +}); + +var _List_sortBy = F2(function(f, xs) +{ + return _List_fromArray(_List_toArray(xs).sort(function(a, b) { + return _Utils_cmp(f(a), f(b)); + })); +}); + +var _List_sortWith = F2(function(f, xs) +{ + return _List_fromArray(_List_toArray(xs).sort(function(a, b) { + var ord = A2(f, a, b); + return ord === $elm$core$Basics$EQ ? 0 : ord === $elm$core$Basics$LT ? -1 : 1; + })); +}); + + + var _JsArray_empty = []; function _JsArray_singleton(value) @@ -712,87 +793,6 @@ function _Utils_ap(xs, ys) -var _List_Nil_UNUSED = { $: 0 }; -var _List_Nil = { $: '[]' }; - -function _List_Cons_UNUSED(hd, tl) { return { $: 1, a: hd, b: tl }; } -function _List_Cons(hd, tl) { return { $: '::', a: hd, b: tl }; } - - -var _List_cons = F2(_List_Cons); - -function _List_fromArray(arr) -{ - var out = _List_Nil; - for (var i = arr.length; i--; ) - { - out = _List_Cons(arr[i], out); - } - return out; -} - -function _List_toArray(xs) -{ - for (var out = []; xs.b; xs = xs.b) // WHILE_CONS - { - out.push(xs.a); - } - return out; -} - -var _List_map2 = F3(function(f, xs, ys) -{ - for (var arr = []; xs.b && ys.b; xs = xs.b, ys = ys.b) // WHILE_CONSES - { - arr.push(A2(f, xs.a, ys.a)); - } - return _List_fromArray(arr); -}); - -var _List_map3 = F4(function(f, xs, ys, zs) -{ - for (var arr = []; xs.b && ys.b && zs.b; xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES - { - arr.push(A3(f, xs.a, ys.a, zs.a)); - } - return _List_fromArray(arr); -}); - -var _List_map4 = F5(function(f, ws, xs, ys, zs) -{ - for (var arr = []; ws.b && xs.b && ys.b && zs.b; ws = ws.b, xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES - { - arr.push(A4(f, ws.a, xs.a, ys.a, zs.a)); - } - return _List_fromArray(arr); -}); - -var _List_map5 = F6(function(f, vs, ws, xs, ys, zs) -{ - for (var arr = []; vs.b && ws.b && xs.b && ys.b && zs.b; vs = vs.b, ws = ws.b, xs = xs.b, ys = ys.b, zs = zs.b) // WHILE_CONSES - { - arr.push(A5(f, vs.a, ws.a, xs.a, ys.a, zs.a)); - } - return _List_fromArray(arr); -}); - -var _List_sortBy = F2(function(f, xs) -{ - return _List_fromArray(_List_toArray(xs).sort(function(a, b) { - return _Utils_cmp(f(a), f(b)); - })); -}); - -var _List_sortWith = F2(function(f, xs) -{ - return _List_fromArray(_List_toArray(xs).sort(function(a, b) { - var ord = A2(f, a, b); - return ord === $elm$core$Basics$EQ ? 0 : ord === $elm$core$Basics$LT ? -1 : 1; - })); -}); - - - // MATH var _Basics_add = F2(function(a, b) { return a + b; }); @@ -4370,6 +4370,91 @@ function _Browser_load(url) } })); } + + + +var _Bitwise_and = F2(function(a, b) +{ + return a & b; +}); + +var _Bitwise_or = F2(function(a, b) +{ + return a | b; +}); + +var _Bitwise_xor = F2(function(a, b) +{ + return a ^ b; +}); + +function _Bitwise_complement(a) +{ + return ~a; +}; + +var _Bitwise_shiftLeftBy = F2(function(offset, a) +{ + return a << offset; +}); + +var _Bitwise_shiftRightBy = F2(function(offset, a) +{ + return a >> offset; +}); + +var _Bitwise_shiftRightZfBy = F2(function(offset, a) +{ + return a >>> offset; +}); + + + +function _Time_now(millisToPosix) +{ + return _Scheduler_binding(function(callback) + { + callback(_Scheduler_succeed(millisToPosix(Date.now()))); + }); +} + +var _Time_setInterval = F2(function(interval, task) +{ + return _Scheduler_binding(function(callback) + { + var id = setInterval(function() { _Scheduler_rawSpawn(task); }, interval); + return function() { clearInterval(id); }; + }); +}); + +function _Time_here() +{ + return _Scheduler_binding(function(callback) + { + callback(_Scheduler_succeed( + A2($elm$time$Time$customZone, -(new Date().getTimezoneOffset()), _List_Nil) + )); + }); +} + + +function _Time_getZoneName() +{ + return _Scheduler_binding(function(callback) + { + try + { + var name = $elm$time$Time$Name(Intl.DateTimeFormat().resolvedOptions().timeZone); + } + catch (e) + { + var name = $elm$time$Time$Offset(new Date().getTimezoneOffset()); + } + callback(_Scheduler_succeed(name)); + }); +} +var $elm$core$Basics$EQ = {$: 'EQ'}; +var $elm$core$Basics$LT = {$: 'LT'}; var $elm$core$List$cons = _List_cons; var $elm$core$Elm$JsArray$foldr = _JsArray_foldr; var $elm$core$Array$foldr = F3( @@ -4447,18 +4532,7 @@ var $elm$core$Set$toList = function (_v0) { var dict = _v0.a; return $elm$core$Dict$keys(dict); }; -var $elm$core$Basics$EQ = {$: 'EQ'}; var $elm$core$Basics$GT = {$: 'GT'}; -var $elm$core$Basics$LT = {$: 'LT'}; -var $author$project$PhotoGroove$initialModel = { - photos: _List_fromArray( - [ - {url: '1.jpeg'}, - {url: '2.jpeg'}, - {url: '3.jpeg'} - ]), - selectedUrl: '1.jpeg' -}; var $elm$core$Result$Err = function (a) { return {$: 'Err', a: a}; }; @@ -5167,42 +5241,302 @@ var $elm$core$Task$perform = F2( $elm$core$Task$Perform( A2($elm$core$Task$map, toMessage, task))); }); +var $elm$browser$Browser$element = _Browser_element; +var $author$project$PhotoGroove$Large = {$: 'Large'}; +var $author$project$PhotoGroove$initialModel = { + chosenSize: $author$project$PhotoGroove$Large, + photos: _List_fromArray( + [ + {url: '1.jpeg'}, + {url: '2.jpeg'}, + {url: '3.jpeg'} + ]), + selectedUrl: '1.jpeg' +}; var $elm$core$Platform$Cmd$batch = _Platform_batch; var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); var $elm$core$Platform$Sub$batch = _Platform_batch; var $elm$core$Platform$Sub$none = $elm$core$Platform$Sub$batch(_List_Nil); -var $elm$browser$Browser$sandbox = function (impl) { - return _Browser_element( - { - init: function (_v0) { - return _Utils_Tuple2(impl.init, $elm$core$Platform$Cmd$none); - }, - subscriptions: function (_v1) { - return $elm$core$Platform$Sub$none; - }, - update: F2( - function (msg, model) { - return _Utils_Tuple2( - A2(impl.update, msg, model), - $elm$core$Platform$Cmd$none); - }), - view: impl.view - }); +var $author$project$PhotoGroove$GotSelectedIndex = function (a) { + return {$: 'GotSelectedIndex', a: a}; }; +var $elm$random$Random$Generate = function (a) { + return {$: 'Generate', a: a}; +}; +var $elm$random$Random$Seed = F2( + function (a, b) { + return {$: 'Seed', a: a, b: b}; + }); +var $elm$core$Bitwise$shiftRightZfBy = _Bitwise_shiftRightZfBy; +var $elm$random$Random$next = function (_v0) { + var state0 = _v0.a; + var incr = _v0.b; + return A2($elm$random$Random$Seed, ((state0 * 1664525) + incr) >>> 0, incr); +}; +var $elm$random$Random$initialSeed = function (x) { + var _v0 = $elm$random$Random$next( + A2($elm$random$Random$Seed, 0, 1013904223)); + var state1 = _v0.a; + var incr = _v0.b; + var state2 = (state1 + x) >>> 0; + return $elm$random$Random$next( + A2($elm$random$Random$Seed, state2, incr)); +}; +var $elm$time$Time$Name = function (a) { + return {$: 'Name', a: a}; +}; +var $elm$time$Time$Offset = function (a) { + return {$: 'Offset', a: a}; +}; +var $elm$time$Time$Zone = F2( + function (a, b) { + return {$: 'Zone', a: a, b: b}; + }); +var $elm$time$Time$customZone = $elm$time$Time$Zone; +var $elm$time$Time$Posix = function (a) { + return {$: 'Posix', a: a}; +}; +var $elm$time$Time$millisToPosix = $elm$time$Time$Posix; +var $elm$time$Time$now = _Time_now($elm$time$Time$millisToPosix); +var $elm$time$Time$posixToMillis = function (_v0) { + var millis = _v0.a; + return millis; +}; +var $elm$random$Random$init = A2( + $elm$core$Task$andThen, + function (time) { + return $elm$core$Task$succeed( + $elm$random$Random$initialSeed( + $elm$time$Time$posixToMillis(time))); + }, + $elm$time$Time$now); +var $elm$random$Random$step = F2( + function (_v0, seed) { + var generator = _v0.a; + return generator(seed); + }); +var $elm$random$Random$onEffects = F3( + function (router, commands, seed) { + if (!commands.b) { + return $elm$core$Task$succeed(seed); + } else { + var generator = commands.a.a; + var rest = commands.b; + var _v1 = A2($elm$random$Random$step, generator, seed); + var value = _v1.a; + var newSeed = _v1.b; + return A2( + $elm$core$Task$andThen, + function (_v2) { + return A3($elm$random$Random$onEffects, router, rest, newSeed); + }, + A2($elm$core$Platform$sendToApp, router, value)); + } + }); +var $elm$random$Random$onSelfMsg = F3( + function (_v0, _v1, seed) { + return $elm$core$Task$succeed(seed); + }); +var $elm$random$Random$Generator = function (a) { + return {$: 'Generator', a: a}; +}; +var $elm$random$Random$map = F2( + function (func, _v0) { + var genA = _v0.a; + return $elm$random$Random$Generator( + function (seed0) { + var _v1 = genA(seed0); + var a = _v1.a; + var seed1 = _v1.b; + return _Utils_Tuple2( + func(a), + seed1); + }); + }); +var $elm$random$Random$cmdMap = F2( + function (func, _v0) { + var generator = _v0.a; + return $elm$random$Random$Generate( + A2($elm$random$Random$map, func, generator)); + }); +_Platform_effectManagers['Random'] = _Platform_createManager($elm$random$Random$init, $elm$random$Random$onEffects, $elm$random$Random$onSelfMsg, $elm$random$Random$cmdMap); +var $elm$random$Random$command = _Platform_leaf('Random'); +var $elm$random$Random$generate = F2( + function (tagger, generator) { + return $elm$random$Random$command( + $elm$random$Random$Generate( + A2($elm$random$Random$map, tagger, generator))); + }); +var $elm$core$Bitwise$and = _Bitwise_and; +var $elm$core$Array$bitMask = 4294967295 >>> (32 - $elm$core$Array$shiftStep); +var $elm$core$Basics$ge = _Utils_ge; +var $elm$core$Elm$JsArray$unsafeGet = _JsArray_unsafeGet; +var $elm$core$Array$getHelp = F3( + function (shift, index, tree) { + getHelp: + while (true) { + var pos = $elm$core$Array$bitMask & (index >>> shift); + var _v0 = A2($elm$core$Elm$JsArray$unsafeGet, pos, tree); + if (_v0.$ === 'SubTree') { + var subTree = _v0.a; + var $temp$shift = shift - $elm$core$Array$shiftStep, + $temp$index = index, + $temp$tree = subTree; + shift = $temp$shift; + index = $temp$index; + tree = $temp$tree; + continue getHelp; + } else { + var values = _v0.a; + return A2($elm$core$Elm$JsArray$unsafeGet, $elm$core$Array$bitMask & index, values); + } + } + }); +var $elm$core$Bitwise$shiftLeftBy = _Bitwise_shiftLeftBy; +var $elm$core$Array$tailIndex = function (len) { + return (len >>> 5) << 5; +}; +var $elm$core$Array$get = F2( + function (index, _v0) { + var len = _v0.a; + var startShift = _v0.b; + var tree = _v0.c; + var tail = _v0.d; + return ((index < 0) || (_Utils_cmp(index, len) > -1)) ? $elm$core$Maybe$Nothing : ((_Utils_cmp( + index, + $elm$core$Array$tailIndex(len)) > -1) ? $elm$core$Maybe$Just( + A2($elm$core$Elm$JsArray$unsafeGet, $elm$core$Array$bitMask & index, tail)) : $elm$core$Maybe$Just( + A3($elm$core$Array$getHelp, startShift, index, tree))); + }); +var $elm$core$Array$fromListHelp = F3( + function (list, nodeList, nodeListSize) { + fromListHelp: + while (true) { + var _v0 = A2($elm$core$Elm$JsArray$initializeFromList, $elm$core$Array$branchFactor, list); + var jsArray = _v0.a; + var remainingItems = _v0.b; + if (_Utils_cmp( + $elm$core$Elm$JsArray$length(jsArray), + $elm$core$Array$branchFactor) < 0) { + return A2( + $elm$core$Array$builderToArray, + true, + {nodeList: nodeList, nodeListSize: nodeListSize, tail: jsArray}); + } else { + var $temp$list = remainingItems, + $temp$nodeList = A2( + $elm$core$List$cons, + $elm$core$Array$Leaf(jsArray), + nodeList), + $temp$nodeListSize = nodeListSize + 1; + list = $temp$list; + nodeList = $temp$nodeList; + nodeListSize = $temp$nodeListSize; + continue fromListHelp; + } + } + }); +var $elm$core$Array$fromList = function (list) { + if (!list.b) { + return $elm$core$Array$empty; + } else { + return A3($elm$core$Array$fromListHelp, list, _List_Nil, 0); + } +}; +var $author$project$PhotoGroove$photoArray = $elm$core$Array$fromList($author$project$PhotoGroove$initialModel.photos); +var $author$project$PhotoGroove$getPhotoUrl = function (id) { + var _v0 = A2($elm$core$Array$get, id, $author$project$PhotoGroove$photoArray); + if (_v0.$ === 'Just') { + var photo = _v0.a; + return photo.url; + } else { + return ''; + } +}; +var $elm$core$Basics$negate = function (n) { + return -n; +}; +var $elm$core$Bitwise$xor = _Bitwise_xor; +var $elm$random$Random$peel = function (_v0) { + var state = _v0.a; + var word = (state ^ (state >>> ((state >>> 28) + 4))) * 277803737; + return ((word >>> 22) ^ word) >>> 0; +}; +var $elm$random$Random$int = F2( + function (a, b) { + return $elm$random$Random$Generator( + function (seed0) { + var _v0 = (_Utils_cmp(a, b) < 0) ? _Utils_Tuple2(a, b) : _Utils_Tuple2(b, a); + var lo = _v0.a; + var hi = _v0.b; + var range = (hi - lo) + 1; + if (!((range - 1) & range)) { + return _Utils_Tuple2( + (((range - 1) & $elm$random$Random$peel(seed0)) >>> 0) + lo, + $elm$random$Random$next(seed0)); + } else { + var threshhold = (((-range) >>> 0) % range) >>> 0; + var accountForBias = function (seed) { + accountForBias: + while (true) { + var x = $elm$random$Random$peel(seed); + var seedN = $elm$random$Random$next(seed); + if (_Utils_cmp(x, threshhold) < 0) { + var $temp$seed = seedN; + seed = $temp$seed; + continue accountForBias; + } else { + return _Utils_Tuple2((x % range) + lo, seedN); + } + } + }; + return accountForBias(seed0); + } + }); + }); +var $elm$core$Array$length = function (_v0) { + var len = _v0.a; + return len; +}; +var $author$project$PhotoGroove$randomPhotoPicker = A2( + $elm$random$Random$int, + 0, + $elm$core$Array$length($author$project$PhotoGroove$photoArray) - 1); var $author$project$PhotoGroove$update = F2( function (msg, model) { - if (msg.$ === 'ClickedThumbnail') { - var thumb = msg.a; - return _Utils_update( - model, - {selectedUrl: thumb}); - } else { - return _Utils_update( - model, - {selectedUrl: '2.jpeg'}); + switch (msg.$) { + case 'ClickedThumbnail': + var thumb = msg.a; + return _Utils_Tuple2( + _Utils_update( + model, + {selectedUrl: thumb}), + $elm$core$Platform$Cmd$none); + case 'ClickedSurpriseMe': + return _Utils_Tuple2( + model, + A2($elm$random$Random$generate, $author$project$PhotoGroove$GotSelectedIndex, $author$project$PhotoGroove$randomPhotoPicker)); + case 'ClickedSize': + var size = msg.a; + return _Utils_Tuple2( + _Utils_update( + model, + {chosenSize: size}), + $elm$core$Platform$Cmd$none); + default: + var idx = msg.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + selectedUrl: $author$project$PhotoGroove$getPhotoUrl(idx) + }), + $elm$core$Platform$Cmd$none); } }); var $author$project$PhotoGroove$ClickedSurpriseMe = {$: 'ClickedSurpriseMe'}; +var $author$project$PhotoGroove$Medium = {$: 'Medium'}; +var $author$project$PhotoGroove$Small = {$: 'Small'}; var $elm$html$Html$button = _VirtualDom_node('button'); var $elm$json$Json$Encode$string = _Json_wrap; var $elm$html$Html$Attributes$stringProperty = F2( @@ -5215,6 +5549,7 @@ var $elm$html$Html$Attributes$stringProperty = F2( var $elm$html$Html$Attributes$class = $elm$html$Html$Attributes$stringProperty('className'); var $elm$html$Html$div = _VirtualDom_node('div'); var $elm$html$Html$h1 = _VirtualDom_node('h1'); +var $elm$html$Html$h3 = _VirtualDom_node('h3'); var $elm$html$Html$Attributes$id = $elm$html$Html$Attributes$stringProperty('id'); var $elm$html$Html$img = _VirtualDom_node('img'); var $elm$virtual_dom$VirtualDom$Normal = function (a) { @@ -5234,6 +5569,16 @@ var $elm$html$Html$Events$onClick = function (msg) { 'click', $elm$json$Json$Decode$succeed(msg)); }; +var $author$project$PhotoGroove$sizeToClass = function (size) { + switch (size.$) { + case 'Small': + return 'small'; + case 'Medium': + return 'med'; + default: + return 'large'; + } +}; var $elm$html$Html$Attributes$src = function (url) { return A2( $elm$html$Html$Attributes$stringProperty, @@ -5243,6 +5588,43 @@ var $elm$html$Html$Attributes$src = function (url) { var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; var $author$project$PhotoGroove$urlPrefix = 'http://elm-in-action.com/'; +var $author$project$PhotoGroove$ClickedSize = function (a) { + return {$: 'ClickedSize', a: a}; +}; +var $elm$html$Html$input = _VirtualDom_node('input'); +var $elm$html$Html$label = _VirtualDom_node('label'); +var $elm$html$Html$Attributes$name = $elm$html$Html$Attributes$stringProperty('name'); +var $author$project$PhotoGroove$sizeToString = function (size) { + switch (size.$) { + case 'Small': + return 'small'; + case 'Medium': + return 'medium'; + default: + return 'large'; + } +}; +var $elm$html$Html$Attributes$type_ = $elm$html$Html$Attributes$stringProperty('type'); +var $author$project$PhotoGroove$viewSizeChooser = function (size) { + return A2( + $elm$html$Html$label, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$input, + _List_fromArray( + [ + $elm$html$Html$Attributes$type_('radio'), + $elm$html$Html$Attributes$name('size'), + $elm$html$Html$Events$onClick( + $author$project$PhotoGroove$ClickedSize(size)) + ]), + _List_Nil), + $elm$html$Html$text( + $author$project$PhotoGroove$sizeToString(size)) + ])); +}; var $author$project$PhotoGroove$ClickedThumbnail = function (a) { return {$: 'ClickedThumbnail', a: a}; }; @@ -5318,10 +5700,30 @@ var $author$project$PhotoGroove$view = function (model) { $elm$html$Html$text('Surprise me!') ])), A2( + $elm$html$Html$h3, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text('Thumbnail Size:') + ])), + A2( $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$id('thumbnails') + $elm$html$Html$Attributes$id('choose-size') + ]), + A2( + $elm$core$List$map, + $author$project$PhotoGroove$viewSizeChooser, + _List_fromArray( + [$author$project$PhotoGroove$Small, $author$project$PhotoGroove$Medium, $author$project$PhotoGroove$Large]))), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$id('thumbnails'), + $elm$html$Html$Attributes$class( + $author$project$PhotoGroove$sizeToClass(model.chosenSize)) ]), A2( $elm$core$List$map, @@ -5337,7 +5739,16 @@ var $author$project$PhotoGroove$view = function (model) { _List_Nil) ])); }; -var $author$project$PhotoGroove$main = $elm$browser$Browser$sandbox( - {init: $author$project$PhotoGroove$initialModel, update: $author$project$PhotoGroove$update, view: $author$project$PhotoGroove$view}); +var $author$project$PhotoGroove$main = $elm$browser$Browser$element( + { + init: function (_v0) { + return _Utils_Tuple2($author$project$PhotoGroove$initialModel, $elm$core$Platform$Cmd$none); + }, + subscriptions: function (_v1) { + return $elm$core$Platform$Sub$none; + }, + update: $author$project$PhotoGroove$update, + view: $author$project$PhotoGroove$view + }); _Platform_export({'PhotoGroove':{'init':$author$project$PhotoGroove$main( $elm$json$Json$Decode$succeed(_Utils_Tuple0))(0)}});}(this)); \ No newline at end of file diff --git a/elm.json b/elm.json index ce2a08d..d100bad 100644 --- a/elm.json +++ b/elm.json @@ -8,7 +8,8 @@ "direct": { "elm/browser": "1.0.2", "elm/core": "1.0.5", - "elm/html": "1.0.0" + "elm/html": "1.0.0", + "elm/random": "1.0.0" }, "indirect": { "elm/json": "1.1.3", diff --git a/src/PhotoGroove.elm b/src/PhotoGroove.elm index 89b2765..2a0a9a9 100644 --- a/src/PhotoGroove.elm +++ b/src/PhotoGroove.elm @@ -2,19 +2,29 @@ module PhotoGroove exposing (main) import Array exposing (Array) import Browser -import Html exposing (Html, button, div, h1, img, text) +import Html exposing (Html, button, div, h1, h3, img, input, label, text) import Html.Attributes exposing (..) import Html.Events exposing (onClick) +import Random type alias Model = - { photos : List Photo, selectedUrl : String } + { photos : List Photo + , selectedUrl : String + , chosenSize : ThumbnailSize + } type alias Photo = { url : String } +type ThumbnailSize + = Small + | Medium + | Large + + initialModel : Model initialModel = { photos = @@ -23,20 +33,42 @@ initialModel = , { url = "3.jpeg" } ] , selectedUrl = "1.jpeg" + , chosenSize = Large } +getPhotoUrl : Int -> String +getPhotoUrl id = + case Array.get id photoArray of + Just photo -> + photo.url + + Nothing -> + "" + + photoArray : Array Photo photoArray = Array.fromList initialModel.photos +randomPhotoPicker : Random.Generator Int +randomPhotoPicker = + Random.int 0 (Array.length photoArray - 1) + + view : Model -> Html Message view model = div [ class "content" ] [ h1 [] [ text "Photo Groove" ] , button [ onClick ClickedSurpriseMe ] [ text "Surprise me!" ] - , div [ id "thumbnails" ] + , h3 [] [ text "Thumbnail Size:" ] + , div [ id "choose-size" ] + (List.map viewSizeChooser [ Small, Medium, Large ]) + , div + [ id "thumbnails" + , class (sizeToClass model.chosenSize) + ] (List.map (viewThumbnail model.selectedUrl) model.photos) , img [ class "large", src (urlPrefix ++ "large/" ++ model.selectedUrl) ] [] ] @@ -52,19 +84,66 @@ viewThumbnail selectedUrl thumb = [] +viewSizeChooser : ThumbnailSize -> Html Message +viewSizeChooser size = + label [] + [ input + [ type_ "radio" + , name "size" + , onClick (ClickedSize size) + ] + [] + , text (sizeToString size) + ] + + +sizeToString : ThumbnailSize -> String +sizeToString size = + case size of + Small -> + "small" + + Medium -> + "medium" + + Large -> + "large" + + +sizeToClass : ThumbnailSize -> String +sizeToClass size = + case size of + Small -> + "small" + + Medium -> + "med" + + Large -> + "large" + + type Message = ClickedThumbnail String | ClickedSurpriseMe + | ClickedSize ThumbnailSize + | GotSelectedIndex Int -update : Message -> Model -> Model +update : Message -> Model -> ( Model, Cmd Message ) update msg model = case msg of ClickedThumbnail thumb -> - { model | selectedUrl = thumb } + ( { model | selectedUrl = thumb }, Cmd.none ) ClickedSurpriseMe -> - { model | selectedUrl = "2.jpeg" } + ( model, Random.generate GotSelectedIndex randomPhotoPicker ) + + ClickedSize size -> + ( { model | chosenSize = size }, Cmd.none ) + + GotSelectedIndex idx -> + ( { model | selectedUrl = getPhotoUrl idx }, Cmd.none ) urlPrefix : String @@ -74,8 +153,9 @@ urlPrefix = main : Program () Model Message main = - Browser.sandbox - { init = initialModel + Browser.element + { init = \_ -> ( initialModel, Cmd.none ) + , subscriptions = \_ -> Sub.none , view = view , update = update }