Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:TUM-Dev/gocast into fix-typo-and-nex…
Browse files Browse the repository at this point in the history
…t-stream
  • Loading branch information
carlobortolan committed Dec 10, 2024
2 parents 5bd0975 + 1a5939d commit f926820
Show file tree
Hide file tree
Showing 15 changed files with 362 additions and 29 deletions.
1 change: 1 addition & 0 deletions web/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ func (d *IndexData) LoadLivestreams(c *gin.Context, daoWrapper dao.DaoWrapper) {
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
logger.Error("could not get current live streams", "err", err)
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"message": "Could not load current livestream from database."})
return
}

tumLiveContext := d.TUMLiveContext
Expand Down
2 changes: 2 additions & 0 deletions web/saml.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func configSaml(r *gin.Engine, daoWrapper dao.DaoWrapper) {
if len(s) == 0 || s[0] == "" {
logger.Error("Can't extract mwn id", "LRZ-ID", lrzID, "firstName", firstName, "lastName", lastName, "mwnID", matrNr)
c.AbortWithStatus(http.StatusInternalServerError)
return
}
matrNr = s[0]
}
Expand All @@ -145,6 +146,7 @@ func configSaml(r *gin.Engine, daoWrapper dao.DaoWrapper) {
if err != nil {
logger.Error("Could not upsert user", "err", err)
c.AbortWithStatus(http.StatusInternalServerError)
return
}
HandleValidLogin(c, &tools.SessionData{Userid: user.ID, SamlSubjectID: &subjectID})
})
Expand Down
4 changes: 2 additions & 2 deletions web/template/admin/admin_tabs/info-pages.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@
</div>
</div>
</div>
<div x-cloak="" x-show="editOpen" class="form-container-body">
<div x-cloak x-show="editOpen" class="form-container-body">
<textarea id="content-{{$i}}"
x-model="newContent"
rows="24"
class="p-2 resize-none font-normal outline-0 border-0 bg-transparent text-3">{{$text.RawContent}}</textarea>
</div>
<div x-cloak="" x-show="editOpen" class="flex items-center justify-end form-container-footer">
<div x-cloak x-show="editOpen" class="flex items-center justify-end form-container-footer">
<button id="save-{{$i}}"
type="reset"
class="btn h-fit mr-2"
Expand Down
4 changes: 2 additions & 2 deletions web/template/course-overview.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
{{if or (.IndexData.TUMLiveContext.User.IsAdminOfCourse .IndexData.TUMLiveContext.Course) .IndexData.IsAdmin}}
<a class="hover:bg-gray-200 dark:hover:bg-gray-600 w-fit mx-2 inline-block rounded px-2 my-auto"
href="/admin/course/{{$course.Model.ID}}"
:title="'Edit course settings'">
title="Edit course settings">
<span class="font-semibold text-lg dark:text-white">
<i class="fa-solid w-5 py-2 fa-pen"></i>
</span>
Expand Down Expand Up @@ -125,7 +125,7 @@
</button>
<a class="hover:bg-gray-200 dark:hover:bg-gray-600 inline-block rounded px-2"
href="/api/download_ics/{{$course.Year}}/{{$course.TeachingTerm}}/{{$course.Slug}}/events.ics"
:title="'Export lecture dates'"
title="Export lecture dates"
x-show="lectures">
<span class="text-sm font-semibold uppercase dark:text-white">
<i class="fa-solid w-5 mr-1 fa-calendar"></i>ics
Expand Down
9 changes: 7 additions & 2 deletions web/template/home.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@
:class="plannedStreams.hasElements() ? 'col-span-2' : 'col-span-full'">
<header>
<h3 class="font-bold">VODs</h3>
<section class="space-x-2">
<section class="button-area space-y-1">
<button type="button" @click="sortNewestFirst()"
class="tum-live-button tum-live-button-tertiary"
:class="{'active' : isNewestFirst() }">
Expand All @@ -433,6 +433,11 @@
:class="{'active' : isListView() }">
List View
</button>
<button type="button" @click="toggleWeekView()"
class="tum-live-button tum-live-button-tertiary"
:class="{'active' : isWeekView() }">
Week View
</button>
</section>
</header>
<section>
Expand All @@ -442,7 +447,7 @@
x-for="group in courseStreams.get(sortFn(streamSortMode), filterPred(streamFilterMode))">
<article class="mb-8">
<header class="mb-2">
<h6 class="font-semibold" x-text="group[0].GetMonthName()"></h6>
<h6 class="font-semibold" x-text="groupNames.get(group[0].ID);"></h6>
</header>
<section class="grid gap-3 grid-cols-1"
:class="isListView() ? 'xl:grid-cols-1 lg:grid-cols-1 md:grid-cols-1 grid-cols-1' : plannedStreams.hasElements()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,33 @@
<div class="mb-4">
<label x-show="formData.premiere || formData.vodup && !loading">
<span class="text-sm text-5">Combined Video (mp4, if possible h264)</span>
<input type="file" accept="video/mp4" class="btn tl-choose-file w-full mt-2 mx-2"
x-on:change="updateFiles('COMB', Object.values($event.target.files))">
<label class="flex">
<input x-ref="fileSelection1" type="file" accept="video/mp4" class="btn tl-choose-file mt-2 mx-2 w-full"
x-on:change="updateFiles('COMB', Object.values($event.target.files));">
<button type="button" title="Deselect File" class="fa fa-trash mt-2 mx-2" @click="updateFiles('COMB', []);$refs.fileSelection1.value = '';"></button>
</label>
</label>
</div>

