Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement/refactor course sections #1156

Merged
merged 71 commits into from
Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
84d18ee
started wit hrefactor of course management
mono424 Aug 23, 2023
eb2fcd7
Merge branch 'dev' into improvement/refactor-course-mgmt
mono424 Aug 28, 2023
429ad67
add dao & route
mono424 Aug 28, 2023
d1ea050
update route
mono424 Aug 28, 2023
8aa4d69
started wit hfetching
mono424 Aug 28, 2023
db3f3bb
Add changeset abstraction
mono424 Aug 28, 2023
0225a59
cleanup file
mono424 Aug 28, 2023
29c0977
remove get all streams again, as there is AdminJson method
mono424 Aug 28, 2023
0f32725
Its rendering
mono424 Aug 28, 2023
797d00d
further dev :S
mono424 Aug 28, 2023
17f460a
added some directive
mono424 Aug 28, 2023
ca9c567
little fixes
mono424 Aug 28, 2023
246fa48
...
mono424 Aug 28, 2023
1e66fc9
... no idea...
mono424 Aug 28, 2023
e36890d
right path i guess
mono424 Aug 29, 2023
fcf15c2
changeset working except video sections
mono424 Aug 29, 2023
e576712
fix discard files
mono424 Aug 29, 2023
c25956a
save from laptop
mono424 Sep 3, 2023
5102141
Add changeset doku
mono424 Sep 3, 2023
7518b5d
make private works like charm
mono424 Sep 3, 2023
8416d26
changing works pretty well
mono424 Sep 3, 2023
8afb2b9
add video upload
mono424 Sep 3, 2023
f4a005f
add series update
mono424 Sep 3, 2023
a258dc5
ported transcoding
mono424 Sep 3, 2023
184b0aa
add readme and lecture hall select
mono424 Sep 5, 2023
81e783d
more description
mono424 Sep 5, 2023
cffbf3e
simplified lecture hall set
mono424 Sep 5, 2023
5548883
Merge branch 'dev' into improvement/refactor-course-mgmt
mono424 Sep 5, 2023
2db8643
linter
mono424 Sep 5, 2023
098b2d5
more fixes
mono424 Sep 5, 2023
91f80cf
:)
mono424 Sep 5, 2023
b224222
add attachments
mono424 Sep 10, 2023
0a65347
:)
mono424 Sep 10, 2023
1b97d1a
Merge branch 'dev' into improvement/refactor-course-mgmt
mono424 Sep 11, 2023
74b180d
add video sections to admin streams
mono424 Sep 11, 2023
85a17f5
main functionality
mono424 Sep 11, 2023
f21f0db
using fetch wrtappers
mono424 Sep 14, 2023
0b939c6
moved uploadFile and postFormData
mono424 Sep 14, 2023
09105a4
Merge branch 'dev' into improvement/refactor-course-sections
mono424 Sep 14, 2023
df179a7
fix linteer
mono424 Sep 14, 2023
4408da4
Impl. Feedback
mono424 Sep 14, 2023
394218e
add video sections to admin streams
mono424 Sep 11, 2023
61b36b5
main functionality
mono424 Sep 11, 2023
f78c548
using fetch wrtappers
mono424 Sep 14, 2023
74cd080
moved uploadFile and postFormData
mono424 Sep 14, 2023
a6cf16e
version workers with tag (#1157)
joschahenningsen Sep 13, 2023
f1ad4a0
fix linteer
mono424 Sep 14, 2023
bf11272
Merge branch 'improvement/refactor-course-sections' of github.com:jos…
mono424 Sep 14, 2023
859555c
fix delete lecture
mono424 Sep 14, 2023
d375cf7
reenable page reload on create
mono424 Sep 14, 2023
8755076
Merge branch 'improvement/refactor-course-mgmt' into improvement/refa…
mono424 Sep 15, 2023
1b1b1ab
some linter fixes
mono424 Sep 15, 2023
b996d07
fix merge complications
mono424 Sep 15, 2023
7bb8870
fix changeset; adding onchange listener
mono424 Sep 15, 2023
8c132ec
fixed adding sections
mono424 Sep 15, 2023
6c57fa0
added directives
mono424 Sep 15, 2023
8090778
fix typo
mono424 Sep 15, 2023
c810b4c
improved directives
mono424 Sep 15, 2023
96ba056
design improvement
mono424 Sep 15, 2023
44d2031
fixed creating and deleting
mono424 Sep 15, 2023
2ebd58a
add sections fixed
mono424 Sep 15, 2023
738087a
cleanup
mono424 Sep 15, 2023
f11c393
:)
mono424 Sep 15, 2023
0beec3a
fix alpine js error issues
mono424 Sep 15, 2023
7e63051
remoev console log
mono424 Sep 15, 2023
a50db12
nested :)
mono424 Sep 15, 2023
0da5f03
remove console log
mono424 Sep 15, 2023
6a181d2
lint-fix
mono424 Sep 15, 2023
cc9f2d0
Merge branch 'dev' into improvement/refactor-course-sections
mono424 Sep 21, 2023
3616440
Merge branch 'dev' into improvement/refactor-course-sections
joschahenningsen Sep 29, 2023
4958d64
fix admin.LectureList initialisation in settings tab
joschahenningsen Sep 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions api/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import (
"strings"
"time"

"github.com/getsentry/sentry-go"
"github.com/gin-gonic/gin"
"github.com/TUM-Dev/gocast/dao"
"github.com/TUM-Dev/gocast/model"
"github.com/TUM-Dev/gocast/tools"
"github.com/TUM-Dev/gocast/tools/bot"
"github.com/TUM-Dev/gocast/voice-service/pb"
"github.com/getsentry/sentry-go"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
log "github.com/sirupsen/logrus"
"gorm.io/gorm"
Expand Down Expand Up @@ -496,6 +496,8 @@ func (r streamRoutes) createVideoSectionBatch(c *gin.Context) {
log.WithError(err).Error("failed to generate video section images")
}
}()

