This commit is contained in:
anhkha2003 2023-10-06 03:45:49 -05:00
commit 509d1ba2f9
22 changed files with 328 additions and 222 deletions

View file

@ -485,6 +485,9 @@ META_REMOTE_ADDRESS_KEY = "REMOTE_ADDR"
DEFAULT_AUTO_FIELD = "django.db.models.AutoField" DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
# Chunk upload
CHUNK_UPLOAD_DIR = "/tmp/chunk_upload_tmp"
try: try:
with open(os.path.join(os.path.dirname(__file__), "local_settings.py")) as f: with open(os.path.join(os.path.dirname(__file__), "local_settings.py")) as f:
exec(f.read(), globals()) exec(f.read(), globals())

View file

@ -44,6 +44,7 @@ from judge.views import (
language, language,
license, license,
mailgun, mailgun,
markdown_editor,
notification, notification,
organization, organization,
preview, preview,
@ -405,6 +406,11 @@ urlpatterns = [
] ]
), ),
), ),
url(
r"^markdown_editor/",
markdown_editor.MarkdownEditor.as_view(),
name="markdown_editor",
),
url( url(
r"^submission_source_file/(?P<filename>(\w|\.)+)", r"^submission_source_file/(?P<filename>(\w|\.)+)",
submission.SubmissionSourceFileView.as_view(), submission.SubmissionSourceFileView.as_view(),

View file

@ -168,7 +168,7 @@ class CommentedDetailView(TemplateResponseMixin, SingleObjectMixin, View):
) )
def _get_queryset(self, target_comment): def _get_queryset(self, target_comment):
if target_comment != None: if target_comment:
queryset = target_comment.get_descendants(include_self=True) queryset = target_comment.get_descendants(include_self=True)
queryset = ( queryset = (
queryset.select_related("author__user") queryset.select_related("author__user")
@ -217,11 +217,11 @@ class CommentedDetailView(TemplateResponseMixin, SingleObjectMixin, View):
context["has_comments"] = queryset.exists() context["has_comments"] = queryset.exists()
context["comment_lock"] = self.is_comment_locked() context["comment_lock"] = self.is_comment_locked()
context["comment_list"] = queryset context["comment_list"] = list(queryset)
context["vote_hide_threshold"] = settings.DMOJ_COMMENT_VOTE_HIDE_THRESHOLD context["vote_hide_threshold"] = settings.DMOJ_COMMENT_VOTE_HIDE_THRESHOLD
if queryset.exists(): if queryset.exists():
context["comment_root_id"] = queryset[0].id context["comment_root_id"] = context["comment_list"][0].id
else: else:
context["comment_root_id"] = 0 context["comment_root_id"] = 0
context["comment_parent_none"] = 1 context["comment_parent_none"] = 1
@ -234,4 +234,5 @@ class CommentedDetailView(TemplateResponseMixin, SingleObjectMixin, View):
context["limit"] = DEFAULT_OFFSET context["limit"] = DEFAULT_OFFSET
context["comment_count"] = comment_count context["comment_count"] = comment_count
context["profile"] = self.request.profile
return context return context

View file

@ -35,7 +35,7 @@ def save_upload(f, path):
# pass callback function to post_upload # pass callback function to post_upload
def handle_upload(f, fileattrs, upload_dir, post_upload=None): def handle_upload(f, fileattrs, upload_dir, post_upload=None):
chunks_dir = os.path.join(tempfile.gettempdir(), "chunk_upload_tmp") chunks_dir = settings.CHUNK_UPLOAD_DIR
if not os.path.exists(os.path.dirname(chunks_dir)): if not os.path.exists(os.path.dirname(chunks_dir)):
os.makedirs(os.path.dirname(chunks_dir)) os.makedirs(os.path.dirname(chunks_dir))
chunked = False chunked = False

View file

@ -15,12 +15,11 @@ from django.http import (
HttpResponseBadRequest, HttpResponseBadRequest,
HttpResponseForbidden, HttpResponseForbidden,
) )
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404, render
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from django.views.generic import DetailView, UpdateView from django.views.generic import DetailView, UpdateView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.template import loader
from reversion import revisions from reversion import revisions
from reversion.models import Version from reversion.models import Version
@ -42,11 +41,6 @@ __all__ = [
@login_required @login_required
# def get_more_reply(request, id):
# queryset = Comment.get_pk(id)
def vote_comment(request, delta): def vote_comment(request, delta):
if abs(delta) != 1: if abs(delta) != 1:
return HttpResponseBadRequest( return HttpResponseBadRequest(
@ -156,6 +150,7 @@ def get_comments(request, limit=10):
revisions=Count("versions", distinct=True), revisions=Count("versions", distinct=True),
)[offset : offset + limit] )[offset : offset + limit]
) )
profile = None
if request.user.is_authenticated: if request.user.is_authenticated:
profile = request.profile profile = request.profile
queryset = queryset.annotate( queryset = queryset.annotate(
@ -164,10 +159,11 @@ def get_comments(request, limit=10):
new_offset = offset + min(len(queryset), limit) new_offset = offset + min(len(queryset), limit)
comment_html = loader.render_to_string( return render(
request,
"comments/content-list.html", "comments/content-list.html",
{ {
"request": request, "profile": profile,
"comment_root_id": comment_root_id, "comment_root_id": comment_root_id,
"comment_list": queryset, "comment_list": queryset,
"vote_hide_threshold": settings.DMOJ_COMMENT_VOTE_HIDE_THRESHOLD, "vote_hide_threshold": settings.DMOJ_COMMENT_VOTE_HIDE_THRESHOLD,
@ -181,8 +177,6 @@ def get_comments(request, limit=10):
}, },
) )
return HttpResponse(comment_html)
def get_show_more(request): def get_show_more(request):
return get_comments(request) return get_comments(request)

View file

@ -0,0 +1,14 @@
from django.views import View
from django.shortcuts import render
from django.utils.translation import gettext_lazy as _
class MarkdownEditor(View):
def get(self, request):
return render(
request,
"markdown_editor/markdown_editor.html",
{
"title": _("Markdown Editor"),
},
)

View file

@ -130,6 +130,18 @@ msgstr "Thể thức"
msgid "Rating" msgid "Rating"
msgstr "" msgstr ""
#: templates/markdown_editor/markdown_editor.html:107
msgid "Insert Image"
msgstr "Chèn hình ảnh"
#: templates/markdown_editor/markdown_editor.html:110
msgid "From the web"
msgstr "Từ web"
#: templates/markdown_editor/markdown_editor.html:116
msgid "From your computer"
msgstr "Từ máy tính của bạn"
#: judge/admin/contest.py:201 #: judge/admin/contest.py:201
msgid "Access" msgid "Access"
msgstr "Truy cập" msgstr "Truy cập"
@ -6255,3 +6267,4 @@ msgstr "Chọn tất cả"
#~ msgid "Hard" #~ msgid "Hard"
#~ msgstr "Khó" #~ msgstr "Khó"

View file

@ -39,6 +39,12 @@ msgstr "Đăng ký tên"
msgid "Report" msgid "Report"
msgstr "Báo cáo" msgstr "Báo cáo"
msgid "Insert Image"
msgstr "Chèn hình ảnh"
msgid "Save"
msgstr "Lưu"
msgid "2sat" msgid "2sat"
msgstr "" msgstr ""
@ -593,3 +599,4 @@ msgstr ""
msgid "z-function" msgid "z-function"
msgstr "" msgstr ""

View file

@ -78,7 +78,7 @@
#chat-container { #chat-container {
display: flex; display: flex;
width: 100%; width: 100%;
height: calc(100vh - 3em); height: calc(100vh - $navbar_height);
border: 1px solid #ccc; border: 1px solid #ccc;
/*border-radius: 0 4px 0 0;*/ /*border-radius: 0 4px 0 0;*/
border-bottom: 0; border-bottom: 0;
@ -220,5 +220,6 @@
@media (max-width: 799px) { @media (max-width: 799px) {
#chat-area { #chat-area {
height: calc(100vh - $navbar_height_mobile); height: calc(100vh - $navbar_height_mobile);
max-height: -webkit-fill-available;
} }
} }