<div class="mb-4">
<label x-show="formData.premiere || formData.vodup && !loading">
<span class="text-sm text-5">Presentation Video (mp4, if possible h264)</span>
<input type="file" accept="video/mp4" class="btn tl-choose-file w-full mt-2 mx-2"
x-on:change="updateFiles('PRES', Object.values($event.target.files))">
<label class="flex">
<input x-ref="fileSelection2" type="file" accept="video/mp4" class="btn tl-choose-file mt-2 mx-2 w-full"
x-on:change="updateFiles('PRES', Object.values($event.target.files));">
<button type="button" title="Deselect File" class="fa fa-trash mt-2 mx-2" @click="updateFiles('PRES', []);$refs.fileSelection2.value = '';"></button>
</label>
</label>
</div>

<div>
<label x-show="formData.premiere || formData.vodup && !loading">
<span class="text-sm text-5">Camera Video (mp4, if possible h264)</span>
<input type="file" accept="video/mp4" class="btn tl-choose-file w-full mt-2 mx-2"
x-on:change="updateFiles('CAM', Object.values($event.target.files))">
<label class="flex">
<input x-ref="fileSelection3" type="file" accept="video/mp4" class="btn tl-choose-file mt-2 mx-2 w-full"
x-on:change="updateFiles('CAM', Object.values($event.target.files));">
<button type="button" title="Deselect File" class="fa fa-trash mt-2 mx-2" @click="updateFiles('CAM', []);$refs.fileSelection3.value = '';"></button>
</label>
</label>
</div>
{{end}}
43 changes: 43 additions & 0 deletions web/template/partial/stream/transcript.gohtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{{define "transcript-modal"}}
<div x-data="{ transcriptController: new watch.TranscriptController(), isOutOfSync: false, showScrollUp: false }"
class="relative h-full border rounded-lg dark:border-gray-800 flex flex-col items-center justify-center overflow-hidden">
<div class="h-full w-full max-w-3xl flex flex-col">
<div class="flex justify-between items-end p-4">
<div class="flex items-center space-x-2">
<h3 class="font-bold text-sm md:text-xl text-3">Transcript</h3>
<span class="text-xs font-semibold text-white bg-red-500 rounded-full px-2 py-1 italic">beta</span>
</div>
<button type="button" title="Download transcript file"
class="text-3 text-xs md:text-sm font-semibold hover:bg-gray-100 dark:hover:bg-gray-600 rounded-full px-2 py-1"
@click="transcriptController.downloadTranscript()">
Export transcript
</button>
</div>
<div class="flex-grow overflow-hidden relative">
{{template "transcript-list"}}
</div>
</div>
</div>
{{end}}

