Filtering by video recording is now possible. Also show video recording states.

This commit is contained in:
Vidir Valberg Gudmundsson 2017-07-18 13:35:17 +02:00
parent 4279653fcb
commit a938f2406f
9 changed files with 130 additions and 20 deletions

View file

@ -52,6 +52,8 @@ eventDecoder =
|> required "slug" string |> required "slug" string
|> required "abstract" string |> required "abstract" string
|> required "speakers" (list speakerDecoder) |> required "speakers" (list speakerDecoder)
|> required "video_recording" bool
|> optional "video_url" string ""
dateDecoder : Decoder Date dateDecoder : Decoder Date

View file

@ -35,7 +35,7 @@ init flags location =
parseLocation location parseLocation location
emptyFilter = emptyFilter =
Filter [] [] Filter [] [] []
initModel = initModel =
(Model [] [] [] [] [] flags Nothing emptyFilter currentRoute) (Model [] [] [] [] [] flags Nothing emptyFilter currentRoute)

View file

@ -2,7 +2,7 @@ module Messages exposing (Msg(..))
-- Local modules -- Local modules
import Models exposing (Day, EventType, EventLocation) import Models exposing (Day, EventType, EventLocation, EventInstance)
-- External modules -- External modules
@ -17,4 +17,5 @@ type Msg
| RemoveActiveDay | RemoveActiveDay
| ToggleEventTypeFilter EventType | ToggleEventTypeFilter EventType
| ToggleEventLocationFilter EventLocation | ToggleEventLocationFilter EventLocation
| ToggleVideoRecordingFilter { name : String, filter : EventInstance -> Bool }
| OnLocationChange Location | OnLocationChange Location

View file

@ -26,6 +26,7 @@ type alias Model =
type alias Filter = type alias Filter =
{ eventTypes : List EventType { eventTypes : List EventType
, eventLocations : List EventLocation , eventLocations : List EventLocation
, videoRecording : List { name : String, filter : EventInstance -> Bool }
} }
@ -73,6 +74,8 @@ type alias Event =
, slug : EventSlug , slug : EventSlug
, abstract : String , abstract : String
, speakers : List Speaker , speakers : List Speaker
, videoRecording : Bool
, videoUrl : String
} }

View file

