cloudstudio
Version:
Run VS Code on a remote server.
255 lines (232 loc) • 7.83 kB
JavaScript
let vscode = acquireVsCodeApi();
let dataSplitObj = {};
let dataObj = {};
let dataArr = [];
let introduction = (document.getElementById("introduction") || {}).value || "";
window.onload = function () {
vscode.postMessage({ type: "metawork.ready" });
window.addEventListener("message", (event) => {
let res = event.data || {};
console.log("addEventListener-message-data", res);
switch (res.type) {
case "metawork.server.sendMessageList": {
let data = res.data || [];
if (Array.isArray(data)) {
appendItemList(splitData(data));
dataArr = dataArr.concat(data);
}
break;
}
case "metawork.server.sendMessage": {
let data = res.data || {};
function appendData(data) {
if (
dataArr.filter(function (item) {
return item.id === data.id;
}).length === 0
) {
appendItem(data);
dataArr.push(data);
}
}
// 若数组里面没有数据并且当前类型是代码,停止操作
// 因为会跟appendItemList()操作重复
if (dataArr.length === 0 && data.type === "code") {
// 若超时1秒后,还没有数据,对数据补偿
setTimeout(() => {
if (dataArr.length === 0) {
appendData(data);
}
}, 100);
return;
}
appendData(data);
break;
}
}
});
// 点击回车按钮,提交
document.querySelector(".enterIcon").addEventListener("click", submitMessage);
};
// 转义
function escape(html) {
var elem = document.createElement("div");
var txt = document.createTextNode(html);
elem.appendChild(txt);
return elem.innerHTML;
}
// 匹配链接
function matchLink(_content) {
let content = _content || "";
// let regLink = new RegExp('((https|http|ftp|rtsp|mms):\\/\\/)[^\\s]+([a-zA-z0-9])|(([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?|((http|ftp|https)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+[\\.|\\/]([a-zA-Z]{1,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)', 'ig');
let regLink = new RegExp(
"((http[s]{0,1}|ftp|rtsp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)",
"ig"
);
let matchArr = content.match(regLink) || [];
let matchTempArr = [];
matchArr.forEach(function (match, index) {
if (match) {
let key = "____$____" + index;
matchTempArr.push({ key: key, value: match });
content = content.replace(match, key);
}
});
matchTempArr.forEach(function (item) {
content = content.replace(
item.key,
`<a onclick="openLink('${item.value}')" href="${item.value}">${item.value}</a>`
);
});
return content;
}
// 生成单个item的html
function createItemHtml(data) {
let time = (data.datetime || "").split(" ")[1] || "";
time = time.split(":").slice(0, 2).join(":");
const typeClass = data.type || "text";
let content = data.content;
let contentHtml = "";
if (data.type === "text") {
content = matchLink(escape(content));
contentHtml = `<div class="${typeClass}">${content}</div>`;
} else if (data.type === "code") {
let codeContent = hljs.highlightAuto(content, [data.filetype]).value;
let codeHtml = `<pre class="monaco-code" data-type="${data.filetype}">${codeContent}</pre>`;
contentHtml = `<div class="${typeClass}" onclick="handleClickContent('${
data.id
}')">${codeHtml}<div class="quote">${introduction}${
data.path || ""
}</div></div>`;
}
let imageStyle = '';
if(data.color){
// imageStyle = `border: 3px solid ${data.color}`;
}
const itemHtml = `
<img class="avatar" src="${data.avatar}" style="${imageStyle}" />
<article class="article">
<div class="title"><span class="name">${data.userName}</span><span class="time">${time}</span></div>
${contentHtml}
</article>
`;
return itemHtml;
}
// 生成dom节点
function createElement(tagName, className, html) {
let element = document.createElement(tagName);
element.className = className;
element.innerHTML = html;
return element;
}
// 添加新消息
function appendItem(data) {
const $list = document.getElementById("list");
if (dataObj[data.id]) {
return;
}
const date = data.datetime.split(" ")?.[0] || "";
const dateClass = ".date_" + date;
if (!document.querySelector(dateClass)) {
$list.append(createElementDate(date));
}
dataObj[data.id] = data;
const lastUserName = (dataArr.splice(-1)[0] || {}).userName || "";
if (lastUserName !== data.userName) {
$list.append(createElement("div", "item-blank", ""));
}
let element = createElement(
"div",
"item item-merge-" + data.type,
createItemHtml(data)
);
$list.append(element);
$list.scrollTop = $list.scrollHeight;
}
// 还原历史记录,添加列表
function appendItemList(data) {
const $list = document.getElementById("list");
const fragment = document.createDocumentFragment();
data.forEach((item) => {
const dateClass = ".date_" + (item.date || "");
if (!document.querySelector(dateClass)) {
fragment.appendChild(createElementDate(item.date));
}
let lastUserName = "";
item.data.forEach((sub) => {
if (!dataObj[sub.id]) {
dataObj[sub.id] = sub;
if (lastUserName !== sub.userName) {
fragment.appendChild(createElement("div", "item-blank", ""));
lastUserName = sub.userName;
}
fragment.appendChild(
createElement(
"div",
"item item-merge-" + sub.type,
createItemHtml(sub)
)
);
}
});
});
$list.append(fragment);
$list.scrollTop = $list.scrollHeight;
}
const target = document.querySelector("body");
// 创建观察者对象
const observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
var theme = mutation.target.getAttribute("data-vscode-theme-kind") === 'vscode-dark'? 'vs-dark': 'vs';
monaco.editor.setTheme(theme);
});
});
// 传入目标节点和观察选项
observer.observe(target, { attributes: true, attributeFilter: ["data-vscode-theme-kind"] });
// 把一维数组拆分成二维数组
function splitData(data) {
data.forEach(function (item) {
const date = item.datetime.split(" ")?.[0] || "";
if (date) {
dataSplitObj[date] = dataSplitObj[date] || [];
dataSplitObj[date].push(item);
}
});
const resultData = [];
for (var key in dataSplitObj) {
resultData.push({ date: key, data: dataSplitObj[key] });
}
return resultData;
}
// 创建日期
function createElementDate(date) {
let dateClass = "dateline date_" + date;
return createElement("p", dateClass, date);
}
// 打开链接
function openLink(url) {
let userAgent = navigator.userAgent.toLowerCase();
let version = (
(userAgent.match(/version\/([\d.]+).*safari/) || [])[1] || ""
).split(".")[0];
const isSafari = /safari/.test(userAgent) && !/chrome/.test(userAgent);
if (isSafari && version === "14" && url && url.indexOf("http") > -1) {
vscode.postMessage({ type: "metawork.openLink", data: { url } });
}
}
// 提交
function submitMessage() {
let val = (document.getElementById("input").value || "").trim();
if (val) {
vscode.postMessage({ type: "metawork.newMessage", data: val });
document.getElementById("input").value = "";
}
return false;
}
// 点击内容
function handleClickContent(id) {
const data = dataObj[id];
if (data) {
vscode.postMessage({ type: "metawork.clickContent", data: data });
}
}