Skip to content
Snippets Groups Projects
Commit 6ddaf76b authored by uhensler's avatar uhensler
Browse files

OO-4043: Peekview of live stream course node

parent d62fa9cd
No related branches found
No related tags found
No related merge requests found
......@@ -40,6 +40,7 @@ import org.olat.course.nodes.livestream.LiveStreamModule;
import org.olat.course.nodes.livestream.LiveStreamSecurityCallback;
import org.olat.course.nodes.livestream.LiveStreamSecurityCallbackFactory;
import org.olat.course.nodes.livestream.ui.LiveStreamEditController;
import org.olat.course.nodes.livestream.ui.LiveStreamPeekviewController;
import org.olat.course.nodes.livestream.ui.LiveStreamRunController;
import org.olat.course.run.navigation.NodeRunConstructionResult;
import org.olat.course.run.userview.NodeEvaluation;
......@@ -100,6 +101,13 @@ public class LiveStreamCourseNode extends AbstractAccessableCourseNode {
Controller ctrl = TitledWrapperHelper.getWrapper(ureq, wControl, runCtrl, this, "o_livestream_icon");
return new NodeRunConstructionResult(ctrl);
}
@Override
public Controller createPeekViewRunController(UserRequest ureq, WindowControl wControl,
UserCourseEnvironment userCourseEnv, NodeEvaluation ne) {
CourseCalendars calendars = CourseCalendars.createCourseCalendarsWrapper(ureq, wControl, userCourseEnv, ne);
return new LiveStreamPeekviewController(ureq, wControl, getIdent(), this.getModuleConfiguration(), calendars);
}
@SuppressWarnings("deprecation")
@Override
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.course.nodes.livestream.ui;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang.time.DateUtils;
import org.olat.commons.calendar.CalendarUtils;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.htmlsite.OlatCmdEvent;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.link.LinkFactory;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.util.StringHelper;
import org.olat.course.nodes.LiveStreamCourseNode;
import org.olat.course.nodes.cal.CourseCalendars;
import org.olat.course.nodes.livestream.LiveStreamEvent;
import org.olat.course.nodes.livestream.LiveStreamService;
import org.olat.modules.ModuleConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 3 Jun 2019<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class LiveStreamPeekviewController extends BasicController implements Controller {
private final VelocityContainer mainVC;
private Link nodeLink;
private final String nodeId;
@Autowired
private LiveStreamService liveStreamService;
public LiveStreamPeekviewController(UserRequest ureq, WindowControl wControl, String nodeId,
ModuleConfiguration moduleConfiguration, CourseCalendars calendars) {
super(ureq, wControl);
this.nodeId = nodeId;
int bufferBeforeMin = moduleConfiguration.getIntegerSafe(LiveStreamCourseNode.CONFIG_BUFFER_BEFORE_MIN, 0);
int bufferAfterMin = moduleConfiguration.getIntegerSafe(LiveStreamCourseNode.CONFIG_BUFFER_AFTER_MIN, 0);
mainVC = createVelocityContainer("peekview");
List<? extends LiveStreamEvent> runningEvents = liveStreamService.getRunningEvents(calendars, bufferBeforeMin, bufferAfterMin);
List<EventWrapper> events;
if (!runningEvents.isEmpty()) {
events = wrapEvents(runningEvents, true);
nodeLink = LinkFactory.createLink("peekview.open.live", mainVC, this);
nodeLink.setIconRightCSS("o_icon o_icon_start");
nodeLink.setElementCssClass("pull-right");
} else {
List<? extends LiveStreamEvent> upcomingEvents = liveStreamService.getUpcomingEvents(calendars, bufferBeforeMin);
if (!upcomingEvents.isEmpty()) {
events = new ArrayList<>(1);
events.add(wrapEvent(upcomingEvents.get(0), false));
nodeLink = LinkFactory.createLink("peekview.open.upcoming", mainVC, this);
nodeLink.setIconRightCSS("o_icon o_icon_start");
nodeLink.setElementCssClass("pull-right");
} else {
events = new ArrayList<>(0);
}
}
mainVC.contextPut("events", events);
putInitialPanel(mainVC);
}
private List<EventWrapper> wrapEvents(List<? extends LiveStreamEvent> events, boolean live) {
List<EventWrapper> wrappedEvents = new ArrayList<>(events.size());
for (LiveStreamEvent event : events) {
wrappedEvents.add(wrapEvent(event, live));
}
return wrappedEvents;
}
private EventWrapper wrapEvent(LiveStreamEvent event, boolean live) {
String titleI18n = live? "peekview.title.live": "peekview.title.upcoming";
String title = translate(titleI18n, new String[] {event.getSubject()});
Locale locale = getLocale();
Calendar cal = CalendarUtils.createCalendarInstance(locale);
Date begin = event.getBegin();
Date end = event.getEnd();
cal.setTime(begin);
StringBuilder dateSb = new StringBuilder();
dateSb.append(StringHelper.formatLocaleDateFull(begin.getTime(), locale));
String date = dateSb.toString();
String time = null;
if (!event.isAllDayEvent()) {
StringBuilder timeSb = new StringBuilder();
timeSb.append(StringHelper.formatLocaleTime(begin.getTime(), locale));
timeSb.append(" - ");
if (!DateUtils.isSameDay(begin, end)) {
timeSb.append(StringHelper.formatLocaleDateFull(end.getTime(), locale)).append(", ");
}
timeSb.append(StringHelper.formatLocaleTime(end.getTime(), locale));
time = timeSb.toString();
}
String location = event.getLocation();
return new EventWrapper(title, date, time, location);
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if (source == nodeLink) {
fireEvent(ureq, new OlatCmdEvent(OlatCmdEvent.GOTONODE_CMD, nodeId));
}
}
@Override
protected void doDispose() {
//
}
public final static class EventWrapper {
private final String title;
private final String date;
private final String time;
private final String location;
private EventWrapper(String title, String date, String time, String location) {
this.title = title;
this.date = date;
this.time = time;
this.location = location;
}
public String getTitle() {
return title;
}
public String getDate() {
return date;
}
public String getTime() {
return time;
}
public String getLocation() {
return location;
}
}
}
<div class="o_livestream_peekview clearfix">
#if($events.isEmpty())
<div class="o_instruction">
$r.translate("peekview.no.streams")
</div>
</div>
#else
#foreach($event in $events)
<div class="o_livestream_peekview_event">
#if($event.getTitle())
<h5>$event.getTitle()</h5>
#end
<div class="o_cal_date text-muted">
<i class="o_icon o_icon-fw o_icon_calendar">&nbsp;</i>
$event.getDate()
</div>
#if($event.getTime() && $event.getTime() != "")
<div class="o_cal_time text-muted">
<i class="o_icon o_icon-fw o_icon_time">&nbsp;</i>
$event.getTime()
</div>
#end
#if($event.getLocation() && $event.getLocation() != "")
<div class="o_cal_location text-muted">
<i class="o_icon o_icon-fw o_icon_home" title="$r.translateInAttribute("cal.form.location")">&nbsp;</i>
$r.escapeHtml($event.getLocation())
</div>
#end
</div>
#end
#if($r.available("peekview.open.live"))
$r.render("peekview.open.live")
#end
#if($r.available("peekview.open.upcoming"))
$r.render("peekview.open.upcoming")
#end
#end
</div>
\ No newline at end of file
......@@ -7,6 +7,11 @@ link.text=Video Livestream
list.title=Anstehende Livestreams
pane.tab.accessibility=Zugang
pane.tab.config=Konfiguration
peekview.no.streams=Es sind keine Livestreams geplant.
peekview.open.live=Livestream anzeigen
peekview.open.upcoming=Alle anzeigen
peekview.title.live=Jetzt live: {0}
peekview.title.upcoming=Demn\u00E4chst: {0}
run.edit.events=Termine bearbeiten
run.streams=Live Streams
table.empty=Es sind keine Livestreams anstehend.
......
......@@ -7,6 +7,11 @@ link.text=Video live stream
list.title=Upcoming live streams
pane.tab.accessibility=Access
pane.tab.config=Configuration
peekview.no.streams=No live streams are planned.
peekview.open.live=Show live stream
peekview.open.upcoming=Show all
peekview.title.live=Live: {0}
peekview.title.upcoming=Upcoming: {0}
run.edit.events=Edit events
run.streams=Livestreams
table.empty=No upcoming live streams are available.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment