|
@@ -17,6 +17,7 @@
|
|
|
--text: #151515;
|
|
--text: #151515;
|
|
|
--muted: #aaaaaa;
|
|
--muted: #aaaaaa;
|
|
|
--orange: #f47d1f;
|
|
--orange: #f47d1f;
|
|
|
|
|
+ --safe-top: env(safe-area-inset-top, 0px);
|
|
|
--safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
--safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -38,6 +39,57 @@
|
|
|
padding-bottom: calc(92px + var(--safe-bottom));
|
|
padding-bottom: calc(92px + var(--safe-bottom));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ .nav {
|
|
|
|
|
+ position: sticky;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ z-index: 10;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ padding-top: calc(10px + var(--safe-top));
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .nav__close {
|
|
|
|
|
+ width: 36px;
|
|
|
|
|
+ height: 36px;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+ font-size: 22px;
|
|
|
|
|
+ line-height: 36px;
|
|
|
|
|
+ color: #151515;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ -webkit-tap-highlight-color: transparent;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .nav__center {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ padding: 0 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .nav__title {
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #151515;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .nav__url {
|
|
|
|
|
+ margin-top: 2px;
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ color: var(--muted);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .nav__side {
|
|
|
|
|
+ width: 36px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.hero {
|
|
.hero {
|
|
|
padding: 16px 15px 0;
|
|
padding: 16px 15px 0;
|
|
|
}
|
|
}
|
|
@@ -238,6 +290,15 @@
|
|
|
</style>
|
|
</style>
|
|
|
</head>
|
|
</head>
|
|
|
<body>
|
|
<body>
|
|
|
|
|
+ <header class="nav">
|
|
|
|
|
+ <button type="button" class="nav__close" id="btnClose" aria-label="关闭">×</button>
|
|
|
|
|
+ <div class="nav__center">
|
|
|
|
|
+ <div class="nav__title" id="navTitle">与AI助手-U宝</div>
|
|
|
|
|
+ <div class="nav__url" id="navUrl">www.ailien.shop</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="nav__side"></div>
|
|
|
|
|
+ </header>
|
|
|
|
|
+
|
|
|
<main id="main">
|
|
<main id="main">
|
|
|
<div class="empty">对话内容加载中…</div>
|
|
<div class="empty">对话内容加载中…</div>
|
|
|
</main>
|
|
</main>
|
|
@@ -361,6 +422,50 @@
|
|
|
return qText + "的讨论";
|
|
return qText + "的讨论";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ function formatNavTitle(question) {
|
|
|
|
|
+ var titled = formatDiscussionTitle(question);
|
|
|
|
|
+ var maxLen = 14;
|
|
|
|
|
+ var short = titled.length > maxLen ? titled.slice(0, maxLen) + "..." : titled;
|
|
|
|
|
+ return short + "-U宝";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function extractFirstQuestionFromContent(content) {
|
|
|
|
|
+ var text = String(content || "").trim();
|
|
|
|
|
+ if (!text) return "";
|
|
|
|
|
+ var match = text.match(/^我[::]([\s\S]+?)(?:\n\n|$)/);
|
|
|
|
|
+ if (match) return String(match[1] || "").trim();
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function parseContentToMessages(content) {
|
|
|
|
|
+ var text = String(content || "").trim();
|
|
|
|
|
+ if (!text) return [];
|
|
|
|
|
+ var messages = [];
|
|
|
|
|
+ var blocks = text.split(/\n\n+/);
|
|
|
|
|
+ for (var i = 0; i < blocks.length; i++) {
|
|
|
|
|
+ var block = String(blocks[i] || "").trim();
|
|
|
|
|
+ if (!block) continue;
|
|
|
|
|
+ var userMatch = block.match(/^我[::]\s*([\s\S]*)$/);
|
|
|
|
|
+ if (userMatch) {
|
|
|
|
|
+ var userText = String(userMatch[1] || "").trim();
|
|
|
|
|
+ if (userText) messages.push({ role: "user", content: userText });
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ var aiMatch = block.match(/^UBAO[::]\s*([\s\S]*)$/i);
|
|
|
|
|
+ if (aiMatch) {
|
|
|
|
|
+ var aiText = String(aiMatch[1] || "").trim();
|
|
|
|
|
+ if (aiText) messages.push({ role: "ai", content: aiText });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return messages;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function resolveShareMessages(data) {
|
|
|
|
|
+ var messages = Array.isArray(data && data.messages) ? data.messages : [];
|
|
|
|
|
+ if (messages.length) return messages;
|
|
|
|
|
+ return parseContentToMessages(data && data.content);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
function formatDate(ts) {
|
|
function formatDate(ts) {
|
|
|
var d = ts ? new Date(Number(ts)) : new Date();
|
|
var d = ts ? new Date(Number(ts)) : new Date();
|
|
|
if (isNaN(d.getTime())) d = new Date();
|
|
if (isNaN(d.getTime())) d = new Date();
|
|
@@ -427,19 +532,33 @@
|
|
|
applyWeixinShareMeta();
|
|
applyWeixinShareMeta();
|
|
|
sharePayloadCache = data || null;
|
|
sharePayloadCache = data || null;
|
|
|
var main = document.getElementById("main");
|
|
var main = document.getElementById("main");
|
|
|
|
|
+ var navTitle = document.getElementById("navTitle");
|
|
|
|
|
+ var navUrl = document.getElementById("navUrl");
|
|
|
if (!data) {
|
|
if (!data) {
|
|
|
|
|
+ if (navTitle) navTitle.textContent = "与AI助手-U宝";
|
|
|
main.innerHTML = '<div class="empty">对话内容不存在或链接已失效</div>';
|
|
main.innerHTML = '<div class="empty">对话内容不存在或链接已失效</div>';
|
|
|
refreshWxLaunchTagAttrs();
|
|
refreshWxLaunchTagAttrs();
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var messages = data.messages || [];
|
|
|
|
|
|
|
+ var messages = resolveShareMessages(data);
|
|
|
var firstQuestion =
|
|
var firstQuestion =
|
|
|
- String(data.firstQuestion || "").trim() || getFirstUserQuestion(messages);
|
|
|
|
|
|
|
+ String(data.firstQuestion || "").trim() ||
|
|
|
|
|
+ getFirstUserQuestion(messages) ||
|
|
|
|
|
+ extractFirstQuestionFromContent(data.content);
|
|
|
var pageTitle = formatDiscussionTitle(firstQuestion);
|
|
var pageTitle = formatDiscussionTitle(firstQuestion);
|
|
|
|
|
+ var navTitleText = formatNavTitle(firstQuestion);
|
|
|
var dateText = formatDate(data.shareTime);
|
|
var dateText = formatDate(data.shareTime);
|
|
|
|
|
|
|
|
- document.title = pageTitle;
|
|
|
|
|
|
|
+ if (navTitle) navTitle.textContent = navTitleText;
|
|
|
|
|
+ if (navUrl) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ navUrl.textContent = location.hostname || "www.ailien.shop";
|
|
|
|
|
+ } catch (eNav) {
|
|
|
|
|
+ navUrl.textContent = "www.ailien.shop";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ document.title = navTitleText;
|
|
|
|
|
|
|
|
var bodyHtml =
|
|
var bodyHtml =
|
|
|
'<section class="hero">' +
|
|
'<section class="hero">' +
|
|
@@ -455,11 +574,6 @@
|
|
|
var convHtml = renderMessages(messages);
|
|
var convHtml = renderMessages(messages);
|
|
|
if (convHtml) {
|
|
if (convHtml) {
|
|
|
bodyHtml += '<section class="conversation">' + convHtml + "</section>";
|
|
bodyHtml += '<section class="conversation">' + convHtml + "</section>";
|
|
|
- } else if (data.content) {
|
|
|
|
|
- bodyHtml +=
|
|
|
|
|
- '<section class="fallback-card"><div class="fallback-card__text">' +
|
|
|
|
|
- escHtml(data.content) +
|
|
|
|
|
- "</div></section>";
|
|
|
|
|
} else {
|
|
} else {
|
|
|
bodyHtml += '<div class="empty">暂无对话内容</div>';
|
|
bodyHtml += '<div class="empty">暂无对话内容</div>';
|
|
|
}
|
|
}
|
|
@@ -964,6 +1078,15 @@
|
|
|
bindWeChatLaunchTagEvents();
|
|
bindWeChatLaunchTagEvents();
|
|
|
scheduleWeChatJssdkBootstrap();
|
|
scheduleWeChatJssdkBootstrap();
|
|
|
document.getElementById("btnContinue").addEventListener("click", tryOpenApp);
|
|
document.getElementById("btnContinue").addEventListener("click", tryOpenApp);
|
|
|
|
|
+ document.getElementById("btnClose").addEventListener("click", function () {
|
|
|
|
|
+ if (window.history.length > 1) {
|
|
|
|
|
+ window.history.back();
|
|
|
|
|
+ } else if (typeof WeixinJSBridge !== "undefined") {
|
|
|
|
|
+ WeixinJSBridge.call("closeWindow");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ window.close();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
render(parsePayload());
|
|
render(parsePayload());
|
|
|
})();
|
|
})();
|
|
|
</script>
|
|
</script>
|