{{define "transcript-list"}}
<div x-cloak
x-data="{ transcriptController: new watch.TranscriptController(), transcript: [] }"
x-init="() => { transcriptController.init('transcript-list', $el); }"
@update="(e) => (transcript = e.detail)"
class="h-full w-full max-w-3xl mx-auto transcript-container overflow-hidden">
<div class="relative grid gap-1 overflow-y-auto pr-3 h-full">
<template x-for="(cue, index) in transcript" :key="index">
<div class="flex items-start space-x-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 p-2 rounded"
@click="watch.jumpTo({ Ms: cue.startTime * 1000 }, true);" :data-cue-start="cue.startTime">
<div class="text-xs text-gray-500 dark:text-gray-400 mt-1">
<span x-text="new Date(cue.startTime * 1000).toISOString().substr(11, 8)"></span>
</div>
<div class="text-sm text-gray-900 dark:text-gray-100">
<span x-text="cue.text"></span>
</div>
</div>
</template>
</div>
</div>
{{end}}
43 changes: 33 additions & 10 deletions web/template/watch.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<script defer src="/static/node_modules/katex/dist/contrib/copy-tex.min.js"></script>
{{end}}
</head>
<body x-data="{'streamID': {{$stream.Model.ID}}, seekLogger: new watch.SeekLogger('{{$stream.ID}}'), sidebar: $persist(watch.SidebarState.Hidden).as('sidebarState'), showShare: false}"
<body x-data="{'streamID': {{$stream.Model.ID}}, seekLogger: new watch.SeekLogger('{{$stream.ID}}'), sidebar: $persist(watch.SidebarState.Hidden).as('sidebarState'), showShare: false, transcriptAvailable: false}"
x-init="seekLogger.attach();">
{{template "header" .IndexData.TUMLiveContext}}
<div id="shortcuts-help-modal" class="hidden flex fixed top-0 h-screen w-screen z-50 backdrop-brightness-50">
Expand Down Expand Up @@ -73,7 +73,7 @@
</div>
</div>
{{if .IndexData.TUMLiveContext.User}}
<div id="bookmarks-mobile" x-cloak="" x-show="sidebar === watch.SidebarState.Bookmarks"
<div id="bookmarks-mobile" x-cloak x-show="sidebar === watch.SidebarState.Bookmarks"
class="md:hidden flex absolute top-0 h-screen w-screen z-50 backdrop-brightness-50">
<div @click.outside="sidebar = watch.SidebarState.Hidden"
class="m-auto w-3/4 h-16/9 bg-white dark:bg-secondary-light border dark:border-gray-800 rounded-lg">
Expand Down Expand Up @@ -417,16 +417,32 @@

<!-- Bookmarks -->
{{if .IndexData.TUMLiveContext.User}}
<div id="bookmarks-desktop" x-cloak="" x-show="sidebar === watch.SidebarState.Bookmarks"
<div id="bookmarks-desktop" x-cloak x-show="sidebar === watch.SidebarState.Bookmarks"
:class="sidebar === watch.SidebarState.Bookmarks ? 'lg:basis-1/4' : 'lg:basis-0'"
class="hidden md:block basis-full h-16/9 lg:h-16/6 px-5 md:px-2 lg:order-none order-4">
{{template "bookmarks-modal" $stream.ID}}
</div>
{{end}}

<!-- Transcript -->
<div id="transcript-desktop" x-cloak x-show="sidebar === watch.SidebarState.Transcript && transcriptAvailable"
:class="sidebar === watch.SidebarState.Transcript ? 'lg:basis-1/4' : 'lg:basis-0'"
class="basis-full md:h-16/9 lg:h-16/6 px-2 lg:order-none order-4 grow">
{{template "transcript-modal" $stream.ID}}
</div>

<!-- Scroll to Top Button -->
<button x-data="{ showScrollUp: false }"
x-show="showScrollUp"
@click="watch.pauseVideo();window.scrollTo({ top: 0, behavior: 'smooth' }); "
class="fixed bottom-4 right-4 md:hidden bg-blue-500 text-white rounded-full p-2 shadow-lg z-50"
@scroll.window="showScrollUp = (window.scrollY > 200)">
<i class="fa-solid fa-arrow-up"></i>
</button>