c.JSON(http.StatusOK, sections)
}

type UpdateVideoSectionRequest struct {
Expand Down
3 changes: 2 additions & 1 deletion dao/courses.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ func (d coursesDao) GetCourseByToken(token string) (course model.Course, err err
func (d coursesDao) GetCourseById(ctx context.Context, id uint) (course model.Course, err error) {
var foundCourse model.Course
dbErr := DB.Preload("Streams.TranscodingProgresses").
Preload("Streams.VideoSections").
Preload("Streams.Files").
Preload("Streams", func(db *gorm.DB) *gorm.DB {
return db.Order("streams.start desc")
Expand All @@ -218,7 +219,7 @@ func (d coursesDao) GetCourseBySlugYearAndTerm(ctx context.Context, slug string,
return cachedCourses.(model.Course), nil
}
var course model.Course
err := DB.Preload("Streams.Units", func(db *gorm.DB) *gorm.DB {
err := DB.Preload("Streams.VideoSections").Preload("Streams.Units", func(db *gorm.DB) *gorm.DB {
return db.Order("unit_start desc")
}).Preload("Streams", func(db *gorm.DB) *gorm.DB {
return db.Order("start desc")
Expand Down
13 changes: 13 additions & 0 deletions model/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,18 @@ func (s Stream) getJson(lhs []LectureHall, course Course) gin.H {
}
}

var videoSections []gin.H
for _, section := range s.VideoSections {
videoSections = append(videoSections, gin.H{
"id": section.ID,
"description": section.Description,
"startHours": section.StartHours,
"startMinutes": section.StartMinutes,
"startSeconds": section.StartSeconds,
"fileID": section.FileID,
})
}

return gin.H{
"lectureId": s.Model.ID,
"courseId": s.CourseID,
Expand All @@ -346,6 +358,7 @@ func (s Stream) getJson(lhs []LectureHall, course Course) gin.H {
"courseSlug": course.Slug,
"private": s.Private,
"downloadableVods": s.GetVodFiles(),
"videoSections": videoSections,
}
}

Expand Down
106 changes: 100 additions & 6 deletions web/assets/init-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ document.addEventListener("alpine:init", () => {
'color'
];

const nativeEventName = "csupdate";

const convert = (modifiers, value) => {
if (modifiers.includes("int")) {
return parseInt(value);
Expand Down Expand Up @@ -79,7 +81,6 @@ document.addEventListener("alpine:init", () => {
Alpine.directive("bind-change-set", (el, { expression, value, modifiers }, { evaluate, cleanup }) => {
const changeSet = evaluate(expression);
const fieldName = value || el.name;
const nativeEventName = "csupdate";

if (el.type === "file") {
const isSingle = modifiers.includes("single")
Expand All @@ -92,7 +93,7 @@ document.addEventListener("alpine:init", () => {
if (!data[fieldName]) {
el.value = "";
}
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: data[fieldName] }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value: data[fieldName] } }));
};

changeSet.listen(onChangeSetUpdateHandler);
Expand All @@ -109,7 +110,7 @@ document.addEventListener("alpine:init", () => {

const onChangeSetUpdateHandler = (data) => {
el.checked = !!data[fieldName];
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: !!data[fieldName] }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value: !!data[fieldName] }}));
};

changeSet.listen(onChangeSetUpdateHandler);
Expand All @@ -122,26 +123,29 @@ document.addEventListener("alpine:init", () => {
})
} else if (el.tagName === "textarea" || textInputTypes.includes(el.type)) {
const keyupHandler = (e) => changeSet.patch(fieldName, convert(modifiers, e.target.value));
const changeHandler = (e) => changeSet.patch(fieldName, convert(modifiers, e.target.value));

const onChangeSetUpdateHandler = (data) => {
el.value = `${data[fieldName]}`;
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: data[fieldName] }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value: data[fieldName] } }));
};

changeSet.listen(onChangeSetUpdateHandler);
el.addEventListener('keyup', keyupHandler)
el.addEventListener('keyup', keyupHandler);
el.addEventListener('change', changeHandler);
el.value = `${changeSet.get()[fieldName]}`;

cleanup(() => {
changeSet.removeListener(onChangeSetUpdateHandler);
el.removeEventListener('keyup', keyupHandler)
el.removeEventListener('change', changeHandler)
})
} else {
const changeHandler = (e) => changeSet.patch(fieldName, convert(modifiers, e.target.value));

const onChangeSetUpdateHandler = (data) => {
el.value = `${data[fieldName]}`;
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: data[fieldName] }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value: data[fieldName] } }));
};

