From a938f2406f0acacf9abab711d509b1559ddd944a Mon Sep 17 00:00:00 2001 From: Vidir Valberg Gudmundsson Date: Tue, 18 Jul 2017 13:35:17 +0200 Subject: [PATCH] Filtering by video recording is now possible. Also show video recording states. --- schedule/src/Decoders.elm | 2 ++ schedule/src/Main.elm | 2 +- schedule/src/Messages.elm | 3 +- schedule/src/Models.elm | 3 ++ schedule/src/Update.elm | 18 ++++++++++- schedule/src/Views/EventDetail.elm | 41 +++++++++++++++++++------ schedule/src/Views/FilterView.elm | 37 ++++++++++++++++++++-- schedule/src/Views/ScheduleOverview.elm | 39 +++++++++++++++++++---- src/program/models.py | 5 +++ 9 files changed, 130 insertions(+), 20 deletions(-) diff --git a/schedule/src/Decoders.elm b/schedule/src/Decoders.elm index 959fedfe..67f99d8a 100644 --- a/schedule/src/Decoders.elm +++ b/schedule/src/Decoders.elm @@ -52,6 +52,8 @@ eventDecoder = |> required "slug" string |> required "abstract" string |> required "speakers" (list speakerDecoder) + |> required "video_recording" bool + |> optional "video_url" string "" dateDecoder : Decoder Date diff --git a/schedule/src/Main.elm b/schedule/src/Main.elm index 8cda9992..db88a8d6 100644 --- a/schedule/src/Main.elm +++ b/schedule/src/Main.elm @@ -35,7 +35,7 @@ init flags location = parseLocation location emptyFilter = - Filter [] [] + Filter [] [] [] initModel = (Model [] [] [] [] [] flags Nothing emptyFilter currentRoute) diff --git a/schedule/src/Messages.elm b/schedule/src/Messages.elm index 9cfc8b31..ce8cc9be 100644 --- a/schedule/src/Messages.elm +++ b/schedule/src/Messages.elm @@ -2,7 +2,7 @@ module Messages exposing (Msg(..)) -- Local modules -import Models exposing (Day, EventType, EventLocation) +import Models exposing (Day, EventType, EventLocation, EventInstance) -- External modules @@ -17,4 +17,5 @@ type Msg | RemoveActiveDay | ToggleEventTypeFilter EventType | ToggleEventLocationFilter EventLocation + | ToggleVideoRecordingFilter { name : String, filter : EventInstance -> Bool } | OnLocationChange Location diff --git a/schedule/src/Models.elm b/schedule/src/Models.elm index fd96d0dc..e1e3c90c 100644 --- a/schedule/src/Models.elm +++ b/schedule/src/Models.elm @@ -26,6 +26,7 @@ type alias Model = type alias Filter = { eventTypes : List EventType , eventLocations : List EventLocation + , videoRecording : List { name : String, filter : EventInstance -> Bool } } @@ -73,6 +74,8 @@ type alias Event = , slug : EventSlug , abstract : String , speakers : List Speaker + , videoRecording : Bool + , videoUrl : String } diff --git a/schedule/src/Update.elm b/schedule/src/Update.elm index 988f8cfe..2f83275c 100644 --- a/schedule/src/Update.elm +++ b/schedule/src/Update.elm @@ -28,7 +28,7 @@ update msg model = "init" -> case Json.Decode.decodeString initDataDecoder str of Ok m -> - m model.flags Nothing (Filter [] []) model.route + m model.flags Nothing (Filter [] [] []) model.route Err error -> model @@ -79,6 +79,22 @@ update msg model = in { model | filter = newFilter } ! [] + ToggleVideoRecordingFilter videoRecording -> + let + videoRecordingFilter = + if List.member videoRecording model.filter.videoRecording then + List.filter (\x -> x /= videoRecording) model.filter.videoRecording + else + videoRecording :: model.filter.videoRecording + + currentFilter = + model.filter + + newFilter = + { currentFilter | videoRecording = videoRecordingFilter } + in + { model | filter = newFilter } ! [] + OnLocationChange location -> let newRoute = diff --git a/schedule/src/Views/EventDetail.elm b/schedule/src/Views/EventDetail.elm index 01e0ebc4..01c1163a 100644 --- a/schedule/src/Views/EventDetail.elm +++ b/schedule/src/Views/EventDetail.elm @@ -11,7 +11,7 @@ import Models exposing (..) import Html exposing (Html, text, div, ul, li, span, i, h4, a, p, hr) import Html.Attributes exposing (class, classList, href) import Markdown -import Date.Extra as Date +import Date.Extra as DateExtra eventDetailView : EventSlug -> Model -> Html Msg @@ -23,7 +23,7 @@ eventDetailView eventSlug model = event Nothing -> - { title = "", slug = "", abstract = "", speakers = [] } + { title = "", slug = "", abstract = "", speakers = [], videoRecording = False, videoUrl = "" } in div [ class "row" ] [ div [ class "col-sm-9" ] @@ -41,15 +41,38 @@ eventDetailView eventSlug model = , ( "schedule-sidebar", True ) ] ] - [ h4 [] - [ text "Speakers" ] - , ul - [] - (List.map speakerDetail event.speakers) + [ videoRecordingSidebar event + , speakerSidebar event.speakers ] ] +videoRecordingSidebar : Event -> Html Msg +videoRecordingSidebar event = + 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 ) + in + div [ classList [ ( "alert", True ), ( "alert-danger", not willBeRecorded ), ( "alert-info", willBeRecorded ) ] ] + [ video ] + + +speakerSidebar : List Speaker -> Html Msg +speakerSidebar speakers = + div [] + [ h4 [] + [ text "Speakers" ] + , ul + [] + (List.map speakerDetail speakers) + ] + + speakerDetail : Speaker -> Html Msg speakerDetail speaker = li [] @@ -76,8 +99,8 @@ eventInstanceItem : EventInstance -> Html Msg eventInstanceItem eventInstance = li [] [ text - ((Date.toFormattedString "y-MM-dd HH:mm" eventInstance.from) + ((DateExtra.toFormattedString "y-MM-dd HH:mm" eventInstance.from) ++ " to " - ++ (Date.toFormattedString "y-MM-d HH:mm" eventInstance.to) + ++ (DateExtra.toFormattedString "y-MM-d HH:mm" eventInstance.to) ) ] diff --git a/schedule/src/Views/FilterView.elm b/schedule/src/Views/FilterView.elm index b8119068..b3a134b9 100644 --- a/schedule/src/Views/FilterView.elm +++ b/schedule/src/Views/FilterView.elm @@ -1,9 +1,9 @@ -module Views.FilterView exposing (filterSidebar) +module Views.FilterView exposing (filterSidebar, videoRecordingFilters, applyVideoRecordingFilters) -- Local modules import Messages exposing (Msg(..)) -import Models exposing (Model) +import Models exposing (Model, EventInstance) -- External modules @@ -27,10 +27,43 @@ filterSidebar model = , div [ class "form-group" ] [ filterView "Type" model.eventTypes model.filter.eventTypes ToggleEventTypeFilter , filterView "Location" model.eventLocations model.filter.eventLocations ToggleEventLocationFilter + , filterView "Video" videoRecordingFilters model.filter.videoRecording ToggleVideoRecordingFilter ] ] +notRecordedFilter : EventInstance -> Bool +notRecordedFilter eventInstance = + eventInstance.videoRecording == False + + +recordedFilter : EventInstance -> Bool +recordedFilter eventInstance = + eventInstance.videoRecording == True + + +hasRecordingFilter : EventInstance -> Bool +hasRecordingFilter eventInstance = + eventInstance.videoUrl /= "" + + +videoRecordingFilters : List { name : String, filter : EventInstance -> Bool } +videoRecordingFilters = + [ { name = "Will not be recorded", filter = notRecordedFilter } + , { name = "Will recorded", filter = recordedFilter } + , { name = "Has recording", filter = hasRecordingFilter } + ] + + +applyVideoRecordingFilters : List (EventInstance -> Bool) -> EventInstance -> Bool +applyVideoRecordingFilters filters eventInstance = + let + results = + List.map (\filter -> filter eventInstance) filters + in + List.member True (Debug.log "results" results) + + filterView : String -> List { a | name : String } diff --git a/schedule/src/Views/ScheduleOverview.elm b/schedule/src/Views/ScheduleOverview.elm index ce39d23e..10b7f352 100644 --- a/schedule/src/Views/ScheduleOverview.elm +++ b/schedule/src/Views/ScheduleOverview.elm @@ -4,7 +4,7 @@ module Views.ScheduleOverview exposing (scheduleOverviewView) import Messages exposing (Msg(..)) import Models exposing (Model, Day, EventInstance) -import Views.FilterView exposing (filterSidebar) +import Views.FilterView exposing (filterSidebar, videoRecordingFilters, applyVideoRecordingFilters) -- External modules @@ -48,6 +48,14 @@ dayRowView day model = model.filter.eventLocations ) + videoFilters = + List.map (\filter -> filter.filter) + (if List.isEmpty model.filter.videoRecording then + videoRecordingFilters + else + model.filter.videoRecording + ) + filteredEventInstances = List.filter (\eventInstance -> @@ -55,6 +63,7 @@ dayRowView day model = && (Date.equalBy Date.Day eventInstance.from day.date) && List.member eventInstance.location locations && List.member eventInstance.eventType types + && applyVideoRecordingFilters videoFilters eventInstance ) model.eventInstances in @@ -76,15 +85,33 @@ dayEventInstanceView eventInstance = , ( "color", eventInstance.forgroundColor ) ] ] - [ small [] + ([ small [] [ text ((Date.toFormattedString "H:m" eventInstance.from) ++ " - " ++ (Date.toFormattedString "H:m" eventInstance.to) ) ] - , i [ classList [ ( "fa", True ), ( "fa-" ++ eventInstance.locationIcon, True ), ( "pull-right", True ) ] ] [] - , p - [] - [ text eventInstance.title ] + ] + ++ (dayEventInstanceIcons eventInstance) + ++ [ p + [] + [ text eventInstance.title ] + ] + ) + + +dayEventInstanceIcons : EventInstance -> List (Html Msg) +dayEventInstanceIcons eventInstance = + let + videoIcon = + if eventInstance.videoUrl /= "" then + [ i [ classList [ ( "fa", True ), ( "fa-film", True ), ( "pull-right", True ) ] ] [] ] + else if eventInstance.videoRecording then + [ i [ classList [ ( "fa", True ), ( "fa-video-camera", True ), ( "pull-right", True ) ] ] [] ] + else + [] + in + [ i [ classList [ ( "fa", True ), ( "fa-" ++ eventInstance.locationIcon, True ), ( "pull-right", True ) ] ] [] ] + ++ videoIcon diff --git a/src/program/models.py b/src/program/models.py index b6ac2626..ceba4bb7 100644 --- a/src/program/models.py +++ b/src/program/models.py @@ -437,7 +437,12 @@ class Event(CampRelatedModel): speaker.serialize() for speaker in self.speakers.all() ], + 'video_recording': self.video_recording, } + + if self.video_url: + data['video_url'] = self.video_url + return data