<!-- Streams -->
{{if .IndexData.TUMLiveContext.User}}
<div id="streams-box" x-cloak="" x-show="sidebar === watch.SidebarState.Streams"
<div id="streams-box" x-cloak x-show="sidebar === watch.SidebarState.Streams"
:class="sidebar === watch.SidebarState.Streams ? 'lg:basis-1/4' : 'lg:basis-0'"
class="order-4 z-20 basis-full px-5 md:px-2 lg:order-none lg:h-16/6 h-16/9">
{{template "playlist" $stream.ID}}
Expand Down Expand Up @@ -467,28 +483,35 @@
<div class="rounded-lg px-3 text-4 py-2 h-fit w-fit bg-gray-100 dark:bg-secondary-light space-x-2">
<a
href="/admin/course/{{$course.Model.ID}}#lecture-li-{{$stream.Model.ID}}"
:title="'Edit course settings'">
title="Edit course settings">
<i class="fa-solid fa-pen text-4"></i>
</a>
<a
href="/admin/stats/{{$course.Model.ID}}/{{$stream.Model.ID}}"
:title="'Watch lecture stats'">
title="Watch lecture stats">
<i class="fa-solid fa-chart-simple text-4"></i>
</a>
</div>
{{end}}

{{if .IndexData.TUMLiveContext.User}}
<button @click="sidebar = (sidebar === watch.SidebarState.Bookmarks ? watch.SidebarState.Hidden : watch.SidebarState.Bookmarks)"
class="rounded-lg px-4 py-2 h-fit w-fit bg-gray-100 hover:bg-gray-200 dark:bg-secondary-light dark:hover:bg-gray-600"
:title="'New Bookmark'">
class="rounded-lg px-3 py-1 md:px-4 py-2 h-fit w-fit bg-gray-100 hover:bg-gray-200 dark:bg-secondary-light dark:hover:bg-gray-600"
title="New Bookmark">
<i class="fa-solid fa-bookmark text-4"></i>
</button>
{{end}}

<!-- Transcript Button -->
<button x-show="transcriptAvailable" @toggletranscript.window="e => {transcriptAvailable=true}" @click="sidebar = (sidebar === watch.SidebarState.Transcript ? watch.SidebarState.Hidden : watch.SidebarState.Transcript)"
class="rounded-lg px-3 py-1 md:px-4 py-2 h-fit w-fit bg-gray-100 hover:bg-gray-200 dark:bg-secondary-light dark:hover:bg-gray-600"
title="Show Transcript">
<i class="fa-solid fa-text-height text-4"></i>
</button>

<button @click="showShare = true;"
class="rounded-lg px-4 py-2 h-fit w-fit bg-gray-100 hover:bg-gray-200 dark:bg-secondary-light dark:hover:bg-gray-600"
:title="'Share'">
class="rounded-lg px-3 py-1 md:px-4 py-2 h-fit w-fit bg-gray-100 hover:bg-gray-200 dark:bg-secondary-light dark:hover:bg-gray-600"
title="Share">
<i class="fa-solid fa-share text-4"></i>
</button>

Expand Down
5 changes: 4 additions & 1 deletion web/ts/TUMLiveVjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ export type jumpToSettings = {
S: number | undefined;
};

export function jumpTo(settings: jumpToSettings) {
export function jumpTo(settings: jumpToSettings, autoplay = false) {
if (settings.timeParts) {
settings.time = new Time(settings.timeParts.hours, settings.timeParts.minutes, settings.timeParts.seconds);
} else if (settings.Ms) {
Expand All @@ -646,6 +646,9 @@ export function jumpTo(settings: jumpToSettings) {
for (let j = 0; j < players.length; j++) {
players[j].ready(() => {
players[j].currentTime(settings.time.toSeconds());
if (autoplay && players[j].paused()) {
players[j].play();
}
});
}
}
Expand Down
6 changes: 6 additions & 0 deletions web/ts/api/courses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ type DownloadableVOD = {
readonly DownloadURL: string;
};

const MS_IN_DAY = 1000 * 60 * 60 * 24;

export class Stream implements Identifiable {
readonly ID: number;
readonly Name: string;
Expand Down Expand Up @@ -118,6 +120,10 @@ export class Stream implements Identifiable {
][this.StartDate().getMonth()];
}

public GetWeekNumber(dateOfFirstWeek: Date): number {
return Math.floor((this.StartDate().getTime() - dateOfFirstWeek.getTime()) / MS_IN_DAY / 7) + 1;
}

private static TimeOf(d: string): string {
return new Date(d).toLocaleTimeString("default", { hour: "2-digit", minute: "2-digit" });
}
Expand Down
Loading

0 comments on commit f926820

Please sign in to comment.