View file

@ -214,7 +214,7 @@ a {
input, textarea { input, textarea {
min-width: 100%; min-width: 100%;
max-width: 100%; max-width: 100%;
font-size: 1em; font-size: 15px;
} }
} }

View file

@ -386,6 +386,11 @@ function onWindowReady() {
}); });
}); });
$('a').click(function() { $('a').click(function() {
var href = $(this).attr('href');
if (!href || href === '#' || href.startsWith("javascript")) {
return;
}
$("#loading-bar").show(); $("#loading-bar").show();
$("#loading-bar").animate({ width: "100%" }, 2000, function() { $("#loading-bar").animate({ width: "100%" }, 2000, function() {
$(this).hide().css({ width: 0}); $(this).hide().css({ width: 0});

View file

@ -1712,10 +1712,10 @@ noscript #noscript {
color: rgb(178, 171, 161); color: rgb(178, 171, 161);
} }
#chat-icon { #chat-icon {
color: rgb(249, 146, 97); color: rgb(200, 196, 189);
} }
#chat-icon:hover { #chat-icon:hover {
color: rgb(114, 255, 114); color: rgb(249, 146, 97);
} }
#nav-lang-icon { #nav-lang-icon {
color: rgb(51, 125, 255); color: rgb(51, 125, 255);
@ -2471,16 +2471,13 @@ input[type="text"], input[type="password"], input[type="email"], input[type="num
box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset; box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset;
} }
textarea { textarea {
color: rgb(178, 172, 162);
background-image: none; background-image: none;
background-color: rgb(24, 26, 27); background-color: rgb(24, 26, 27);
border-color: rgb(62, 68, 70); border-color: rgb(62, 68, 70);
box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset; box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset;
} }
textarea:hover { textarea:hover {
border-color: rgba(16, 87, 144, 0.8); border-color: rgb(140, 130, 115);
box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset,
rgba(16, 91, 150, 0.6) 0px 0px 4px;
} }
input[type="text"]:hover, input[type="password"]:hover { input[type="text"]:hover, input[type="password"]:hover {
border-color: rgba(16, 87, 144, 0.8); border-color: rgba(16, 87, 144, 0.8);
@ -2488,9 +2485,7 @@ input[type="text"]:hover, input[type="password"]:hover {
rgba(16, 91, 150, 0.6) 0px 0px 4px; rgba(16, 91, 150, 0.6) 0px 0px 4px;
} }
textarea:focus { textarea:focus {
border-color: rgba(16, 87, 144, 0.8); border-color: rgb(140, 130, 115); outline-color: initial;
box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset,
rgba(16, 91, 150, 0.6) 0px 0px 8px; outline-color: initial;
} }
input[type="text"]:focus, input[type="password"]:focus { input[type="text"]:focus, input[type="password"]:focus {
border-color: rgba(16, 87, 144, 0.8); border-color: rgba(16, 87, 144, 0.8);
@ -2552,7 +2547,7 @@ input[type="text"]:focus, input[type="password"]:focus {
ul.pagination a:hover { ul.pagination a:hover {
color: rgb(232, 230, 227); color: rgb(232, 230, 227);
background-image: initial; background-image: initial;
background-color: rgb(8, 128, 104); background-color: rgb(163, 62, 18);
border-color: initial; border-color: initial;
} }
ul.pagination > li > a, ul.pagination > li > a,
@ -2563,14 +2558,14 @@ ul.pagination > li > span {
border-color: rgb(199, 70, 8); border-color: rgb(199, 70, 8);
} }
ul.pagination > .disabled-page > a { ul.pagination > .disabled-page > a {
color: rgb(157, 148, 136); color: rgb(223, 220, 215);
background-color: rgba(3, 66, 54, 0.5); background-color: rgb(137, 78, 57);
border-color: rgba(126, 117, 103, 0.5); border-color: rgb(199, 68, 21);
} }
ul.pagination > .disabled-page > span { ul.pagination > .disabled-page > span {
color: rgb(157, 148, 136); color: rgb(223, 220, 215);
background-color: rgba(3, 66, 54, 0.5); background-color: rgb(137, 78, 57);
border-color: rgba(126, 117, 103, 0.5); border-color: rgb(199, 68, 21);
} }
ul.pagination > .active-page > a { ul.pagination > .active-page > a {
color: rgb(232, 230, 227); color: rgb(232, 230, 227);
@ -2922,8 +2917,8 @@ a.voted {
color: rgb(152, 143, 129); color: rgb(152, 143, 129);
} }
.list-contest { .list-contest {
box-shadow: rgba(3, 66, 54, 0.2) 0px 4px 8px, box-shadow: rgb(49, 53, 55) 0px 1px 2px,
rgba(3, 66, 54, 0.19) 0px 6px 20px; rgb(49, 53, 55) 0px 1px 5px;
} }
#contest-calendar th { #contest-calendar th {
border-bottom-color: rgb(62, 68, 70); border-bottom-color: rgb(62, 68, 70);
@ -3058,7 +3053,13 @@ a.voted {
} }
#chat-input { #chat-input {
color: rgb(232, 230, 227); color: rgb(232, 230, 227);
border-color: rgb(159, 117, 19); border-color: rgb(140, 130, 115);
}
#chat-input::-webkit-input-placeholder {
color: rgb(152, 143, 129);
}
#chat-input::placeholder {
color: rgb(152, 143, 129);
} }
.selected-status-row { .selected-status-row {
background-color: rgb(49, 53, 55); background-color: rgb(49, 53, 55);
@ -3077,15 +3078,6 @@ a.voted {
#chat-info { #chat-info {
box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 3px; box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 3px;
} }
#refresh-button {
background-image: initial;
background-color: transparent;
border-color: initial;
}
#refresh-button:hover {
background-image: initial;
background-color: rgb(40, 111, 17);
}
.status-circle { .status-circle {
stroke: rgb(232, 230, 227); stroke: rgb(232, 230, 227);
} }
@ -3104,11 +3096,12 @@ a.voted {
color: rgb(232, 230, 227); color: rgb(232, 230, 227);
} }
.chat-input-icon { .chat-input-icon {
color: rgb(249, 146, 97); color: rgb(232, 230, 227);
background-color: rgb(48, 104, 78);
} }
.chat-input-icon:hover { .chat-input-icon:hover {
background-image: initial; background-image: initial;
background-color: rgb(49, 53, 55); background-color: rgb(62, 136, 112);
} }
.chat .active-span { .chat .active-span {
color: rgb(169, 162, 151); color: rgb(169, 162, 151);
@ -3873,64 +3866,11 @@ mjx-assistive-mml {
mjx-stretchy-v > mjx-ext { mjx-stretchy-v > mjx-ext {
border-color: transparent; border-color: transparent;
} }
.noUi-target, .recently-attempted ul {
.noUi-target * { list-style-image: initial;
-webkit-tap-highlight-color: transparent;
} }
.noUi-target { .organization-row:last-child {
background-image: initial; border-bottom-color: initial;
background-color: rgb(27, 29, 30);
border-color: rgb(60, 65, 68);
box-shadow: rgb(32, 35, 37) 0px 1px 1px inset,
rgb(62, 68, 70) 0px 3px 6px -5px;
}
.noUi-connect {
background-image: initial;
background-color: rgb(50, 147, 140);
box-shadow: rgba(38, 42, 43, 0.45) 0px 0px 3px inset;
}
.noUi-handle {
border-color: rgb(59, 64, 66);
background-image: initial;
background-color: rgb(24, 26, 27);
box-shadow: rgb(24, 26, 27) 0px 0px 1px inset,
rgb(35, 38, 40) 0px 1px 7px inset,
rgb(62, 68, 70) 0px 3px 6px -3px;
}
.noUi-active {
box-shadow: rgb(24, 26, 27) 0px 0px 1px inset,
rgb(43, 47, 49) 0px 1px 7px inset,
rgb(62, 68, 70) 0px 3px 6px -3px;
}
.noUi-handle::after,
.noUi-handle::before {
background-image: initial;
background-color: rgb(38, 41, 42);
}
[disabled] .noUi-connect {
background-image: initial;
background-color: rgb(64, 69, 72);
}
.noUi-pips {
color: rgb(168, 160, 149);
}
.noUi-value-sub {
color: rgb(200, 195, 188);
}
.noUi-marker {
background-image: initial;
background-color: rgb(53, 57, 59);
}
.noUi-marker-large,
.noUi-marker-sub {
background-image: initial;
background-color: rgb(72, 78, 81);
}
.noUi-tooltip {
border-color: rgb(59, 64, 66);
background-image: initial;
background-color: rgb(24, 26, 27);
color: rgb(232, 230, 227);
} }
/* Override Style */ /* Override Style */

View file

@ -13,7 +13,7 @@ div.dmmd-preview-update {
} }
div.dmmd-preview-content { div.dmmd-preview-content {
padding: 0 7px; padding: 0 8px;
} }
div.dmmd-preview.dmmd-preview-has-content div.dmmd-preview-update { div.dmmd-preview.dmmd-preview-has-content div.dmmd-preview-update {
@ -21,7 +21,8 @@ div.dmmd-preview.dmmd-preview-has-content div.dmmd-preview-update {
} }
div.dmmd-preview-has-content div.dmmd-preview-content { div.dmmd-preview-has-content div.dmmd-preview-content {
padding-bottom: 7px; padding-bottom: 8px;
padding-top: 8px;
} }
div.dmmd-no-button div.dmmd-preview-update { div.dmmd-no-button div.dmmd-preview-update {

View file

@ -14,7 +14,7 @@
width: 100%; width: 100%;
background: #fff; background: #fff;
border: 1px solid DarkGray; border: 1px solid DarkGray;
font-family: Consolas, "Liberation Mono", Monaco, "Courier New", monospace !important; font-family: "Noto Sans",Arial,"Lucida Grande",sans-serif !important;
} }
.wmd-preview { .wmd-preview {

View file

@ -14,7 +14,7 @@
width: 100%; width: 100%;
background: #fff; background: #fff;
border: 1px solid DarkGray; border: 1px solid DarkGray;
font-family: Consolas, "Liberation Mono", Monaco, "Courier New", monospace !important; font-family: "Noto Sans",Arial,"Lucida Grande",sans-serif !important;
} }
.wmd-preview { .wmd-preview {
@ -174,51 +174,51 @@
/* Extra styles to allow for image upload */ /* Extra styles to allow for image upload */
.pagedown-image-upload { .pagedown-image-upload {
display: none; display: none;
z-index: 10001; z-index: 10001;
position: fixed; position: fixed;
background: white; background: white;
top: 50%; top: 50%;
left: 50%; left: 50%;
padding: 10px; padding: 10px;
width: 400px; width: 400px;
max-width: 90%; max-width: 90%;
transform: translate3d(-50%, -50%, 0); transform: translate3d(-50%, -50%, 0);
box-shadow: 2px 2px 10px 0px rgba(0, 0, 0, 0.5); box-shadow: 2px 2px 10px 0px rgba(0, 0, 0, 0.5);
} }
.pagedown-image-upload .submit-row { .pagedown-image-upload .submit-row {
margin: 10px 0 0 0; margin: 10px 0 0 0;
} }
.pagedown-image-upload.show { .pagedown-image-upload.show {
display: block; display: block;
} }
.pagedown-image-upload .submit-loading { .pagedown-image-upload .submit-loading {
display: none; display: none;
vertical-align: middle; vertical-align: middle;
border: 4px solid #f3f3f3; /* Light grey */ border: 4px solid #f3f3f3; /* Light grey */
border-top: 4px solid #79aec8; /* Blue */ border-top: 4px solid #79aec8; /* Blue */
border-radius: 50%; border-radius: 50%;
width: 24px; width: 24px;
height: 24px; height: 24px;
animation: spin 1s linear infinite; animation: spin 1s linear infinite;
} }
.pagedown-image-upload .submit-loading.show { .pagedown-image-upload .submit-loading.show {
display: inline-block; display: inline-block;
} }
.pagedown-image-upload .submit-input { .pagedown-image-upload .submit-input {
display: none; display: none;
} }
.pagedown-image-upload .submit-input.show { .pagedown-image-upload .submit-input.show {
display: inline-block; display: inline-block;
} }
@keyframes spin { @keyframes spin {
0% { transform: rotate(0deg); } 0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); } 100% { transform: rotate(360deg); }
} }

View file

@ -161,8 +161,7 @@ input {
} }
textarea { textarea {
padding: 4px 8px; padding: 8px;
color: #555;
background: #FFF none; background: #FFF none;
border: 1px solid $border_gray; border: 1px solid $border_gray;
border-radius: $widget_border_radius; border-radius: $widget_border_radius;
@ -172,8 +171,7 @@ textarea {
} }
textarea:hover { textarea:hover {
border-color: rgba(82, 168, 236, 0.8); border-color: black;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 4px rgba(82, 168, 236, 0.6);
} }
input { input {
@ -184,8 +182,8 @@ input {
} }
textarea:focus { textarea:focus {
border-color: rgba(82, 168, 236, 0.8); border-color: black;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); border-width: unset;
outline: 0; outline: 0;
} }
@ -322,7 +320,7 @@ input {
// Bootstrap-y pagination // Bootstrap-y pagination
ul.pagination a:hover { ul.pagination a:hover {
color: #FFF; color: #FFF;
background: #0aa082; background: #cc4e17;
border: none; border: none;
} }
@ -338,22 +336,6 @@ ul.pagination {
li { li {
display: inline; display: inline;
// &:first-child > {
// a, span {
// margin-left: 0;
// border-top-left-radius: $widget_border_radius;
// border-bottom-left-radius: $widget_border_radius;
// }
// }
// &:last-child > {
// a, span {
// margin-left: 0;
// border-top-right-radius: $widget_border_radius;
// border-bottom-right-radius: $widget_border_radius;
// }
// }
> { > {
a, span { a, span {
position: relative; position: relative;
@ -373,15 +355,15 @@ ul.pagination {
.disabled-page > { .disabled-page > {
a { a {
color: #888; color: #f1efef;
background-color: #04534380; background-color: #ab6247;
border-color: #04534380; border-color: #6a240b;
} }
span { span {
color: #888; color: #f1efef;
background-color: #04534380; background-color: #ab6247;
border-color: #04534380; border-color: #6a240b;
} }
} }

View file

@ -195,8 +195,8 @@
#chat-input-container { #chat-input-container {
padding-left: 3%; padding-left: 3%;
} }
#chat-area { .back-button {
padding-bottom: 1.5em; display: none;
} }
.back-button { .back-button {
display: none; display: none;

View file

@ -1,13 +1,10 @@
{% set logged_in = request.user.is_authenticated %}
{% set profile = request.profile if logged_in else None %}
{% for node in mptt_tree(comment_list) recursive %} {% for node in mptt_tree(comment_list) recursive %}
<li id="comment-{{ node.id }}" data-revision="{{ node.revisions - 1 }}" data-max-revision="{{ node.revisions - 1 }}" <li id="comment-{{ node.id }}" data-revision="{{ node.revisions - 1 }}" data-max-revision="{{ node.revisions - 1 }}"
data-revision-ajax="{{ url('comment_revision_ajax', node.id) }}" class="comment"> data-revision-ajax="{{ url('comment_revision_ajax', node.id) }}" class="comment">
<div class="comment-display{% if node.score <= vote_hide_threshold %} bad-comment{% endif %}"> <div class="comment-display{% if node.score <= vote_hide_threshold %} bad-comment{% endif %}">
<div class="info"> <div class="info">
<div class="vote"> <div class="vote">
{% if logged_in %} {% if profile %}
<a href="javascript:comment_upvote({{ node.id }})" <a href="javascript:comment_upvote({{ node.id }})"
class="upvote-link fa fa-chevron-up fa-fw{% if node.vote_score == 1 %} voted{% endif %}"></a> class="upvote-link fa fa-chevron-up fa-fw{% if node.vote_score == 1 %} voted{% endif %}"></a>
{% else %} {% else %}
@ -16,7 +13,7 @@
{% endif %} {% endif %}
<br> <br>
<div class="comment-score">{{ node.score }}</div> <div class="comment-score">{{ node.score }}</div>
{% if logged_in %} {% if profile %}
<a href="javascript:comment_downvote({{ node.id }})" <a href="javascript:comment_downvote({{ node.id }})"
class="downvote-link fa fa-chevron-down fa-fw{% if node.vote_score == -1 %} voted{% endif %}"></a> class="downvote-link fa fa-chevron-down fa-fw{% if node.vote_score == -1 %} voted{% endif %}"></a>
{% else %} {% else %}
@ -55,7 +52,7 @@
<a href="?comment-id={{node.id}}#comment-{{ node.id }}" title="{{ _('Link') }}" class="comment-link"> <a href="?comment-id={{node.id}}#comment-{{ node.id }}" title="{{ _('Link') }}" class="comment-link">
<i class="fa fa-link fa-fw"></i> <i class="fa fa-link fa-fw"></i>
</a> </a>
{% if logged_in and not comment_lock %} {% if profile and not comment_lock %}
{% set can_edit = node.author.id == profile.id and not profile.mute %} {% set can_edit = node.author.id == profile.id and not profile.mute %}
{% if can_edit %} {% if can_edit %}
<a data-featherlight="{{ url('comment_edit_ajax', node.id) }}" <a data-featherlight="{{ url('comment_edit_ajax', node.id) }}"

View file

@ -3,7 +3,7 @@
<h2 id="comment-header"> <h2 id="comment-header">
<i style="padding-right: 0.3em" class="fa fa-comments"></i>{{ _('Comments') }} <i style="padding-right: 0.3em" class="fa fa-comments"></i>{{ _('Comments') }}
{% if can_comment %} {% if can_comment %}
<a href="" id="write-comment" style="float: right; font-size: 0.6em; margin-right: -26px;"> {{ _('Write comment') }} </a> <a href="#" id="write-comment" style="float: right; font-size: 0.6em; margin-right: -26px;"> {{ _('Write comment') }} </a>
{% endif %} {% endif %}
</h2> </h2>
{% if can_comment %} {% if can_comment %}

View file

@ -30,7 +30,7 @@
{% endif %} {% endif %}
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {
let loading_gif = "<img src=\"{{static('loading.gif')}}\" style=\"height: 1.5em; margin-bottom: 3px\" class=\"loading\">"; let loading_gif = "<img src=\"{{static('loading.gif')}}\" style=\"height: 3em; margin-bottom: 3px\" class=\"loading\">";
window.reply_comment = function (parent) { window.reply_comment = function (parent) {
var $comment_reply = $('#comment-' + parent + '-reply'); var $comment_reply = $('#comment-' + parent + '-reply');
var reply_id = 'reply-' + parent; var reply_id = 'reply-' + parent;
@ -186,6 +186,7 @@
var $comment = $("#comment-" + id + "-children"); var $comment = $("#comment-" + id + "-children");
$comment.append(data); $comment.append(data);
} }
MathJax.typeset($('#comments')[0]);
} }
}) })
} }

View file

@ -112,56 +112,54 @@
{% endblock %} {% endblock %}
{% macro contest_head(contest) %} {% macro contest_head(contest) %}
{% spaceless %} <a href="{{ url('contest_view', contest.key) }}" class="contest-list-title" style="margin-right: 5px;">
<a href="{{ url('contest_view', contest.key) }}" class="contest-list-title" style="margin-right: 5px;"> {{contest.name}}
{{- contest.name -}} </a>
</a> <br>
<br> <div class="contest-tags" style="margin-top: 5px;">
<div class="contest-tags" style="margin-top: 5px;"> {% if not contest.is_visible %}
{% if not contest.is_visible %} <span class="contest-tag contest-tag-hidden">
<span class="contest-tag contest-tag-hidden"> <i class="fa fa-eye-slash"></i> {{ _('hidden') }}
<i class="fa fa-eye-slash"></i> {{ _('hidden') }} </span>
</span> {% endif %}
{% if contest.is_editable %}
<span class="contest-tag contest-tag-edit">
<a href="{{ url('organization_contest_edit', organization.id, organization.slug, contest.key) }}" class="white">
<i class="fa fa-edit"></i> {{ _('Edit') }}
</a>
</span>
{% endif %}
{% if contest.is_private %}
<span class="contest-tag contest-tag-private">
<i class="fa fa-lock"></i> {{ _('private') }}
</span>
{% endif %}
{% if not hide_contest_orgs %}
{% if contest.is_organization_private %}
{% for org in contest.organizations.all() %}
<span class="contest-tag contest-tag-org">
<a href="{{ org.get_absolute_url() }}">
<i class="fa fa-lock"></i> {{ org.name }}
</a>
</span>
{% endfor %}
{% endif %} {% endif %}
{% if contest.is_editable %} {% endif %}
<span class="contest-tag contest-tag-edit"> {% if contest.is_rated %}
<a href="{{ url('organization_contest_edit', organization.id, organization.slug, contest.key) }}" class="white"> <span class="contest-tag contest-tag-rated">
<i class="fa fa-edit"></i> {{ _('Edit') }} <i class="fa fa-bar-chart"></i> {{ _('rated') }}
</a> </span>
</span> {% endif %}
{% endif %} {% for tag in contest.tags.all() %}
{% if contest.is_private %} <span style="background-color: {{ tag.color }}" class="contest-tag">
<span class="contest-tag contest-tag-private"> <a href="{{ url('contest_tag', tag.name) }}"
<i class="fa fa-lock"></i> {{ _('private') }} style="color: {{ tag.text_color }}"
</span> data-featherlight="{{ url('contest_tag_ajax', tag.name) }}">
{% endif %} {{- tag.name -}}
{% if not hide_contest_orgs %} </a>
{% if contest.is_organization_private %} </span>
{% for org in contest.organizations.all() %} {% endfor %}
<span class="contest-tag contest-tag-org"> </div>
<a href="{{ org.get_absolute_url() }}">
<i class="fa fa-lock"></i> {{ org.name }}
</a>
</span>
{% endfor %}
{% endif %}
{% endif %}
{% if contest.is_rated %}
<span class="contest-tag contest-tag-rated">
<i class="fa fa-bar-chart"></i> {{ _('rated') }}
</span>
{% endif %}
{% for tag in contest.tags.all() %}
<span style="background-color: {{ tag.color }}" class="contest-tag">
<a href="{{ url('contest_tag', tag.name) }}"
style="color: {{ tag.text_color }}"
data-featherlight="{{ url('contest_tag_ajax', tag.name) }}">
{{- tag.name -}}
</a>
</span>
{% endfor %}
</div>
{% endspaceless %}
{% endmacro %} {% endmacro %}
{% macro time_left(contest, padding_top = true) %} {% macro time_left(contest, padding_top = true) %}

View file

@ -0,0 +1,143 @@
{% extends "base.html" %}
{% block media %}
<style>
main{
overflow: hidden;
}
#content{
width: 100%;
}
#content.wrapper{
padding: 0;
}
.form-area{
float: left;
width: 47%;
height: 100%
}
.wmd-preview{
float: right;
margin-top: 0;
}
.width-controller{
width: 51%;
}
.wmd-input{
height: calc(100vh - 72px);
}
.right-markdown{
height: calc(100vh - 72px);
overflow-y: scroll;
}
.wrap{
display: flex;
}
</style>
{% endblock %}
{% block js_media %}
<script>
$(document).ready(function(){
$("#wmd-input-id_body").on("keyup", function() {
const csrfToken = "{{ csrf_token }}";
$.ajax({
url: "{{url('blog_preview')}}",
type: 'POST',
headers: {
'X-CSRFToken': csrfToken, // Include the CSRF token in the headers
},
data: {
preview: $(this).val()
},
success: function(data) {
$('#display').html(data);
MathJax.typeset();
},
error: function(error) {
alert(error);
console.log(error.message)
}
})
});
});
</script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const leftDiv = document.getElementById("wmd-input-id_body");
const rightDiv = document.getElementById("display");
leftDiv.addEventListener("scroll", function() {
rightDiv.scrollTop = leftDiv.scrollTop;
});
rightDiv.addEventListener("scroll", function() {
leftDiv.scrollTop = rightDiv.scrollTop;
});
});
</script>
<script src="{{ static('pagedown/Markdown.Converter.js') }}"></script>
<script src="{{ static('pagedown-extra/pagedown/Markdown.Converter.js') }}"></script>
<script src="{{ static('pagedown/Markdown.Sanitizer.js') }}"></script>
<script src="{{ static('pagedown/Markdown.Editor.js') }}"></script>
<script src="{{ static('pagedown-extra/Markdown.Extra.js') }}"></script>
<script src="{{ static('pagedown_init.js') }}"></script>
<script src="{{ static('mathjax3_config.js') }}"></script>
<script src="http://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
<script src="{{ static('pagedown_math.js') }}"></script>
{% endblock %}
{% block title_row %}
{% endblock %}
{% block title_ruler %}
{% endblock %}
{% block body %}
<div class="wrap">
<div id="new-comment" class="form-area">
<input type="hidden" name="parent" id="id_parent">
<div class="comment-post-wrapper">
<div id="comment-form-body"><div class="wmd-wrapper image-upload-enabled">
<div class="wmd-panel">
<div id="wmd-button-bar-id_body"></div>
<textarea id="wmd-input-id_body" class="wmd-input" name="body" required=""></textarea>
</div>
<div id="id_body-preview" data-preview-url="{{url('comment_preview')}}" data-textarea-id="wmd-input-id_body" data-timeout="1000" class="wmd-panel wmd-preview dmmd-preview dmmd-no-button">
<div class="dmmd-preview-update"><i class="fa fa-refresh"></i> {{_('Update Preview')}}</div>
<div class="dmmd-preview-content content-description"></div>
</div>
<div class="pagedown-image-upload">
<h2>{{_('Insert Image')}}</h2>
<div class="form-row">
<div>
<label class="label">{{_('From the web')}}</label>
<input class="url-input" type="text" placeholder="http://">
</div>
</div>
<div class="form-row">
<div>
<label class="label">{{_('From your computer')}}</label>
<input class="file-input" type="file" name="image" id="file" data-action="/pagedown/image-upload/" accept="image/*">
</div>
</div>
<div class="submit-row">
<div class="submit-loading"></div>
<input class="submit-input show" type="submit" value="{{_('Save')}}" name="_addanother">
<p class="deletelink-box"><a href="#" class="close-image-upload deletelink">{{_('Cancel')}}</a></p>
</div>
</div>
</div></div>
</div>
</div>
<div id="id_body-preview" data-preview-url="{{url('comment_preview')}}" data-textarea-id="wmd-input-id_body" data-timeout="1000" class="width-controller wmd-panel wmd-preview dmmd-preview dmmd-no-button dmmd-preview-has-content">
<div class="right-markdown dmmd-preview-content content-description" id="display"></div>
</div>
</div>
{% endblock %}