Skip to content

Commit

Permalink
Merge branch 'dev' into improvement/refactor-course-mgmt
Browse files Browse the repository at this point in the history
  • Loading branch information
mono424 committed Sep 11, 2023
2 parents 0a65347 + 8170ab5 commit 1b97d1a
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 64 deletions.
2 changes: 1 addition & 1 deletion dao/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (d chatDao) GetReactions(chatID uint) ([]model.ChatReaction, error) {
func (d chatDao) GetVisibleChats(userID uint, streamID uint) ([]model.Chat, error) {
var chats []model.Chat
query := DB.
Preload("Replies").
Preload("Replies", "(visible = 1) OR (user_id = ?)", userID).
Preload("Reactions").
Preload("AddressedToUsers").
Where("(visible = 1) OR (user_id = ?)", userID).
Expand Down
41 changes: 26 additions & 15 deletions web/template/components/chat.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@
<span x-show="m.admin"
class="fa-video text-white bg-red-400 p-1 rounded fas"></span>
<span class="text-2 font-semibold" x-text="m.name" :style="'color:'+m.color"></span>
<span x-show="!m.visible" class="text-5 font-light">
This message is currently only visible to you and admins.
</span>
<span x-show="!m.visible" class="text-5 font-light">This message is currently only visible to you and admins.</span>
</div>
<div class="relative group p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-600">
<div class="flex justify-between">
Expand Down Expand Up @@ -190,26 +188,39 @@


<!-- replies -->
<div x-cloak x-show="m.ShowReplies.value"
class="grid gap-y-3 py-1 pl-2 mt-2 ml-4 border-l-2 dark:border-secondary-light">
<article x-cloak x-show="m.ShowReplies.value"
class="grid gap-y-3 py-1 pl-2 mt-2 ml-4 border-l-2 dark:border-secondary-light">
<template x-for="reply in m.replies">
<div class="grid gap-y-1">
<section class="grid gap-y-1">
<div>
<span x-show="reply.admin"
class="text-white bg-red-400 p-1 text-xs rounded fas fa-video"></span>
<span x-show="reply.admin"
class="text-white bg-red-400 p-1 text-xs rounded fas fa-video"></span>
<span class="text-2 font-semibold" x-text="reply.name"
:style="'color:'+reply.color"></span>
<span x-show="!reply.visible" class="text-xs text-5 font-light">This message is currently only visible to you and admins.</span>
</div>
<div class="group p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
<div class="flex justify-between">
<span class="w-5/6 overflow-wrap-anywhere my-auto" x-html="reply.message"></span>
<span class="hidden group-hover:inline text-xs text-5 font-light mt-auto"
x-text="reply.friendlyCreatedAt()"></span>
<div class="flex">
<div class="group p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 flex-grow">
<div class="flex justify-between">
<span class="w-5/6 overflow-wrap-anywhere my-auto" x-html="reply.message"></span>
<span class="hidden group-hover:inline text-xs text-5 font-light mt-auto"
x-text="reply.friendlyCreatedAt()"></span>
</div>
</div>
{{if $course.ModeratedChatEnabled}}
<template x-if="isAdmin()">
<button x-cloak x-show="!reply.visible"
@click="approveMessage(reply.ID)"
title="Approve Message"
class="tum-live-icon-button shrink mx-2">
<i class="fa-solid fa-spell-check"></i>
</button>
</template>
{{end}}
</div>
</div>
</section>
</template>
</div>
</article>
</section>
</template>
</div>
Expand Down
8 changes: 4 additions & 4 deletions web/template/home.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -431,18 +431,18 @@
</header>
<section>
<template x-if="courseStreams.hasElements()">
<article class="flex flex-col" :class="{'flex-col-reverse' : !isOldestFirst() }">
<article class="grid">
<template
x-for="[m, streams] of Object.entries(courseStreams.get(sortFn(streamSortMode), filterPred(streamFilterMode)))">
x-for="group in courseStreams.get(sortFn(streamSortMode), filterPred(streamFilterMode))">
<article class="mb-8">
<header class="mb-2">
<h6 class="font-semibold" x-text="getMonthName(m)"></h6>
<h6 class="font-semibold" x-text="group[0].GetMonthName()"></h6>
</header>
<section class="grid gap-3 md:grid-cols-2 grid-cols-1"
:class="plannedStreams.hasElements()
? 'xl:grid-cols-4 lg:grid-cols-3'
: 'xl:grid-cols-5 lg:grid-cols-4'">
<template x-for="vod in streams" :key="vod.ID">
<template x-for="vod in group" :key="vod.ID">
<article
class="tum-live-stream group sm:col-span-1 col-span-full"
@click.outside="vod.Dropdown.toggle(false)">
Expand Down
7 changes: 7 additions & 0 deletions web/ts/api/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ export class ChatMessageArray {
this.messages = filtered;
}

approveReply(m: ChatMessage) {
const base = this.messages.find((msg) => msg.ID === m.replyTo.Int64);
const filtered = base.replies.filter((msg) => msg.ID !== m.ID);
filtered.push(Object.assign(new ChatMessage(), m));
base.replies = filtered;
}

retract(msg: ChatMessage, isAdmin: boolean) {
if (isAdmin) {
this.messages.find((m) => m.ID === msg.ID).visible = false;
Expand Down
33 changes: 25 additions & 8 deletions web/ts/api/courses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ export class Stream implements Identifiable {
});
}

public MonthOfStart(): string {
return new Date(this.Start).toLocaleString("default", { month: "short" });
public StartDate(): Date {
return new Date(this.Start);
}

public NumericMonthOfStart(): number {
return new Date(this.Start).getMonth() + 1;
public MonthOfStart(): string {
return this.StartDate().toLocaleString("default", { month: "short" });
}

public DayOfStart(): number {
return new Date(this.Start).getDate();
return this.StartDate().getDate();
}

public TimeOfStart(): string {
Expand All @@ -63,11 +63,11 @@ export class Stream implements Identifiable {
}

public IsToday(): boolean {
return same_day(new Date(this.Start), new Date());
return same_day(this.StartDate(), new Date());
}

public MinutesLeftToStart(): number {
return Math.round((new Date(this.Start).valueOf() - new Date().valueOf()) / 60000);
return Math.round((this.StartDate().valueOf() - new Date().valueOf()) / 60000);
}

public DurationString() {
Expand All @@ -86,7 +86,7 @@ export class Stream implements Identifiable {
}

public CompareStart(other: Stream) {
const a = new Date(this.Start);
const a = this.StartDate();
const b = new Date(other.Start);
if (a < b) {
return 1;
Expand All @@ -101,6 +101,23 @@ export class Stream implements Identifiable {
this.Thumbnail.src = `/api/stream/${this.ID}/thumbs/vod`;
}

public GetMonthName(): string {
return [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
][this.StartDate().getMonth()];
}

private static TimeOf(d: string): string {
return new Date(d).toLocaleTimeString("default", { hour: "2-digit", minute: "2-digit" });
}
Expand Down
3 changes: 2 additions & 1 deletion web/ts/components/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ export function chatContext(streamId: number, user: User, isRecording: boolean):

handleApprove(msg: ChatMessage) {
this.preprocessors.forEach((f) => f(msg, this.user));
this.messages.approve(msg);
if (msg.replyTo.Valid) this.messages.approveReply(msg);
else this.messages.approve(msg);
},

handleRetract(msg: ChatMessage) {
Expand Down
21 changes: 2 additions & 19 deletions web/ts/components/course.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function courseContext(slug: string, year: number, term: string, userId:

course: new Course() as Course,

courseStreams: new GroupedSmartArray<Stream, number>([], (_) => 0),
courseStreams: new GroupedSmartArray<Stream, number>(),
plannedStreams: new Paginator<Stream>([], 3),
upcomingStreams: new Paginator<Stream>([], 3),

Expand Down Expand Up @@ -64,7 +64,7 @@ export function courseContext(slug: string, year: number, term: string, userId:
this.upcomingStreams.set(this.course.Upcoming).reset();
this.loadProgresses(this.course.Recordings.map((s: Stream) => s.ID)).then((progresses) => {
this.course.Recordings.forEach((s: Stream, i) => (s.Progress = progresses[i]));
this.courseStreams.set(this.course.Recordings, (s: Stream) => s.NumericMonthOfStart());
this.courseStreams.set(this.course.Recordings, (s: Stream) => s.StartDate().getMonth());
});
console.log("🌑 init course", this.course);
});
Expand Down Expand Up @@ -135,23 +135,6 @@ export function courseContext(slug: string, year: number, term: string, userId:
dropdown.toggle(false);
},

getMonthName(m: number): string {
return [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
][m - 1];
},

async loadCourse() {
this.course = await CoursesAPI.get(this.slug, this.year, this.term, this.userId);
},
Expand Down
38 changes: 22 additions & 16 deletions web/ts/utilities/smartarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,18 @@ export class SmartArray<T> {
}
}

export class GroupedSmartArray<T, K extends keyof never> {
export class GroupedSmartArray<T, K> {
private list: T[];
private key: (i: T) => K;

constructor(list: T[], key: (i: T) => K) {
this.list = list;
this.key = key;
constructor() {
this.list = [];
}

get(sortFn?: CompareFunction<T>, filterPred?: FilterPredicate<T>) {
const copy = filterPred ? [...this.list].filter(filterPred) : [...this.list];
const _list = sortFn ? copy.sort(sortFn) : copy;
return groupBy(_list, this.key);
return this.group(_list, this.key);
}

set(list: T[], key: (i: T) => K): GroupedSmartArray<T, K> {
Expand All @@ -49,18 +48,25 @@ export class GroupedSmartArray<T, K extends keyof never> {
hasElements() {
return this.list.length > 0;
}

private group(list: T[], key: (i: T) => K) {
const groups = [];

let lastKey = null;
let currentGroup = [];

list.forEach((l) => {
if (lastKey !== null && key(l) != lastKey) {
groups.push(currentGroup);
currentGroup = [];
}
currentGroup.push(l);
lastKey = key(l);
});
groups.push(currentGroup);
return groups;
}
}

export type CompareFunction<T> = (a: T, b: T) => number;
export type FilterPredicate<T> = (o: T) => boolean;

/* eslint-disable */
function groupBy<T, K extends keyof never>(list: T[], getKey: (item: T) => K) {
/* eslint-disable */
return list.reduce(function (previous, currentItem) {
const group = getKey(currentItem);
if (!previous[group]) previous[group] = [];
previous[group].push(currentItem);
return previous;
}, {} as Record<K, T[]>);
}

0 comments on commit 1b97d1a

Please sign in to comment.