Skip to content

Commit

Permalink
Fix start page issues (#1024)
Browse files Browse the repository at this point in the history
* Make course names bigger; Only show vods

* Don't deliver hidden courses

* Update loop

* Fix side navigation hover

* Remove buggy loading indicator

* Add pinned courses section

* Fix side navigation padding

* Minor changes

* Update promise array
  • Loading branch information
MatthiasReumann committed May 15, 2023
1 parent 0f31cb9 commit 069095b
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 100 deletions.
42 changes: 39 additions & 3 deletions api/courses.go
Expand Up @@ -39,6 +39,7 @@ func configGinCourseRouter(router *gin.Engine, daoWrapper dao.DaoWrapper) {
api.GET("/courses/live", routes.getLive)
api.GET("/courses/public", routes.getPublic)
api.GET("/courses/users", routes.getUsers)
api.GET("/courses/users/pinned", routes.getPinned)

courseById := api.Group("/courses/:id")
{
Expand Down Expand Up @@ -230,9 +231,44 @@ func (r coursesRoutes) getUsers(c *gin.Context) {

sortCourses(courses)
courses = commons.Unique(courses, func(c model.Course) uint { return c.ID })
resp := make([]model.CourseDTO, len(courses))
for i, course := range courses {
resp[i] = course.ToDTO()
resp := make([]model.CourseDTO, 0, len(courses))
for _, course := range courses {
if !course.IsHidden() {
resp = append(resp, course.ToDTO())
}
}

c.JSON(http.StatusOK, resp)
}

func (r coursesRoutes) getPinned(c *gin.Context) {
tumLiveContext := c.MustGet("TUMLiveContext").(tools.TUMLiveContext)

year, term := tum.GetCurrentSemester()
year, err := strconv.Atoi(c.DefaultQuery("year", strconv.Itoa(year)))
if err != nil {
_ = c.Error(tools.RequestError{
Status: http.StatusBadRequest,
CustomMessage: "invalid year",
Err: err,
})
}
term = c.DefaultQuery("term", term)

var pinnedCourses []model.Course
if tumLiveContext.User != nil {
pinnedCourses = tumLiveContext.User.PinnedCourses
} else {
pinnedCourses = []model.Course{}
}

sortCourses(pinnedCourses)
pinnedCourses = commons.Unique(pinnedCourses, func(c model.Course) uint { return c.ID })
resp := make([]model.CourseDTO, 0, len(pinnedCourses))
for _, course := range pinnedCourses {
if !course.IsHidden() && course.Year == year && course.TeachingTerm == term {
resp = append(resp, course.ToDTO())
}
}

c.JSON(http.StatusOK, resp)
Expand Down
38 changes: 21 additions & 17 deletions model/course.go
Expand Up @@ -43,24 +43,26 @@ type Course struct {
}

type CourseDTO struct {
ID uint
Name string
Slug string
TeachingTerm string
Year int
NextLecture StreamDTO
LastLecture StreamDTO
ID uint
Name string
Visibility string
Slug string
TeachingTerm string
Year int
NextLecture StreamDTO
LastRecording StreamDTO
}

func (c *Course) ToDTO() CourseDTO {
return CourseDTO{
ID: c.ID,
Name: c.Name,
Slug: c.Slug,
TeachingTerm: c.TeachingTerm,
Year: c.Year,
NextLecture: c.GetNextLecture().ToDTO(),
LastLecture: c.GetLastLecture().ToDTO(),
ID: c.ID,
Name: c.Name,
Visibility: c.Visibility,
Slug: c.Slug,
TeachingTerm: c.TeachingTerm,
Year: c.Year,
NextLecture: c.GetNextLecture().ToDTO(),
LastRecording: c.GetLastRecording().ToDTO(),
}
}

Expand Down Expand Up @@ -229,16 +231,18 @@ func (c Course) GetNextLecture() Stream {
return earliestLecture
}

// GetLastLecture returns the most recent lecture of the course
// GetLastRecording returns the most recent lecture of the course
// Assumes an ascending order of c.Streams
func (c Course) GetLastLecture() Stream {
func (c Course) GetLastRecording() Stream {
var lastLecture Stream
now := time.Now()
for _, s := range c.Streams {
if s.Start.After(now) {
return lastLecture
}
lastLecture = s
if s.Recording {
lastLecture = s
}
}
return lastLecture
}
Expand Down
15 changes: 8 additions & 7 deletions web/assets/css/home.css
Expand Up @@ -79,15 +79,16 @@
}

.tum-live-side-navigation {
@apply flex-col sticky top-0 overflow-y-scroll font-light text-3 shrink-0 divide-y dark:divide-gray-800
@apply flex-col sticky top-0 overflow-y-scroll font-light text-3 shrink-0
}

.tum-live-side-navigation > .tum-live-side-navigation-group {
@apply px-5
.tum-live-side-navigation-group {
@apply mx-5 grid py-4 content-baseline
}

.tum-live-side-navigation-group {
@apply grid py-4 content-baseline
/* not:last-two-children */
.tum-live-side-navigation-group:not(:nth-last-child(-n + 2)){
@apply border-b dark:border-gray-800
}

.tum-live-side-navigation-group > header {
Expand All @@ -102,7 +103,7 @@
@apply text-sm rounded-lg text-left px-3 py-2
}

.tum-live-side-navigation-group-item ~ .hover {
.tum-live-side-navigation-group-item.hover {
@apply hover:bg-gray-100 dark:hover:bg-gray-800
}

Expand Down Expand Up @@ -135,7 +136,7 @@
}

.tum-live-stream .course {
@apply block text-5 hover:bg-gray-50 dark:hover:bg-gray-800 rounded
@apply text-5 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg py-1 break-words leading-relaxed
}

.tum-live-stream .title {
Expand Down
86 changes: 53 additions & 33 deletions web/template/home.gohtml
Expand Up @@ -33,7 +33,6 @@
<body x-data="home.context()"
@popstate.window="onPopState"
class="h-screen flex flex-col items-stretch tum-live-bg">
<div :style="`width: ${loadingIndicator}%`" class="bg-blue-500/50 h-px fixed top-0 transition-all duration-300"></div>
<header x-data="home.header()"
class="text-3 flex z-50 w-full items-center px-3 py-2 h-16 justify-between shrink-0 grow-0">
<div class="flex items-center">
Expand Down Expand Up @@ -145,34 +144,48 @@
<span class="tum-live-side-navigation-group-item mb-1 border-l-4 bg-blue-100/50 border-blue-500/50 dark:bg-indigo-500/25 dark:border-indigo-600/50"
x-text="semesters[selectedSemesterIndex]?.FriendlyString()"></span>
<template x-if="navigation.getChild('allSemesters').value">
<template x-for="(s, i) in semesters">
<template x-for="s in semesters">
<button type="button" @click="switchSemester(s.Year, s.TeachingTerm)"
class="tum-live-side-navigation-group-item hover"
x-text="s.FriendlyString()"></button>
</template>
</template>
<button @click="navigation.getChild('allSemesters').toggle()"
class="tum-live-side-navigation-group-item">
class="tum-live-side-navigation-group-item hover">
<i class="fa-solid"
:class="navigation.getChild('allSemesters').value ? 'fa-chevron-up' : 'fa-chevron-down'"></i>
<span x-text="navigation.getChild('allSemesters').value ? 'Show less' : 'Show all'"></span>
</button>
</article>
<template x-if="pinnedCourses.length > 0">
<article class="tum-live-side-navigation-group">
<header>
<i class="fa-solid fa-thumbtack"></i>
Pinned Courses
</header>
<template x-for="course in pinnedCourses" :key="course.ID">
<a class="tum-live-side-navigation-group-item hover"
:href="course.URL()"
x-text="course.Name">
</a>
</template>
</article>
</template>
<template x-if="userCourses.length > 0">
<article class="tum-live-side-navigation-group">
<header>
<i class="fa-solid fa-graduation-cap"></i>
My Courses
</header>
<template x-for="(course, i) in userCourses.slice(0, 8)" :key="course.ID">
<a class="tum-live-side-navigation-group-item"
<template x-for="course in userCourses.slice(0, 8)" :key="course.ID">
<a class="tum-live-side-navigation-group-item hover"
:href="course.URL()"
x-text="course.Name">
</a>
</template>
<template x-if="userCourses.length > 8 && view !== home.Views.UserCourses">
<button @click="showUserCourses()"
class="tum-live-side-navigation-group-item">
class="tum-live-side-navigation-group-item hover">
<i class="fa-solid fa-chevron-right"></i>
Show all my courses
</button>
Expand All @@ -185,14 +198,14 @@
Public Courses
</header>
<template x-for="(course, i) in publicCourses.slice(0, 5)" :key="course.ID">
<a class="tum-live-side-navigation-group-item"
<a class="tum-live-side-navigation-group-item hover"
:href="course.URL()"
x-text="course.Name">
</a>
</template>
<template x-if="publicCourses.length > 5 && view !== home.Views.PublicCourses">
<button @click="showPublicCourses()"
class="tum-live-side-navigation-group-item">
class="tum-live-side-navigation-group-item hover">
<i class="fa-solid fa-chevron-right"></i>
Show all public courses
</button>
Expand All @@ -210,11 +223,11 @@
</footer>
</section>
<article class="text-3 p-4 grow" :class="{'hidden' : navigation.value}">
<template x-for="(n, i) in serverNotifications">
<template x-for="n in serverNotifications">
<div class="tum-live-notification mx-3 mb-3"
:class="n.Warn ? 'tum-live-notification-warn' :'tum-live-notification-info'">
<i class="icon fa-solid" :class="n.Warn ? 'fa-triangle-exclamation' : 'fa-circle-info'"></i>
<span class = "title" x-html="n.Text"></span>
<span class="title" x-html="n.Text"></span>
</div>
</template>
<template x-if="view === home.Views.PublicCourses">
Expand All @@ -230,14 +243,14 @@
</button>
</header>
<article class="grid gap-3 pb-4">
<template x-for="(course, i) in publicCourses" :key="course.ID">
<template x-for="course in publicCourses" :key="course.ID">
<section class="tum-live-course-list-item">
<a class="title" x-text="course.Name" :href="course.URL()"></a>
<div class="links">
<span x-text="course.NextLecture.ID !== 0
? `Next lecture: ${course.NextLecture.FriendlyDateStart()}`
: 'No upcoming lecture.'"></span>
<a x-cloak x-show="course.LastLecture.ID !== 0" :href="course.LastLectureURL()">
<a x-cloak x-show="course.LastRecording.ID !== 0" :href="course.LastRecordingURL()">
<i class="fa-solid fa-square-up-right"></i>
<span class="hover:underline">Most recent lecture</span>
</a>
Expand All @@ -260,14 +273,14 @@
</button>
</header>
<article class="grid gap-3 pb-4">
<template x-for="(course, i) in userCourses" :key="course.ID">
<template x-for="course in userCourses" :key="course.ID">
<section class="tum-live-course-list-item">
<a class="title" x-text="course.Name" :href="course.URL()"></a>
<div class="links">
<span x-text="course.LastLecture.ID !== 0
? `Next lecture: ${course.LastLecture.FriendlyDateStart()}`
<span x-text="course.LastRecording.ID !== 0
? `Next lecture: ${course.LastRecording.FriendlyDateStart()}`
: 'No upcoming lecture.'"></span>
<a x-cloak x-show="course.LastLecture.ID !== 0" :href="course.LastLectureURL()">
<a x-cloak x-show="course.LastRecording.ID !== 0" :href="course.LastRecordingURL()">
<i class="fa-solid fa-square-up-right"></i>
<span class="hover:underline">Most recent lecture</span>
</a>
Expand Down Expand Up @@ -302,7 +315,7 @@
<h3 class="py-1 mx-3 bg-danger text-white text-sm w-fit uppercase rounded animate-pulse">
Live</h3>
<section class="grid xl:grid-cols-3 2xl:grid-cols-4 lg:grid-cols-2 grid-cols-1">
<template x-for="(livestream, i) in livestreams" :key="livestream.Stream.ID">
<template x-for="livestream in livestreams" :key="livestream.Stream.ID">
<article class="tum-live-stream p-3 lg:col-span-1 col-span-full"
:id="`livestream-${livestream.Stream.ID}`">
<div class="aspect-video relative mb-2">
Expand All @@ -327,9 +340,11 @@
<div class="px-2">
<a class="course text-sm" :href="livestream.Course.URL()"
x-text="livestream.Course.Name"></a>
<a class="title"
:href="`/w/${livestream.Course.Slug}/${livestream.Stream.ID}`"
x-text="livestream.Stream.Name"></a>
<template x-if="livestream.Stream.HasName()">
<a class="title"
:href="`/w/${livestream.Course.Slug}/${livestream.Stream.ID}`"
x-text="livestream.Stream.Name"></a>
</template>
<span class="date text-sm" x-text="livestream.Stream.UntilString()"></span>
</div>
</article>
Expand Down Expand Up @@ -365,35 +380,40 @@
<article class="tum-live-content-grid-item" id="recent-vods">
<h3>Recent VODs</h3>
<section class="grid xl:grid-cols-4 2xl:grid-cols-5 lg:grid-cols-3 grid-cols-1">
<template x-for="(course, i) in recently.get()" :key="course.ID">
<template x-for="course in recently.get()" :key="course.ID">
<article class="tum-live-stream lg:col-span-1 col-span-full p-3">
<a :href="course.LastLectureURL()" class="block mb-2">
<div :style="`background-image:url('/api/stream/${course.LastLecture.ID}/thumbs/vod')`"
<a :href="course.LastRecordingURL()" class="block mb-2">
<div :style="`background-image:url('/api/stream/${course.LastRecording.ID}/thumbs/vod')`"
class="aspect-video tum-live-thumbnail">
<div :id="`vod-progress-${course.LastLecture.ID}`"
<div :id="`vod-progress-${course.LastRecording.ID}`"
class="tum-live-thumbnail-progress">
<div>
<template x-if="course.LastLecture.Progress !== undefined">
<span :style="`width: ${course.LastLecture.Progress.Percentage()}%`"
:class="{'rounded-br-lg': course.LastLecture.Progress.HasProgressOne()}"></span>
<template x-if="course.LastRecording.Progress !== undefined">
<span :style="`width: ${course.LastRecording.Progress.Percentage()}%`"
:class="{'rounded-br-lg': course.LastRecording.Progress.HasProgressOne()}"></span>
</template>
</div>
</div>
</div>
</a>
<div class="px-1">
<a class="course text-xs" x-text="course.Name" :href="course.URL()"></a>
<a class="title" :href="course.LastLectureURL()"
x-text="course.LastLecture.Name"></a>
<a class="course"
x-text="course.Name" :href="course.URL()"
:class="course.LastRecording.HasName() ? 'text-xs' : 'text-sm'"></a>
<template x-if="course.LastRecording.HasName()">
<a class="title" :href="course.LastRecordingURL()"
x-text="course.LastRecording.Name"></a>
</template>
<span class="date text-xs"
x-text="course.LastLecture.FriendlyDateStart()"></span>
x-text="course.LastRecording.FriendlyDateStart()"></span>
</div>
</article>
</template>
</section>
<template x-if="recently.hasNext()">
<div class = "flex flex-grow justify-center">
<button class = "tum-live-button tum-live-button-secondary" type="button" @click="recently.next()">
<div class="flex flex-grow justify-center">
<button class="tum-live-button tum-live-button-secondary" type="button"
@click="recently.next()">
<i class="fa-solid fa-angles-down mr-2"></i>
Next
</button>
Expand Down

0 comments on commit 069095b

Please sign in to comment.