美化url和mp4链接

This commit is contained in:
Vaica committed 2026-06-02 12:44:47 +08:00
1 parent 791be8bd4f
commit cc5887a74d
8 files changed
+244 -2641

No files matched your search

@@ -24,11 +24,11 @@ ai_comment: >-
前几天在浏览博友博客时,我发现了几个很有意思的文章,核心思路都是用静态博客实现一个后台,主要分为以下三个方案:
小十的博客(https://www.xiaoten.com/posts/2026/03/ai-build-hugo-cms/)——用AI为Hugo打造了博客文章发布平台;
小十的博客 https://www.xiaoten.com/posts/2026/03/ai-build-hugo-cms——用AI为Hugo打造了博客文章发布平台;
东风博主的博客(https://easte.cc/posts/feishu-sync-bot-deploy)——飞书同步机器人,利用飞书提供的接口,将飞书文档同步到博客中,这个想法非常有趣;
东风博主的博客 https://easte.cc/posts/feishu-sync-bot-deploy ——飞书同步机器人,利用飞书提供的接口,将飞书文档同步到博客中,这个想法非常有趣;
小饿博主的博客(https://dongjunke.cn/posts/2026/05/05/50369.html)——我的独立博客,终于拥有了一个像样的后台。
小饿博主的博客 https://dongjunke.cn/posts/2026/05/05/50369.html ——我的独立博客,终于拥有了一个像样的后台。
经朋友推荐,我尝试使用了DeepSeek V4 Pro。DeepSeek的收费模式跟其他家有点不一样,主要是通过充值余额,直接消耗余额来使用,没有其他家所谓的coding plan。对于我这种使用频率较低的用户来说,还是很不错的。
File diff suppressed because it is too large. Load diff
@@ -1 +0,0 @@
{"Target":"css/style.css","MediaType":"text/css","Data":{}}
+106 -69
View File
@@ -4994,26 +4994,89 @@ html[data-theme="light"] .atk-loading-spinner svg circle {
/* Lazy Load Animation */
.lazyload {
opacity: 1;
transform: none;
filter: none;
transition: none;
will-change: auto;
/* Link Card */
a.link-card {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
margin: 1rem 0;
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 12px;
background: linear-gradient(135deg, rgba(0, 0, 0, 0.015), rgba(0, 0, 0, 0.005));
text-decoration: none !important;
color: #1e1e1e;
font-size: 14px;
line-height: 1.5;
max-width: 100%;
transition: all 0.2s ease;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
}
.lazyload.lazy-loaded {
opacity: 1;
transform: none;
filter: none;
a.link-card:hover {
border-color: rgba(0, 0, 0, 0.15);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
transform: translateY(-1px);
text-decoration: none !important;
}
[data-theme="dark"] .ai-comment-card .atk-content p {
color: var(--text-content-dark-color);
.link-card-icon {
width: 24px;
height: 24px;
border-radius: 5px;
flex-shrink: 0;
object-fit: contain;
}
.link-card-body {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 1px;
}
.link-card-title {
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 13.5px;
color: rgba(30, 30, 30, 0.92);
}
.link-card-url {
font-size: 11px;
color: rgba(30, 30, 30, 0.45);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.link-card-arrow {
flex-shrink: 0;
color: rgba(30, 30, 30, 0.3);
font-size: 13px;
transition: color 0.2s;
}
a.link-card:hover .link-card-arrow {
color: rgba(30, 30, 30, 0.6);
}
[data-theme="dark"] a.link-card {
border-color: rgba(148, 163, 184, 0.15);
background: linear-gradient(135deg, rgba(30, 41, 59, 0.7), rgba(15, 23, 42, 0.5));
color: #e2e8f0;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}
[data-theme="dark"] a.link-card:hover {
border-color: rgba(148, 163, 184, 0.3);
}
[data-theme="dark"] .link-card-title {
color: rgba(226, 232, 240, 0.96);
}
[data-theme="dark"] .link-card-url {
color: rgba(226, 232, 240, 0.4);
}
[data-theme="dark"] .link-card-arrow {
color: rgba(226, 232, 240, 0.3);
}
[data-theme="dark"] a.link-card:hover .link-card-arrow {
color: rgba(226, 232, 240, 0.6);
}
/* Reward System */
.reward-container {
@@ -5168,39 +5231,28 @@ html[data-theme="light"] .atk-loading-spinner svg circle {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
gap: 10px;
}
.reward-qr-img-wrapper {
width: 160px;
height: 160px;
background: rgba(255,255,255,0.5);
border-radius: 16px;
width: 180px;
height: 180px;
border-radius: 12px;
overflow: hidden;
padding: 10px;
/* border: 1px solid rgba(0,0,0,0.05); */
transition: transform 0.3s ease;
border: 2px solid var(--line);
transition: transform 0.3s ease, box-shadow 0.3s ease;
background: #fff;
}
.reward-qr-img-wrapper:hover {
transform: translateY(-5px);
}
[data-theme='dark'] .reward-qr-img-wrapper {
background: rgba(255,255,255,0.05);
border-color: rgba(255,255,255,0.1);
}
.reward-qr-item img {
.reward-qr-img-wrapper img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
border-radius: 8px;
object-fit: cover;
}
.reward-qr-img-wrapper:hover {
transform: translateY(-5px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}
.reward-qr-item span {
font-size: 0.9rem;
font-size: 14px;
color: #666;
font-weight: 500;
}
@@ -5219,34 +5271,19 @@ html[data-theme="light"] .atk-loading-spinner svg circle {
.reward-qr-group {
gap: 15px;
}
.reward-qr-img-wrapper {
width: 120px;
height: 120px;
}
.reward-title {
font-size: 1.1rem;
margin-bottom: 20px;
}
}
/* Dark Mode Background Mask */
body {
position: relative;
/* Post Video */
.post-video {
display: block;
max-width: 100%;
margin: 1rem 0;
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.08);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
background: #000;
}
[data-theme='dark'] body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
z-index: -1;
pointer-events: none;
transition: background 0.3s ease;
[data-theme="dark"] .post-video {
border-color: rgba(148, 163, 184, 0.15);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
}
+83
View File
@@ -0,0 +1,83 @@
// linkify.js - Convert bare URLs to link cards, video URLs to players
(function() {
var URL_RE = /(https?:\/\/[^\s一-鿿 -〿＀-￯<>"')\]]+)/g;
var VIDEO_RE = /\.(mp4|webm|ogg|mov)(\?|$)/i;
var FAVICON_API = 'https://api.usj.cc/api/favicon?url=';
function getDomain(url) {
try { return new URL(url).hostname; } catch (e) { return url; }
}
function makeVideo(url) {
var video = document.createElement('video');
video.className = 'post-video';
video.controls = true;
video.preload = 'metadata';
video.playsInline = true;
var source = document.createElement('source');
source.src = url;
video.appendChild(source);
return video;
}
function makeCard(url) {
var domain = getDomain(url);
var card = document.createElement('a');
card.className = 'link-card';
card.href = '/tiaozhuan.html?target=' + btoa(url);
card.target = '_blank';
card.rel = 'noopener';
card.innerHTML = '<img class="link-card-icon" src="' + FAVICON_API + domain + '" alt="" loading="lazy" onerror="this.style.display=\'none\'">' +
'<span class="link-card-body"><span class="link-card-title">' + domain + '</span>' +
'<span class="link-card-url">' + url + '</span></span>' +
'<span class="link-card-arrow">↗</span>';
return card;
}
function linkify(root) {
var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
var textNodes = [];
while (walker.nextNode()) {
var node = walker.currentNode;
if (node.parentElement && node.parentElement.closest('a, .link-card, code, pre, video')) continue;
if (URL_RE.test(node.textContent)) textNodes.push(node);
}
textNodes.forEach(function(node) {
URL_RE.lastIndex = 0;
var text = node.textContent;
var parts = [];
var lastIdx = 0;
var match;
while ((match = URL_RE.exec(text)) !== null) {
if (match.index > lastIdx) {
parts.push(document.createTextNode(text.slice(lastIdx, match.index)));
}
if (VIDEO_RE.test(match[1])) {
parts.push(makeVideo(match[1]));
} else {
parts.push(makeCard(match[1]));
}
lastIdx = match.index + match[0].length;
}
if (parts.length === 0) return;
if (lastIdx < text.length) {
parts.push(document.createTextNode(text.slice(lastIdx)));
}
var frag = document.createDocumentFragment();
parts.forEach(function(p) { frag.appendChild(p); });
node.parentNode.replaceChild(frag, node);
});
}
function run() {
var content = document.querySelector('.post-content');
if (content) linkify(content);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', run);
} else {
run();
}
})();
@@ -1,10 +1,35 @@
{{ $url := .Destination }}
<a
{{ if or (in $url "www.usj.cc") (strings.HasPrefix $url "/") }}
href="{{ $url }}"
{{ else }}
href="/tiaozhuan.html?target={{ $url | base64Encode }}"
{{ end }}
{{ if strings.HasPrefix .Destination "http" }} target="_blank"{{ end }}
>
{{ .Text | safeHTML }}</a>
{{ $isExternal := strings.HasPrefix $url "http" }}
{{ $isBareUrl := eq .Text .Destination }}
{{ $displayText := .Text }}
{{ $isVideo := or (strings.HasSuffix $url ".mp4") (strings.HasSuffix $url ".webm") (strings.HasSuffix $url ".ogg") (strings.HasSuffix $url ".mov") }}
{{- if $isVideo -}}
<video class="post-video" controls preload="metadata" playsinline>
<source src="{{ $url }}">
</video>
{{- else if $isExternal -}}
{{- $domain := urls.Parse $url -}}
{{- $faviconUrl := printf "https://api.usj.cc/api/favicon?url=%s" $domain.Host -}}
{{- if $isBareUrl -}}
<a class="link-card" href="/tiaozhuan.html?target={{ $url | base64Encode }}" target="_blank" rel="noopener">
<img class="link-card-icon" src="{{ $faviconUrl }}" alt="" loading="lazy" onerror="this.style.display='none'">
<span class="link-card-body">
<span class="link-card-title">{{ $domain.Host }}</span>
<span class="link-card-url">{{ $url }}</span>
</span>
<span class="link-card-arrow">↗</span>
</a>
{{- else -}}
<a class="link-card" href="/tiaozhuan.html?target={{ $url | base64Encode }}" target="_blank" rel="noopener">
<img class="link-card-icon" src="{{ $faviconUrl }}" alt="" loading="lazy" onerror="this.style.display='none'">
<span class="link-card-body">
<span class="link-card-title">{{ $displayText }}</span>
<span class="link-card-url">{{ $domain.Host }}</span>
</span>
<span class="link-card-arrow">↗</span>
</a>
{{- end -}}
{{- else -}}
<a href="{{ $url }}">{{ $displayText | safeHTML }}</a>
{{- end -}}
+16 -1
View File
@@ -20,10 +20,25 @@
<div class="post-content" id="post-writing" itemprop="articleBody" uk-scrollspy="target: > h2, > h3, > h4, > blockquote, > table, > figure; cls: uk-animation-slide-bottom-small; delay: 100">
<div class="post-content" id="post-writing" itemprop="articleBody">
{{ .Content }}
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var content = document.getElementById('post-writing');
if (!content) return;
// 滚动时内容从下方淡入,符合"往下看"的直觉
content.querySelectorAll('h2, h3, h4, p, ul, ol, blockquote, table').forEach(function(el) {
el.setAttribute('uk-scrollspy', 'cls: uk-animation-fade; delay: 60');
});
// 图片/视频/链接卡片稍微带点位移,更有"出现感"
content.querySelectorAll('figure, img, .post-video, .link-card').forEach(function(el) {
el.setAttribute('uk-scrollspy', 'cls: uk-animation-slide-bottom-small; delay: 100');
});
});
</script>
</article>
<hr class="uk-divider-icon">
+2 -1
View File
@@ -67,8 +67,9 @@
{{ $infiniteScroll := resources.Get "js/modules/infinite-scroll.js" }}
{{ $artalkModule := resources.Get "js/modules/artalk.js" }}
{{ $pjaxLib := resources.Get "js/libs/pjax.js" }}
{{ $linkify := resources.Get "js/modules/linkify.js" }}
{{ $scripts := slice $iconfont $uikit $easylazyload $viewimage $utils $loader $cache $search $floatingTools $paragraphComments $infiniteScroll $artalkModule $nprogress $pjaxLib $main $mypjax $toast $tiaozhuan $reward | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
{{ $scripts := slice $iconfont $uikit $easylazyload $viewimage $utils $loader $cache $search $floatingTools $paragraphComments $infiniteScroll $artalkModule $nprogress $pjaxLib $linkify $main $mypjax $toast $tiaozhuan $reward | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
{{ $aiGreetings := "static/js/ai_greetings.js" }}
{{ if os.FileExists $aiGreetings }}