@ -28,7 +28,7 @@ update msg model =
"init" -> "init" ->
case Json.Decode.decodeString initDataDecoder str of case Json.Decode.decodeString initDataDecoder str of
Ok m -> Ok m ->
m model.flags Nothing (Filter [] []) model.route m model.flags Nothing (Filter [] [] []) model.route
Err error -> Err error ->
model model
@ -79,6 +79,22 @@ update msg model =
in in
{ model | filter = newFilter } ! [] { 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 -> OnLocationChange location ->
let let
newRoute = newRoute =

View file

@ -11,7 +11,7 @@ import Models exposing (..)
import Html exposing (Html, text, div, ul, li, span, i, h4, a, p, hr) import Html exposing (Html, text, div, ul, li, span, i, h4, a, p, hr)
import Html.Attributes exposing (class, classList, href) import Html.Attributes exposing (class, classList, href)
import Markdown import Markdown
import Date.Extra as Date import Date.Extra as DateExtra
eventDetailView : EventSlug -> Model -> Html Msg eventDetailView : EventSlug -> Model -> Html Msg
@ -23,7 +23,7 @@ eventDetailView eventSlug model =
event event
Nothing -> Nothing ->
{ title = "", slug = "", abstract = "", speakers = [] } { title = "", slug = "", abstract = "", speakers = [], videoRecording = False, videoUrl = "" }
in in
div [ class "row" ] div [ class "row" ]
[ div [ class "col-sm-9" ] [ div [ class "col-sm-9" ]
@ -41,15 +41,38 @@ eventDetailView eventSlug model =
, ( "schedule-sidebar", True ) , ( "schedule-sidebar", True )
] ]
] ]
[ h4 [] [ videoRecordingSidebar event
[ text "Speakers" ] , speakerSidebar event.speakers
, ul
[]
(List.map speakerDetail 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 -> Html Msg
speakerDetail speaker = speakerDetail speaker =
li [] li []
@ -76,8 +99,8 @@ eventInstanceItem : EventInstance -> Html Msg
eventInstanceItem eventInstance = eventInstanceItem eventInstance =
li [] li []
[ text [ text
((Date.toFormattedString "y-MM-dd HH:mm" eventInstance.from) ((DateExtra.toFormattedString "y-MM-dd HH:mm" eventInstance.from)
++ " to " ++ " to "
++ (Date.toFormattedString "y-MM-d HH:mm" eventInstance.to) ++ (DateExtra.toFormattedString "y-MM-d HH:mm" eventInstance.to)
) )
] ]

View file

@ -1,9 +1,9 @@
module Views.FilterView exposing (filterSidebar) module Views.FilterView exposing (filterSidebar, videoRecordingFilters, applyVideoRecordingFilters)
-- Local modules -- Local modules
import Messages exposing (Msg(..)) import Messages exposing (Msg(..))
import Models exposing (Model) import Models exposing (Model, EventInstance)
-- External modules -- External modules
@ -27,10 +27,43 @@ filterSidebar model =
, div [ class "form-group" ] , div [ class "form-group" ]
[ filterView "Type" model.eventTypes model.filter.eventTypes ToggleEventTypeFilter [ filterView "Type" model.eventTypes model.filter.eventTypes ToggleEventTypeFilter
, filterView "Location" model.eventLocations model.filter.eventLocations ToggleEventLocationFilter , 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 : filterView :
String String
-> List { a | name : String } -> List { a | name : String }

View file

@ -4,7 +4,7 @@ module Views.ScheduleOverview exposing (scheduleOverviewView)
import Messages exposing (Msg(..)) import Messages exposing (Msg(..))
import Models exposing (Model, Day, EventInstance) import Models exposing (Model, Day, EventInstance)
import Views.FilterView exposing (filterSidebar) import Views.FilterView exposing (filterSidebar, videoRecordingFilters, applyVideoRecordingFilters)
-- External modules -- External modules
@ -48,6 +48,14 @@ dayRowView day model =
model.filter.eventLocations model.filter.eventLocations
) )
videoFilters =
List.map (\filter -> filter.filter)
(if List.isEmpty model.filter.videoRecording then
videoRecordingFilters
else
model.filter.videoRecording
)
filteredEventInstances = filteredEventInstances =
List.filter List.filter
(\eventInstance -> (\eventInstance ->
@ -55,6 +63,7 @@ dayRowView day model =
&& (Date.equalBy Date.Day eventInstance.from day.date) && (Date.equalBy Date.Day eventInstance.from day.date)
&& List.member eventInstance.location locations && List.member eventInstance.location locations
&& List.member eventInstance.eventType types && List.member eventInstance.eventType types
&& applyVideoRecordingFilters videoFilters eventInstance
) )
model.eventInstances model.eventInstances
in in
@ -76,15 +85,33 @@ dayEventInstanceView eventInstance =
, ( "color", eventInstance.forgroundColor ) , ( "color", eventInstance.forgroundColor )
] ]
] ]
[ small [] ([ small []
[ text [ text
((Date.toFormattedString "H:m" eventInstance.from) ((Date.toFormattedString "H:m" eventInstance.from)
++ " - " ++ " - "
++ (Date.toFormattedString "H:m" eventInstance.to) ++ (Date.toFormattedString "H:m" eventInstance.to)
) )
] ]
, i [ classList [ ( "fa", True ), ( "fa-" ++ eventInstance.locationIcon, True ), ( "pull-right", True ) ] ] [] ]
, p ++ (dayEventInstanceIcons eventInstance)
[] ++ [ p
[ text eventInstance.title ] []
[ 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

View file

@ -437,7 +437,12 @@ class Event(CampRelatedModel):
speaker.serialize() speaker.serialize()
for speaker in self.speakers.all() for speaker in self.speakers.all()
], ],
'video_recording': self.video_recording,
} }
if self.video_url:
data['video_url'] = self.video_url
return data return data