Filtering by video recording is now possible. Also show video recording states.
This commit is contained in:
parent
4279653fcb
commit
a938f2406f
|
@ -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
|
||||
|
|
|
@ -35,7 +35,7 @@ init flags location =
|
|||
parseLocation location
|
||||
|
||||
emptyFilter =
|
||||
Filter [] []
|
||||
Filter [] [] []
|
||||
|
||||
initModel =
|
||||
(Model [] [] [] [] [] flags Nothing emptyFilter currentRoute)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
]
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue