From 885cc431c9e3675b4fc296b723f45ee1b2b78baf Mon Sep 17 00:00:00 2001 From: Todd Morey Date: Fri, 31 Oct 2014 12:48:27 -0500 Subject: [PATCH] Upgrades to summit video pages Conflicts: openstack/code/Presentation.php openstack/code/PresentationCategoryPage.php openstack/code/summit/SchedToolsPage.php themes/openstack/templates/Layout/PresentationCategoryPage.ss themes/openstack/templates/Layout/PresentationCategoryPage_presentation.ss --- openstack/code/Presentation.php | 301 ++++++------- openstack/code/PresentationCategoryPage.php | 56 +-- openstack/code/summit/SchedToolsPage.php | 75 +++- themes/openstack/css/videos.css | 403 ++++++++++++++++++ themes/openstack/images/no-video.jpg | Bin 0 -> 6255 bytes .../Layout/Includes/VideoThumbnails.ss | 57 +++ .../Layout/PresentationCategoryPage.ss | 152 +++---- .../PresentationCategoryPage_presentation.ss | 110 ++--- 8 files changed, 801 insertions(+), 353 deletions(-) create mode 100644 themes/openstack/css/videos.css create mode 100644 themes/openstack/images/no-video.jpg create mode 100644 themes/openstack/templates/Layout/Includes/VideoThumbnails.ss diff --git a/openstack/code/Presentation.php b/openstack/code/Presentation.php index 02563c8..e5ccd83 100644 --- a/openstack/code/Presentation.php +++ b/openstack/code/Presentation.php @@ -1,4 +1,5 @@ 'HTMLText', @@ -28,14 +30,15 @@ class Presentation extends DataObject { 'Type' => 'Text', 'Day' => 'Int', 'Speakers' => 'Text', - 'SlidesLink' => 'Varchar(255)' + 'SlidesLink' => 'Varchar(255)', + 'event_key' => 'Varchar(255)' ); Static $defaults = array( 'DisplayOnSite' => TRUE, 'Country' => 'United States' ); - + static $has_one = array( 'PresentationCategoryPage' => 'PresentationCategoryPage', 'Summit' => 'Summit' @@ -47,110 +50,144 @@ class Presentation extends DataObject { static $singular_name = 'Presentation'; static $plural_name = 'Presentations'; - - static $summary_fields = array( - 'Name' => 'Presentation Name' - ); - - function getCMSFields() { + + static $summary_fields = array( + 'Name' => 'Presentation Name' + ); + + function getCMSFields() + { $fields = new FieldList ( - new TextField('Name','Name of Presentation'), - new TextField('Speakers','Speakers'), - new DropdownField('Day','Day', array('1' => '1', '2' => '2', '3' => '3', '4' => '4')), - new TextField('URLSegment','URL Segment'), - new LiteralField('Break','

(Automatically filled in on first save.)

'), - new LiteralField('Break','
'), - new TextField('YouTubeID','YouTube Vidoe ID'), - new TextField('SlidesLink','Link To Slides (if available)'), - new TextField('StartTime','Video Start Time'), - new TextField('EndTime','Video End Time'), - new HTMLEditorField('Description','Description') + new TextField('Name', 'Name of Presentation'), + new TextField('Speakers', 'Speakers'), + new DropdownField('Day', 'Day', array('1' => '1', '2' => '2', '3' => '3', '4' => '4')), + new TextField('URLSegment', 'URL Segment'), + new LiteralField('Break', '

(Automatically filled in on first save.)

'), + new LiteralField('Break', '
'), + new TextField('YouTubeID', 'YouTube Vidoe ID'), + new TextField('SlidesLink', 'Link To Slides (if available)'), + new TextField('StartTime', 'Video Start Time'), + new TextField('EndTime', 'Video End Time'), + new HTMLEditorField('Description', 'Description') ); return $fields; } - - function onBeforeWrite() { + function FormattedStartTime() + { + $Date = new DateTime($this->StartTime); + return $Date->format('l h:i a'); + } + + function PresentationDay() + { + $Date = new DateTime($this->StartTime); + return $Date->format('M d'); + } + + + function onBeforeWrite() + { parent::onBeforeWrite(); // If there is no URLSegment set, generate one from Title - if((!$this->URLSegment || $this->URLSegment == 'new-presentation') && $this->Title != 'New Presentation') - { - $this->URLSegment = SiteTree::generateURLSegment($this->Title); - } - else if($this->isChanged('URLSegment')) - { - // Make sure the URLSegment is valid for use in a URL - $segment = preg_replace('/[^A-Za-z0-9]+/','-',$this->URLSegment); - $segment = preg_replace('/-+/','-',$segment); - - // If after sanitising there is no URLSegment, give it a reasonable default - if(!$segment) { - $segment = "presentation-".$this->ID; - } - $this->URLSegment = $segment; - } - - // Ensure that this object has a non-conflicting URLSegment value by appending number if needed - $count = 2; - while($this->LookForExistingURLSegment($this->URLSegment)) - { - $this->URLSegment = preg_replace('/-[0-9]+$/', null, $this->URLSegment) . '-' . $count; - $count++; - } + if ((!$this->URLSegment || $this->URLSegment == 'new-presentation') && $this->Title != 'New Presentation') { + $this->URLSegment = SiteTree::generateURLSegment($this->Title); + } else if ($this->isChanged('URLSegment')) { + // Make sure the URLSegment is valid for use in a URL + $segment = preg_replace('/[^A-Za-z0-9]+/', '-', $this->URLSegment); + $segment = preg_replace('/-+/', '-', $segment); + + // If after sanitising there is no URLSegment, give it a reasonable default + if (!$segment) { + $segment = "presentation-" . $this->ID; + } + $this->URLSegment = $segment; + } + + // Ensure that this object has a non-conflicting URLSegment value by appending number if needed + $count = 2; + while ($this->LookForExistingURLSegment($this->URLSegment)) { + $this->URLSegment = preg_replace('/-[0-9]+$/', null, $this->URLSegment) . '-' . $count; + $count++; + } + + // If there's no PresentationCategoryPage, add the current summit + + if (!$this->PresentationCategoryPageID) { + $SummitPageID = 0; + $SummitRedirector = DataObject::get_by_id('RedirectorPage', 154); + If ($SummitRedirector) { + $SummitPageID = $SummitRedirector->LinkToID; + $VideoPage = DataObject::get_one('PresentationCategoryPage', '`ParentID` = ' . $SummitPageID); + } + + if ($VideoPage) $this->PresentationCategoryPageID = $VideoPage->ID; + } } - //Test whether the URLSegment exists already on another Video - function LookForExistingURLSegment($URLSegment) - { - return Company::get()->filter(array('URLSegment' => $URLSegment, 'ID:not' => $this->ID))->first(); - } - - // Pull video thumbnail from YouTube API - function ThumbnailURL() { - if ($this->YouTubeID) { - - - /* $response = @file_get_contents("http://gdata.youtube.com/feeds/api/videos/".$this->YouTubeID."?v=2&alt=jsonc"); - - if ($response) { - $json = json_decode($response); - if (isset($json->data->thumbnail->sqDefault)) { - return $json->data->thumbnail->sqDefault; - } - } */ - - return "http://i.ytimg.com/vi/".$this->YouTubeID."/default.jpg"; - +//Test whether the URLSegment exists already on another Video + function LookForExistingURLSegment($URLSegment) + { + return (DataObject::get_one('Company', "URLSegment = '" . $URLSegment . "' AND ID != " . $this->ID)); + } +// Pull video thumbnail from YouTube API + function ThumbnailURL() + { + if ($this->YouTubeID) { + return "http://i.ytimg.com/vi/" . $this->YouTubeID . "/default.jpg"; } - } + } +//Generate the link for this product + function ShowLink() + { + $ParentPage = $this->PresentationCategoryPage(); - //Generate the link for this product - function ShowLink() - { - $ParentPage = $this->PresentationCategoryPage(); - - if ($ParentPage) { - return $ParentPage->Link()."presentation/".$this->URLSegment; - } - } - - // See if the presentation slides can be embedded - function EmbedSlides() - { - // Slides can be emdedded if they are hosted on crocodoc. Otherwise, there's only a download button displayed by the template - if (strpos($this->SlidesLink,'crocodoc.com') !== false) { - return true; + if ($ParentPage) { + return $ParentPage->Link() . "presentation/" . $this->URLSegment; } - } + } - function SchedEventImport($ParentPageID) { - $Events = SchedEvent::get(); - foreach ($Events as $Event) { +// See if the presentation slides can be embedded + function EmbedSlides() + { + // Slides can be emdedded if they are hosted on crocodoc. Otherwise, there's only a download button displayed by the template + if (strpos($this->SlidesLink, 'crocodoc.com') !== false) { + return true; + } + } + + function PopulateFromSchedEvent($SchedEventID) + { + + $SchedEvent = DataObject::get_by_id('SchedEvent', $SchedEventID); + + $this->Name = $SchedEvent->eventtitle; + $this->DisplayOnSite = TRUE; + $this->Description = $SchedEvent->description; + $this->StartTime = $SchedEvent->event_start; + $this->EndTime = $SchedEvent->event_end; + $this->Type = $SchedEvent->event_type; + $this->Speakers = $SchedEvent->speakers; + $this->event_key = $SchedEvent->event_key; + $this->write(); + + } + + function AddYouTubeID($YouTubeID) + { + $this->YouTubeID = $YouTubeID; + $this->write(); + } + + function SchedEventImport($ParentPageID) + { + $Events = DataObject::get_one('SchedEvent', ''); + foreach ($Events as $Event) { $Presentation = new Presentation(); // Bring over existing data @@ -161,82 +198,20 @@ class Presentation extends DataObject { $Presentation->EndTime = $Event->event_end; $Presentation->Type = $Event->event_type; $Presentation->Speakers = $Event->speakers; - - // Determine day - $day = 1; + // Assign parent page + $Presentation->PresentationCategoryPageID = $ParentPageID; + $Presentation->write(); - switch ($Event->event_start) { - case '2013-11-05': - $day = 1; - break; - case '2013-11-06': - $day = 2; - break; - case '2013-11-07': - $day = 3; - break; - case '2013-11-08': - $day = 4; - break; - case '2013-11-09': - $day = 5; - break; - } + if ($Event->UploadedMedia()) { + $Presentation->SlidesLink = $Event->UploadedMedia()->link(); + } elseif ($Event->HostedMediaURL()) { + $Presentation->SlidesLink = $Event->HostedMediaURL(); + } - $Presentation->Day = $day; + $Presentation->write(); - // Assign parent page - $Presentation->PresentationCategoryPageID = $ParentPageID; - $Presentation->write(); + } + } +} - if($Event->UploadedMedia()) { - $Presentation->SlidesLink = $Event->UploadedMedia()->link(); - } elseif ($Event->HostedMediaURL()) { - $Presentation->SlidesLink = $Event->HostedMediaURL(); - } - - $Presentation->write(); - - } - - } - - function AddMedia($ParentPageID) { - - $Presentations = Presentation::get()->filter('PresentationCategoryPageID', $ParentPageID); - - foreach ($Presentations as $Presentation) { - if(!$Presentation->SlidesLink) { - - $SchedEventMatch = SchedEvent::get()->filter('eventtitle',$Presentation->Name)->first(); - - if($SchedEventMatch && $SchedEventMatch->UploadedMedia()) { - $Presentation->SlidesLink = $SchedEventMatch->UploadedMedia()->link(); - $Presentation->write(); - echo 'Added slides to "' . $Presentation->Name . '"
'; - } elseif ($SchedEventMatch && $SchedEventMatch->HostedMediaURL()) { - $Presentation->SlidesLink = $SchedEventMatch->HostedMediaURL(); - $Presentation->write(); - echo 'Added slides to "' . $Presentation->Name . '"
'; - } - } - } - - } - - function AdjustDates() { - $Events = SchedEvent::get(); - foreach ($Events as $Event) { - $Presentation = Presentation::get()->filter('Name', $Event->eventtitle)->first(); - if($Presentation) { - $Presentation->StartTime = $Event->event_start; - $Presentation->EndTime = $Event->event_end; - $Presentation->write(); - } - } - - } - - -} \ No newline at end of file diff --git a/openstack/code/PresentationCategoryPage.php b/openstack/code/PresentationCategoryPage.php index 5541d61..b2b7552 100644 --- a/openstack/code/PresentationCategoryPage.php +++ b/openstack/code/PresentationCategoryPage.php @@ -23,7 +23,7 @@ class PresentationCategoryPage extends Page { static $has_many = array( 'Presentations' => 'Presentation' ); - + static $allowed_children = array('PresentationCategoryPage'); /** static $icon = "icon/path"; */ @@ -44,52 +44,46 @@ class PresentationCategoryPage extends Page { } } - + class PresentationCategoryPage_Controller extends Page_Controller { static $allowed_actions = array( 'presentation', 'updateURLS' => 'admin' - ); - + ); + public function Presentations(){ - if(isset($_GET['day'])){ - $sessions = ""; - $day = Convert::raw2xml($_GET['day']); - $day = (int)$day; - if (is_numeric($day)) { - $sessions = Presentation::get()->filter(array( 'PresentationCategoryPageID' => $this->ID , 'Day' => $day))->sort('StartTime','ASC'); - } else { - $sessions = Presentation::get()->filter(array( 'PresentationCategoryPageID' => $this->ID , 'Day' => 1))->sort('StartTime','ASC'); - } - } else { - $sessions = Presentation::get()->filter(array( 'PresentationCategoryPageID' => $this->ID , 'Day' => 1))->sort('StartTime','ASC'); - } + $sessions = dataobject::get('Presentation','`YouTubeID` IS NOT NULL AND PresentationCategoryPageID = '.$this->ID,'StartTime DESC'); return $sessions; - } - + } + function init() { parent::init(); if(isset($_GET['day'])) { Session::set('Day', $_GET['day']); } else { - Session::set('Day', 1); + Session::set('Day', 1); } + if (Director::urlParam("OtherID") != "presentation") Session::set('Autoplay',TRUE); } //Show the Presentation detail page using the PresentationCategoryPage_presentation.ss template - function presentation() - { + function presentation() + { if($Presentation = $this->getPresentationByURLSegment()) { $Data = array( 'Presentation' => $Presentation ); - - $this->Title = $Presentation->Name; + + $this->Title = $Presentation->Name; + $this->Autoplay = Session::get('Autoplay'); + + // Clear autoplay so it only happens when you come directly from videos index + Session::set('Autoplay',FALSE); //return our $Data to use on the page return $this->Customise($Data); @@ -101,6 +95,15 @@ class PresentationCategoryPage_Controller extends Page_Controller { } } + function PresentationDayID($PresentationDay) { + return trim($PresentationDay,' '); + } + + function LatestPresentation() + { + return $this->Presentations()->first(); + } + // Check to see if the page is being accessed in Chinese // We use this in the templates to tell Chinese visitors how to obtain the videos on a non-youtube source @@ -119,8 +122,8 @@ class PresentationCategoryPage_Controller extends Page_Controller { { $Params = $this->getURLParams(); $Segment = convert::raw2sql($Params['ID']); - if($Params['ID'] && $Presentation = Presentation::get()->filter(array('URLSegment' => $Segment, 'PresentationCategoryPageID' => $this->ID))->first()) - { + if($Params['ID'] && $Presentation = DataObject::get_one('Presentation', "`URLSegment` = '".$Segment."' AND `PresentationCategoryPageID` = ".$this->ID)) + { return $Presentation; } } @@ -141,7 +144,6 @@ class PresentationCategoryPage_Controller extends Page_Controller { } } echo "Presentation URLS updated."; - } - + } } \ No newline at end of file diff --git a/openstack/code/summit/SchedToolsPage.php b/openstack/code/summit/SchedToolsPage.php index e327f0d..209bc28 100644 --- a/openstack/code/summit/SchedToolsPage.php +++ b/openstack/code/summit/SchedToolsPage.php @@ -1,4 +1,5 @@ 'ADMIN', - 'ImportSessionsFromSched' => 'ADMIN', - 'ListSpeakers' => 'ADMIN', - 'SpeakerTable' => 'ADMIN', - 'Presentations', - 'Upload', - 'Form', - 'Success', - 'LinkTo', - 'LinkToForm', - 'EmailSpeakers' => 'ADMIN' - ); + public static $allowed_actions = array( + 'ImportSpeakersFromSched' => 'ADMIN', + 'ImportSessionsFromSched' => 'ADMIN', + 'ListSpeakers' => 'ADMIN', + 'SpeakerTable' => 'ADMIN', + 'Presentations', + 'Upload', + 'Form', + 'Success', + 'LinkTo', + 'LinkToForm', + 'EmailSpeakers' => 'ADMIN', + 'AssignYouTubeID' + ); function init() { @@ -81,13 +83,50 @@ class SchedToolsPage_Controller extends Page_Controller "); + + } + + function AssignYouTubeID() + { + if (isset($_GET['token']) && + $_GET['token'] == "fcv4x7Nl8v" && + isset($_GET['youtubeid']) && + isset($_GET['schedid']) + ) { + + $CleanedYoutubeID = Convert::raw2sql($_GET['youtubeid']); + $CleanedSchedID = Convert::raw2sql($_GET['schedid']); + + $Presentation = DataObject::get_one('Presentation', "`event_key` = '" . $CleanedSchedID . "'"); + + If ($Presentation) { + + // Add the YouTubeID to an existing presentation + $Presentation->YouTubeID = $CleanedYoutubeID; + $Presentation->write(); + + } else { + + // Create a new presentation with this sched event and add the youtube id + $SchedEvent = DataObject::get_one('SchedEvent', "`event_key` = '" . $CleanedSchedID . "'"); + if ($SchedEvent) { + $Presentation = new Presentation(); + $Presentation->PopulateFromSchedEvent($SchedEvent->ID); + $Presentation->YouTubeID = $CleanedYoutubeID; + $Presentation->sched_key = $SchedEvent->sched_key; + $Presentation->write(); + } + + } + + } } function ImportSpeakersFromSched() { - $feed = new RestfulService('http://openstacksummitnovember2014paris.sched.org/api/role/export?api_key=41caf3c5cafc24e286ade21926eaeb41&role=speaker&format=xml&fields=username,name,email',7200); + $feed = new RestfulService('http://openstacksummitnovember2014paris.sched.org/api/role/export?api_key=41caf3c5cafc24e286ade21926eaeb41&role=speaker&format=xml&fields=username,name,email', 7200); $feedXML = $feed->request()->getBody(); @@ -167,7 +206,7 @@ class SchedToolsPage_Controller extends Page_Controller $key = Convert::raw2sql($_GET['key']); $username = SchedSpeaker::HashToUsername($key); - $Speaker = SchedSpeaker::get()->filter('username',$username)->first(); + $Speaker = SchedSpeaker::get()->filter('username', $username)->first(); } elseif ($speakerID = Session::get('UploadMedia.SpeakerID')) { @@ -232,7 +271,7 @@ class SchedToolsPage_Controller extends Page_Controller if ( // make sure the data is numeric is_numeric($PresentationID) && // make sure there's a presentation by that id - ($Presentation = SchedEvent::get()->byID( $PresentationID)) && + ($Presentation = SchedEvent::get()->byID($PresentationID)) && // pull the speaker from the session and make sure they are a speaker for this presentation ($SpeakerID = Session::get('UploadMedia.SpeakerID')) && ($Presentation->IsASpeaker($SpeakerID)) @@ -260,7 +299,7 @@ class SchedToolsPage_Controller extends Page_Controller { $PresentationID = Session::get('UploadMedia.PresentationID'); - $Presentation = SchedEvent::get()->byID( $PresentationID); + $Presentation = SchedEvent::get()->byID($PresentationID); $Form = new PresentationLinkToForm($this, 'LinkToForm'); if ($Presentation && $Presentation->Metadata()) $Form->loadDataFrom($Presentation->Metadata()); @@ -309,7 +348,7 @@ class SchedToolsPage_Controller extends Page_Controller $Speakers = SchedSpeaker::get(); foreach ($Speakers as $Speaker) { - if ($Speaker->PresentationsForThisSpeaker() && + if ($Speaker->PresentationsForThisSpeaker() && !$Speaker->GeneralOrKeynote() && !SchedSpeakerEmailLog::BeenEmailed($Speaker->email) && $this->validEmail($Speaker->email) diff --git a/themes/openstack/css/videos.css b/themes/openstack/css/videos.css new file mode 100644 index 0000000..31a0f85 --- /dev/null +++ b/themes/openstack/css/videos.css @@ -0,0 +1,403 @@ +/*Videos Home Page*/ +.main-video-wrapper { + width: 100%; + background: #222; + height: auto; + margin: 0 0 30px; + text-align: center; + box-sizing: border-box; } + +a.main-video { + position: relative; + display: block; + max-width: 617px; + margin: 0 auto; + border-left: 1px solid #eee; + border-right: 1px solid #eee; } + +a.main-video .video-description-wrapper { + position: absolute; + display: block; + background: rgba(0, 0, 0, 0.7); + bottom: 0; + left: 0; + right: 0; + top: 230px; + text-align: left; + z-index: 1000; + padding: 20px; } + +@media (max-width: 767px) { + a.main-video .video-description-wrapper { + top: 60%; } } + +@media (max-width: 480px) { + a.main-video .video-description-wrapper { + top: 50%; } } + +a.main-video .video-description-wrapper .video-description { + width: 80%; + float: left; } + +a.main-video .video-description-wrapper .video-description h3 { + color: white; + font-size: 22px; + font-weight: 600; + width: 100%; + height: 25px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + +a.main-video .video-description-wrapper .video-description p { + color: white; + font-size: 13px; + line-height: 1.2; + font-weight: 400; + padding: 0; + display: block; + width: 100%; + height: 15px; + margin: 0 auto; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } + +a.main-video:hover .video-description-wrapper { + top: 0; } + +a.main-video:hover .video-description-wrapper .video-description h3 { + height: 10%; + white-space: normal; } + +a.main-video:hover .video-description-wrapper .video-description p { + height: 90%; + white-space: normal; } + +@media (max-width: 480px) { + a.main-video:hover .video-description-wrapper { + top: 50%; } + a.main-video:hover .video-description-wrapper .video-description h3 { + height: 25px; + white-space: nowrap; } + a.main-video:hover .video-description-wrapper .video-description p { + height: 15px; + white-space: nowrap; } } + +.main-video img { + margin: 0 auto; + width: 100%; + max-width: 615px; + max-height: 100%; + display: block; + position: relative; + z-index: 1; } + +.play-btn { + float: right; + color: white; + font-size: 40px; + width: 20%; + margin-top: 5px; + text-align: center; } + +.play-btn img#play { + max-width: 70px; + max-height: 70px; } + +.featured-row { + width: 100%; + background: #2A4E68; + padding: 0; + position: relative; + display: block; + margin-bottom: 50px; } + +.featured-row h2 { + color: white; + font-weight: 400; + font-size: 24px; } + +.featured-row h2 span { + font-weight: 400; + font-size: 12px; + color: #edf2f7; + margin-left: 20px; } + +.featured-row:after { + top: 100%; + left: 10%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-color: rgba(42, 78, 104, 0); + border-top-color: #2A4E68; + border-width: 15px; + margin-left: -15px; } + +.daily-recap-wrapper .video-thumb-title { + text-align: center; } + +.video-thumb { + /*background: $lightblue;*/ + text-align: center; + width: 100%; + height: 0; + position: relative; + display: table; + overflow: hidden; + margin-bottom: 20px; + box-sizing: border-box; } + +.thumb-play { + display: none; + background-image: url("//www.openstack.org/themes/openstack/images/landing-pages/auto/play-button.png"); + background-repeat: no-repeat; + background-position: center center; + background-color: rgba(0, 0, 0, 0.3); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; } + +.video-thumb:hover .thumb-play { + display: block; } + +@media (max-width: 767px) { + .video-thumb .thumb-play { + display: block; + background-color: transparent; } } + +.video-thumb img.video-thumb-img { + max-width: 100%; + width: 100%; } + +.video-thumb p { + color: #C6CDD6; + font-size: 14px; + font-weight: 700; + display: table-cell; + vertical-align: middle; } + +.sort-row { + background: #edf2f7; + width: 100%; + min-height: 50px; + padding: 25px 0; + position: relative; + display: block; + margin: 50px 0; + color: #2A4E68; } + +.sort-left { + float: left; } + +.sort-left i { + color: #b4c5d6; + line-height: 1; + margin-right: 10px; } + +.sort-left i:hover { + color: #2A4E68; + cursor: pointer; } + +.sort-left i.active { + color: #2A4E68; } + +.sort-right { + float: right; + font-size: 12px; + text-transform: uppercase; + font-weight: 600; } + +.sort-right i { + margin-left: 10px; + font-weight: 700; + font-size: 14px; } + +.video-thumb-title { + margin: -10px 0 0; + color: #30739C; + font-size: 12px; + font-weight: 400; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } + +.video-thumb-speaker { + color: #30739C; + font-size: 12px; + font-weight: 600; + margin-bottom: 40px; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } + +@media (max-width: 767px) { + .daily-recap-wrapper .video-thumb-title { + margin-bottom: 40px; } + .video-thumb-title, .video-thumb-speaker { + text-align: center; } } + +.video-dropdown > .dropdown-menu { + margin: 20px -20px 0; + padding: 10px 0; + min-width: 230px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + left: -99%; + right: 100%; + background-color: #edf2f7; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0); + box-shadow: none; } + +/*.video-dropdown>.dropdown-menu:after, .video-dropdown>.dropdown-menu:before { + bottom: 100%; + right: 25%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; +} +.video-dropdown>.dropdown-menu:after { + border-color: rgba(255, 255, 255, 0); + border-bottom-color: #fff; + border-width: 15px; + margin-left: -15px; +} +.video-dropdown>.dropdown-menu:before { + border-color: rgba(170, 170, 170, 0); + border-bottom-color: #aaaaaa; + border-width: 15px; + margin-left: -16px; +}*/ +.video-dropdown > .dropdown-menu li a { + text-transform: uppercase; + padding: 13px 20px; + font-size: 12px; + color: #2A4E68; } + +.video-dropdown > .dropdown-menu li a:hover { + color: white; + background: #2A4E68; } + +.video-dropdown > .dropdown-menu li a:focus { + outline: none; } + +/*End Videos Home Page*/ +/*Video Inner Page*/ +.single-video-details { + margin: 60px auto; } + +.single-video-details h3 { + text-align: left; } + +.single-video-details strong { + color: #2A4E68; } + +.video-share { + text-align: right; + float: right; } + +.video-share a i { + font-size: 22px; + margin-left: 20px; + vertical-align: middle; + color: #759bb7; } + +.video-share a i:hover { + color: #2A4E68; } + +@media (max-width: 767px) { + .video-share { + float: none; + text-align: center; + margin: -20px 0 20px; + padding-top: 20px; + padding-bottom: 20px; + border-top: 1px solid #eee; + border-bottom: 1px solid #eee; } + .video-share a i { + margin: 0 10px; } } + +.video-share a i.fa-twitter { + font-size: 24px; + margin-bottom: -1px; } + +p.single-video-description { + margin: 10px 0 40px; } + +.video-categories a { + margin-left: 10px; + text-decoration: underline; } + +.video-tags { + margin-top: 15px; } + +.video-tags a { + background: #edf2f7; + font-size: 10px; + font-weight: 600; + border-radius: 3px; + margin-left: 10px; + padding: 5px 10px; } + +.video-speakers { + margin-top: 15px; + display: block; } + +.video-speakers p a { + margin-left: 0; + text-decoration: underline; } + +.video-speakers .twitter-follow-button { + margin-left: 10px; } + +.video-media-title { + margin: 0 0 10px; + display: block; } + +@media (max-width: 767px) { + .video-media-wrapper { + margin-top: 30px; } } + +.media-btn-wrapper { + float: left; + margin-top: 10px; } + +a.media-btn { + background: #2A4E68; + color: white; + padding: 10px 20px; + border-radius: 4px; + border: 0; } + +a.media-btn:hover { + text-decoration: none; + background: #16283A; } + +a.media-btn i { + margin-right: 10px; } + +a.media-btn.right { + border-top-left-radius: 0px; + border-bottom-left-radius: 0px; + margin-left: -2px; + border-left: 1px solid #3E71A4; } + +a.media-btn.left { + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; + margin-right: -2px; + border-right: 1px solid #122231; } + +/*End Video Inner Page*/ diff --git a/themes/openstack/images/no-video.jpg b/themes/openstack/images/no-video.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9aad1ed916bc7d1c887417ff899f752c6c3b327c GIT binary patch literal 6255 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 literal 0 HcmV?d00001 diff --git a/themes/openstack/templates/Layout/Includes/VideoThumbnails.ss b/themes/openstack/templates/Layout/Includes/VideoThumbnails.ss new file mode 100644 index 0000000..d6dad78 --- /dev/null +++ b/themes/openstack/templates/Layout/Includes/VideoThumbnails.ss @@ -0,0 +1,57 @@ +
+
+
+ + +
+
+ +
+
+
+ +
+ +
+
+ + <% control Presentations.GroupedBy(PresentationDay) %> +
+

$PresentationDay

+ +
+ <% end_control %> + +
+
+ + +
+ diff --git a/themes/openstack/templates/Layout/PresentationCategoryPage.ss b/themes/openstack/templates/Layout/PresentationCategoryPage.ss index 49f30e7..261e35b 100644 --- a/themes/openstack/templates/Layout/PresentationCategoryPage.ss +++ b/themes/openstack/templates/Layout/PresentationCategoryPage.ss @@ -1,86 +1,74 @@ -<% require themedCSS(conference) %> +<% require themedCSS(videos) %> -<% loop Parent %> -$HeaderArea +
+
+
+
+

Paris Summit 2014: Videos

+
+
+
+
+<% loop LatestPresentation %> + <% end_loop %> - -
-

The OpenStack Summit
$Parent.MenuTitle.XML

- - <% loop Parent %> - <% include HeadlineSponsors %> - <% end_loop %> -
- -
- <% if StillUploading %> -
-

Note: Presentations are still being uploaded. If you do not see the presentation you are looking for, please check back soon.

+ +
+
+
+
+ +
+

+ Day 1 - Coming Soon +

+
+
+
+ +
+

+ Day 2 - Coming Soon +

+
+
+
+ +
+

+ Day 3 - Coming Soon +

+
+
+
+ +
+

+ Day 4 - Coming Soon +

+
+
+
+ +<% include VideoThumbnails %> diff --git a/themes/openstack/templates/Layout/PresentationCategoryPage_presentation.ss b/themes/openstack/templates/Layout/PresentationCategoryPage_presentation.ss index cf6bb43..510e709 100644 --- a/themes/openstack/templates/Layout/PresentationCategoryPage_presentation.ss +++ b/themes/openstack/templates/Layout/PresentationCategoryPage_presentation.ss @@ -1,69 +1,53 @@ -<% require themedCSS(presentation) %> +<% require themedCSS(videos) %> -

OpenStack Summit Presentations

-
+<% loop Presentation %> -

- -
- -
-

"$Presentation.Name"

-

By: $Presentation.Speakers

- - <% if Presentation.Description %> - $Presentation.Description - <% end_if %> - -
- - -

Watch Presentation

- - - - <% loop Presentation %> - <% if SlidesLink %> -

-
- - - - <% if EmbedSlides %> -

View Slides

- - <% else %> -

Download The Presentation Slides

-

Download Slides

- <% end_if %> - <% end_if %> - <% end_loop %> - - -
- -
- \ No newline at end of file + +<% include VideoThumbnails %>