feat: Video Trimmer and more

This commit is contained in:
Markos Gogoulos
2025-06-11 14:48:30 +03:00
committed by GitHub
parent d34fc328bf
commit b28c2d8271
124 changed files with 15696 additions and 586 deletions

View File

@@ -389,77 +389,39 @@
document.addEventListener('DOMContentLoaded', function() {
const breadcrumbItems = document.querySelectorAll('.breadcrumb-item a');
breadcrumbItems.forEach(function(link) {
if (link.getAttribute('href') === '/admin/account/') {
link.setAttribute('href', '/admin/users/');
link.textContent = 'Users';
}
if (link.getAttribute('href') === '/admin/rbac/') {
link.setAttribute('href', '/admin/users/');
link.textContent = 'Users';
}
});
const identityProvidersHeader = Array.from(document.querySelectorAll('.nav-header')).find(
header => header.textContent.trim() === 'Identity_Providers'
);
if (identityProvidersHeader) {
identityProvidersHeader.style.display = 'none';
const loginOptionsItem = document.querySelector('.nav-item a[href="/admin/identity_providers/loginoption/"]');
if (loginOptionsItem) {
loginOptionsItem.closest('.nav-item').style.display = 'none';
}
const userLogsItem = document.querySelector('.nav-item a[href="/admin/identity_providers/identityprovideruserlog/"]');
if (userLogsItem) {
userLogsItem.closest('.nav-item').style.display = 'none';
}
}
const tables = document.querySelectorAll('table.table-sm');
for (const table of tables) {
const userLink = table.querySelector('a[href="/admin/users/user/"]');
if (userLink) {
const tbody = table.querySelector('tbody');
if (tbody) {
const emailAddressesRow = document.createElement('tr');
emailAddressesRow.innerHTML = `
<td>
<a href="/admin/account/emailaddress/">Email Addresses</a>
</td>
<td>
<div class="btn-group float-right">
<a href="/admin/account/emailaddress/add/" class="btn btn-xs btn-success addlink">Add</a>
<a href="/admin/account/emailaddress/" class="btn btn-xs btn-info changelink">Change</a>
</div>
</td>
`;
const groupsRow = document.createElement('tr');
groupsRow.innerHTML = `
<td>
<a href="/admin/rbac/rbacgroup/">Groups</a>
</td>
<td>
<div class="btn-group float-right">
<a href="/admin/rbac/rbacgroup/add/" class="btn btn-xs btn-success addlink">Add</a>
<a href="/admin/rbac/rbacgroup/" class="btn btn-xs btn-info changelink">Change</a>
</div>
</td>
`;
tbody.appendChild(emailAddressesRow);
tbody.appendChild(groupsRow);
break;
}
}
}
});
</script>

View File

@@ -0,0 +1,82 @@
{% load crispy_forms_field %}
<style>
/* Form group styling */
.form-group {
margin-bottom: 1.5rem;
}
/* Control label container styling */
.control-label-container {
margin-bottom: 0.5rem;
}
/* Label styling */
.control-label {
display: flex;
align-items: baseline;
font-weight: bold;
font-size: 1rem;
}
/* Help text styling */
.help-text-inline {
font-size: 0.85rem;
color: #6c757d;
margin-left: 5px;
font-weight: normal;
}
/* Full width fields */
.controls.full-width input,
.controls.full-width textarea,
.controls.full-width select {
width: 100%;
}
/* Error styling */
.invalid-feedback {
color: #dc3545;
display: block;
margin-top: 0.25rem;
}
/* Button styling */
button[type="submit"],
input[type="submit"] {
background-color: #28a745;
border-color: #28a745;
color: white;
}
button[type="submit"]:hover,
input[type="submit"]:hover {
background-color: #218838;
border-color: #1e7e34;
}
</style>
<div class="form-group{% if field.errors %} has-error{% endif %}">
<div class="control-label-container">
{% if field.label %}
<label for="{{ field.id_for_label }}" class="control-label">
{{ field.label }}
{% if field.help_text %}
<span class="help-text-inline">- {{ field.help_text|safe }}</span>
{% endif %}
</label>
{% endif %}
</div>
<div class="controls {% if field.name == 'title' or field.name == 'new_tags' or field.name == 'description' %}full-width{% endif %}">
{% crispy_field field %}
{% if field.errors %}
<div class="error-container">
{% for error in field.errors %}
<p class="invalid-feedback">{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
</div>

View File

@@ -0,0 +1,44 @@
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load static %}
{% block headtitle %}Edit video chapters - {{PORTAL_NAME}}{% endblock headtitle %}
{% block topimports %}
<link href="{% static "video_editor/video-editor.css" %}" rel="preload" as="style">
<link href="{% static "video_editor/video-editor.css" %}" rel="stylesheet">
<script>
window.MEDIA_DATA = {
videoUrl: "",
mediaId: "{{ media_id }}",
chapters: [
{
id: "1",
title: "Chapter AAA",
timestamp: 0
},
{
id: "2",
title: "Chapter BBB",
timestamp: 10
},
{
id: "3",
title: "Chapter CCC",
timestamp: 20
}
]
};
</script>
<script src="{% static 'video_editor/video-editor.js' %}"></script>
{%endblock topimports %}
{% block innercontent %}
<div class="user-action-form-wrap">
{% include "cms/media_nav.html" with active_tab="chapters" %}
<div class="user-action-form-inner" style="max-width: 1280px; margin: 0 auto; padding: 20px; border-radius: 8px; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);">
<div id="video-editor-chapters-root"></div>
</div>
</div>
{% endblock innercontent %}

