Files
tamabox/templates/chat/conversation.html
T
tamakyi 001306d940 模板样式令牌化:字号落到 5 档阶梯、圆角改走 --tb-radius
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())。
2026-10-21 18:28:26 +08:00

196 lines
9.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{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">&times;</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" .}}