11 个模板里的硬编码字号/圆角换成令牌,为之后的深色与主题一致性打底。 字号(base.css 的 --tb-fs-xs/md/lg/xl/hero = 12/14/16/24/28): - 0.70~0.88rem、0.72rem 等五六档零碎值 → --tb-fs-xs(标签/meta) / --tb-fs-md(正文、列表、按钮) - 0.95~1rem → --tb-fs-lg;1.5rem 大数字 → --tb-fs-xl;1.75rem 首页主标题 → --tb-fs-hero - 以下几处**故意改变了观感**(不是等价替换,先记下来免得以后当 regression 查): explore 的 .explore-name 1.2rem → 1rem;.hot-vote-title 0.98 → 0.875; 首页 .tb-stat-num 手机端 1.25 → 1rem;.hot-vote-action 0.82 → 0.875(变大)。 圆角: - 8/9/10px → --tb-radius-sm(8) / --tb-radius(12,对话框与气泡);3/4/5/6px → --tb-radius-xs(6) - 头像 50%、胶囊 999px 保留原样(语义值,不是视觉随意值) 其它:header 验证码输入框边框 #ccc → var(--tb-border);chat 气泡与图片的圆角走内联 var()。 仍未令牌化(留给下一轮):templates/user/profile.html 还有 16 处 font-size、base.css 自身 11 处 (0.78/0.82/0.88/0.95/1.1),邮件模板 mail/* 保持 px 不动(邮件客户端不保证 var())。
196 lines
9.8 KiB
HTML
196 lines
9.8 KiB
HTML
{{template "base/header" .}}
|
||
<style>
|
||
/* 自定义灯箱样式 */
|
||
.custom-lightbox {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(0,0,0,0.85);
|
||
z-index: 9999;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-direction: column;
|
||
}
|
||
.custom-lightbox.active {
|
||
display: flex;
|
||
}
|
||
.custom-lightbox img {
|
||
max-width: 90%;
|
||
max-height: 80%;
|
||
border-radius: var(--tb-radius-sm);
|
||
box-shadow: 0 0 30px rgba(0,0,0,0.5);
|
||
}
|
||
.custom-lightbox .close-btn {
|
||
position: absolute;
|
||
top: 20px;
|
||
right: 30px;
|
||
color: #fff;
|
||
font-size: 40px;
|
||
cursor: pointer;
|
||
font-weight: bold;
|
||
}
|
||
.custom-lightbox .caption {
|
||
color: #ccc;
|
||
margin-top: 10px;
|
||
font-size: 14px;
|
||
}
|
||
</style>
|
||
|
||
<div class="uk-container uk-container-small uk-margin-top" data-page-node-id="VJALGxXgA3LjvngL2idiPd">
|
||
{{template "base/alert" .}}
|
||
<h2 class="uk-text-center" data-page-node-id="4ZhL4EHH1LeTPtFA5wpgbh">
|
||
{{ if .IsOwner }}{{t .LangCode "chat.withAsker"}}{{ else }}{{t .LangCode "chat.withUser" .PageUser.Name}}{{ end }}
|
||
</h2>
|
||
<p class="uk-text-center uk-text-meta" data-page-node-id="NNKGVnXP49GNhyCvho0PAw">
|
||
{{ if .Conversation.IsClosed }}
|
||
<span class="uk-label uk-label-danger" data-page-node-id="QuKE1FE9CzlNmbQOXq68zA">{{t .LangCode "chat.closed"}}</span>
|
||
{{ else }}
|
||
{{t .LangCode "chat.remaining" (sub .Conversation.MaxMessages .Conversation.MessageCount) .Conversation.MaxMessages}}
|
||
{{ end }}
|
||
</p>
|
||
|
||
<div class="uk-card uk-card-default uk-card-body uk-margin uk-padding-small" data-page-node-id="Ngi6SbUffTDHaNpDFcCzjT">
|
||
<ul class="uk-list uk-list-divider" data-page-node-id="VrxQ4Bp6BfmklKAkEqykZf">
|
||
{{ range .Messages }}
|
||
{{ $isMyMessage := eq .SenderID $.LoggedUser.ID }}
|
||
<li class="uk-margin-small-bottom" data-page-node-id="LSFm4EINd1XxnwZSFbAlji">
|
||
<div class="uk-flex {{ if $isMyMessage }}uk-flex-right{{ else }}uk-flex-left{{ end }}" data-page-node-id="afhl9aZDsknmAlut7imPnp">
|
||
<div class="uk-card uk-card-hover uk-card-body uk-padding-small uk-margin-small-left uk-margin-small-right"
|
||
style="max-width: 75%; border-radius: var(--tb-radius); background-color: {{ if $isMyMessage }}#e6ffe6{{ else }}#f0f8ff{{ end }};" data-page-node-id="zPuwctcKF6xPKnwQKaYADD">
|
||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" data-page-node-id="NuHyY57VYOUYQWdpRPqeS6">
|
||
<span class="uk-icon" uk-icon="user" data-page-node-id="ctN3HeenrU4wiv39zSfOgY"></span>
|
||
<strong class="uk-margin-small-left" data-page-node-id="V7t5pBo43sNBv1a6rvp0jv">
|
||
{{ if $isMyMessage }}{{t $.LangCode "chat.me"}}{{ else }}{{t $.LangCode "chat.other"}}{{ end }}
|
||
</strong>
|
||
<span class="uk-text-meta uk-margin-small-left" style="font-size: 0.75rem;" data-page-node-id="JidfstvpABpsDBPRL3WY6I">
|
||
{{ .CreatedAt.Format "01-02 15:04" }}
|
||
</span>
|
||
</div>
|
||
{{ if and $.IsOwner $.IsBlocked (eq .SenderID $.Conversation.AskerID) }}
|
||
<p class="uk-margin-remove" data-page-node-id="LSDlwCDxP0hWTAw2tjVSvA"><span class="uk-text-muted uk-text-italic" data-page-node-id="nTFMPXU5SSa8Affx4vPAm8">{{t $.LangCode "chat.userBlocked"}}</span></p>
|
||
{{ else }}
|
||
{{ if .Content }}
|
||
<p class="uk-margin-remove" data-page-node-id="KMOMzUxidmbA4tMskOa1z2">{{ .Content }}</p>
|
||
{{ end }}
|
||
{{ range (index $.MessageImages .ID) }}
|
||
<div class="uk-margin-small-top" data-page-node-id="sB1P5iHpDXEjFBdUymfkxz">
|
||
<img src="{{ .URL }}" alt="{{ .FileName }}"
|
||
style="max-width: 200px; max-height: 200px; border-radius: var(--tb-radius-sm); cursor: pointer;"
|
||
onclick="openLightbox('{{ .URL }}', '{{ .FileName }}')" data-page-node-id="siJUfJdLhG2zPrXzGC1KZ3" />
|
||
</div>
|
||
{{ end }}
|
||
{{ end }}
|
||
</div>
|
||
</div>
|
||
</li>
|
||
{{ end }}
|
||
</ul>
|
||
</div>
|
||
|
||
{{ if .CanSend }}
|
||
<div class="uk-card uk-card-default uk-card-body uk-margin-top" data-page-node-id="ZAXQKcFkCuSMdF0fOQ5dYH">
|
||
<form method="post" action="/_/{{.PageUser.Domain}}/chat/{{.Conversation.Token}}/send" enctype="multipart/form-data" data-page-node-id="9xSD9GJlKfqAkKPgVBuOAn">
|
||
{{ .CSRFTokenHTML }}
|
||
<textarea name="content" class="uk-textarea" rows="3" placeholder="{{t .LangCode "chat.input"}}" maxlength="{{ .ChatMessageLimit }}">{{ .Content }}</textarea>
|
||
|
||
<div class="uk-margin-small-top" style="display: flex; align-items: center; gap: 10px;" data-page-node-id="jtjlLfDzoOkYDKdiOzZ6vl">
|
||
<div uk-form-custom data-page-node-id="elqLK3luiM7Q4FamlGb3pV">
|
||
<a href="#" class="uk-icon-link" uk-icon="image" data-page-node-id="uZN2LSBiXgLUmffpnhXWH6"></a>
|
||
<span style="font-size: 13px; color: #666;" data-page-node-id="TKZ0z7rbdw4u4YcNs6VmAv">{{t .LangCode "chat.addImage"}}</span>
|
||
<input type="file" name="image" accept="image/*" data-page-node-id="37rmGJRHggLssaZUDxV4FV">
|
||
</div>
|
||
<span class="uk-text-meta" id="file-name" data-page-node-id="EBlY0CCL4DtDxgbNBrlLaw"></span>
|
||
</div>
|
||
|
||
<div class="uk-margin-small-top uk-text-right" data-page-node-id="Tr2UTO7GlEX9LFxDVo1RlK">
|
||
<button type="submit" class="uk-button uk-button-primary" data-page-node-id="IH6ljh8Db7Wo4xfsEz9P5w">{{t .LangCode "chat.send"}}</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
{{ else }}
|
||
<div class="uk-text-center uk-margin-top" data-page-node-id="ZfG2zLwjExCXoA9YaDrqCn">
|
||
<p class="uk-text-warning" data-page-node-id="YKwFufPMOEUVlUvX4yBHAB">{{t .LangCode "chat.closedNoSend"}}</p>
|
||
<a href="/_/{{.PageUser.Domain}}" class="uk-button uk-button-default" data-page-node-id="iVHgoa52j3R1yuhJWbLPXF">{{t .LangCode "common.backHome"}}</a>
|
||
</div>
|
||
{{ end }}
|
||
|
||
{{ if .IsOwner }}
|
||
<div class="uk-margin-top uk-text-center" data-page-node-id="YuzOGI8cGxQAGXx3EsCnKq">
|
||
<a class="uk-button uk-button-{{ if .IsBlocked }}default{{ else }}warning{{ end }} uk-button-small" href="#" data-page-node-id="sG8R1GMpGC52pNeUFJEkTD">
|
||
{{ if .IsBlocked }}{{t .LangCode "chat.unblock"}}{{ else }}{{t .LangCode "chat.block"}}{{ end }}
|
||
</a>
|
||
<div class="uk-dropbar uk-dropbar-top" uk-drop="stretch: x; mode: click" data-page-node-id="iW9QyGsZ1XWa4Bq7Ch0805">
|
||
<div class="uk-card uk-card-default uk-card-body" data-page-node-id="UebLy6cpqCXeiPoX1JLRcE">
|
||
<h3 class="uk-card-title" data-page-node-id="qVRELxzwy4UR2ANNo6PNCi">{{ if .IsBlocked }}{{t .LangCode "chat.unblock"}}{{ else }}{{t .LangCode "chat.block"}}{{ end }}?</h3>
|
||
<p data-page-node-id="DrquhcYxj4Dkx7yGjoed4o">{{ if .IsBlocked }}{{t .LangCode "chat.confirmUnblock"}}{{ else }}{{t .LangCode "chat.confirmBlock"}}{{ end }}</p>
|
||
<form method="post" action="/_/{{.PageUser.Domain}}/chat/{{.Conversation.Token}}/block" data-page-node-id="gN7rHfCpdQ5b3HR05NNiaI">
|
||
{{ .CSRFTokenHTML }}
|
||
<button type="submit" class="uk-button uk-button-{{ if .IsBlocked }}primary{{ else }}danger{{ end }}" data-page-node-id="Bv6TCmw3NFsNXmUfGQ0s9K">
|
||
{{t .LangCode "chat.confirm"}}{{ if .IsBlocked }}{{t .LangCode "chat.unblock"}}{{ else }}{{t .LangCode "chat.block"}}{{ end }}
|
||
</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<a class="uk-button uk-button-danger uk-button-small" href="#" data-page-node-id="LD7jP6dOcVE2UuLTnEuNCZ">{{t .LangCode "chat.delete"}}</a>
|
||
<div class="uk-dropbar uk-dropbar-top" uk-drop="stretch: x; mode: click" data-page-node-id="hmBJTLVxTGAh3eaZJFbd4u">
|
||
<div class="uk-card uk-card-default uk-card-body" data-page-node-id="vdlAgEiEKDXhfsLG3U6qt3">
|
||
<h3 class="uk-card-title" data-page-node-id="uELuLnRDZnyl09lrlJGgpG">{{t .LangCode "qitem.danger"}}</h3>
|
||
<p data-page-node-id="vCyeXBe3K710pdnGTnCpBl">{{t .LangCode "chat.deleteConfirm"}}</p>
|
||
<form method="post" action="/_/{{.PageUser.Domain}}/chat/{{.Conversation.Token}}/delete" data-page-node-id="83mnoGpvXiYyvWETOUlsna">
|
||
{{ .CSRFTokenHTML }}
|
||
<button type="submit" class="uk-button uk-button-danger" data-page-node-id="XjUAxGnN5V8BrLG9n4zVcX">{{t .LangCode "qitem.deleteConfirmBtn"}}</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{{ end }}
|
||
|
||
</div>
|
||
|
||
<!-- 自定义灯箱结构 -->
|
||
<div id="customLightbox" class="custom-lightbox" onclick="closeLightbox()" data-page-node-id="xmqzFCKLG0BSnAeRPCQBEP">
|
||
<span class="close-btn" onclick="closeLightbox()" data-page-node-id="UVNFSFTxluTqzyZ4rPyYLe">×</span>
|
||
<img id="lightboxImg" src="" alt="" data-page-node-id="wX0DtrO8n9OxRAAdFaDtAx" />
|
||
<div id="lightboxCaption" class="caption" data-page-node-id="bCQzLy8AgSWOKL7ZcMU3ZR"></div>
|
||
</div>
|
||
|
||
<script>
|
||
// 显示已选文件名
|
||
var fileInput = document.querySelector('input[name="image"]');
|
||
var fileNameSpan = document.getElementById('file-name');
|
||
if (fileInput && fileNameSpan) {
|
||
fileInput.addEventListener('change', function() {
|
||
if (fileInput.files.length > 0) {
|
||
fileNameSpan.textContent = fileInput.files[0].name;
|
||
} else {
|
||
fileNameSpan.textContent = '';
|
||
}
|
||
});
|
||
}
|
||
|
||
// 自定义灯箱函数
|
||
function openLightbox(src, caption) {
|
||
document.getElementById('lightboxImg').src = src;
|
||
document.getElementById('lightboxCaption').textContent = caption || '';
|
||
document.getElementById('customLightbox').classList.add('active');
|
||
}
|
||
|
||
function closeLightbox() {
|
||
document.getElementById('customLightbox').classList.remove('active');
|
||
// 清空图片避免后台加载消耗
|
||
document.getElementById('lightboxImg').src = '';
|
||
}
|
||
|
||
// ESC 关闭
|
||
document.addEventListener('keydown', function(e) {
|
||
if (e.key === 'Escape') {
|
||
closeLightbox();
|
||
}
|
||
});
|
||
</script>
|
||
|
||
{{template "base/footer" .}} |