로직 수정

This commit is contained in:
kim365my 2024-04-12 23:06:24 +09:00
parent aa52baa0e0
commit 4f77319251
2 changed files with 103 additions and 118 deletions

View File

@ -52,12 +52,13 @@ class StatefulDecorationSet {
linkEl.addClass("markdown-rendered");
linkEl.addClass("external-link");
div.appendChild(linkEl);
LinkThumbnailWidgetParams(token.value).then(params => {
const params = await LinkThumbnailWidgetParams(token.value);
if (params) {
linkEl.innerHTML = params;
linkEl.addEventListener("click", (e) => e.stopPropagation());
} else if (params === null) {
linkEl.innerHTML = token.value;
}
});
deco = this.decoCache[token.value] = Decoration.replace({widget: new ogLinkWidget(div), block: true});
}
decorations.push(deco.range(token.from, token.to));

View File

@ -13,41 +13,24 @@ const OGDATACHACHE = "ogDataCache"
// url 정규식
const urlRegex = new RegExp("^(http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/|https:\\/\\/)?[a-z0-9]+([\\-.]{1}[a-z0-9]+)*\\.[a-z]{2,5}(:[0-9]{1,5})?(\\/.*)?$");
// 로컬데이터 접근
function loadLocalOgData(url: string) {
const data = localStorage.getItem(OGDATACHACHE + url);
if (data) {
const ogData: ogData = JSON.parse(data);
return ogData;
}
}
async function saveLocalOgData(url:string, ogData: ogData) {
const imgUrl = ogData.ogImage;
if (imgUrl !== "") {
// 저장하기 전에 img 데이터를 url-> blob -> base64로 변환 후 저장
async function getImgFile(imgUrl: string) {
const imgFormat = ["jpg", "jpeg", "png", "bmp", "tif", "gif", "svg"];
try {
const lastDot = imgUrl.lastIndexOf(".");
let imgType = imgUrl.substring(lastDot + 1, imgUrl.length).toLowerCase();
let imgType = "";
imgFormat.forEach((format) => {
if (imgUrl.includes(format)) {
imgType = format;
}
});
const options: RequestUrlParam = {
url: imgUrl,
method: "POST",
contentType: `image/${imgType}`
}
const file = await requestUrl(options);
const fileArrayBuffer = file.arrayBuffer;
// 방법 1) blob 변환
// const fileBlob = new Blob([fileArrayBuffer], { type: `image/${imgType}`});
// // 파일 리더 생성
// const reader = new FileReader();
// reader.readAsDataURL(fileBlob);
// let base64String = "";
// reader.onloadend = () => {
// const base64 = reader.result;
// if (typeof base64 === "string") base64String = base64;
// };
// 방법 2) ArrayBuffer 자체를 base64로 변환
const uint8 = new Uint8Array(fileArrayBuffer);
@ -55,27 +38,25 @@ async function saveLocalOgData(url:string, ogData: ogData) {
return data + String.fromCharCode(byte);
}, ''));
if (imgType.includes("svg")) imgType += "+xml";
ogData.ogImage = `data:image/${imgType};charset=utf-8;base64,` + base64String;
return `data:image/${imgType};charset=utf-8;base64,` + base64String;
} catch (error) {
console.log(error);
return "";
}
}
// 저장하기 전에 img 데이터를 url-> blob -> base64로 변환 후 저장
localStorage.setItem(OGDATACHACHE + url, JSON.stringify(ogData));
}
async function getOgData(url: string) {
// 로컬데이터 접근
const data = localStorage.getItem(OGDATACHACHE + url);
if (data) {
const ogData: ogData = JSON.parse(data);
return ogData;
} else {
const urlArr = urlRegex.exec(url);
if (urlArr) {
try {
const options: RequestUrlParam = {
url: url,
method: "POST",
}
const response = await requestUrl(options);
const response = await requestUrl(url);
if (response && response.headers && response.headers['content-type'] && !response.headers['content-type']?.includes('text/')) {
throw new Error('Page must return a header content-type with text/');
}
@ -96,11 +77,17 @@ async function getOgData(url: string) {
const ogTitle = document.querySelector("meta[property='og:title']")?.getAttribute("content") || document.querySelector("title")?.textContent || "";
const ogDescription = document.querySelector("meta[property='og:description']")?.getAttribute("content") || "";
let ogImage = document.querySelector("meta[property='og:image']")?.getAttribute("content") || "";
if (ogImage.startsWith("/")) {
let ogImage = "";
let imgUrl = document.querySelector("meta[property='og:image']")?.getAttribute("content") || "";
if (imgUrl !== "") {
const baseUrl = url.replace(urlArr[4], "");
ogImage = baseUrl + ogImage;
if (!imgUrl.startsWith("http")) {
imgUrl = baseUrl + (imgUrl.startsWith("/"))? "" : "/" + imgUrl;
}
ogImage = await getImgFile(imgUrl);
}
const ogImageAlt = document.querySelector("meta[property='og:image:alt']")?.getAttribute("content") || "";
const ogUrl = document.querySelector("meta[property='og:url']")?.getAttribute("content") || url;
@ -112,7 +99,7 @@ async function getOgData(url: string) {
"ogUrl": ogUrl
}
await saveLocalOgData(url, data);
localStorage.setItem(OGDATACHACHE + url, JSON.stringify(data));
return data;
} catch (error) {
console.error(error);
@ -120,25 +107,22 @@ async function getOgData(url: string) {
}
}
}
}
function renderOgData(data:ogData) {
export async function LinkThumbnailWidgetParams(url: string) {
const data = await getOgData(url);
if (data) {
return `
<div class="openGraphPreview">
${(data?.ogImage === "")? "" : `<div class="se-oglink-thumbnail"><img src="${data?.ogImage}" alt="${data?.ogImageAlt}" class="se-oglink-thumbnail-resource"></img></div>`}
<div class="se-oglink-info-container">
<strong class="se-oglink-info">${data?.ogTitle}</strong>
<description class="se-oglink-summary">${data?.ogDescription}</description>
<p class="se-oglink-url">${data?.ogUrl}</p>
<span class="se-oglink-url">${data?.ogUrl}</span>
</div>
</div>
`;
}
export async function LinkThumbnailWidgetParams(url: string) {
const data = loadLocalOgData(url) || await getOgData(url);
if (data) {
const result = renderOgData(data);
return result;
}
return null;
}