diff --git a/assets/gostart.html b/assets/gostart.html index bd14a02..a4deb41 100644 --- a/assets/gostart.html +++ b/assets/gostart.html @@ -44,13 +44,31 @@ } .bar { + display: grid; + grid-template-columns: repeat(2, 1fr); padding: 5px !important; border-bottom: 1px solid black; border-radius: 10px 10px 0px 0px; background-color: #dedeff; + cursor: pointer; + } + + .bar-left { + text-align: left; + } + + .bar-right { text-align: right; } + .form-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + } + + .form-content { + } + header { padding: 0 !important; } diff --git a/assets/main.js b/assets/main.js index c39fad2..5877568 100644 --- a/assets/main.js +++ b/assets/main.js @@ -6195,7 +6195,14 @@ var $author$project$Main$getWatches = $elm$http$Http$get( url: '/watches' }); var $author$project$Main$Loading = {$: 'Loading'}; -var $author$project$Main$initialModel = {errors: _List_Nil, links: _List_Nil, status: $author$project$Main$Loading, watches: _List_Nil}; +var $author$project$Main$initialModel = { + errors: _List_Nil, + links: _List_Nil, + newlink: {logo_url: '', name: '', shared: false, url: ''}, + newwatch: {name: '', repo: ''}, + status: $author$project$Main$Loading, + watches: _List_Nil +}; var $author$project$Main$init = function (_v0) { return _Utils_Tuple2( $author$project$Main$initialModel, @@ -6226,14 +6233,98 @@ var $elm$core$List$head = function (list) { return $elm$core$Maybe$Nothing; } }; +var $author$project$Main$HidItem = function (a) { + return {$: 'HidItem', a: a}; +}; +var $elm$json$Json$Encode$int = _Json_wrap; +var $elm$http$Http$jsonBody = function (value) { + return A2( + _Http_pair, + 'application/json', + A2($elm$json$Json$Encode$encode, 0, value)); +}; +var $elm$json$Json$Encode$object = function (pairs) { + return _Json_wrap( + A3( + $elm$core$List$foldl, + F2( + function (_v0, obj) { + var k = _v0.a; + var v = _v0.b; + return A3(_Json_addField, k, v, obj); + }), + _Json_emptyObject(_Utils_Tuple0), + pairs)); +}; +var $elm$http$Http$post = function (r) { + return $elm$http$Http$request( + {body: r.body, expect: r.expect, headers: _List_Nil, method: 'POST', timeout: $elm$core$Maybe$Nothing, tracker: $elm$core$Maybe$Nothing, url: r.url}); +}; +var $elm$json$Json$Encode$string = _Json_wrap; +var $author$project$Main$hideWatched = F2( + function (id, repo) { + var body = $elm$http$Http$jsonBody( + $elm$json$Json$Encode$object( + _List_fromArray( + [ + _Utils_Tuple2( + 'number', + $elm$json$Json$Encode$int(id)), + _Utils_Tuple2( + 'repo', + $elm$json$Json$Encode$string(repo)) + ]))); + return $elm$http$Http$post( + { + body: body, + expect: A2($elm$http$Http$expectJson, $author$project$Main$HidItem, $elm$json$Json$Decode$string), + url: '/prignores' + }); + }); var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); var $author$project$Main$update = F2( function (msg, model) { switch (msg.$) { - case 'AddLink': - return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); - case 'AddWatch': - return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); + case 'HidItem': + if (msg.a.$ === 'Err') { + return _Utils_Tuple2( + _Utils_update( + model, + { + status: $author$project$Main$Errored('Server error when hiding a watch item!') + }), + $elm$core$Platform$Cmd$none); + } else { + return _Utils_Tuple2( + model, + $elm$core$Platform$Cmd$batch( + _List_fromArray( + [$author$project$Main$getWatches, $author$project$Main$getLinks]))); + } + case 'HideWatchedItem': + var itemId = msg.a; + var repo = msg.b; + return _Utils_Tuple2( + model, + $elm$core$Platform$Cmd$batch( + _List_fromArray( + [ + A2($author$project$Main$hideWatched, itemId, repo) + ]))); + case 'SubmitWatch': + return _Utils_Tuple2( + _Utils_update( + model, + {newwatch: model.newwatch}), + $elm$core$Platform$Cmd$batch( + _List_fromArray( + [$author$project$Main$getWatches]))); + case 'SubmitLink': + return _Utils_Tuple2( + model, + $elm$core$Platform$Cmd$batch( + _List_fromArray( + [$author$project$Main$getLinks]))); case 'Reload': return _Utils_Tuple2( model, @@ -6328,7 +6419,6 @@ var $author$project$Main$update = F2( } } }); -var $elm$json$Json$Encode$string = _Json_wrap; var $elm$html$Html$Attributes$stringProperty = F2( function (key, string) { return A2( @@ -6338,7 +6428,6 @@ 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$footer = _VirtualDom_node('footer'); var $elm$virtual_dom$VirtualDom$node = function (tag) { return _VirtualDom_node( _VirtualDom_noScript(tag)); @@ -6348,16 +6437,157 @@ var $author$project$Main$mainEle = F2( function (attributes, children) { return A3($elm$html$Html$node, 'main', attributes, children); }); -var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; -var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; -var $author$project$Main$AddLink = {$: 'AddLink'}; var $author$project$Main$ReloadLinks = {$: 'ReloadLinks'}; var $elm$html$Html$a = _VirtualDom_node('a'); var $elm$html$Html$header = _VirtualDom_node('header'); +var $author$project$Main$bar = F2( + function (left, right) { + return A2( + $elm$html$Html$header, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('bar') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('bar-left') + ]), + _List_fromArray( + [left])), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('bar-right') + ]), + _List_fromArray( + [right])) + ])); + }); +var $author$project$Main$SubmitLink = {$: 'SubmitLink'}; +var $elm$html$Html$button = _VirtualDom_node('button'); +var $elm$html$Html$details = _VirtualDom_node('details'); +var $elm$html$Html$form = _VirtualDom_node('form'); +var $elm$html$Html$Events$alwaysPreventDefault = function (msg) { + return _Utils_Tuple2(msg, true); +}; +var $elm$virtual_dom$VirtualDom$MayPreventDefault = function (a) { + return {$: 'MayPreventDefault', a: a}; +}; +var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; +var $elm$html$Html$Events$preventDefaultOn = F2( + function (event, decoder) { + return A2( + $elm$virtual_dom$VirtualDom$on, + event, + $elm$virtual_dom$VirtualDom$MayPreventDefault(decoder)); + }); +var $elm$html$Html$Events$onSubmit = function (msg) { + return A2( + $elm$html$Html$Events$preventDefaultOn, + 'submit', + A2( + $elm$json$Json$Decode$map, + $elm$html$Html$Events$alwaysPreventDefault, + $elm$json$Json$Decode$succeed(msg))); +}; +var $elm$html$Html$summary = _VirtualDom_node('summary'); +var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; +var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; +var $author$project$Main$createForm = F2( + function (action, content) { + return A2( + $elm$html$Html$details, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$summary, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text('') + ])), + A2( + $elm$html$Html$form, + _List_fromArray( + [ + $elm$html$Html$Events$onSubmit(action), + $elm$html$Html$Attributes$class('form-container') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('form-content') + ]), + _List_fromArray( + [ + content, + A2( + $elm$html$Html$button, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text('Submit') + ])) + ])) + ])) + ])); + }); +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 $elm$html$Html$Attributes$placeholder = $elm$html$Html$Attributes$stringProperty('placeholder'); +var $elm$html$Html$Attributes$type_ = $elm$html$Html$Attributes$stringProperty('type'); +var $author$project$Main$labeledTextBox = F3( + function (labelStr, placeStr, inputName) { + return A2( + $elm$html$Html$label, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text(labelStr), + A2( + $elm$html$Html$input, + _List_fromArray( + [ + $elm$html$Html$Attributes$type_('text'), + $elm$html$Html$Attributes$name(inputName), + $elm$html$Html$Attributes$placeholder(placeStr) + ]), + _List_Nil) + ])); + }); +var $author$project$Main$linkForm = function (_v0) { + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A2( + $author$project$Main$createForm, + $author$project$Main$SubmitLink, + A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A3($author$project$Main$labeledTextBox, 'Name: ', 'Potato', ''), + A3($author$project$Main$labeledTextBox, 'URL: ', 'https://....', ''), + A3($author$project$Main$labeledTextBox, 'Icon: ', 'https://....', '') + ]))) + ])); +}; var $elm$virtual_dom$VirtualDom$Normal = function (a) { return {$: 'Normal', a: a}; }; -var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; var $elm$html$Html$Events$on = F2( function (event, decoder) { return A2( @@ -6431,58 +6661,49 @@ var $author$project$Main$viewLink = function (link) { ])); }; var $author$project$Main$viewLinks = function (model) { - var _v0 = model.links; - if (_v0.b) { - return A2( - $elm$html$Html$div, - _List_Nil, - _List_fromArray( - [ - A2( - $elm$html$Html$header, + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A2( + $author$project$Main$bar, + $author$project$Main$linkForm(model), + A2( + $elm$html$Html$a, _List_fromArray( [ - $elm$html$Html$Attributes$class('bar') + $elm$html$Html$Events$onClick($author$project$Main$ReloadLinks) ]), _List_fromArray( [ - A2( - $elm$html$Html$a, - _List_fromArray( - [ - $elm$html$Html$Events$onClick($author$project$Main$ReloadLinks) - ]), - _List_fromArray( - [ - $elm$html$Html$text(' ⟳') - ])), - A2( - $elm$html$Html$a, - _List_fromArray( - [ - $elm$html$Html$Events$onClick($author$project$Main$AddLink) - ]), - _List_fromArray( - [ - $elm$html$Html$text(' + ') - ])) - ])), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('icon-grid') - ]), - A2($elm$core$List$map, $author$project$Main$viewLink, model.links)) - ])); - } else { - return $elm$html$Html$text('No Links!'); - } + $elm$html$Html$text(' ⟳') + ]))), + function () { + var _v0 = model.links; + if (_v0.b) { + return A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('icon-grid') + ]), + A2($elm$core$List$map, $author$project$Main$viewLink, model.links)); + } else { + return $elm$html$Html$text('No links found!'); + } + }() + ])); }; -var $author$project$Main$AddWatch = {$: 'AddWatch'}; var $author$project$Main$ReloadWatches = {$: 'ReloadWatches'}; var $elm$html$Html$ul = _VirtualDom_node('ul'); +var $elm$html$Html$b = _VirtualDom_node('b'); +var $author$project$Main$HideWatchedItem = F2( + function (a, b) { + return {$: 'HideWatchedItem', a: a, b: b}; + }); var $elm$html$Html$li = _VirtualDom_node('li'); +var $elm$html$Html$span = _VirtualDom_node('span'); var $author$project$Main$displayResult = function (node) { return A2( $elm$html$Html$li, @@ -6500,7 +6721,20 @@ var $author$project$Main$displayResult = function (node) { $elm$html$Html$text( $elm$core$String$fromInt(node.number)) ])), - $elm$html$Html$text(' :: ' + node.title) + $elm$html$Html$text(' :: '), + A2( + $elm$html$Html$span, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$Main$HideWatchedItem, node.number, node.repository.nameWithOwner)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('⦸') + ])), + $elm$html$Html$text(' :: '), + $elm$html$Html$text(node.title) ])); }; var $author$project$Main$viewWatch = function (watch) { @@ -6523,9 +6757,15 @@ var $author$project$Main$viewWatch = function (watch) { _List_Nil, _List_fromArray( [ - $elm$html$Html$text(watch.repo), - $elm$html$Html$text(' :: '), - $elm$html$Html$text(watch.name), + A2( + $elm$html$Html$b, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text(watch.repo), + $elm$html$Html$text(' -> '), + $elm$html$Html$text(watch.name) + ])), A2( $elm$html$Html$ul, _List_Nil, @@ -6535,51 +6775,57 @@ var $author$project$Main$viewWatch = function (watch) { ])); } }; -var $author$project$Main$viewWatches = function (model) { - var _v0 = model.watches; - if (_v0.b) { - return A2( - $elm$html$Html$div, - _List_Nil, - _List_fromArray( - [ - A2( - $elm$html$Html$header, +var $author$project$Main$SubmitWatch = {$: 'SubmitWatch'}; +var $author$project$Main$watchForm = function (_v0) { + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A2( + $author$project$Main$createForm, + $author$project$Main$SubmitWatch, + A2( + $elm$html$Html$div, + _List_Nil, _List_fromArray( [ - $elm$html$Html$Attributes$class('bar') + A3($author$project$Main$labeledTextBox, 'Item: ', 'some string...', ''), + A3($author$project$Main$labeledTextBox, 'Repository: ', 'NixOS/nixpkgs', '') + ]))) + ])); +}; +var $author$project$Main$viewWatches = function (model) { + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A2( + $author$project$Main$bar, + $author$project$Main$watchForm(model), + A2( + $elm$html$Html$a, + _List_fromArray( + [ + $elm$html$Html$Events$onClick($author$project$Main$ReloadWatches) ]), _List_fromArray( [ - A2( - $elm$html$Html$a, - _List_fromArray( - [ - $elm$html$Html$Events$onClick($author$project$Main$ReloadWatches) - ]), - _List_fromArray( - [ - $elm$html$Html$text(' ⟳') - ])), - A2( - $elm$html$Html$a, - _List_fromArray( - [ - $elm$html$Html$Events$onClick($author$project$Main$AddWatch) - ]), - _List_fromArray( - [ - $elm$html$Html$text(' + ') - ])) - ])), - A2( - $elm$html$Html$ul, - _List_Nil, - A2($elm$core$List$map, $author$project$Main$viewWatch, model.watches)) - ])); - } else { - return $elm$html$Html$text('No Watches!'); - } + $elm$html$Html$text(' ⟳') + ]))), + function () { + var _v0 = model.watches; + if (_v0.b) { + return A2( + $elm$html$Html$ul, + _List_Nil, + A2($elm$core$List$map, $author$project$Main$viewWatch, model.watches)); + } else { + return $elm$html$Html$text('No watches found!'); + } + }() + ])); }; var $author$project$Main$view = function (model) { return A2( @@ -6620,13 +6866,6 @@ var $author$project$Main$view = function (model) { [ $author$project$Main$viewLinks(model) ])) - ])), - A2( - $elm$html$Html$footer, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text('the foot') ])) ])) ])); diff --git a/src/Main.elm b/src/Main.elm index b232144..fe22b55 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -3,7 +3,7 @@ module Main exposing (..) import Browser import Data import Html exposing (..) -import Html.Attributes exposing (class, href, src) +import Html.Attributes exposing (class, href, name, placeholder, src, type_) import Html.Events exposing (..) import Http import Json.Decode as Decode @@ -17,6 +17,7 @@ import Json.Decode as Decode , map6 , string ) +import Json.Encode as Encode main : Program () Model Msg @@ -29,6 +30,18 @@ main = } +type Msg + = Reload + | ReloadLinks + | ReloadWatches + | GotWatches (Result Http.Error (List Data.Watch)) + | GotLinks (Result Http.Error (List Data.Link)) + | SubmitWatch + | SubmitLink + | HideWatchedItem Int String + | HidItem (Result Http.Error String) + + type Status = Loading | LoadedWatches (List Data.Watch) @@ -36,11 +49,27 @@ type Status | Errored String +type alias NewWatch = + { name : String + , repo : String + } + + +type alias NewLink = + { name : String + , url : String + , shared : Bool + , logo_url : String + } + + type alias Model = { watches : List Data.Watch , links : List Data.Link , errors : List String , status : Status + , newlink : NewLink + , newwatch : NewWatch } @@ -50,6 +79,16 @@ initialModel = , links = [] , errors = [] , status = Loading + , newlink = + { name = "" + , url = "" + , shared = False + , logo_url = "" + } + , newwatch = + { name = "" + , repo = "" + } } @@ -58,24 +97,40 @@ init _ = ( initialModel, Cmd.batch [ getLinks, getWatches ] ) -type Msg - = Reload - | ReloadLinks - | ReloadWatches - | AddLink - | AddWatch - | GotWatches (Result Http.Error (List Data.Watch)) - | GotLinks (Result Http.Error (List Data.Link)) +hideWatched : Int -> String -> Cmd Msg +hideWatched id repo = + let + body = + Encode.object + [ ( "number", Encode.int id ) + , ( "repo", Encode.string repo ) + ] + |> Http.jsonBody + in + Http.post + { url = "/prignores" + , body = body + , expect = Http.expectJson HidItem string + } update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of - AddLink -> - ( model, Cmd.none ) + HidItem (Err _) -> + ( { model | status = Errored "Server error when hiding a watch item!" }, Cmd.none ) - AddWatch -> - ( model, Cmd.none ) + HidItem (Ok _) -> + ( model, Cmd.batch [ getWatches, getLinks ] ) + + HideWatchedItem itemId repo -> + ( model, Cmd.batch [ hideWatched itemId repo ] ) + + SubmitWatch -> + ( { model | newwatch = model.newwatch }, Cmd.batch [ getWatches ] ) + + SubmitLink -> + ( model, Cmd.batch [ getLinks ] ) Reload -> ( model, Cmd.batch [ getWatches, getLinks ] ) @@ -154,8 +209,6 @@ view model = [ viewLinks model ] ] - , footer [] - [ text "the foot" ] ] ] @@ -223,40 +276,96 @@ repoInfoDecoder = (field "nameWithOwner" string) +watchForm : Model -> Html Msg +watchForm _ = + div [] + [ createForm SubmitWatch + (div + [] + [ labeledTextBox "Item: " "some string..." "" + , labeledTextBox "Repository: " "NixOS/nixpkgs" "" + ] + ) + ] + + +linkForm : Model -> Html Msg +linkForm _ = + div [] + [ createForm SubmitLink + (div + [] + [ labeledTextBox "Name: " "Potato" "" + , labeledTextBox "URL: " "https://...." "" + , labeledTextBox "Icon: " "https://...." "" + ] + ) + ] + + +labeledTextBox : String -> String -> String -> Html Msg +labeledTextBox labelStr placeStr inputName = + label [] + [ text labelStr + , input + [ type_ "text" + , name inputName + , placeholder placeStr + ] + [] + ] + + +createForm : Msg -> Html Msg -> Html Msg +createForm action content = + details [] + [ summary [] [ text "" ] + , Html.form + [ onSubmit action + , class "form-container" + ] + [ div [ class "form-content" ] + [ content + , button [] [ text "Submit" ] + ] + ] + ] + + +bar : Html Msg -> Html Msg -> Html Msg +bar left right = + header [ class "bar" ] + [ div [ class "bar-left" ] [ left ] + , div [ class "bar-right" ] [ right ] + ] + + viewLinks : Model -> Html Msg viewLinks model = - case model.links of - _ :: _ -> - div [] - [ header [ class "bar" ] - [ a [ onClick ReloadLinks ] [ text " ⟳" ] - , a [ onClick AddLink ] [ text " + " ] - ] - , div + div [] + [ bar (linkForm model) (a [ onClick ReloadLinks ] [ text " ⟳" ]) + , case model.links of + _ :: _ -> + div [ class "icon-grid" ] (List.map viewLink model.links) - ] - [] -> - text "No Links!" + [] -> + text "No links found!" + ] viewWatches : Model -> Html Msg viewWatches model = - case model.watches of - _ :: _ -> - div [] - [ header [ class "bar" ] - [ a [ onClick ReloadWatches ] [ text " ⟳" ] - , a [ onClick AddWatch ] [ text " + " ] - ] - , ul - [] - (List.map viewWatch model.watches) - ] + div [] + [ bar (watchForm model) (a [ onClick ReloadWatches ] [ text " ⟳" ]) + , case model.watches of + _ :: _ -> + ul [] (List.map viewWatch model.watches) - [] -> - text "No Watches!" + [] -> + text "No watches found!" + ] viewLink : Data.Link -> Html Msg @@ -287,9 +396,11 @@ viewWatch watch = [ ul [] [ li [] - [ text watch.repo - , text " :: " - , text watch.name + [ b [] + [ text watch.repo + , text " -> " + , text watch.name + ] , ul [] (List.map displayResult watch.results) ] ] @@ -300,5 +411,8 @@ displayResult : Data.Node -> Html Msg displayResult node = li [] [ a [ href node.url ] [ text (String.fromInt node.number) ] - , text (" :: " ++ node.title) + , text " :: " + , span [ onClick (HideWatchedItem node.number node.repository.nameWithOwner) ] [ text "⦸" ] + , text " :: " + , text node.title ]