Skip to content

Commit

Permalink
Refactor 3-col-content
Browse files Browse the repository at this point in the history
  • Loading branch information
cuom1999 committed Jun 25, 2024
1 parent 326b3d5 commit a711fb9
Show file tree
Hide file tree
Showing 37 changed files with 448 additions and 379 deletions.
2 changes: 1 addition & 1 deletion django_ace/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def render(self, name, value, attrs=None, renderer=None):
if self.toolbar:
toolbar = (
'<div style="width: {}" class="django-ace-toolbar">'
'<a href="./" class="django-ace-max_min"></a>'
'<a href="#" class="django-ace-max_min"></a>'
"</div>"
).format(self.width)
html = toolbar + html
Expand Down
10 changes: 1 addition & 9 deletions judge/views/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down
295 changes: 232 additions & 63 deletions resources/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,44 +386,230 @@ 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 = $('<form>')
.attr('action', fullUrl)
.attr('method', 'POST')
.appendTo('body');

$formToSubmit.append($('<input>').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 = $('<form>')
.attr('action', fullUrl)
.attr('method', 'POST')
.appendTo('body');

$formToSubmit.append($('<input>').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);
$("#loading-bar").stop(true, true);
$("#loading-bar").hide().css({ width: 0});

for (let elem of toUpdateElements) {
$(elem).replaceWith($(data).find(elem).first());
}

$(reload_container).replaceWith(reload_content);

$(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 replaceLoadingPage(reload_container) {
const loadingPage = `
<div style="height: 80vh; margin: 0; display: flex; align-items: center; justify-content: center; width: 100%; font-size: xx-large;">
<i class="fa fa-spinner fa-pulse"></i>
</div>
`;
$(reload_container).fadeOut(100, function() {
$(this).html(loadingPage).fadeIn(100);
});
}

function registerNavigation() {
const containerMap = {
'.left-sidebar-item': '.middle-right-content',
'.pagination li a': '.middle-content',
'.tabs li a': '.middle-content',
'#control-panel a': '.middle-content',
};

$.each(containerMap, function(selector, target) {
$(selector).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() {
Expand Down Expand Up @@ -528,7 +714,7 @@ function onWindowReady() {
$("#loading-bar").animate({ width: "100%" }, 2000, function() {
$(this).stop(true, true);
$(this).hide().css({ width: 0});
});
});
});

$('.errorlist').each(function() {
Expand All @@ -537,12 +723,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();
Expand Down Expand Up @@ -582,33 +769,15 @@ $(function() {
$nav_list.hide();
});

$(window).on('beforeunload', function() {
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();
sessionStorage.setItem(key, JSON.stringify({
"html": $contentClone.html(),
"page": window.page,
"has_next_page": window.has_next_page,
"scrollOffset": $(window).scrollTop(),
}));
});
$(window).on('beforeunload', saveCurrentPageToSessionStorage);

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;
}
loadPageFromSessionStorage();
}

window.addEventListener('popstate', (e) => {
window.location.href = e.currentTarget.location.href;
});
});
23 changes: 22 additions & 1 deletion resources/html/loading-page.html
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
<style>.preloader{display:flex;font-size:calc(16px + (24 - 16)*(100vw - 320px)/ (1280 - 320));color:#3df1f1;font:1em Dosis,sans-serif;height:100vh;line-height:1.5;perspective:40em}.preloader{animation:tiltSpin 8s linear infinite;flex-direction:column;justify-content:center;align-items:center;margin:auto;width:17em;height:17em}.preloader,.preloader__ring{transform-style:preserve-3d}.preloader__ring{animation-name:spin;animation-duration:4s;animation-timing-function:inherit;animation-iteration-count:inherit;font-size:2em;position:relative;height:3rem;width:1.5rem}.preloader__ring:nth-child(even){animation-direction:reverse}.preloader__sector{font-weight:600;position:absolute;top:0;left:0;text-align:center;text-transform:uppercase;transform:translateZ(7rem)}.preloader__sector,.preloader__sector:empty:before{display:inline-block;width:100%;height:100%}.preloader__sector:empty:before{background:linear-gradient(transparent 45%,currentColor 45% 55%,transparent 55%);content:""}.preloader__sector:nth-child(2){transform:rotateY(12deg) translateZ(7rem)}.preloader__sector:nth-child(3){transform:rotateY(24deg) translateZ(7rem)}.preloader__sector:nth-child(4){transform:rotateY(36deg) translateZ(7rem)}.preloader__sector:nth-child(5){transform:rotateY(48deg) translateZ(7rem)}.preloader__sector:nth-child(6){transform:rotateY(60deg) translateZ(7rem)}.preloader__sector:nth-child(7){transform:rotateY(72deg) translateZ(7rem)}.preloader__sector:nth-child(8){transform:rotateY(84deg) translateZ(7rem)}.preloader__sector:nth-child(9){transform:rotateY(96deg) translateZ(7rem)}.preloader__sector:nth-child(10){transform:rotateY(108deg) translateZ(7rem)}.preloader__sector:nth-child(11){transform:rotateY(120deg) translateZ(7rem)}.preloader__sector:nth-child(12){transform:rotateY(132deg) translateZ(7rem)}.preloader__sector:nth-child(13){transform:rotateY(144deg) translateZ(7rem)}.preloader__sector:nth-child(14){transform:rotateY(156deg) translateZ(7rem)}.preloader__sector:nth-child(15){transform:rotateY(168deg) translateZ(7rem)}.preloader__sector:nth-child(16){transform:rotateY(180deg) translateZ(7rem)}.preloader__sector:nth-child(17){transform:rotateY(192deg) translateZ(7rem)}.preloader__sector:nth-child(18){transform:rotateY(204deg) translateZ(7rem)}.preloader__sector:nth-child(19){transform:rotateY(216deg) translateZ(7rem)}.preloader__sector:nth-child(20){transform:rotateY(228deg) translateZ(7rem)}.preloader__sector:nth-child(21){transform:rotateY(240deg) translateZ(7rem)}.preloader__sector:nth-child(22){transform:rotateY(252deg) translateZ(7rem)}.preloader__sector:nth-child(23){transform:rotateY(264deg) translateZ(7rem)}.preloader__sector:nth-child(24){transform:rotateY(276deg) translateZ(7rem)}.preloader__sector:nth-child(25){transform:rotateY(288deg) translateZ(7rem)}.preloader__sector:nth-child(26){transform:rotateY(300deg) translateZ(7rem)}.preloader__sector:nth-child(27){transform:rotateY(312deg) translateZ(7rem)}.preloader__sector:nth-child(28){transform:rotateY(324deg) translateZ(7rem)}.preloader__sector:nth-child(29){transform:rotateY(336deg) translateZ(7rem)}.preloader__sector:nth-child(30){transform:rotateY(348deg) translateZ(7rem)}@keyframes tiltSpin{from{transform:rotateY(0) rotateX(30deg)}to{transform:rotateY(1turn) rotateX(30deg)}}@keyframes spin{from{transform:rotateY(0)}to{transform:rotateY(1turn)}}</style><div class="preloader"><div class="preloader__ring"><div class="preloader__sector">L</div><div class="preloader__sector">Q</div><div class="preloader__sector">D</div><div class="preloader__sector">O</div><div class="preloader__sector">J</div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector">.</div><div class="preloader__sector">.</div><div class="preloader__sector">.</div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div></div><div class="preloader__ring"><div class="preloader__sector">L</div><div class="preloader__sector">Q</div><div class="preloader__sector">D</div><div class="preloader__sector">O</div><div class="preloader__sector">J</div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div><div class="preloader__sector"></div></div></div>
<style>
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-20px);
}
60% {
transform: translateY(-10px);
}
}
</style>
<div style="height: 80vh; margin: 0; display: flex; align-items: center; justify-content: center; font-family: cursive; width: 100%;">
<div class="loader" style="display: flex; align-items: center; justify-content: center;">
<span style="color: #1b9b66; font-size: 2rem; font-weight: bold; margin: 0 0.2rem; animation: bounce 1.5s infinite;">L</span>
<span style="color: #daa335; font-size: 2rem; font-weight: bold; margin: 0 0.2rem; animation: bounce 1.5s infinite; animation-delay: 0.3s;">Q</span>
<span style="color: #283a7e; font-size: 2rem; font-weight: bold; margin: 0 0.2rem; animation: bounce 1.5s infinite; animation-delay: 0.6s;">D</span>
<span style="color: #dd7030; font-size: 2rem; font-weight: bold; margin: 0 0.2rem; animation: bounce 1.5s infinite; animation-delay: 0.9s;">O</span>
<span style="color: #983c35; font-size: 2rem; font-weight: bold; margin: 0 0.2rem; animation: bounce 1.5s infinite; animation-delay: 1.2s;">J</span>
</div>
</div>
Loading

0 comments on commit a711fb9

Please sign in to comment.