changeSet.listen(onChangeSetUpdateHandler);
Expand All @@ -154,4 +158,94 @@ document.addEventListener("alpine:init", () => {
})
}
});

/**
* Alpine.js directive for dynamically triggering a custom event and updating an element's inner text
* based on changes to a "change set" object's field.
*
* Syntax:
* <div x-change-set-listen.text="changeSetExpression.fieldName"></div>
*
* Parameters:
* - changeSetExpression: The JavaScript expression evaluating to the change set object
* - fieldName: The specific field within the change set to monitor for changes
*
* Modifiers:
* - "text": When provided, the directive will also update the element's innerText.
*
* Custom Events:
* - "csupdate": Custom event triggered when the change set is updated.
* The detail property of the event object contains the new value of the specified field.
*/
Alpine.directive("change-set-listen", (el, { expression, modifiers }, { effect, evaluate, cleanup }) => {
effect(() => {
const [changeSetExpression, fieldName = null] = expression.split(".");
const changeSet = evaluate(changeSetExpression);

const onChangeSetUpdateHandler = (data) => {
const value = fieldName != null ? data[fieldName] : data;
if (modifiers.includes("text")) {
el.innerText = `${value}`;
}
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value } }));
};

if (!changeSet) {
return;
}

changeSet.removeListener(onChangeSetUpdateHandler);
onChangeSetUpdateHandler(changeSet.get());
changeSet.listen(onChangeSetUpdateHandler);

cleanup(() => {
changeSet.removeListener(onChangeSetUpdateHandler);
})
});
});

/**
* Alpine.js directive for executing custom logic in response to the "csupdate" event,
* which is usually triggered by changes in a "change set" object's field.
*
* Syntax:
* <div x-on-change-set-update="[expression]"></div>
*
* Parameters:
* - expression: The JavaScript expression to be evaluated when the "csupdate" event is triggered.
*
* Modifiers:
* - "init": When provided, the directive will execute the expression during initialization (no matter if its dirty or clean).
* - "clean": When provided, the directive will only execute if changeSet is not dirty.
* - "dirty": When provided, the directive will only execute if changeSet is dirty.
*
* Example usage:
* <div x-change-set-listen="sectionEditChangeSet"
* x-on-change-set-update.init="$el.innerText = friendlySectionTimestamp(sectionEditChangeSet.get())">
* </div>
*/
Alpine.directive("on-change-set-update", (el, { expression, modifiers }, { evaluate, evaluateLater, cleanup }) => {
const onUpdate = evaluateLater(expression);

const onChangeSetUpdateHandler = (e) => {
const isDirty = e.detail.changeSet.isDirty();

if (modifiers.includes("clean") && isDirty) {
return;
}
if (modifiers.includes("dirty") && !isDirty) {
return;
}
onUpdate();
};
el.addEventListener(nativeEventName, onChangeSetUpdateHandler);

if (modifiers.includes("init")) {
evaluate(expression);
}

cleanup(() => {
el.removeEventListener(nativeEventName, onChangeSetUpdateHandler);
})
})
});
2 changes: 1 addition & 1 deletion web/template/partial/course/manage/course_settings.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
}">
<form class="form-container-body" id="course-settings-form" method="post" @submit.prevent="
async () => {
if(admin.LectureList.hasIndividualChatEnabledSettings()){
if((new admin.LectureList({{.ID}})).hasIndividualChatEnabledSettings()){
showCourseSettingsModal = true;
}
else{
Expand Down
Loading
Loading