Redesign UI
This commit is contained in:
parent
516646ae85
commit
881c165ef5
18 changed files with 569 additions and 286 deletions
|
@ -323,7 +323,7 @@ def get_status_context(request, include_ignored=False):
|
|||
'user_list': get_online_status(request.profile, friend_list),
|
||||
},
|
||||
{
|
||||
'title': 'Admins',
|
||||
'title': 'Admin',
|
||||
'user_list': get_online_status(request.profile, admin_list),
|
||||
},
|
||||
{
|
||||
|
@ -359,6 +359,7 @@ def get_or_create_room(request):
|
|||
return HttpResponseBadRequest()
|
||||
|
||||
request_id, other_id = decrypt_url(decrypted_other_id)
|
||||
|
||||
if not other_id or not request_id or request_id != request.profile.id:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ urlpatterns = [
|
|||
url(r'^problem/(?P<problem>[^/]+)', include([
|
||||
url(r'^$', problem.ProblemDetail.as_view(), name='problem_detail'),
|
||||
url(r'^/editorial$', problem.ProblemSolution.as_view(), name='problem_editorial'),
|
||||
url(r'^/comments$', problem.ProblemComments.as_view(), name='problem_comments'),
|
||||
url(r'^/raw$', problem.ProblemRaw.as_view(), name='problem_raw'),
|
||||
url(r'^/pdf$', problem.ProblemPdfView.as_view(), name='problem_pdf'),
|
||||
url(r'^/pdf/(?P<language>[a-z-]+)$', problem.ProblemPdfView.as_view(), name='problem_pdf'),
|
||||
|
|
|
@ -8,7 +8,7 @@ from statici18n.templatetags.statici18n import inlinei18n
|
|||
|
||||
from judge.highlight_code import highlight_code
|
||||
from judge.user_translations import gettext
|
||||
from . import (camo, datetime, filesize, gravatar, language, markdown, rating, reference, render, social,
|
||||
from . import (camo, chat, datetime, filesize, gravatar, language, markdown, rating, reference, render, social,
|
||||
spaceless, submission, timedelta)
|
||||
from . import registry
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from judge.utils.camo import client as camo_client
|
||||
from . import registry
|
||||
|
||||
|
||||
@registry.filter
|
||||
def camo(url):
|
||||
if camo_client is None:
|
||||
|
|
6
judge/jinja2/chat.py
Normal file
6
judge/jinja2/chat.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from . import registry
|
||||
from chat_box.utils import encrypt_url
|
||||
|
||||
@registry.function
|
||||
def chat_param(request_profile, profile):
|
||||
return encrypt_url(request_profile.id, profile.id)
|
|
@ -12,6 +12,7 @@ from lxml.etree import ParserError, XMLSyntaxError
|
|||
from judge.highlight_code import highlight_code
|
||||
from judge.jinja2.markdown.lazy_load import lazy_load as lazy_load_processor
|
||||
from judge.jinja2.markdown.math import MathInlineGrammar, MathInlineLexer, MathRenderer
|
||||
from judge.jinja2.markdown.spoiler import SpoilerInlineGrammar, SpoilerInlineLexer, SpoilerRenderer
|
||||
from judge.utils.camo import client as camo_client
|
||||
from judge.utils.texoid import TEXOID_ENABLED, TexoidRenderer
|
||||
from .. import registry
|
||||
|
@ -26,15 +27,15 @@ class CodeSafeInlineGrammar(mistune.InlineGrammar):
|
|||
emphasis = re.compile(r'^\*((?:\*\*|[^\*])+?)()\*(?!\*)') # *word*
|
||||
|
||||
|
||||
class AwesomeInlineGrammar(MathInlineGrammar, CodeSafeInlineGrammar):
|
||||
class AwesomeInlineGrammar(MathInlineGrammar, SpoilerInlineGrammar, CodeSafeInlineGrammar):
|
||||
pass
|
||||
|
||||
|
||||
class AwesomeInlineLexer(MathInlineLexer, mistune.InlineLexer):
|
||||
class AwesomeInlineLexer(MathInlineLexer, SpoilerInlineLexer, mistune.InlineLexer):
|
||||
grammar_class = AwesomeInlineGrammar
|
||||
|
||||
|
||||
class AwesomeRenderer(MathRenderer, mistune.Renderer):
|
||||
class AwesomeRenderer(MathRenderer, SpoilerRenderer, mistune.Renderer):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.nofollow = kwargs.pop('nofollow', True)
|
||||
self.texoid = TexoidRenderer() if kwargs.pop('texoid', False) else None
|
||||
|
@ -128,7 +129,6 @@ def markdown(value, style, math_engine=None, lazy_load=False):
|
|||
markdown = mistune.Markdown(renderer=renderer, inline=AwesomeInlineLexer,
|
||||
parse_block_html=1, parse_inline_html=1)
|
||||
result = markdown(value)
|
||||
|
||||
if post_processors:
|
||||
try:
|
||||
tree = html.fromstring(result, parser=html.HTMLParser(recover=True))
|
||||
|
|
27
judge/jinja2/markdown/spoiler.py
Normal file
27
judge/jinja2/markdown/spoiler.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
import re
|
||||
import mistune
|
||||
|
||||
|
||||
class SpoilerInlineGrammar(mistune.InlineGrammar):
|
||||
spoiler = re.compile(r'^\|\|(.+?)\s+([\s\S]+?)\s*\|\|')
|
||||
|
||||
|
||||
class SpoilerInlineLexer(mistune.InlineLexer):
|
||||
grammar_class = SpoilerInlineGrammar
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.default_rules.insert(0, 'spoiler')
|
||||
super(SpoilerInlineLexer, self).__init__(*args, **kwargs)
|
||||
|
||||
def output_spoiler(self, m):
|
||||
return self.renderer.spoiler(m.group(1), m.group(2))
|
||||
|
||||
|
||||
class SpoilerRenderer(mistune.Renderer):
|
||||
def spoiler(self, summary, text):
|
||||
return '''<details>
|
||||
<summary style="color: brown">
|
||||
<span class="spoiler-summary">%s</span>
|
||||
</summary>
|
||||
<div class="spoiler-text">%s</div>
|
||||
</details>''' % (summary, text)
|
|
@ -21,7 +21,7 @@ from django.utils.functional import cached_property
|
|||
from django.utils.html import escape, format_html
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext as _, gettext_lazy
|
||||
from django.views.generic import ListView, View
|
||||
from django.views.generic import DetailView, ListView, View
|
||||
from django.views.generic.base import TemplateResponseMixin
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
|
||||
|
@ -154,13 +154,10 @@ class ProblemRaw(ProblemMixin, TitleMixin, TemplateResponseMixin, SingleObjectMi
|
|||
))
|
||||
|
||||
|
||||
class ProblemDetail(ProblemMixin, SolvedProblemMixin, CommentedDetailView):
|
||||
class ProblemDetail(ProblemMixin, SolvedProblemMixin, DetailView):
|
||||
context_object_name = 'problem'
|
||||
template_name = 'problem/problem.html'
|
||||
|
||||
def get_comment_page(self):
|
||||
return 'p:%s' % self.object.code
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(ProblemDetail, self).get_context_data(**kwargs)
|
||||
user = self.request.user
|
||||
|
@ -221,6 +218,21 @@ class ProblemDetail(ProblemMixin, SolvedProblemMixin, CommentedDetailView):
|
|||
return context
|
||||
|
||||
|
||||
class ProblemComments(ProblemMixin, TitleMixin, CommentedDetailView):
|
||||
context_object_name = 'problem'
|
||||
template_name = 'problem/comments.html'
|
||||
|
||||
def get_title(self):
|
||||
return _('Disscuss {0}').format(self.object.name)
|
||||
|
||||
def get_content_title(self):
|
||||
return format_html(_(u'Discuss <a href="{1}">{0}</a>'), self.object.name,
|
||||
reverse('problem_detail', args=[self.object.code]))
|
||||
|
||||
def get_comment_page(self):
|
||||
return 'p:%s' % self.object.code
|
||||
|
||||
|
||||
class LatexError(Exception):
|
||||
pass
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -112,6 +112,7 @@
|
|||
margin-left: 10px;
|
||||
font-size: 2em;
|
||||
font-weight: bold !important;
|
||||
display: flex;
|
||||
}
|
||||
.info-name a {
|
||||
display: table-caption;
|
||||
|
|
|
@ -517,11 +517,17 @@ ul.select2-selection__rendered {
|
|||
}
|
||||
}
|
||||
|
||||
details {
|
||||
border: 1px solid $border_gray;
|
||||
background: $background_light_gray;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
.spoiler-text {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
margin-top: 0.5em;
|
||||
border-radius: 5px;
|
||||
background: #def;
|
||||
}
|
||||
|
||||
.spoiler-summary {
|
||||
padding-left: 0.5em;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
|
|
|
@ -14,6 +14,12 @@ let message_template = `
|
|||
{% include "chat/message.html" %}
|
||||
{% endwith %}
|
||||
`;
|
||||
let META_HEADER = [
|
||||
"{{_('Recent')}}",
|
||||
"{{_('Following')}}",
|
||||
"{{_('Admin')}}",
|
||||
"{{_('Other')}}",
|
||||
];
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
window.currentPage = 1;
|
||||
|
|
|
@ -26,7 +26,13 @@
|
|||
</button>
|
||||
<div id="setting-content">
|
||||
<li>
|
||||
<a href="{{url('toggle_ignore', other_user.id)}}" style="color: {{'green' if is_ignored else 'red'}}">{{_('Unignore') if is_ignored else _('Ignore')}}</a>
|
||||
<a href="{{url('toggle_ignore', other_user.id)}}" style="color: {{'green' if is_ignored else 'red'}}">
|
||||
{% if is_ignored %}
|
||||
{{_('Unignore')}}
|
||||
{% else %}
|
||||
{{_('Ignore')}}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</span>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div id="comments" class="comment-area">
|
||||
<h2><i style="padding-right: 0.3em" class="fa fa-comments"></i>{{ _('Comments') }}</h2>
|
||||
<h2 id="comment-header"><i style="padding-right: 0.3em" class="fa fa-comments"></i>{{ _('Comments') }}</h2>
|
||||
{% if has_comments %}
|
||||
<ul class="comments top-level-comments new-comments">
|
||||
{% set logged_in = request.user.is_authenticated %}
|
||||
|
|
25
templates/problem/comments.html
Normal file
25
templates/problem/comments.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
{% extends "common-content.html" %}
|
||||
|
||||
{% block content_js_media %}
|
||||
{% include "comments/media-js.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content_media %}
|
||||
{% include "comments/media-css.html" %}
|
||||
<style>
|
||||
#comment-header {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% include "comments/list.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyend %}
|
||||
{% if REQUIRE_JAX %}
|
||||
{% include "mathjax-load.html" %}
|
||||
{% endif %}
|
||||
{% include "comments/math.html" %}
|
||||
{% endblock %}
|
|
@ -1,6 +1,5 @@
|
|||
{% extends "common-content.html" %}
|
||||
{% block content_media %}
|
||||
{% include "comments/media-css.html" %}
|
||||
<style>
|
||||
.title-state {
|
||||
font-size: 2em;
|
||||
|
@ -59,7 +58,6 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content_js_media %}
|
||||
{% include "comments/media-js.html" %}
|
||||
{% if request.in_contest %}
|
||||
<script type="text/javascript">
|
||||
window.register_contest_notification("{{url('contest_clarification_ajax', request.participation.contest.key)}}");
|
||||
|
@ -166,9 +164,10 @@
|
|||
{% endif %}
|
||||
<div><a href="{{ url('chronological_submissions', problem.code) }}">{{ _('All submissions') }}</a></div>
|
||||
<div><a href="{{ url('ranked_submissions', problem.code) }}">{{ _('Best submissions') }}</a></div>
|
||||
<hr>
|
||||
<div><a href="{{ url('problem_comments', problem.code) }}">{{ _('Discuss') }}</a></div>
|
||||
{% if editorial and editorial.is_public and
|
||||
not (request.user.is_authenticated and request.profile.current_contest) %}
|
||||
<hr>
|
||||
<div><a href="{{ url('problem_editorial', problem.code) }}">{{ _('Read editorial') }}</a></div>
|
||||
{% endif %}
|
||||
{% if can_edit_problem %}
|
||||
|
@ -345,7 +344,8 @@
|
|||
|
||||
{% block post_description_end %}
|
||||
{% if request.user.is_authenticated and not request.profile.mute %}
|
||||
<a href="{{ url('new_problem_ticket', problem.code) }}" class="button clarify">
|
||||
<a href="{{ url('new_problem_ticket', problem.code) }}" class="clarify">
|
||||
<i class="fa fa-flag" style="margin-right:0.5em"></i>
|
||||
{%- if contest_problem and contest_problem.contest.use_clarifications and request.profile.current_contest.live -%}
|
||||
{{ _('Request clarification') }}
|
||||
{%- else -%}
|
||||
|
@ -372,8 +372,6 @@
|
|||
<p class="no-comments-message">{{ _('No clarifications have been made at this time.') }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{% include "comments/list.html" %}
|
||||
{% endif %}
|
||||
<iframe name="raw_problem" id="raw_problem"></iframe>
|
||||
{% endblock %}
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<input type="submit" value="{{ _('View submissions') }}" style="width:135px">
|
||||
</form>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<form action="{{ url('get_or_create_room') }}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" value="{{ chat_param(request.profile, user)}}" name="other">
|
||||
<input type="submit" value="{{ _('Send message') }}" style="width:135px">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if ratings %}
|
||||
<br>
|
||||
|
|
Loading…
Reference in a new issue