From a447ca476fb52ee6f67fc8cb20a78c33e1f6a2a1 Mon Sep 17 00:00:00 2001 From: Vidir Valberg Gudmundsson Date: Thu, 27 Jul 2017 23:21:16 +0200 Subject: [PATCH] Working on event detail. Also small visual help in DayView. Also some favorite stuff. --- schedule/src/Decoders.elm | 4 +- schedule/src/Models.elm | 2 + schedule/src/Views/DayView.elm | 29 +++- schedule/src/Views/EventDetail.elm | 154 +++++++++++-------- src/program/models.py | 1 + src/program/templates/schedule_overview.html | 2 +- src/static_src/css/bornhack.css | 8 +- 7 files changed, 131 insertions(+), 69 deletions(-) diff --git a/schedule/src/Decoders.elm b/schedule/src/Decoders.elm index 85b7108e..09ae2452 100644 --- a/schedule/src/Decoders.elm +++ b/schedule/src/Decoders.elm @@ -7,7 +7,7 @@ import Models exposing (Day, Speaker, Event, EventInstance, EventLocation, Event -- Core modules -import Json.Decode exposing (int, string, float, list, bool, dict, Decoder) +import Json.Decode exposing (int, string, float, list, bool, dict, Decoder, nullable) import Json.Decode.Pipeline exposing (decode, required, optional, hardcoded) import Date exposing (Date, Month(..)) @@ -55,6 +55,7 @@ eventDecoder = |> required "speakers" (list speakerDecoder) |> required "video_recording" bool |> optional "video_url" string "" + |> required "event_type" string dateDecoder : Decoder Date @@ -86,6 +87,7 @@ eventInstanceDecoder = |> required "location_icon" string |> required "video_recording" bool |> optional "video_url" string "" + |> optional "is_favorited" (nullable bool) Nothing eventLocationDecoder : Decoder EventLocation diff --git a/schedule/src/Models.elm b/schedule/src/Models.elm index b2df690c..b8f09f10 100644 --- a/schedule/src/Models.elm +++ b/schedule/src/Models.elm @@ -75,6 +75,7 @@ type alias EventInstance = , locationIcon : String , videoRecording : Bool , videoUrl : String + , isFavorited : Maybe Bool } @@ -85,6 +86,7 @@ type alias Event = , speakers : List Speaker , videoRecording : Bool , videoUrl : String + , eventType : String } diff --git a/schedule/src/Views/DayView.elm b/schedule/src/Views/DayView.elm index b2fc099c..4c659fa1 100644 --- a/schedule/src/Views/DayView.elm +++ b/schedule/src/Views/DayView.elm @@ -52,12 +52,12 @@ dayView day model = div [ classList [ ( "row", True ) ] ] [ gutter minutes - , locationColumns filteredEventInstances model.eventLocations model.flags.schedule_midnight_offset_hours + , locationColumns filteredEventInstances model.eventLocations model.flags.schedule_midnight_offset_hours minutes ] -locationColumns : List EventInstance -> List EventLocation -> Int -> Html Msg -locationColumns eventInstances eventLocations offset = +locationColumns : List EventInstance -> List EventLocation -> Int -> List Date -> Html Msg +locationColumns eventInstances eventLocations offset minutes = let columnWidth = 100.0 / toFloat (List.length eventLocations) @@ -71,11 +71,11 @@ locationColumns eventInstances eventLocations offset = [ ( "col-sm-11", True ) ] ] - (List.map (\location -> locationColumn columnWidth eventInstances offset location) eventLocations) + (List.map (\location -> locationColumn columnWidth eventInstances offset minutes location) eventLocations) -locationColumn : Float -> List EventInstance -> Int -> EventLocation -> Html Msg -locationColumn columnWidth eventInstances offset location = +locationColumn : Float -> List EventInstance -> Int -> List Date -> EventLocation -> Html Msg +locationColumn columnWidth eventInstances offset minutes location = let locationInstances = List.filter (\instance -> instance.location == location.slug) eventInstances @@ -102,6 +102,23 @@ locationColumn columnWidth eventInstances offset location = ] [ text location.name ] ] + ++ (List.map + (\x -> + div + [ style + [ ( "backgroundColor" + , if Date.minute x == 30 || Date.minute x == 45 then + "#f8f8f8" + else + "#fff" + ) + , ( "height", px blockHeight ) + ] + ] + [] + ) + minutes + ) ++ (List.map (\group -> renderGroup offset group) overlappingGroups) ) diff --git a/schedule/src/Views/EventDetail.elm b/schedule/src/Views/EventDetail.elm index 0ddf5e17..a098f5a3 100644 --- a/schedule/src/Views/EventDetail.elm +++ b/schedule/src/Views/EventDetail.elm @@ -6,9 +6,14 @@ import Messages exposing (Msg(..)) import Models exposing (..) +-- Core modules + +import Date + + -- External modules -import Html exposing (Html, text, div, ul, li, span, i, h4, a, p, hr) +import Html exposing (Html, text, div, ul, li, span, i, h3, h4, a, p, hr, strong) import Html.Attributes exposing (class, classList, href) import Html.Events exposing (onClick) import Markdown @@ -22,58 +27,84 @@ eventDetailView eventSlug model = model.events |> List.filter (\e -> e.slug == eventSlug) |> List.head + + eventInstances = + List.filter (\instance -> instance.eventSlug == eventSlug) model.eventInstances in case event of Just event -> div [ class "row" ] - [ div [ class "col-sm-9" ] - [ a [ onClick BackInHistory, classList [ ( "btn", True ), ( "btn-default", True ) ] ] - [ i [ classList [ ( "fa", True ), ( "fa-chevron-left", True ) ] ] [] - , text " Back" - ] - , h4 [] [ text event.title ] - , p [] [ Markdown.toHtml [] event.abstract ] - , hr [] [] - , eventInstancesList eventSlug model.eventInstances - ] - , div - [ classList - [ ( "col-sm-3", True ) - , ( "schedule-sidebar", True ) - , ( "sticky", True ) - ] - ] - [ videoRecordingSidebar event - , speakerSidebar event.speakers - ] + [ eventDetailContent event + , eventDetailSidebar event eventInstances ] Nothing -> div [ class "row" ] - [ text - (case model.dataLoaded of - True -> - "Event not found." - - False -> - "Loading..." - ) + [ h4 [] [ text "Event not found." ] + , a [ href "#" ] [ text "Click here to go the schedule overview." ] ] -videoRecordingSidebar : Event -> Html Msg -videoRecordingSidebar event = +eventDetailContent : Event -> Html Msg +eventDetailContent event = + div [ class "col-sm-9" ] + [ a [ onClick BackInHistory, classList [ ( "btn", True ), ( "btn-default", True ) ] ] + [ i [ classList [ ( "fa", True ), ( "fa-chevron-left", True ) ] ] [] + , text " Back" + ] + , h3 [] [ text event.title ] + , p [] [ Markdown.toHtml [] event.abstract ] + ] + + +eventDetailSidebar : Event -> List EventInstance -> Html Msg +eventDetailSidebar event eventInstances = let - ( video, willBeRecorded ) = - if event.videoUrl /= "" then - ( h4 [] [ text "Watch the video here!" ], True ) - else if event.videoRecording == True then - ( h4 [] [ text "This event will be recorded!" ], True ) - else - ( h4 [] [ text "This event will NOT be recorded!" ], False ) + videoRecordingLink = + case event.videoUrl of + "" -> + [] + + _ -> + [ a [ href event.videoUrl, classList [ ( "btn", True ), ( "btn-success", True ) ] ] + [ i [ classList [ ( "fa", True ), ( "fa-film", True ) ] ] [] + , text " Watch recording here!" + ] + ] in - div [ classList [ ( "alert", True ), ( "alert-danger", not willBeRecorded ), ( "alert-info", willBeRecorded ) ] ] - [ video ] + div + [ classList + [ ( "col-sm-3", True ) + , ( "schedule-sidebar", True ) + , ( "sticky", True ) + ] + ] + (videoRecordingLink + ++ [ speakerSidebar event.speakers + , eventMetaDataSidebar event + , eventInstancesSidebar eventInstances + ] + ) + + +eventMetaDataSidebar : Event -> Html Msg +eventMetaDataSidebar event = + let + videoRecording = + case event.videoRecording of + True -> + "Yes" + + False -> + "No" + in + div [] + [ h4 [] [ text "Metadata" ] + , ul [] + [ li [] [ strong [] [ text "Type: " ], text event.eventType ] + , li [] [ strong [] [ text "Recording: " ], text videoRecording ] + ] + ] speakerSidebar : List Speaker -> Html Msg @@ -94,27 +125,30 @@ speakerDetail speaker = ] -eventInstancesList : String -> List EventInstance -> Html Msg -eventInstancesList eventSlug eventInstances = - let - instances = - List.filter (\instance -> instance.eventSlug == eventSlug) eventInstances - in - div [] - [ h4 [] - [ text "This event will occur at:" ] - , ul - [] - (List.map eventInstanceItem instances) - ] +eventInstancesSidebar : List EventInstance -> Html Msg +eventInstancesSidebar eventInstances = + div [] + [ h4 [] + [ text "This event will occur at:" ] + , ul + [] + (List.map eventInstanceItem eventInstances) + ] eventInstanceItem : EventInstance -> Html Msg eventInstanceItem eventInstance = - li [] - [ text - ((Date.Extra.toFormattedString "y-MM-dd HH:mm" eventInstance.from) - ++ " to " - ++ (Date.Extra.toFormattedString "y-MM-d HH:mm" eventInstance.to) - ) - ] + let + toFormat = + if Date.day eventInstance.from == Date.day eventInstance.to then + "HH:mm" + else + "E HH:mm" + in + li [] + [ text + ((Date.Extra.toFormattedString "E HH:mm" eventInstance.from) + ++ " to " + ++ (Date.Extra.toFormattedString toFormat eventInstance.to) + ) + ] diff --git a/src/program/models.py b/src/program/models.py index ceba4bb7..2bdea6b1 100644 --- a/src/program/models.py +++ b/src/program/models.py @@ -438,6 +438,7 @@ class Event(CampRelatedModel): for speaker in self.speakers.all() ], 'video_recording': self.video_recording, + 'event_type': self.event_type.name, } if self.video_url: diff --git a/src/program/templates/schedule_overview.html b/src/program/templates/schedule_overview.html index f12afe7c..4aba3379 100644 --- a/src/program/templates/schedule_overview.html +++ b/src/program/templates/schedule_overview.html @@ -5,7 +5,7 @@ {% block extra_head %} {% endblock %} diff --git a/src/static_src/css/bornhack.css b/src/static_src/css/bornhack.css index 12f19341..c9241aba 100644 --- a/src/static_src/css/bornhack.css +++ b/src/static_src/css/bornhack.css @@ -220,10 +220,16 @@ footer { .schedule-filter ul { list-style: none; padding: 0; + display: flex; + flex-wrap: wrap; +} + +.schedule-filter ul li { + flex: 1; } .schedule-filter .btn { - min-width: 200px; + width: 100%; text-align: left; }