mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-12-22 13:41:52 +00:00
feat: dark mode (#43)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
commit
34270c328a
@ -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-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 class="card-footer bg-transparent small text-muted">
|
||||
|
@ -50,7 +50,7 @@ function echoFilePre($file_name) {
|
||||
|
||||
echo '<h5 class="mb-1">', htmlspecialchars($file_name), '</h5>';
|
||||
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;
|
||||
if (strStartWith($mimetype, 'text/')) {
|
||||
@ -124,7 +124,7 @@ $info_form->appendHTML(<<<EOD
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 control-label">提交文件配置</label>
|
||||
<div class="col-sm-9">
|
||||
<pre class="uoj-pre bg-light rounded">
|
||||
<pre class="uoj-pre bg-body-tertiary rounded">
|
||||
$esc_submission_requirement
|
||||
</pre>
|
||||
</div>
|
||||
@ -135,7 +135,7 @@ $info_form->appendHTML(<<<EOD
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 control-label">其它配置</label>
|
||||
<div class="col-sm-9">
|
||||
<pre class="uoj-pre bg-light rounded">
|
||||
<pre class="uoj-pre bg-body-tertiary rounded">
|
||||
$esc_extra_config
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -77,7 +77,7 @@ EOD;
|
||||
die();
|
||||
};
|
||||
$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['confirm']['text'] = '你真的要添加新题吗?';
|
||||
$new_problem_form->runAtServer();
|
||||
|
@ -174,7 +174,7 @@ if (UOJUserBlog::userHasManagePermission(Auth::user())) {
|
||||
]);
|
||||
$hide_form->addInput('comment_hide_reason', [
|
||||
'div_class' => 'mt-3',
|
||||
'label' => '自定义隐藏理由',
|
||||
'label' => '自定义隐藏理由(当上方隐藏理由为自定义时有效)',
|
||||
'default_value' => '该评论由于违反社区规定,已被管理员隐藏',
|
||||
'validator_php' => 'validateString',
|
||||
]);
|
||||
@ -327,9 +327,10 @@ $comments_pag = new Paginator([
|
||||
|
||||
<script>
|
||||
$('.uoj-blog-hide-comment-btn').each(function() {
|
||||
$(this).click(function() {
|
||||
$(this).click(function(event) {
|
||||
var comment_id = $(this).data('comment-id');
|
||||
|
||||
|
||||
event.preventDefault();
|
||||
toggleModalHideComment(comment_id, $('#comment-content-' + comment_id).html());
|
||||
});
|
||||
})
|
||||
|
@ -299,7 +299,7 @@ if ($cur_tab == 'profile') {
|
||||
$update_profile_form->appendHTML(<<<EOD
|
||||
<div class="mb-3">
|
||||
<label for="input-username_color" class="form-label">用户名颜色</label>
|
||||
<input type="text" class="form-control" id="input-username_color" aria-describedby="help-username_color" value="棕色 - #996600" disabled>
|
||||
<input type="text" class="form-control" id="input-username_color" aria-describedby="help-username_color" value="棕色" disabled>
|
||||
<div id="help-username_color" class="form-text">被封禁的用户无法修改用户名颜色。</div>
|
||||
</div>
|
||||
EOD);
|
||||
@ -307,29 +307,22 @@ if ($cur_tab == 'profile') {
|
||||
$update_profile_form->appendHTML(<<<EOD
|
||||
<div class="mb-3">
|
||||
<label for="input-username_color" class="form-label">用户名颜色</label>
|
||||
<input type="text" class="form-control" id="input-username_color" aria-describedby="help-username_color" value="灰色 - #707070" disabled>
|
||||
<input type="text" class="form-control" id="input-username_color" aria-describedby="help-username_color" value="灰色" disabled>
|
||||
<div id="help-username_color" class="form-text">临时用户无法修改用户名颜色。</div>
|
||||
</div>
|
||||
EOD);
|
||||
} else {
|
||||
$additional_colors = [];
|
||||
$username_colors = UOJUser::USERNAME_COLORS['user'];
|
||||
|
||||
if (isSuperUser($user)) {
|
||||
$additional_colors['#9d3dcf'] = '紫色 - #9d3dcf';
|
||||
$username_colors += UOJUser::USERNAME_COLORS['admin'];
|
||||
}
|
||||
|
||||
$update_profile_form->addSelect('username_color', [
|
||||
'div_class' => 'mb-3',
|
||||
'label' => '用户名颜色',
|
||||
'default_value' => $extra['username_color'],
|
||||
'options' => $additional_colors + [
|
||||
'#0d6efd' => '蓝色 - #0d6efd',
|
||||
'#2da44e' => '绿色 - #2da44e',
|
||||
'#e85aad' => '粉色 - #e85aad',
|
||||
'#f32a38' => '红色 - #f32a38',
|
||||
'#f57c00' => '橙色 - #f57c00',
|
||||
'#00acc1' => '青色 - #00acc1',
|
||||
],
|
||||
'options' => $username_colors,
|
||||
]);
|
||||
}
|
||||
$update_profile_form->handle = function (&$vdata) use ($user, $extra) {
|
||||
|
@ -355,7 +355,7 @@ function echoSubmissionContent($submission, $requirement) {
|
||||
echo '<h4 class="card-title">' . $req['name'] . '</h4>';
|
||||
echo '</div>';
|
||||
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 class="card-footer">' . $footer_text . '</div>';
|
||||
echo '</div>';
|
||||
@ -369,7 +369,7 @@ function echoSubmissionContent($submission, $requirement) {
|
||||
echo '<h4 class="card-title">' . $req['file_name'] . '</h4>';
|
||||
echo '</div>';
|
||||
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 class="card-footer">' . $footer_text . '</div>';
|
||||
echo '</div>';
|
||||
@ -406,7 +406,7 @@ class JudgmentDetailsPrinter {
|
||||
}
|
||||
private function _print(DOMElement $node) {
|
||||
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);
|
||||
echo "\n</pre>";
|
||||
} elseif ($node->nodeName == 'remote-result-container') {
|
||||
@ -432,7 +432,7 @@ class JudgmentDetailsPrinter {
|
||||
$language = $node->getAttribute("language");
|
||||
echo '<div class="border-bottom p-3 copy-button-container">';
|
||||
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);
|
||||
echo "</code></pre>";
|
||||
echo '</div>';
|
||||
@ -662,22 +662,22 @@ class JudgmentDetailsPrinter {
|
||||
}
|
||||
} elseif ($node->nodeName == 'in') {
|
||||
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);
|
||||
echo "\n</pre>";
|
||||
} elseif ($node->nodeName == 'out') {
|
||||
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);
|
||||
echo "\n</pre>";
|
||||
} elseif ($node->nodeName == 'ans') {
|
||||
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);
|
||||
echo "\n</pre>";
|
||||
} elseif ($node->nodeName == 'res') {
|
||||
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()) {
|
||||
$this->_print_c($node);
|
||||
} else {
|
||||
@ -698,7 +698,7 @@ class JudgmentDetailsPrinter {
|
||||
}
|
||||
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);
|
||||
echo "\n</pre>";
|
||||
echo '</div>';
|
||||
|
@ -1,4 +1,29 @@
|
||||
<?php
|
||||
class CustomClassDef extends HTMLPurifier_AttrDef {
|
||||
private $classes, $prefixes;
|
||||
|
||||
public function __construct($classes, $prefixes) {
|
||||
$this->classes = $classes;
|
||||
$this->prefixes = is_array($prefixes) ? join('|', $prefixes) : $prefixes;
|
||||
}
|
||||
|
||||
public function validate($string, $config, $context) {
|
||||
$classes = preg_split('/\s+/', $string);
|
||||
$valid_classes = [];
|
||||
|
||||
foreach ($classes as $class) {
|
||||
if (
|
||||
in_array($class, $this->classes) ||
|
||||
preg_match("/^({$this->prefixes})/i", $class)
|
||||
) {
|
||||
|
||||
$valid_classes[] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
return join(' ', $valid_classes);
|
||||
}
|
||||
}
|
||||
|
||||
class HTML {
|
||||
public static function escape(?string $str, $cfg = []) {
|
||||
@ -454,7 +479,7 @@ class HTML {
|
||||
'data-src' => 'URI',
|
||||
],
|
||||
'span' => [
|
||||
'class' => 'Enum#uoj-username',
|
||||
'class' => new CustomClassDef(['uoj-username'], ['uoj-username-']),
|
||||
'data-realname' => 'Text',
|
||||
'data-color' => 'Color',
|
||||
],
|
||||
@ -485,7 +510,7 @@ class HTML {
|
||||
'del' => [],
|
||||
'br' => [],
|
||||
'span' => [
|
||||
'class' => 'Enum#uoj-username',
|
||||
'class' => new CustomClassDef(['uoj-username'], ['uoj-username-']),
|
||||
'data-realname' => 'Text',
|
||||
'data-color' => 'Color',
|
||||
],
|
||||
|
@ -73,7 +73,7 @@ class UOJProblemDataDisplayer {
|
||||
|
||||
echo '<h5 class="mb-1">', HTML::escape($file_name), '</h5>';
|
||||
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';
|
||||
echo HTML::escape(uojStringPreview($content, $max_len, $type));
|
||||
echo "\n</pre>";
|
||||
|
@ -218,7 +218,7 @@ trait UOJSubmissionLikeTrait {
|
||||
{$req['name']}
|
||||
</div>
|
||||
<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 class="{$card_footer_class}">$footer_text</div>
|
||||
</div>
|
||||
@ -238,7 +238,7 @@ trait UOJSubmissionLikeTrait {
|
||||
{$req['file_name']}
|
||||
</div>
|
||||
<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 class="{$card_footer_class}">{$footer_text}</div>
|
||||
</div>
|
||||
|
@ -11,6 +11,21 @@ class UOJUser {
|
||||
const MAX_UA_LEN = 300;
|
||||
const MAX_HISTORY_LEN = 20;
|
||||
|
||||
// Don't forget to change values in `models/HTML.php` and `css/uoj-bs5.css`
|
||||
const USERNAME_COLORS = [
|
||||
'user' => [
|
||||
'blue' => 'Blue',
|
||||
'green' => 'Green',
|
||||
'pink' => 'Pink',
|
||||
'red' => 'Red',
|
||||
'orange' => 'Orange',
|
||||
'cyan' => 'Cyan',
|
||||
],
|
||||
'admin' => [
|
||||
'purple' => 'Purple',
|
||||
],
|
||||
];
|
||||
|
||||
public static $visibility_codes = [
|
||||
'all' => [
|
||||
'html' => '',
|
||||
@ -277,23 +292,23 @@ class UOJUser {
|
||||
|
||||
public static function getUserColor2($usergroup, $custom_color = null) {
|
||||
if ($usergroup == 'B') {
|
||||
return '#996600';
|
||||
return 'brown';
|
||||
}
|
||||
|
||||
if ($usergroup == 'T') {
|
||||
return '#707070';
|
||||
return 'gray';
|
||||
}
|
||||
|
||||
if ($usergroup == 'S') {
|
||||
return $custom_color ?: '#9d3dcf';
|
||||
return $custom_color ?: 'purple';
|
||||
}
|
||||
|
||||
// 前管理员设置颜色为紫色的,颜色改为蓝色
|
||||
if ($custom_color == '#9d3dcf') {
|
||||
return '#0d6efd';
|
||||
if ($custom_color == 'purple') {
|
||||
return 'blue';
|
||||
}
|
||||
|
||||
return $custom_color ?: '#0d6efd';
|
||||
return $custom_color ?: 'blue';
|
||||
}
|
||||
|
||||
public static function getLink($user, $cfg = []) {
|
||||
@ -318,10 +333,12 @@ class UOJUser {
|
||||
$realname = '';
|
||||
}
|
||||
|
||||
$color = $cfg['color'] ? UOJUser::getUserColor($user) : '';
|
||||
|
||||
return HTML::tag('span', [
|
||||
'class' => 'uoj-username',
|
||||
'data-color' => $cfg['color'] ? UOJUser::getUserColor($user) : '',
|
||||
'class' => "uoj-username uoj-username-{$color}",
|
||||
'data-realname' => trim(HTML::escape($realname)),
|
||||
'data-color' => $color,
|
||||
], $user['username']);
|
||||
}
|
||||
|
||||
|
60
web/app/upgrade/43_dark_mode/upgrade.php
Normal file
60
web/app/upgrade/43_dark_mode/upgrade.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
return function ($type) {
|
||||
if ($type == 'up') {
|
||||
DB::init();
|
||||
|
||||
function getColorName($color) {
|
||||
switch ($color) {
|
||||
case '#0d6efd':
|
||||
case 'blue':
|
||||
return 'blue';
|
||||
case '#2da44e':
|
||||
case 'green':
|
||||
return 'green';
|
||||
case '#e85aad':
|
||||
case 'pink':
|
||||
return 'pink';
|
||||
case '#f32a38':
|
||||
case 'red':
|
||||
return 'red';
|
||||
case '#f57c00':
|
||||
case 'orange':
|
||||
return 'orange';
|
||||
case '#00acc1':
|
||||
case 'cyan':
|
||||
return 'cyan';
|
||||
case '#9d3dcf':
|
||||
case 'purple':
|
||||
return 'purple';
|
||||
case '#707070':
|
||||
case 'gray':
|
||||
return 'gray';
|
||||
case '#996600':
|
||||
case 'brown':
|
||||
return 'brown';
|
||||
default:
|
||||
return 'blue';
|
||||
}
|
||||
}
|
||||
|
||||
$users = DB::selectAll("select * from user_info");
|
||||
|
||||
foreach ($users as $user) {
|
||||
$extra = UOJUser::getExtra($user);
|
||||
$original_color = $extra['username_color'];
|
||||
$new_color = getColorName($original_color);
|
||||
$extra['username_color'] = $new_color;
|
||||
DB::update([
|
||||
"update user_info",
|
||||
"set", [
|
||||
"extra" => json_encode($extra)
|
||||
],
|
||||
"where", [
|
||||
"username" => $user['username']
|
||||
],
|
||||
]);
|
||||
echo "{$user['username']}: {$original_color} -> {$new_color}\n";
|
||||
}
|
||||
}
|
||||
};
|
@ -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">
|
||||
|
||||
@ -41,98 +41,11 @@
|
||||
|
||||
<hr class="d-md-none text-muted">
|
||||
|
||||
<ul class="nav navbar-nav ms-md-auto">
|
||||
<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>
|
||||
<?php uojIncludeView('nav-right', [
|
||||
'new_msg_tot' => $new_msg_tot,
|
||||
'new_user_msg_num' => $new_user_msg_num,
|
||||
'new_system_msg_num' => $new_system_msg_num,
|
||||
]) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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;
|
||||
?>
|
||||
|
||||
<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)) : ?>
|
||||
mb-4
|
||||
<?php endif ?>
|
||||
@ -99,98 +99,11 @@ mb-4
|
||||
|
||||
<hr class="d-md-none text-muted">
|
||||
|
||||
<ul class="nav navbar-nav ms-md-auto">
|
||||
<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>
|
||||
<?php uojIncludeView('nav-right', [
|
||||
'new_msg_tot' => $new_msg_tot,
|
||||
'new_user_msg_num' => $new_user_msg_num,
|
||||
'new_system_msg_num' => $new_system_msg_num,
|
||||
]) ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
118
web/app/views/nav-right.php
Normal file
118
web/app/views/nav-right.php
Normal 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"> 切换主题</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>
|
@ -11,7 +11,7 @@ if (!isset($ShowPageFooter)) {
|
||||
</script>
|
||||
<?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>
|
||||
<div>
|
||||
|
@ -188,7 +188,7 @@ if (!isset($PageContainerClass)) {
|
||||
<?php endif ?>
|
||||
|
||||
<?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') ?>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
@ -242,7 +242,7 @@ if (!isset($PageContainerClass)) {
|
||||
|
||||
<body class="d-flex flex-column min-vh-100
|
||||
<?php if ($ShowPageHeader) : ?>
|
||||
bg-light
|
||||
bg-body-tertiary
|
||||
<?php endif ?>">
|
||||
<?php if ($ShowPageHeader) : ?>
|
||||
<?php uojIncludeView($PageNav, array('REQUIRE_LIB' => $REQUIRE_LIB)) ?>
|
||||
|
142
web/css/highlightjs.github.min.css
vendored
142
web/css/highlightjs.github.min.css
vendored
@ -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);
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ h6,
|
||||
|
||||
.markdown-body pre {
|
||||
padding: 1em;
|
||||
background-color: rgba(var(--bs-light-rgb));
|
||||
background-color: var(--bs-tertiary-bg);
|
||||
}
|
||||
|
||||
.markdown-body table th[align='left'] {
|
||||
@ -541,3 +541,93 @@ form.form-horizontal {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
}
|
||||
|
||||
/* Username color */
|
||||
|
||||
.uoj-username,
|
||||
.uoj-username-blue {
|
||||
color: #1e88e5;
|
||||
}
|
||||
|
||||
.uoj-username-green {
|
||||
color: #2da44e;
|
||||
}
|
||||
|
||||
.uoj-username-pink {
|
||||
color: #e85aad;
|
||||
}
|
||||
|
||||
.uoj-username-red {
|
||||
color: #f32a38;
|
||||
}
|
||||
|
||||
.uoj-username-orange {
|
||||
color: #f57c00;
|
||||
}
|
||||
|
||||
.uoj-username-cyan {
|
||||
color: #00acc1;
|
||||
}
|
||||
|
||||
.uoj-username-purple {
|
||||
color: #9d3dcf;
|
||||
}
|
||||
|
||||
.uoj-username-gray {
|
||||
color: #707070;
|
||||
}
|
||||
|
||||
.uoj-username-brown {
|
||||
color: #996600;
|
||||
}
|
||||
|
||||
/* Dark: Username color */
|
||||
|
||||
[data-bs-theme='dark'] .uoj-username,
|
||||
[data-bs-theme='dark'] .uoj-username-blue {
|
||||
color: #218bff;
|
||||
}
|
||||
|
||||
[data-bs-theme='green'] .uoj-username-green {
|
||||
color: #19a140;
|
||||
}
|
||||
|
||||
[data-bs-theme='dark'] .uoj-username-pink {
|
||||
color: #bf3989;
|
||||
}
|
||||
|
||||
[data-bs-theme='dark'] .uoj-username-red {
|
||||
color: #cf222e;
|
||||
}
|
||||
|
||||
[data-bs-theme='dark'] .uoj-username-orange {
|
||||
color: #e16f24;
|
||||
}
|
||||
|
||||
[data-bs-theme='dark'] .uoj-username-cyan {
|
||||
color: #00acc1;
|
||||
}
|
||||
|
||||
[data-bs-theme='dark'] .uoj-username-purple {
|
||||
color: #9366e5;
|
||||
}
|
||||
|
||||
[data-bs-theme='dark'] .uoj-username-gray {
|
||||
color: #8c959f;
|
||||
}
|
||||
|
||||
[data-bs-theme='dark'] .uoj-username-brown {
|
||||
color: #996f1c;
|
||||
}
|
||||
|
||||
/* Dark: Table Colors */
|
||||
|
||||
[data-bs-theme='dark'] .table-success {
|
||||
--bs-table-bg: #d1e7ddb9;
|
||||
--bs-table-border-color: #bcd0c7b9;
|
||||
}
|
||||
|
||||
[data-bs-theme='dark'] .table-warning {
|
||||
--bs-table-bg: #fff3cdb9;
|
||||
--bs-table-border-color: #e6dbb9b9;
|
||||
}
|
||||
|
@ -100,7 +100,6 @@ function blog_editor_init(name, editor_config) {
|
||||
enabled: false,
|
||||
},
|
||||
wordWrap: 'on',
|
||||
theme: 'vs',
|
||||
unicodeHighlight: {
|
||||
ambiguousCharacters: false,
|
||||
},
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -123,7 +123,7 @@ function getUserLink(username, realname, color) {
|
||||
return '';
|
||||
}
|
||||
var text = username;
|
||||
var style = '';
|
||||
var className = 'uoj-username';
|
||||
if (username.charAt(0) == '@') {
|
||||
username = username.substr(1);
|
||||
}
|
||||
@ -131,16 +131,16 @@ function getUserLink(username, realname, color) {
|
||||
text = text + ' <span class="uoj-realname d-inline-block">(' + realname + ')</span>';
|
||||
}
|
||||
if (color) {
|
||||
style += 'color: ' + color + ';';
|
||||
className += ' uoj-username-' + color;
|
||||
}
|
||||
return '<a class="uoj-username" href="' + uojHome + '/user/' + username + '" ' + 'style="' + style + '">' + text + '</a>';
|
||||
return '<a class="' + className + '" href="' + uojHome + '/user/' + username + '">' + text + '</a>';
|
||||
}
|
||||
function getUserSpan(username, realname, color) {
|
||||
if (!username) {
|
||||
return '';
|
||||
}
|
||||
var text = username;
|
||||
var style = '';
|
||||
var className = 'uoj-username';
|
||||
if (username.charAt(0) == '@') {
|
||||
username = username.substr(1);
|
||||
}
|
||||
@ -148,9 +148,9 @@ function getUserSpan(username, realname, color) {
|
||||
text = text + ' <span class="uoj-realname d-inline-block">(' + realname + ')</span>';
|
||||
}
|
||||
if (color) {
|
||||
style += 'color: ' + color + ';';
|
||||
className += ' uoj-username-' + color;
|
||||
}
|
||||
return '<span class="uoj-username" ' + 'style="' + style + '">' + text + '</span>';
|
||||
return '<span class="' + className + '">' + text + '</span>';
|
||||
}
|
||||
|
||||
function replaceWithHighlightUsername() {
|
||||
@ -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.js').wait(function() {
|
||||
$LAB.script('/js/monaco-themes.js').wait(function() {
|
||||
update_monaco_theme(getPreferredTheme());
|
||||
|
||||
if (config.markdown) {
|
||||
$LAB.script('/js/blog-editor/monaco-markdown.js').wait(callback);
|
||||
} 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) {
|
||||
switch (lang) {
|
||||
case 'C++':
|
||||
@ -1365,7 +1377,7 @@ $.fn.problem_conf_preview = function(problem_conf) {
|
||||
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(
|
||||
user_can_hide_comment
|
||||
? $('<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);
|
||||
})
|
||||
)
|
||||
@ -2118,8 +2131,75 @@ $(document).ready(function() {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Fallback user avatar
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
$('img.uoj-user-avatar').on('error', function() {
|
||||
// same as gravatar d=mm
|
||||
$(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);
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user