From 473c16d813fa72d37f80fe658f1dad5e0a858a6b Mon Sep 17 00:00:00 2001 From: cuom1999 Date: Mon, 24 Jun 2024 14:56:00 -0500 Subject: [PATCH] Refactor 3-col-content --- django_ace/widgets.py | 2 +- judge/views/organization.py | 10 +- resources/base.scss | 10 - resources/common.js | 309 ++++++++++++------ resources/html/loading-page.html | 24 +- templates/base.html | 27 +- templates/blog/blog.html | 5 - templates/blog/list.html | 2 +- templates/chat/chat.html | 7 +- templates/chat/chat_js.html | 12 +- templates/comments/math.html | 3 - templates/contest/contest.html | 2 +- templates/contest/list.html | 3 +- templates/contest/moss.html | 2 +- templates/contest/stats.html | 2 +- templates/course/edit_lesson.html | 2 +- templates/course/grades.html | 2 +- templates/internal/problem/problem.html | 2 +- templates/organization/add.html | 2 +- templates/organization/blog/add.html | 2 +- templates/organization/blog/edit.html | 2 +- templates/organization/contest/add.html | 2 +- templates/organization/contest/edit.html | 2 +- templates/organization/home-base.html | 2 +- templates/organization/home-js.html | 10 +- templates/organization/list.html | 5 +- templates/organization/org-right-sidebar.html | 2 +- templates/problem/editorial.html | 6 +- templates/problem/list-base.html | 2 +- templates/problem/problem.html | 5 - templates/submission/list.html | 2 +- templates/tabs-base.html | 4 +- templates/three-column-content.html | 89 ----- templates/ticket/ticket.html | 5 - templates/two-column-content.html | 4 - templates/user/base-users-two-col.html | 2 +- templates/user/user-base.html | 2 +- templates/user/user-tabs.html | 8 +- 38 files changed, 307 insertions(+), 277 deletions(-) delete mode 100644 templates/comments/math.html diff --git a/django_ace/widgets.py b/django_ace/widgets.py index ec4df402..659ec759 100644 --- a/django_ace/widgets.py +++ b/django_ace/widgets.py @@ -66,7 +66,7 @@ def render(self, name, value, attrs=None, renderer=None): if self.toolbar: toolbar = ( '
' - '' + '' "
" ).format(self.width) html = toolbar + html diff --git a/judge/views/organization.py b/judge/views/organization.py index 54d6adbb..0a3fc316 100644 --- a/judge/views/organization.py +++ b/judge/views/organization.py @@ -671,21 +671,13 @@ class OrganizationRequestBaseView( LoginRequiredMixin, SingleObjectTemplateResponseMixin, SingleObjectMixin, + AdminOrganizationMixin, ): model = Organization slug_field = "key" slug_url_kwarg = "key" tab = None - def get_object(self, queryset=None): - organization = super(OrganizationRequestBaseView, self).get_object(queryset) - if not ( - organization.admins.filter(id=self.request.profile.id).exists() - or organization.registrant_id == self.request.profile.id - ): - raise PermissionDenied() - return organization - def get_content_title(self): return _("Manage join requests") diff --git a/resources/base.scss b/resources/base.scss index 79452fcb..5e34d9f6 100644 --- a/resources/base.scss +++ b/resources/base.scss @@ -806,16 +806,6 @@ noscript #noscript { margin-bottom: 1em; } -#loading-bar { - position: fixed; - top: 0; - left: 0; - height: 2px; - background-color: $theme_color; - width: 0; - z-index: 9999; -} - .nav-right-text { font-weight: normal; font-size: small; diff --git a/resources/common.js b/resources/common.js index 1e4c76dc..aaaceec4 100644 --- a/resources/common.js +++ b/resources/common.js @@ -386,44 +386,215 @@ function activateBlogBoxOnClick() { } function changeTabParameter(newTab) { - const url = new URL(window.location); - const searchParams = new URLSearchParams(url.search); - searchParams.set('tab', newTab); - searchParams.delete('page'); - url.search = searchParams.toString(); - return url.href; + const url = new URL(window.location); + const searchParams = new URLSearchParams(url.search); + searchParams.set('tab', newTab); + searchParams.delete('page'); + url.search = searchParams.toString(); + return url.href; } function submitFormWithParams($form, method) { - const currentUrl = new URL(window.location.href); - const searchParams = new URLSearchParams(currentUrl.search); - const formData = $form.serialize(); - - const params = new URLSearchParams(formData); - - if (searchParams.has('tab')) { - params.set('tab', searchParams.get('tab')); - } - - const fullUrl = currentUrl.pathname + '?' + params.toString(); - - if (method === "GET") { - window.location.href = fullUrl; - } - else { - var $formToSubmit = $('
') - .attr('action', fullUrl) - .attr('method', 'POST') - .appendTo('body'); - - $formToSubmit.append($('').attr({ - type: 'hidden', - name: 'csrfmiddlewaretoken', - value: $.cookie('csrftoken') - })); - - $formToSubmit.submit(); - } + const currentUrl = new URL(window.location.href); + const searchParams = new URLSearchParams(currentUrl.search); + const formData = $form.serialize(); + + const params = new URLSearchParams(formData); + + if (searchParams.has('tab')) { + params.set('tab', searchParams.get('tab')); + } + + const fullUrl = currentUrl.pathname + '?' + params.toString(); + + if (method === "GET") { + window.location.href = fullUrl; + } + else { + var $formToSubmit = $('') + .attr('action', fullUrl) + .attr('method', 'POST') + .appendTo('body'); + + $formToSubmit.append($('').attr({ + type: 'hidden', + name: 'csrfmiddlewaretoken', + value: $.cookie('csrftoken') + })); + + $formToSubmit.submit(); + } +} + +function saveCurrentPageToSessionStorage() { + const storageLimit = 5; + const sessionStorageKey = 'oj-content-keys'; + + let key = `oj-content-${window.location.href}`; + let $contentClone = $('body').clone(); + $contentClone.find('.select2').remove(); + $contentClone.find('.select2-hidden-accessible').removeClass('select2-hidden-accessible'); + $contentClone.find('.noUi-base').remove(); + $contentClone.find('.wmd-button-row').remove(); + + let contentData = JSON.stringify({ + "html": $contentClone.html(), + "page": window.page, + "has_next_page": window.has_next_page, + "scrollOffset": $(window).scrollTop(), + }); + + let keys = JSON.parse(sessionStorage.getItem(sessionStorageKey)) || []; + + // Remove the existing key if it exists + if (keys.includes(key)) { + keys = keys.filter(k => k !== key); + } + + keys.push(key); + + if (keys.length > storageLimit) { + let oldestKey = keys.shift(); + sessionStorage.removeItem(oldestKey); + } + + sessionStorage.setItem(sessionStorageKey, JSON.stringify(keys)); + sessionStorage.setItem(key, contentData); +} + +function loadPageFromSessionStorage() { + let key = `oj-content-${window.location.href}`; + let content = sessionStorage.getItem(key); + if (content) { + content = JSON.parse(content); + $('body').html(content.html); + onWindowReady(); + window.PAGE_FROM_BACK_BUTTON_CACHE = true; + setTimeout(() => { + $(window).scrollTop(content.scrollOffset - 50); + }, 1); + window.page = content.page; + window.has_next_page = content.has_next_page; + } +} + +let currentRequest = null; // Variable to keep track of the current request + +function navigateTo(url, reload_container, force_new_page=false) { + if (url === '#') return; + if (force_new_page) { + window.location.href = url; + return; + } + + if (!reload_container || !$(reload_container).length) { + reload_container = "#content"; + } + + if (currentRequest) { + currentRequest.abort(); + } + + const controller = new AbortController(); + const signal = controller.signal; + currentRequest = controller; + + $(window).off("scroll"); + + saveCurrentPageToSessionStorage(); + replaceLoadingPage(reload_container); + + const toUpdateElements = [ + "#nav-container", + "#js_media", + "#media", + ".left-sidebar", + "#bodyend", + ]; + + $.ajax({ + url: url, + method: 'GET', + dataType: 'html', + signal: signal, + success: function (data) { + let reload_content = $(data).find(reload_container).first(); + if (!reload_content.length) { + reload_container = "#content"; + reload_content = $(data).find(reload_container).first(); + } + + if (reload_content.length) { + window.history.pushState("", "", url); + $(window).scrollTop(0); + + $(reload_container).replaceWith(reload_content); + + for (let elem of toUpdateElements) { + $(elem).replaceWith($(data).find(elem).first()); + } + $(document).prop('title', $(data).filter('title').text()); + renderKatex($(reload_container)[0]); + onWindowReady(); + $('.xdsoft_datetimepicker').hide(); + } else { + window.location.href = url; + } + }, + error: function (xhr, status, error) { + if (status !== 'abort') { // Ignore aborted requests + window.location.href = url; + } + } + }); +} + +function isEligibleLinkToRegister($e) { + if ($e.attr('target') === '_blank') { + return false; + } + if ($e.data('initialized_navigation')) { + return false; + } + const href = $e.attr('href'); + if (!href) return false; + return ( + href.startsWith('http') + || href.startsWith('/') + || href.startsWith('#') + || href.startsWith('?') + ); +}; + +function registerNavigation() { + const containerMap = { + '.left-sidebar-item': '.middle-right-content', + '.pagination li a': '.middle-content', + '.user-content .tabs li a': '.user-content', + '.tabs li a': '.middle-content', + '#control-panel a': '.middle-content', + }; + + $('a').each(function() { + const href = $(this).attr('href'); + const force_new_page = $(this).data('force_new_page'); + + if (isEligibleLinkToRegister($(this))) { + $(this).data('initialized_navigation', true); + + $(this).on('click', function(e) { + e.preventDefault(); + let containerSelector = null; + for (let key in containerMap) { + if ($(this).is(key)) { + containerSelector = containerMap[key]; + break; + } + } + navigateTo(href, containerSelector, force_new_page); + }); + } + }); } function onWindowReady() { @@ -523,12 +694,6 @@ function onWindowReady() { ) { return; } - - $("#loading-bar").show(); - $("#loading-bar").animate({ width: "100%" }, 2000, function() { - $(this).stop(true, true); - $(this).hide().css({ width: 0}); - }); }); $('.errorlist').each(function() { @@ -537,12 +702,13 @@ function onWindowReady() { }); register_all_toggles(); activateBlogBoxOnClick(); + registerNavigation(); + registerPopper($('#nav-lang-icon'), $('#lang-dropdown')); + registerPopper($('#user-links'), $('#userlink_dropdown')); } $(function() { onWindowReady(); - registerPopper($('#nav-lang-icon'), $('#lang-dropdown')); - registerPopper($('#user-links'), $('#userlink_dropdown')); var $nav_list = $('#nav-list'); $('#navicon').click(function (event) { event.stopPropagation(); @@ -582,54 +748,13 @@ $(function() { $nav_list.hide(); }); - $(window).on('beforeunload', function() { - const storageLimit = 5; - const sessionStorageKey = 'oj-content-keys'; - - let key = `oj-content-${window.location.href}`; - let $contentClone = $('#content').clone(); - $contentClone.find('.select2').remove(); - $contentClone.find('.select2-hidden-accessible').removeClass('select2-hidden-accessible'); - $contentClone.find('.noUi-base').remove(); - $contentClone.find('.wmd-button-row').remove(); - - let contentData = JSON.stringify({ - "html": $contentClone.html(), - "page": window.page, - "has_next_page": window.has_next_page, - "scrollOffset": $(window).scrollTop(), - }); - - let keys = JSON.parse(sessionStorage.getItem(sessionStorageKey)) || []; - - // Remove the existing key if it exists - if (keys.includes(key)) { - keys = keys.filter(k => k !== key); - } - - keys.push(key); - - if (keys.length > storageLimit) { - let oldestKey = keys.shift(); - sessionStorage.removeItem(oldestKey); - } + $(window).on('beforeunload', saveCurrentPageToSessionStorage); + + // if (window.performance && + // window.performance.navigation.type + // === window.performance.navigation.TYPE_BACK_FORWARD) { + // loadPageFromSessionStorage(); + // } - sessionStorage.setItem(sessionStorageKey, JSON.stringify(keys)); - sessionStorage.setItem(key, contentData); - }); - if (window.performance && - window.performance.navigation.type - === window.performance.navigation.TYPE_BACK_FORWARD) { - let key = `oj-content-${window.location.href}`; - let content = sessionStorage.getItem(key); - if (content) { - content = JSON.parse(content); - $('#content').html(content.html); - onWindowReady(); - window.PAGE_FROM_BACK_BUTTON_CACHE = true; - $(window).scrollTop(content.scrollOffset - 100); - window.page = content.page; - window.has_next_page = content.has_next_page; - } - } + window.addEventListener('popstate', loadPageFromSessionStorage); }); \ No newline at end of file diff --git a/resources/html/loading-page.html b/resources/html/loading-page.html index bf1813ee..1195f299 100644 --- a/resources/html/loading-page.html +++ b/resources/html/loading-page.html @@ -1 +1,23 @@ -
L
Q
D
O
J
.
.
.
L
Q
D
O
J
\ No newline at end of file +
+
+ L + Q + D + O + J +
+ + +
\ No newline at end of file diff --git a/templates/base.html b/templates/base.html index 969558c0..c853ec98 100644 --- a/templates/base.html +++ b/templates/base.html @@ -67,7 +67,7 @@ } {% endif %} - {% block media %}{% endblock %} + {% if use_darkmode %} @@ -102,6 +102,15 @@ {% else %} {% endif %} + @@ -210,7 +219,7 @@ {% if request.user.is_impersonate %} - + {% else %} @@ -234,7 +243,6 @@ -
{% if request.in_contest %}
@@ -261,6 +269,9 @@
{% endif %}
+
+ {% block media %}{% endblock %} +
@@ -303,8 +314,9 @@

}); {% endcompress %} - - {% block js_media %}{% endblock %} +
+ {% block js_media %}{% endblock %} +
{% if request.in_contest %} {% include "katex-load.html" %} {% block footer %} diff --git a/templates/blog/blog.html b/templates/blog/blog.html index de3f7596..66b99fb7 100644 --- a/templates/blog/blog.html +++ b/templates/blog/blog.html @@ -46,8 +46,3 @@
{% include "comments/list.html" %} {% endblock %} - -{% block bodyend %} - {{ super() }} - {% include "comments/math.html" %} -{% endblock %} \ No newline at end of file diff --git a/templates/blog/list.html b/templates/blog/list.html index cb546927..4ac69b18 100644 --- a/templates/blog/list.html +++ b/templates/blog/list.html @@ -19,7 +19,7 @@ {% endblock %} -{% block three_col_js %} +{% block js_media %} {% include "actionbar/media-js.html" %} {% include "feed/feed_js.html" %} {% compress js %} @@ -41,11 +39,12 @@ return receiver; } - let message_template = ` + function message_template() { + return` {% with message=message_template %} {% include "chat/message.html" %} {% endwith %} - `; + `}; $(function() { load_dynamic_update({{last_msg}}); }); diff --git a/templates/chat/chat_js.html b/templates/chat/chat_js.html index 70c52a0b..e98517f9 100644 --- a/templates/chat/chat_js.html +++ b/templates/chat/chat_js.html @@ -1,5 +1,7 @@ -{% endcompress %} diff --git a/templates/contest/contest.html b/templates/contest/contest.html index ceac37f7..19e23a3f 100644 --- a/templates/contest/contest.html +++ b/templates/contest/contest.html @@ -10,7 +10,7 @@

