feat(editor): 添加预加载动画和编辑器功能优化
- 新增预加载动画组件及样式 - 优化编辑器图片和视频上传处理逻辑 - 修复编辑器内容转换和格式处理问题 - 添加上传进度显示功能 - 改进编辑器工具栏图标和布局
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provide } = Vue;
|
||||
const ASSET_VERSION = window.__ASSET_VERSION__ || "20251126";
|
||||
const withVer = (p) => `${p}?v=${ASSET_VERSION}`;
|
||||
|
||||
const { itemForum } = await import(withVer("../component/item-forum/item-forum.js"));
|
||||
const { itemOffer } = await import(withVer("../component/item-offer/item-offer.js"));
|
||||
const { itemSummary } = await import(withVer("../component/item-summary/item-summary.js"));
|
||||
@@ -80,6 +79,9 @@ const appSectionIndex = createApp({
|
||||
let uniqidRef = ref(null);
|
||||
|
||||
onMounted(() => {
|
||||
const preLoader = document.getElementById("pre-loader");
|
||||
if (preLoader) preLoader.style.display = "none";
|
||||
|
||||
uniqid = uniqidRef.value.innerText;
|
||||
|
||||
init();
|
||||
@@ -121,7 +123,7 @@ const appSectionIndex = createApp({
|
||||
ajaxGet(`/v2/api/forum/getTopicDetails?uniqid=${uniqid}`).then((res) => {
|
||||
if (res.code != 200) {
|
||||
creationAlertBox("error", res.message || "主题不存在");
|
||||
setTimeout(() => redirectToExternalWebsite(`/`), 3000);
|
||||
// setTimeout(() => redirectToExternalWebsite(`/`), 3000);
|
||||
return;
|
||||
}
|
||||
const data = res.data;
|
||||
@@ -130,27 +132,6 @@ const appSectionIndex = createApp({
|
||||
|
||||
if (!targetInfo.hidden) targetInfo.hidden = 0;
|
||||
|
||||
targetInfo.attachments = {
|
||||
images: [
|
||||
{
|
||||
aid: 708161,
|
||||
url: "https://o.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-S_pItc37qqsgFptxhXa6RWi26P-BuTQYWFOfCsdkb8LQ0NDI5",
|
||||
},
|
||||
],
|
||||
files: [],
|
||||
videos: [
|
||||
{
|
||||
aid: 1009770,
|
||||
posterid: 1009849,
|
||||
posterurl: "https://o.x-php.com/Zvt57TuJSUvkyhw-xG_Y2l-U_polfXuP1NFX9ddrB_WbUGy8P79gQxdHR-HKts0V7NkzNDQyOQ~~",
|
||||
url: "https://o.x-php.com/Zvt57TuJSUvkyhw-xG_Y2l-U_polcniG1NFX9ddrB_WbUGy8P79gQxcSFbqQ78MV7NkzNDQyOQ~~",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// targetInfo.content = '<p style="text-align: center;">红红火火<strong>恍恍惚惚</strong></p>[b]红红火火恍恍惚惚有[/b]<p>\n</p><p>\n</p><p>[attach]1009770[/attach]</p><p>\n</p><p>\n</p><p style="text-align: center;">[img=96]708161[/img]</p><p style="text-align: center;">65456456456456465 <a href="11111" target="_blank" contenteditable="false">111</a> </p><p style="text-align: center;">\n</p>';
|
||||
targetInfo.content = '如果你热爱古典文献,又希望在现代职场大展身手——这个项目可能就是你的“本命”!作为香港最正统的中国语言文学项目,它既传承经典,又为你打跨境传播等全新赛道!\n\n<b>🌟 项目核心亮点</b>权威认证:中国语言文学专业认证,考公考编无障碍\n古今结合:深耕古典文献与理论,同时对接AI内容创作等新兴领域\n语言友好:全程中文授课(普通话+粤语),无语言适应压力\n规模可观:每年录取150+,机会相对较多\n\n点击前往 [港校项目库] 查看 \n<a href="https://program.gter.net/details/tf1yFYIBSda7Y5k7s9iHeLVSxDiuYTljNA~~" target="_blank" contenteditable="false">中国语言文学</a>\n手机扫码查看\n[attachimg]1008942[/attachimg]\n\n<b>🎯 谁最适合申请?</b>中文系、汉语言、古代文学等对口专业背景\n希望在教育、传媒、AI内容或国际中文教育领域发展\n看重学校声誉与专业正统性的同学\n<b>💼 毕业出路超多元</b>除了教师、公务员等传统路径,毕业生还活跃于:\n✔ 跨境文化传播\n✔ AI内容策划与生成\n✔ 国际中文教育\n✔ 出版与编辑行业\n<b>📌 申请指南</b>专业背景:严格限定中文相关专业,暂不接受跨专业申请\n成绩要求:985/211同学建议86+\n语言成绩:雅思7.0(小分5.5)即可\n面试体验:氛围轻松,专业问题较少\n<b>💡 内部消息参考</b>前几轮拿到面试邀请的同学基本都能录取\n985背景优势明显,建议尽早提交申请\n双非同学如背景特别匹配也可尝试\n<b>🤝 欢迎交流</b>你对中国文学在AI时代的发展有什么想法?或者对哪个就业方向,申请问题欢迎在评论区分享交流!\n欢迎加入寄托香港群交流\n\n[attachimg]969489[/attachimg]';
|
||||
|
||||
// 替换换行
|
||||
targetInfo.content = targetInfo.content?.replace(/\n/g, "<br>") || "";
|
||||
|
||||
@@ -330,6 +311,11 @@ const appSectionIndex = createApp({
|
||||
let isLikeGif = ref(false);
|
||||
|
||||
const likeClick = () => {
|
||||
if (realname.value == 0 && userInfoWin.value?.uin > 0) {
|
||||
openAttest();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isLogin.value) {
|
||||
goLogin();
|
||||
return;
|
||||
@@ -558,6 +544,15 @@ const appSectionIndex = createApp({
|
||||
|
||||
const handleAnswerText = (e) => {
|
||||
if (e.target.tagName === "IMG") {
|
||||
// 检查点击的图片是否被a标签包裹
|
||||
const anchorTag = e.target.closest("a");
|
||||
|
||||
// 如果被a标签包裹,则不执行图片预览,让链接正常跳转
|
||||
if (anchorTag) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 否则,执行图片预览
|
||||
var src = e.target.getAttribute("src");
|
||||
previewImage.initComponent(src);
|
||||
}
|
||||
@@ -603,7 +598,6 @@ const appSectionIndex = createApp({
|
||||
|
||||
let emojiState = ref(false);
|
||||
let emojiMaskState = ref(false);
|
||||
let emojiBottomDistance = ref(0);
|
||||
let inputTextarea = ref("");
|
||||
|
||||
// 打开 Emoji
|
||||
@@ -622,6 +616,28 @@ const appSectionIndex = createApp({
|
||||
}
|
||||
|
||||
emojiMaskState.value = true;
|
||||
|
||||
let emojiBottomDistance = 0;
|
||||
const doc = document.documentElement;
|
||||
try {
|
||||
const targetEl = (event && (event.currentTarget || event.target)) || null;
|
||||
const rect = targetEl && targetEl.getBoundingClientRect ? targetEl.getBoundingClientRect() : null;
|
||||
if (rect) {
|
||||
const elementBottomDocY = rect.bottom + window.scrollY;
|
||||
emojiBottomDistance = Math.max(doc.scrollHeight - elementBottomDocY, 0);
|
||||
} else {
|
||||
const pageY = event && (event.pageY != null ? event.pageY : event.clientY != null ? event.clientY + window.scrollY : 0);
|
||||
emojiBottomDistance = Math.max(doc.scrollHeight - pageY, 0);
|
||||
}
|
||||
|
||||
const itemEl = targetEl && targetEl.closest ? targetEl.closest(".item") : null;
|
||||
|
||||
const boxEl = itemEl ? itemEl.querySelector(".emoji-box") : null;
|
||||
if (boxEl) {
|
||||
if (emojiBottomDistance < 500) boxEl.classList.add("top");
|
||||
else boxEl.classList.remove("top");
|
||||
}
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
// 关闭 Emoji
|
||||
@@ -1063,6 +1079,7 @@ const appSectionIndex = createApp({
|
||||
element.timestamp = strtimeago(element.created_at, 4);
|
||||
element["isReplyBoxShow"] = 0;
|
||||
element["picture"] = [];
|
||||
if (element["content"]) element["content"] = restoreHtml(element["content"], element.attachments, "comment");
|
||||
});
|
||||
|
||||
let merged = [...commentList.value[index]["child"], ...data.data.filter((item2) => !commentList.value[index]["child"].find((item1) => item1.id == item2.id))];
|
||||
@@ -1218,7 +1235,7 @@ const appSectionIndex = createApp({
|
||||
ajax(`/v2/api/forum/postTopicShare`, { token });
|
||||
};
|
||||
|
||||
return { emojiBottomDistance, uniqidRef, share, reportToken, isReplyBoxShow, matterHeight, sidebarHeight, deleteItem, maxPicture, sidebarFixed, matterRef, sidebarRef, pitchInputState, ismyself, edit, searchInput, defaultSearchText, goSearch, goPersonalHomepage, QRcode, alsoCommentsData, copyLinkClick, reportState, tokentoken, essence, recommend, hide, report, cutShow, ismanager, show, openDiscuss, commentDelete, handleInputPaste, autoResize, editCommentState, selectEditEmoji, closeEditEmoji, openEditEmoji, closeEdit, openEdit, closeEditFileUpload, postEditComment, submitAnswerComments, closePictureUpload, closeFileUpload, picture, editToken, editPicture, editInput, editEmojiState, handleFileUpload, inputTextarea, judgeLogin, handleEditFile, selectEmoji, emojiData, emojiMaskState, emojiState, closeEmoji, openEmoji, closeAnswerCommentsChild, openAnswerCommentsChild, handleAnswerText, sendMessage, TAHomePage, operateAnswerCommentsLike, closeUserInfo, openUserInfo, permissions, commentList, commentPage, commentTotalCount, picture, userInfoWin, relatedList, relatedTime, coinNubmer, coinList, coinAmount, coinSubmit, strategy, mybalance, coinsState, openCoinBox, closeCoinBox, isLikeGif, likeClick, collectClick, islike, iscollect, recentlyList, medal, count, sectionn, tags, authorInfo, info, timestamp, updatedTime };
|
||||
return { uniqidRef, share, reportToken, isReplyBoxShow, matterHeight, sidebarHeight, deleteItem, maxPicture, sidebarFixed, matterRef, sidebarRef, pitchInputState, ismyself, edit, searchInput, defaultSearchText, goSearch, goPersonalHomepage, QRcode, alsoCommentsData, copyLinkClick, reportState, tokentoken, essence, recommend, hide, report, cutShow, ismanager, show, openDiscuss, commentDelete, handleInputPaste, autoResize, editCommentState, selectEditEmoji, closeEditEmoji, openEditEmoji, closeEdit, openEdit, closeEditFileUpload, postEditComment, submitAnswerComments, closePictureUpload, closeFileUpload, picture, editToken, editPicture, editInput, editEmojiState, handleFileUpload, inputTextarea, judgeLogin, handleEditFile, selectEmoji, emojiData, emojiMaskState, emojiState, closeEmoji, openEmoji, closeAnswerCommentsChild, openAnswerCommentsChild, handleAnswerText, sendMessage, TAHomePage, operateAnswerCommentsLike, closeUserInfo, openUserInfo, permissions, commentList, commentPage, commentTotalCount, picture, userInfoWin, relatedList, relatedTime, coinNubmer, coinList, coinAmount, coinSubmit, strategy, mybalance, coinsState, openCoinBox, closeCoinBox, isLikeGif, likeClick, collectClick, islike, iscollect, recentlyList, medal, count, sectionn, tags, authorInfo, info, timestamp, updatedTime };
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user