美化url和mp4链接
This commit is contained in:
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
@@ -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);
|
||||
}
|
||||
@@ -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 -}}
|
||||
@@ -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">
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
Reference in new issue
Block a user