{{contest.name}}

{% include "contest/contest-tabs.html" %} {% endblock %} -{% block two_col_js %} +{% block js_media %} {% include "contest/media-js.html" %} {% include "comments/media-js.html" %} {% include "actionbar/media-js.html" %} diff --git a/templates/contest/list.html b/templates/contest/list.html index c7a0995b..78a2de5b 100644 --- a/templates/contest/list.html +++ b/templates/contest/list.html @@ -31,13 +31,14 @@ {% block contest_list_media %}{% endblock %} {% endblock %} -{% block three_col_js %} +{% block js_media %} diff --git a/templates/course/edit_lesson.html b/templates/course/edit_lesson.html index 257fbe15..2cfe84b3 100644 --- a/templates/course/edit_lesson.html +++ b/templates/course/edit_lesson.html @@ -12,7 +12,7 @@ {% endblock %} -{% block two_col_js %} +{% block js_media %} {{ form.media.js }} {% endblock %} diff --git a/templates/course/grades.html b/templates/course/grades.html index 09627851..a560cc05 100644 --- a/templates/course/grades.html +++ b/templates/course/grades.html @@ -18,7 +18,7 @@ {% endblock %} -{% block two_col_js %} +{% block js_media %} \ No newline at end of file diff --git a/templates/organization/list.html b/templates/organization/list.html index 8d6108e1..30f721f2 100644 --- a/templates/organization/list.html +++ b/templates/organization/list.html @@ -1,11 +1,12 @@ {% extends "three-column-content.html" %} -{% block three_col_js %} +{% block js_media %} -{% endblock %} - {% macro make_tab_item(name, fa, url, text, force_new_page=False) %} @@ -128,12 +48,3 @@
{% block after_posts %}{% endblock %} {% endblock %} - -{% block extra_js %} - {% block three_col_js %}{% endblock %} -{% endblock %} - -{% block bodyend %} - {{ super() }} - {% include "comments/math.html" %} -{% endblock %} \ No newline at end of file diff --git a/templates/ticket/ticket.html b/templates/ticket/ticket.html index f5a20098..52ce6552 100644 --- a/templates/ticket/ticket.html +++ b/templates/ticket/ticket.html @@ -223,8 +223,3 @@
{% endblock %} - -{% block bodyend %} - {{ super() }} - {% include "comments/math.html" %} -{% endblock %} diff --git a/templates/two-column-content.html b/templates/two-column-content.html index 3c86d27a..2b1ed79f 100644 --- a/templates/two-column-content.html +++ b/templates/two-column-content.html @@ -1,10 +1,6 @@ {% set is_two_column = true %} {% extends "three-column-content.html" %} -{% block three_col_js %} - {% block two_col_js %}{% endblock %} -{% endblock %} - {% block three_col_media %}