View File

@@ -7,16 +7,12 @@
{% block headermeta %}{% endblock headermeta %}
{% block innercontent %}
<div class="user-action-form-wrap">
<div class="user-action-form-inner">
<h1>Edit Media</h1>
<form enctype="multipart/form-data" action="" method="post" class="post-form">
<div class="user-action-form-wrap">
{% include "cms/media_nav.html" with active_tab="metadata" %}
<div style="max-width: 900px; margin: 0 auto; padding: 20px; border-radius: 8px; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);">
{% csrf_token %}
{{ form|crispy }}
<button class="primaryAction" type="submit">Update Media</button>
</form>
</div>
{% crispy form %}
</div>
</div>
{% endblock innercontent %}
{% endblock innercontent %}

View File

@@ -0,0 +1,33 @@
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load static %}
{% block headtitle %}Edit video - {{PORTAL_NAME}}{% endblock headtitle %}
{% block topimports %}
<link href="{% static "video_editor/video-editor.css" %}" rel="preload" as="style">
<link href="{% static "video_editor/video-editor.css" %}" rel="stylesheet">
<script src="{% static 'video_editor/video-editor.js' %}"></script>
<script>
window.MEDIA_DATA = {
videoUrl: "{{ media_file_path }}",
mediaId: "{{ media_object.friendly_token }}",
redirectURL: "{{ media_object.get_absolute_url }}",
redirectUserMediaURL: "{{ media_object.user.get_absolute_url }}"
};
</script>
{%endblock topimports %}
{% block innercontent %}
<div class="user-action-form-wrap">
{% include "cms/media_nav.html" with active_tab="trim" %}
<div class="user-action-form-inner" style="max-width: 1280px; margin: 0 auto; padding: 20px; border-radius: 8px; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);">
<div id="video-editor-trim-root"></div>
</div>
</div>
{% endblock innercontent %}

View File

@@ -0,0 +1,34 @@
<div class="media-edit-nav" style="background-color: #f0f0f0; padding: 10px 0; margin-bottom: 20px;">
<ul style="list-style: none; display: flex; justify-content: space-around; margin: 0; padding: 0;">
<li style="display: inline-block;">
<a href="{% url 'edit_media' %}?m={{media_object.friendly_token}}"
style="text-decoration: none; {% if active_tab == 'metadata' %}font-weight: bold; color: #333; padding-bottom: 3px; border-bottom: 2px solid #333;{% else %}color: #666;{% endif %}">
Metadata
</a>
</li>
{% if media_object.media_type == 'video' %}
<li style="display: inline-block;">
<a href="{% url 'edit_video' %}?m={{media_object.friendly_token}}"
style="text-decoration: none; {% if active_tab == 'trim' %}font-weight: bold; color: #333; padding-bottom: 3px; border-bottom: 2px solid #333;{% else %}color: #666;{% endif %}">
Trim
</a>
</li>
{% comment %}
<li style="display: inline-block;">
<a href="{% url 'edit_chapters' %}?m={{media_object.friendly_token}}"
style="text-decoration: none; {% if active_tab == 'chapters' %}font-weight: bold; color: #333; padding-bottom: 3px; border-bottom: 2px solid #333;{% else %}color: #666;{% endif %}">
Chapters
</a>
</li>
{% endcomment %}
{% endif %}
<li style="display: inline-block;">
<a href="{% url 'publish_media' %}?m={{media_object.friendly_token}}"
style="text-decoration: none; {% if active_tab == 'publish' %}font-weight: bold; color: #333; padding-bottom: 3px; border-bottom: 2px solid #333;{% else %}color: #666;{% endif %}">
Publish
</a>
</li>
</ul>
</div>

View File

@@ -0,0 +1,17 @@
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load static %}
{% block headtitle %}Publish media - {{PORTAL_NAME}}{% endblock headtitle %}
{% block headermeta %}{% endblock headermeta %}
{% block innercontent %}
<div class="user-action-form-wrap">
{% include "cms/media_nav.html" with active_tab="publish" %}
<div style="max-width: 900px; margin: 0 auto; padding: 20px; border-radius: 8px; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);">
{% csrf_token %}
{% crispy form %}
</div>
</div>
{% endblock innercontent %}

View File

@@ -9,7 +9,7 @@
{% include "common/head-meta.html" %}
{% block headermeta %}
<meta property="og:title" content="{{PORTAL_NAME}}">
<meta property="og:type" content="website">
@@ -22,6 +22,16 @@
{% block topimports %}{%endblock topimports %}
{% include "config/index.html" %}
{% if not USE_ROUNDED_CORNERS %}
<style>
.viewer-container .player-container, .item-thumb, a.item-thumb {
border-radius: revert !important;
}
</style>
{% endif %}
{% endblock head %}