feat: dark mode

This commit is contained in:
Baoshuo Ren 2023-02-23 18:28:20 +08:00
parent df7d1784d3
commit b98edf87b0
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
17 changed files with 2286 additions and 392 deletions

View File

@ -35,7 +35,7 @@ foreach ($problem_configure->problem_conf->conf as $key => $val) {
<div class="card-header fw-bold">problem.conf 预览</div> <div class="card-header fw-bold">problem.conf 预览</div>
<div class="card-body p-0" id="problem-conf-preview"> <div class="card-body p-0" id="problem-conf-preview">
<pre class="bg-light mb-0 p-3"><code><?= $problem_conf_str ?></code></pre> <pre class="bg-body-tertiary mb-0 p-3"><code><?= $problem_conf_str ?></code></pre>
</div> </div>
<div class="card-footer bg-transparent small text-muted"> <div class="card-footer bg-transparent small text-muted">

View File

@ -50,7 +50,7 @@ function echoFilePre($file_name) {
echo '<h5 class="mb-1">', htmlspecialchars($file_name), '</h5>'; echo '<h5 class="mb-1">', htmlspecialchars($file_name), '</h5>';
echo '<div class="text-muted small mb-1 font-monospace">', $mimetype, '</div>'; echo '<div class="text-muted small mb-1 font-monospace">', $mimetype, '</div>';
echo '<pre class="bg-light rounded uoj-pre">', "\n"; echo '<pre class="bg-body-tertiary rounded uoj-pre">', "\n";
$output_limit = 1000; $output_limit = 1000;
if (strStartWith($mimetype, 'text/')) { if (strStartWith($mimetype, 'text/')) {
@ -124,7 +124,7 @@ $info_form->appendHTML(<<<EOD
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-3 control-label">提交文件配置</label> <label class="col-sm-3 control-label">提交文件配置</label>
<div class="col-sm-9"> <div class="col-sm-9">
<pre class="uoj-pre bg-light rounded"> <pre class="uoj-pre bg-body-tertiary rounded">
$esc_submission_requirement $esc_submission_requirement
</pre> </pre>
</div> </div>
@ -135,7 +135,7 @@ $info_form->appendHTML(<<<EOD
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-3 control-label">其它配置</label> <label class="col-sm-3 control-label">其它配置</label>
<div class="col-sm-9"> <div class="col-sm-9">
<pre class="uoj-pre bg-light rounded"> <pre class="uoj-pre bg-body-tertiary rounded">
$esc_extra_config $esc_extra_config
</pre> </pre>
</div> </div>

View File

@ -77,7 +77,7 @@ EOD;
die(); die();
}; };
$new_problem_form->config['submit_container']['class'] = ''; $new_problem_form->config['submit_container']['class'] = '';
$new_problem_form->config['submit_button']['class'] = 'bg-transparent border-0 d-block w-100 px-3 py-2 text-start'; $new_problem_form->config['submit_button']['class'] = 'bg-transparent text-body border-0 d-block w-100 px-3 py-2 text-start';
$new_problem_form->config['submit_button']['text'] = '<i class="bi bi-plus-lg"></i> 新建本地题目'; $new_problem_form->config['submit_button']['text'] = '<i class="bi bi-plus-lg"></i> 新建本地题目';
$new_problem_form->config['confirm']['text'] = '你真的要添加新题吗?'; $new_problem_form->config['confirm']['text'] = '你真的要添加新题吗?';
$new_problem_form->runAtServer(); $new_problem_form->runAtServer();

View File

@ -174,7 +174,7 @@ if (UOJUserBlog::userHasManagePermission(Auth::user())) {
]); ]);
$hide_form->addInput('comment_hide_reason', [ $hide_form->addInput('comment_hide_reason', [
'div_class' => 'mt-3', 'div_class' => 'mt-3',
'label' => '自定义隐藏理由', 'label' => '自定义隐藏理由(当上方隐藏理由为自定义时有效)',
'default_value' => '该评论由于违反社区规定,已被管理员隐藏', 'default_value' => '该评论由于违反社区规定,已被管理员隐藏',
'validator_php' => 'validateString', 'validator_php' => 'validateString',
]); ]);
@ -327,9 +327,10 @@ $comments_pag = new Paginator([
<script> <script>
$('.uoj-blog-hide-comment-btn').each(function() { $('.uoj-blog-hide-comment-btn').each(function() {
$(this).click(function() { $(this).click(function(event) {
var comment_id = $(this).data('comment-id'); var comment_id = $(this).data('comment-id');
event.preventDefault();
toggleModalHideComment(comment_id, $('#comment-content-' + comment_id).html()); toggleModalHideComment(comment_id, $('#comment-content-' + comment_id).html());
}); });
}) })

View File

@ -355,7 +355,7 @@ function echoSubmissionContent($submission, $requirement) {
echo '<h4 class="card-title">' . $req['name'] . '</h4>'; echo '<h4 class="card-title">' . $req['name'] . '</h4>';
echo '</div>'; echo '</div>';
echo '<div class="card-body">'; echo '<div class="card-body">';
echo '<pre><code class="' . $sh_class . ' bg-light rounded p-3">' . $file_content . "\n" . '</code></pre>'; echo '<pre><code class="' . $sh_class . ' bg-body-tertiary rounded p-3">' . $file_content . "\n" . '</code></pre>';
echo '</div>'; echo '</div>';
echo '<div class="card-footer">' . $footer_text . '</div>'; echo '<div class="card-footer">' . $footer_text . '</div>';
echo '</div>'; echo '</div>';
@ -369,7 +369,7 @@ function echoSubmissionContent($submission, $requirement) {
echo '<h4 class="card-title">' . $req['file_name'] . '</h4>'; echo '<h4 class="card-title">' . $req['file_name'] . '</h4>';
echo '</div>'; echo '</div>';
echo '<div class="card-body">'; echo '<div class="card-body">';
echo '<pre class="bg-light rounded p-3 ">', "\n" . $file_content . "\n" . '</pre>'; echo '<pre class="bg-body-tertiary rounded p-3 ">', "\n" . $file_content . "\n" . '</pre>';
echo '</div>'; echo '</div>';
echo '<div class="card-footer">' . $footer_text . '</div>'; echo '<div class="card-footer">' . $footer_text . '</div>';
echo '</div>'; echo '</div>';
@ -406,7 +406,7 @@ class JudgmentDetailsPrinter {
} }
private function _print(DOMElement $node) { private function _print(DOMElement $node) {
if ($node->nodeName == 'error') { if ($node->nodeName == 'error') {
echo '<pre class="bg-light rounded p-3">', "\n"; echo '<pre class="bg-body-tertiary rounded p-3">', "\n";
$this->_print_c($node); $this->_print_c($node);
echo "\n</pre>"; echo "\n</pre>";
} elseif ($node->nodeName == 'remote-result-container') { } elseif ($node->nodeName == 'remote-result-container') {
@ -432,7 +432,7 @@ class JudgmentDetailsPrinter {
$language = $node->getAttribute("language"); $language = $node->getAttribute("language");
echo '<div class="border-bottom p-3 copy-button-container">'; echo '<div class="border-bottom p-3 copy-button-container">';
echo '<div class="fw-bold mb-2">源代码</div>'; echo '<div class="fw-bold mb-2">源代码</div>';
echo '<pre class="mb-0"><code class="language-', $language, ' bg-light rounded p-3">'; echo '<pre class="mb-0"><code class="language-', $language, ' bg-body-tertiary rounded p-3">';
$this->_print_c($node); $this->_print_c($node);
echo "</code></pre>"; echo "</code></pre>";
echo '</div>'; echo '</div>';
@ -662,22 +662,22 @@ class JudgmentDetailsPrinter {
} }
} elseif ($node->nodeName == 'in') { } elseif ($node->nodeName == 'in') {
echo '<h4 class="fs-6 fw-bold">输入文件</h4>'; echo '<h4 class="fs-6 fw-bold">输入文件</h4>';
echo '<pre class="bg-light p-3 rounded">', "\n"; echo '<pre class="bg-body-tertiary p-3 rounded">', "\n";
$this->_print_c($node); $this->_print_c($node);
echo "\n</pre>"; echo "\n</pre>";
} elseif ($node->nodeName == 'out') { } elseif ($node->nodeName == 'out') {
echo '<h4 class="fs-6 fw-bold">程序输出</h4>'; echo '<h4 class="fs-6 fw-bold">程序输出</h4>';
echo '<pre class="bg-light p-3 rounded">', "\n"; echo '<pre class="bg-body-tertiary p-3 rounded">', "\n";
$this->_print_c($node); $this->_print_c($node);
echo "\n</pre>"; echo "\n</pre>";
} elseif ($node->nodeName == 'ans') { } elseif ($node->nodeName == 'ans') {
echo '<h4 class="fs-6 fw-bold">答案文件</h4>'; echo '<h4 class="fs-6 fw-bold">答案文件</h4>';
echo '<pre class="bg-light p-3 rounded">', "\n"; echo '<pre class="bg-body-tertiary p-3 rounded">', "\n";
$this->_print_c($node); $this->_print_c($node);
echo "\n</pre>"; echo "\n</pre>";
} elseif ($node->nodeName == 'res') { } elseif ($node->nodeName == 'res') {
echo '<h4 class="fs-6 fw-bold"><span>检查器信息</span></h4>'; echo '<h4 class="fs-6 fw-bold"><span>检查器信息</span></h4>';
echo '<pre class="bg-light p-3 rounded">', "\n"; echo '<pre class="bg-body-tertiary p-3 rounded">', "\n";
if ($node->hasChildNodes()) { if ($node->hasChildNodes()) {
$this->_print_c($node); $this->_print_c($node);
} else { } else {
@ -698,7 +698,7 @@ class JudgmentDetailsPrinter {
} }
echo '<h4 class="mb-2">', $node->getAttribute("title"), ":</h4>"; echo '<h4 class="mb-2">', $node->getAttribute("title"), ":</h4>";
} }
echo '<pre class="bg-light p-3 rounded">', "\n"; echo '<pre class="bg-body-tertiary p-3 rounded">', "\n";
$this->_print_c($node); $this->_print_c($node);
echo "\n</pre>"; echo "\n</pre>";
echo '</div>'; echo '</div>';

View File

@ -73,7 +73,7 @@ class UOJProblemDataDisplayer {
echo '<h5 class="mb-1">', HTML::escape($file_name), '</h5>'; echo '<h5 class="mb-1">', HTML::escape($file_name), '</h5>';
echo '<div class="text-muted small mb-1 font-monospace">', $mimetype, '</div>'; echo '<div class="text-muted small mb-1 font-monospace">', $mimetype, '</div>';
echo '<pre class="bg-light rounded uoj-pre">', "\n"; echo '<pre class="bg-body-tertiary rounded uoj-pre">', "\n";
$type = $mimetype == 'binary' ? 'binary' : 'text'; $type = $mimetype == 'binary' ? 'binary' : 'text';
echo HTML::escape(uojStringPreview($content, $max_len, $type)); echo HTML::escape(uojStringPreview($content, $max_len, $type));
echo "\n</pre>"; echo "\n</pre>";

View File

@ -218,7 +218,7 @@ trait UOJSubmissionLikeTrait {
{$req['name']} {$req['name']}
</div> </div>
<div class="{$card_body_class} copy-button-container"> <div class="{$card_body_class} copy-button-container">
<pre class="mb-0"><code class="$sh_class bg-light rounded p-3">{$file_content}\n</code></pre> <pre class="mb-0"><code class="$sh_class bg-body-tertiary rounded p-3">{$file_content}\n</code></pre>
</div> </div>
<div class="{$card_footer_class}">$footer_text</div> <div class="{$card_footer_class}">$footer_text</div>
</div> </div>
@ -238,7 +238,7 @@ trait UOJSubmissionLikeTrait {
{$req['file_name']} {$req['file_name']}
</div> </div>
<div class="{$card_body_class}"> <div class="{$card_body_class}">
<pre class="mb-0 bg-light rounded p-3">\n{$file_content}\n</pre> <pre class="mb-0 bg-body-tertiary rounded p-3">\n{$file_content}\n</pre>
</div> </div>
<div class="{$card_footer_class}">{$footer_text}</div> <div class="{$card_footer_class}">{$footer_text}</div>
</div> </div>

View File

@ -1,4 +1,4 @@
<div class="navbar navbar-light navbar-expand-md bg-white shadow-sm mb-4" role="navigation"> <div class="navbar navbar-light navbar-expand-md bg-body shadow-sm mb-4" role="navigation">
<div class="container"> <div class="container">
@ -41,98 +41,11 @@
<hr class="d-md-none text-muted"> <hr class="d-md-none text-muted">
<ul class="nav navbar-nav ms-md-auto"> <?php uojIncludeView('nav-right', [
<li class="nav-item dropdown"> 'new_msg_tot' => $new_msg_tot,
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"> 'new_user_msg_num' => $new_user_msg_num,
<i class="bi bi-translate"></i> 'new_system_msg_num' => $new_system_msg_num,
<?= UOJLocale::get('_common_name') ?> ]) ?>
</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="<?= HTML::url(UOJContext::requestURI(), array('params' => array('locale' => 'zh-cn'))) ?>">
中文
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url(UOJContext::requestURI(), array('params' => array('locale' => 'en'))) ?>">
English
</a>
</li>
</ul>
</li>
<?php if (Auth::check()) : ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-fill"></i>
<span class="position-relative">
<?= Auth::id() ?>
<?php if ($new_msg_tot) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_msg_tot > 99 ? "99+" : $new_msg_tot ?>
</span>
<?php endif ?>
</span>
</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="<?= HTML::url('/user/' . Auth::id()) ?>">
<?= UOJLocale::get('my profile') ?>
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/user_msg') ?>">
<?= UOJLocale::get('private message') ?>
<?php if ($new_user_msg_num) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_user_msg_num > 99 ? "99+" : $new_user_msg_num ?>
</span>
<?php endif ?>
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/user/' . Auth::id() . '/system_msg') ?>">
<?= UOJLocale::get('system message') ?>
<?php if ($new_system_msg_num) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_system_msg_num > 99 ? "99+" : $new_system_msg_num ?>
</span>
<?php endif ?>
</a>
</li>
<?php if (isSuperUser(Auth::user())) : ?>
<li>
<a class="dropdown-item" href="<?= HTML::url('/super_manage') ?>">
<?= UOJLocale::get('system manage') ?>
</a>
</li>
<?php endif ?>
<li>
<hr class="dropdown-divider">
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/logout?_token=' . crsf_token()) ?>">
<?= UOJLocale::get('logout') ?>
</a>
</li>
</ul>
</li>
<?php else : ?>
<li class="nav-item">
<a class="nav-link" href="<?= HTML::url('/login') ?>">
<i class="bi bi-box-arrow-in-right"></i>
<?= UOJLocale::get('login') ?>
</a>
</li>
<?php if (UOJConfig::$data['switch']['open-register'] || !DB::selectCount("SELECT COUNT(*) FROM user_info")) : ?>
<li class="nav-item">
<a class="nav-link" href="<?= HTML::url('/register') ?>">
<i class="bi bi-person-plus-fill"></i>
<?= UOJLocale::get('register') ?>
</a>
</li>
<?php endif ?>
<?php endif ?>
</ul>
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,7 +4,7 @@ $new_system_msg_num = DB::selectCount("select count(*) from user_system_msg wher
$new_msg_tot = $new_user_msg_num + $new_system_msg_num; $new_msg_tot = $new_user_msg_num + $new_system_msg_num;
?> ?>
<div class="navbar navbar-light navbar-expand-md bg-white shadow-sm <div class="navbar navbar-light navbar-expand-md bg-body shadow-sm
<?php if (!isset($disable_navbar_margin_bottom)) : ?> <?php if (!isset($disable_navbar_margin_bottom)) : ?>
mb-4 mb-4
<?php endif ?> <?php endif ?>
@ -99,98 +99,11 @@ mb-4
<hr class="d-md-none text-muted"> <hr class="d-md-none text-muted">
<ul class="nav navbar-nav ms-md-auto"> <?php uojIncludeView('nav-right', [
<li class="nav-item dropdown"> 'new_msg_tot' => $new_msg_tot,
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"> 'new_user_msg_num' => $new_user_msg_num,
<i class="bi bi-translate"></i> 'new_system_msg_num' => $new_system_msg_num,
<?= UOJLocale::get('_common_name') ?> ]) ?>
</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="<?= HTML::url(UOJContext::requestURI(), array('params' => array('locale' => 'zh-cn'))) ?>">
中文
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url(UOJContext::requestURI(), array('params' => array('locale' => 'en'))) ?>">
English
</a>
</li>
</ul>
</li>
<?php if (Auth::check()) : ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-fill"></i>
<span class="position-relative">
<?= Auth::id() ?>
<?php if ($new_msg_tot) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_msg_tot > 99 ? "99+" : $new_msg_tot ?>
</span>
<?php endif ?>
</span>
</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="<?= HTML::url('/user/' . Auth::id()) ?>">
<?= UOJLocale::get('my profile') ?>
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/user_msg') ?>">
<?= UOJLocale::get('private message') ?>
<?php if ($new_user_msg_num) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_user_msg_num > 99 ? "99+" : $new_user_msg_num ?>
</span>
<?php endif ?>
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/user/' . Auth::id() . '/system_msg') ?>">
<?= UOJLocale::get('system message') ?>
<?php if ($new_system_msg_num) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_system_msg_num > 99 ? "99+" : $new_system_msg_num ?>
</span>
<?php endif ?>
</a>
</li>
<?php if (isSuperUser(Auth::user())) : ?>
<li>
<a class="dropdown-item" href="<?= HTML::url('/super_manage') ?>">
<?= UOJLocale::get('system manage') ?>
</a>
</li>
<?php endif ?>
<li>
<hr class="dropdown-divider">
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/logout?_token=' . crsf_token()) ?>">
<?= UOJLocale::get('logout') ?>
</a>
</li>
</ul>
</li>
<?php else : ?>
<li class="nav-item">
<a class="nav-link" href="<?= HTML::url('/login') ?>">
<i class="bi bi-box-arrow-in-right"></i>
<?= UOJLocale::get('login') ?>
</a>
</li>
<?php if (UOJConfig::$data['switch']['open-register'] || !DB::selectCount("SELECT COUNT(*) FROM user_info")) : ?>
<li class="nav-item">
<a class="nav-link" href="<?= HTML::url('/register') ?>">
<i class="bi bi-person-plus-fill"></i>
<?= UOJLocale::get('register') ?>
</a>
</li>
<?php endif ?>
<?php endif ?>
</ul>
</div> </div>
</div> </div>

118
web/app/views/nav-right.php Normal file
View File

@ -0,0 +1,118 @@
<ul class="nav navbar-nav ms-md-auto">
<li class="nav-item dropdown">
<button class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center" id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" data-bs-display="static">
<i class="bi bi-circle-half theme-icon-active" data-icon="bi-circle-half"></i>
<span class="d-lg-none">&nbsp;切换主题</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-theme" style="--bs-dropdown-min-width: 6rem;">
<li>
<button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="auto">
<i class="bi bi-circle-half me-2 opacity-50 theme-icon" data-icon="bi-circle-half"></i>
系统
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light">
<i class="bi bi-sun-fill me-2 opacity-50 theme-icon" data-icon="bi-sun-fill"></i>
亮色
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark">
<i class="bi bi-moon-stars-fill me-2 opacity-50 theme-icon" data-icon="bi-moon-stars-fill"></i>
暗色
</button>
</li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-translate"></i>
<?= UOJLocale::get('_common_name') ?>
</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="<?= HTML::url(UOJContext::requestURI(), array('params' => array('locale' => 'zh-cn'))) ?>">
中文
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url(UOJContext::requestURI(), array('params' => array('locale' => 'en'))) ?>">
English
</a>
</li>
</ul>
</li>
<?php if (Auth::check()) : ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-fill"></i>
<span class="position-relative">
<?= Auth::id() ?>
<?php if ($new_msg_tot) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_msg_tot > 99 ? "99+" : $new_msg_tot ?>
</span>
<?php endif ?>
</span>
</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="<?= HTML::url('/user/' . Auth::id()) ?>">
<?= UOJLocale::get('my profile') ?>
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/user_msg') ?>">
<?= UOJLocale::get('private message') ?>
<?php if ($new_user_msg_num) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_user_msg_num > 99 ? "99+" : $new_user_msg_num ?>
</span>
<?php endif ?>
</a>
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/user/' . Auth::id() . '/system_msg') ?>">
<?= UOJLocale::get('system message') ?>
<?php if ($new_system_msg_num) : ?>
<span class="badge bg-danger rounded-pill">
<?= $new_system_msg_num > 99 ? "99+" : $new_system_msg_num ?>
</span>
<?php endif ?>
</a>
</li>
<?php if (isSuperUser(Auth::user())) : ?>
<li>
<a class="dropdown-item" href="<?= HTML::url('/super_manage') ?>">
<?= UOJLocale::get('system manage') ?>
</a>
</li>
<?php endif ?>
<li>
<hr class="dropdown-divider">
</li>
<li>
<a class="dropdown-item" href="<?= HTML::url('/logout?_token=' . crsf_token()) ?>">
<?= UOJLocale::get('logout') ?>
</a>
</li>
</ul>
</li>
<?php else : ?>
<li class="nav-item">
<a class="nav-link" href="<?= HTML::url('/login') ?>">
<i class="bi bi-box-arrow-in-right"></i>
<?= UOJLocale::get('login') ?>
</a>
</li>
<?php if (UOJConfig::$data['switch']['open-register'] || !DB::selectCount("SELECT COUNT(*) FROM user_info")) : ?>
<li class="nav-item">
<a class="nav-link" href="<?= HTML::url('/register') ?>">
<i class="bi bi-person-plus-fill"></i>
<?= UOJLocale::get('register') ?>
</a>
</li>
<?php endif ?>
<?php endif ?>
</ul>

View File

@ -11,7 +11,7 @@ if (!isset($ShowPageFooter)) {
</script> </script>
<?php endif ?> <?php endif ?>
<footer class="bg-white text-muted pt-3 pb-4 mt-4" style="font-size: 0.9em"> <footer class="bg-body text-muted pt-3 pb-4 mt-4" style="font-size: 0.9em">
<div class="container d-lg-flex justify-content-lg-between"> <div class="container d-lg-flex justify-content-lg-between">
<div> <div>
<div> <div>

View File

@ -188,7 +188,7 @@ if (!isset($PageContainerClass)) {
<?php endif ?> <?php endif ?>
<?php if (isset($REQUIRE_LIB['hljs'])) : ?> <?php if (isset($REQUIRE_LIB['hljs'])) : ?>
<?= HTML::css_link('/css/highlightjs.github.min.css?v=11.6.0-20221005') ?> <?= HTML::css_link('/css/highlightjs.github.min.css?v=11.6.0-20230223') ?>
<?= HTML::js_src('/js/highlightjs.min.js?v=11.6.0-20221005') ?> <?= HTML::js_src('/js/highlightjs.min.js?v=11.6.0-20221005') ?>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
@ -242,7 +242,7 @@ if (!isset($PageContainerClass)) {
<body class="d-flex flex-column min-vh-100 <body class="d-flex flex-column min-vh-100
<?php if ($ShowPageHeader) : ?> <?php if ($ShowPageHeader) : ?>
bg-light bg-body-tertiary
<?php endif ?>"> <?php endif ?>">
<?php if ($ShowPageHeader) : ?> <?php if ($ShowPageHeader) : ?>
<?php uojIncludeView($PageNav, array('REQUIRE_LIB' => $REQUIRE_LIB)) ?> <?php uojIncludeView($PageNav, array('REQUIRE_LIB' => $REQUIRE_LIB)) ?>

View File

@ -1 +1,141 @@
pre code.hljs{display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:rgba(var(--bs-light-rgb))}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0} :root,
[data-bs-theme='light'] {
--hljs-color: #24292e;
--hljs-keyword: #d73a49;
--hljs-title: #6f42c1;
--hljs-attr: #005cc5;
--hljs-string: #032f62;
--hljs-symbol: #e36209;
--hljs-comment: #6a737d;
--hljs-quote: #22863a;
--hljs-subst: #24292e;
--hljs-selection: #005cc5;
--hljs-bullet: #735c0f;
--hljs-emphasis: #24292e;
--hljs-strong: #24292e;
--hljs-addition: #22863a;
--hljs-addition-bg: #f0fff4;
--hljs-deletion: #b31d28;
--hljs-deletion-bg: #ffeef0;
}
[data-bs-theme='dark'] {
--hljs-color: #c9d1d9;
--hljs-keyword: #ff7b72;
--hljs-title: #d2a8ff;
--hljs-attr: #79c0ff;
--hljs-string: #a5d6ff;
--hljs-symbol: #ffa657;
--hljs-comment: #8b949e;
--hljs-quote: #7ee787;
--hljs-subst: #c9d1d9;
--hljs-selection: #1f6feb;
--hljs-bullet: #f2cc60;
--hljs-emphasis: #c9d1d9;
--hljs-strong: #c9d1d9;
--hljs-addition: #aff5b4;
--hljs-addition-bg: #033a16;
--hljs-deletion: #ffdcd7;
--hljs-deletion-bg: #67060c;
}
pre code.hljs {
display: block;
overflow-x: auto;
}
code.hljs {
padding: 3px 5px;
}
.hljs {
color: var(--hljs-color);
background: var(--bs-tertiary-bg);
}
.hljs-doctag,
.hljs-keyword,
.hljs-meta .hljs-keyword,
.hljs-template-tag,
.hljs-template-variable,
.hljs-type,
.hljs-variable.language_ {
color: var(--hljs-keyword);
}
.hljs-title,
.hljs-title.class_,
.hljs-title.class_.inherited__,
.hljs-title.function_ {
color: var(--hljs-title);
}
.hljs-attr,
.hljs-attribute,
.hljs-literal,
.hljs-meta,
.hljs-number,
.hljs-operator,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-id,
.hljs-variable {
color: var(--hljs-attr);
}
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: var(--hljs-string);
}
.hljs-built_in,
.hljs-symbol {
color: var(--hljs-symbol);
}
.hljs-code,
.hljs-comment,
.hljs-formula {
color: var(--hljs-comment);
}
.hljs-name,
.hljs-quote,
.hljs-selector-pseudo,
.hljs-selector-tag {
color: var(--hljs-quote);
}
.hljs-subst {
color: var(--hljs-subst);
}
.hljs-section {
color: var(--hljs-selection);
font-weight: 700;
}
.hljs-bullet {
color: var(--hljs-bullet);
}
.hljs-emphasis {
color: var(--hljs-emphasis);
font-style: italic;
}
.hljs-strong {
color: var(--hljs-strong);
font-weight: 700;
}
.hljs-addition {
color: var(--hljs-addition);
background-color: var(--hljs-addition-bg);
}
.hljs-deletion {
color: var(--hljs-deletion);
background-color: var(--hljs-deletion-bg);
}

View File

@ -294,7 +294,7 @@ h6,
.markdown-body pre { .markdown-body pre {
padding: 1em; padding: 1em;
background-color: rgba(var(--bs-light-rgb)); background-color: var(--bs-tertiary-bg);
} }
.markdown-body table th[align='left'] { .markdown-body table th[align='left'] {

View File

@ -100,7 +100,6 @@ function blog_editor_init(name, editor_config) {
enabled: false, enabled: false,
}, },
wordWrap: 'on', wordWrap: 'on',
theme: 'vs',
unicodeHighlight: { unicodeHighlight: {
ambiguousCharacters: false, ambiguousCharacters: false,
}, },

File diff suppressed because it is too large Load Diff

View File

@ -602,6 +602,8 @@ function require_monaco(config, callback) {
.script('/js/monaco-editor/min/vs/editor/editor.main.nls.zh-cn.js').wait() .script('/js/monaco-editor/min/vs/editor/editor.main.nls.zh-cn.js').wait()
.script('/js/monaco-editor/min/vs/editor/editor.main.js').wait(function() { .script('/js/monaco-editor/min/vs/editor/editor.main.js').wait(function() {
$LAB.script('/js/monaco-themes.js').wait(function() { $LAB.script('/js/monaco-themes.js').wait(function() {
update_monaco_theme(getPreferredTheme());
if (config.markdown) { if (config.markdown) {
$LAB.script('/js/blog-editor/monaco-markdown.js').wait(callback); $LAB.script('/js/blog-editor/monaco-markdown.js').wait(callback);
} else { } else {
@ -611,6 +613,16 @@ function require_monaco(config, callback) {
}); });
} }
function update_monaco_theme(theme) {
if (!('monaco' in window)) return;
if (theme == 'dark') {
monaco.editor.setTheme('github-dark');
} else {
monaco.editor.setTheme('github');
}
}
function get_monaco_mode(lang) { function get_monaco_mode(lang) {
switch (lang) { switch (lang) {
case 'C++': case 'C++':
@ -1365,7 +1377,7 @@ $.fn.problem_conf_preview = function(problem_conf) {
res += key + ' ' + value + '\n'; res += key + ' ' + value + '\n';
} }
$(this).html('<pre class="bg-light mb-0 p-3"><code>' + res + '</code></pre>'); $(this).html('<pre class="bg-body-tertiary mb-0 p-3"><code>' + res + '</code></pre>');
}); });
} }
@ -1698,7 +1710,8 @@ function showCommentReplies(id, replies) {
).append( ).append(
user_can_hide_comment user_can_hide_comment
? $('<li class="list-inline-item" />').append( ? $('<li class="list-inline-item" />').append(
$('<a href="#" class="text-warning-emphasis text-decoration-none p-0" />').data('comment-id', reply.id).text('隐藏').click(function() { $('<a href="#" class="text-warning-emphasis text-decoration-none p-0" />').data('comment-id', reply.id).text('隐藏').click(function(event) {
event.preventDefault();
toggleModalHideComment(reply.id, reply.content); toggleModalHideComment(reply.id, reply.content);
}) })
) )
@ -2118,8 +2131,75 @@ $(document).ready(function() {
}); });
}); });
/**
* Fallback user avatar
*/
$(document).ready(function() { $(document).ready(function() {
$('img.uoj-user-avatar').on('error', function() { $('img.uoj-user-avatar').on('error', function() {
// same as gravatar d=mm
$(this).attr('src', 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4NzIgODcyIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMCAwaDg3MnY4NzJIMHoiLz48cGF0aCBmaWxsPSIjYzVjNWM1IiBkPSJNMCAwdjg3MmgxMTBhMzI3IDM4MyAwIDAxMjM2LTM0NSAxOTUgMTk1IDAgMDEtMTA0LTE3MiAxOTUgMTk1IDAgMDExOTUtMTk1IDE5NSAxOTUgMCAwMTE5NSAxOTUgMTk1IDE5NSAwIDAxLTEwNiAxNzMgMzI3IDM4MyAwIDAxMjM2IDM0NGgxMTBWMHoiLz48L3N2Zz4='); $(this).attr('src', 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4NzIgODcyIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMCAwaDg3MnY4NzJIMHoiLz48cGF0aCBmaWxsPSIjYzVjNWM1IiBkPSJNMCAwdjg3MmgxMTBhMzI3IDM4MyAwIDAxMjM2LTM0NSAxOTUgMTk1IDAgMDEtMTA0LTE3MiAxOTUgMTk1IDAgMDExOTUtMTk1IDE5NSAxOTUgMCAwMTE5NSAxOTUgMTk1IDE5NSAwIDAxLTEwNiAxNzMgMzI3IDM4MyAwIDAxMjM2IDM0NGgxMTBWMHoiLz48L3N2Zz4=');
}); });
}); });
function getPreferredTheme() {
if (!('localStorage' in window)) return 'light';
var storedTheme = localStorage.getItem('theme');
if (storedTheme) {
return storedTheme;
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
/**
* Theme toggler
*/
(function() {
if (!('localStorage' in window)) return;
var storedTheme = localStorage.getItem('theme');
function setTheme(theme) {
if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-bs-theme', 'dark');
update_monaco_theme('dark');
} else {
document.documentElement.setAttribute('data-bs-theme', theme);
update_monaco_theme(theme == 'auto' ? 'light' : theme);
}
}
setTheme(getPreferredTheme());
function showActiveTheme(theme) {
var currentIcon = $('.theme-icon-active').attr('data-icon');
var newIcon = $('[data-bs-theme-value="' + theme +'"] .theme-icon').attr('data-icon');
$('[data-bs-theme-value]').removeClass('active');
$('[data-bs-theme-value="' + theme +'"]').addClass('active');
$('.theme-icon-active')
.removeClass(currentIcon)
.addClass(newIcon)
.attr('data-icon', newIcon);
}
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function() {
if (storedTheme !== 'light' || storedTheme !== 'dark') {
setTheme(getPreferredTheme());
}
});
$(document).ready(function() {
showActiveTheme(getPreferredTheme());
$('[data-bs-theme-value]').click(function() {
var theme = $(this).data('bs-theme-value');
localStorage.setItem('theme', theme);
setTheme(theme);
showActiveTheme(theme);
});
});
})();