markdown 수정 페이지 호출 방식 변경
All checks were successful
Build And Test / build-and-push (push) Successful in 4m20s
All checks were successful
Build And Test / build-and-push (push) Successful in 4m20s
This commit is contained in:
parent
fd3ab674c3
commit
06d6010c19
@ -42,13 +42,14 @@
|
|||||||
<!-- Highlight.js Script -->
|
<!-- Highlight.js Script -->
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Initialize Highlight.js
|
// 문서 로드 후 동작
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
document
|
// 코드 블럭 하이라이트
|
||||||
.querySelectorAll("pre code")
|
document.querySelectorAll("pre code").forEach((block) => {
|
||||||
.forEach((block) => {
|
hljs.highlightElement(block);
|
||||||
hljs.highlightElement(block);
|
});
|
||||||
});
|
|
||||||
|
await updateImagesWithPresignedUrls();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Function to update images with presigned URLs
|
// Function to update images with presigned URLs
|
||||||
@ -90,9 +91,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the function when the page loads
|
|
||||||
document.addEventListener("DOMContentLoaded", updateImagesWithPresignedUrls);
|
|
||||||
|
|
||||||
// Delete post
|
// Delete post
|
||||||
document
|
document
|
||||||
.getElementById("delete-button")
|
.getElementById("delete-button")
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
{% extends "components/base.html" %}
|
{% extends "components/base.html" %}
|
||||||
{% block title %}Update Post{% endblock %}
|
{% block title %}post edit{% endblock %}
|
||||||
|
|
||||||
{% block main_area %}
|
{% block main_area %}
|
||||||
<h1 class="pt-3">Update Post</h1>
|
<h1 class="pt-3">post edit</h1>
|
||||||
<div class="container mt-3">
|
<div class="container">
|
||||||
<h5 class="text-danger">◇마크다운 미리보기는 Contents 편집 내용 입력시 동작합니다.</h5>
|
|
||||||
<div class="row mt-3">
|
<div class="row mt-3">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<form method="POST" id="post-form">
|
<form method="POST" id="post-form">
|
||||||
@ -27,9 +26,10 @@
|
|||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{{ form.contents }}
|
{{ form.contents }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 버튼 -->
|
<!-- 버튼 -->
|
||||||
<div class="d-flex justify-content-end mt-4">
|
<div class="d-flex justify-content-end mt-4">
|
||||||
<button type="submit" class="btn btn-primary me-2">Save Changes</button>
|
<button type="submit" class="btn btn-primary me-2">Save</button>
|
||||||
<a href="{% url 'blog:post_list' %}" class="btn btn-secondary">Cancel</a>
|
<a href="{% url 'blog:post_list' %}" class="btn btn-secondary">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -44,25 +44,20 @@
|
|||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// 마크다운 파서 초기화
|
|
||||||
const md = window.markdownit({
|
const md = window.markdownit({
|
||||||
highlight: function (str, lang) {
|
highlight: function (str, lang) {
|
||||||
if (lang && hljs.getLanguage(lang)) {
|
if (lang && hljs.getLanguage(lang)) {
|
||||||
try {
|
try {
|
||||||
return hljs
|
return hljs.highlight(str, { language: lang }).value;
|
||||||
.highlight(str, {language: lang})
|
|
||||||
.value;
|
|
||||||
} catch (__) {}
|
} catch (__) {}
|
||||||
}
|
}
|
||||||
return ''; // 기본 HTML 이스케이프 처리
|
return '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// content 필드와 미리보기 연결
|
|
||||||
const textarea = document.getElementById("markdown-editor");
|
const textarea = document.getElementById("markdown-editor");
|
||||||
const preview = document.getElementById("preview");
|
const preview = document.getElementById("preview");
|
||||||
|
|
||||||
// 미리보기 업데이트 함수
|
|
||||||
async function updatePreview() {
|
async function updatePreview() {
|
||||||
const markdownContent = textarea.value;
|
const markdownContent = textarea.value;
|
||||||
const lines = markdownContent.split("\n");
|
const lines = markdownContent.split("\n");
|
||||||
@ -74,10 +69,8 @@
|
|||||||
try {
|
try {
|
||||||
const response = await fetch("/obs_minio/get_presigned_url/", {
|
const response = await fetch("/obs_minio/get_presigned_url/", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: { "Content-Type": "application/json" },
|
||||||
"Content-Type": "application/json"
|
body: JSON.stringify({ object_name: objectName })
|
||||||
},
|
|
||||||
body: JSON.stringify({object_name: objectName})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
@ -91,35 +84,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderedContent = md.render(lines.join("\n"));
|
preview.innerHTML = md.render(lines.join("\n"));
|
||||||
preview.innerHTML = renderedContent;
|
|
||||||
|
|
||||||
// Highlight.js로 코드 블록 강조
|
// 코드 블록 하이라이트 적용
|
||||||
document
|
document.querySelectorAll("#preview pre code").forEach((block) => {
|
||||||
.querySelectorAll("#preview pre code")
|
hljs.highlightElement(block);
|
||||||
.forEach((block) => {
|
});
|
||||||
hljs.highlightElement(block);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 실시간 미리보기 업데이트
|
// 페이지 로드되자마자 초기 미리보기 렌더링
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
updatePreview();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 입력할 때마다 미리보기 업데이트
|
||||||
textarea.addEventListener("input", updatePreview);
|
textarea.addEventListener("input", updatePreview);
|
||||||
|
|
||||||
// Ctrl+V로 이미지 붙여넣기 처리
|
// 이미지 붙여넣기
|
||||||
textarea.addEventListener("paste", async function (event) {
|
textarea.addEventListener("paste", async function (event) {
|
||||||
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||||
|
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (item.type.startsWith("image/")) {
|
if (item.type.startsWith("image/")) {
|
||||||
const file = item.getAsFile();
|
const file = item.getAsFile();
|
||||||
if (!file)
|
if (!file) return;
|
||||||
return;
|
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("image", file);
|
formData.append("image", file);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 이미지 업로드 API 호출
|
|
||||||
const response = await fetch("/obs_minio/upload/", {
|
const response = await fetch("/obs_minio/upload/", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData
|
body: formData
|
||||||
@ -127,17 +120,12 @@
|
|||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
const fullImageUrl = data.url; // 전체 URL
|
const fullImageUrl = data.url;
|
||||||
const objectName = fullImageUrl
|
const objectName = fullImageUrl.split("/").slice(-2).join("/");
|
||||||
.split("/")
|
|
||||||
.slice(-2)
|
|
||||||
.join("/");
|
|
||||||
|
|
||||||
// 마크다운 에디터에 이미지 삽입
|
|
||||||
const markdownImage = `\n`;
|
const markdownImage = `\n`;
|
||||||
textarea.value += markdownImage;
|
textarea.value += markdownImage;
|
||||||
|
|
||||||
// 미리보기 업데이트
|
|
||||||
updatePreview();
|
updatePreview();
|
||||||
} else {
|
} else {
|
||||||
alert("Image upload failed. Please try again.");
|
alert("Image upload failed. Please try again.");
|
||||||
|
@ -54,10 +54,38 @@
|
|||||||
const textarea = document.getElementById("markdown-editor");
|
const textarea = document.getElementById("markdown-editor");
|
||||||
const preview = document.getElementById("preview");
|
const preview = document.getElementById("preview");
|
||||||
|
|
||||||
// 실시간 미리보기 업데이트
|
// 미리보기 업데이트 함수
|
||||||
textarea.addEventListener("input", function () {
|
async function updatePreview() {
|
||||||
const markdownContent = textarea.value; // textarea 내용 가져오기
|
const markdownContent = textarea.value;
|
||||||
const renderedContent = md.render(markdownContent); // 마크다운 -> HTML 변환
|
const lines = markdownContent.split("\n");
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const match = lines[i].match(/!\[Image\]\((.+)\)/);
|
||||||
|
if (match) {
|
||||||
|
const objectName = match[1];
|
||||||
|
try {
|
||||||
|
// Presigned URL 가져오기
|
||||||
|
const response = await fetch("/obs_minio/get_presigned_url/", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({object_name: objectName})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
const presignedUrl = data.presigned_url;
|
||||||
|
lines[i] = ``; // Presigned URL로 업데이트
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching presigned URL:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 마크다운 렌더링 및 미리보기 업데이트
|
||||||
|
const renderedContent = md.render(lines.join("\n"));
|
||||||
preview.innerHTML = renderedContent;
|
preview.innerHTML = renderedContent;
|
||||||
|
|
||||||
// Highlight.js로 코드 블록 강조
|
// Highlight.js로 코드 블록 강조
|
||||||
@ -66,6 +94,54 @@
|
|||||||
.forEach((block) => {
|
.forEach((block) => {
|
||||||
hljs.highlightElement(block);
|
hljs.highlightElement(block);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 실시간 미리보기 업데이트
|
||||||
|
textarea.addEventListener("input", updatePreview);
|
||||||
|
|
||||||
|
// Ctrl+V로 이미지 붙여넣기 처리
|
||||||
|
textarea.addEventListener("paste", async function (event) {
|
||||||
|
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
if (item.type.startsWith("image/")) {
|
||||||
|
const file = item.getAsFile();
|
||||||
|
if (!file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("image", file);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 이미지 업로드 API 호출
|
||||||
|
const response = await fetch("/obs_minio/upload/", {
|
||||||
|
method: "POST",
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
const fullImageUrl = data.url; // 전체 URL
|
||||||
|
const objectName = fullImageUrl
|
||||||
|
.split("/")
|
||||||
|
.slice(-2)
|
||||||
|
.join("/");
|
||||||
|
|
||||||
|
// 마크다운 에디터에 이미지 삽입
|
||||||
|
const markdownImage = `\n`;
|
||||||
|
textarea.value += markdownImage;
|
||||||
|
|
||||||
|
// 미리보기 업데이트
|
||||||
|
updatePreview();
|
||||||
|
} else {
|
||||||
|
alert("Image upload failed. Please try again.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error uploading image:", error);
|
||||||
|
alert("An error occurred during image upload.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,15 +4,18 @@
|
|||||||
{% block main_area %}
|
{% block main_area %}
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<h1 class="mt-4">{{ notice.title }}</h1>
|
<h1 class="mt-4">{{ notice.title }}</h1>
|
||||||
|
|
||||||
<!-- Author -->
|
<!-- Author -->
|
||||||
<div class="text-muted fst-italic mb-2">{{ notice.created_at }}
|
<div class="text-muted fst-italic mb-2">
|
||||||
<br>
|
{{ notice.created_at }}<br>
|
||||||
by.
|
by. {{ notice.author | upper }}
|
||||||
{{ notice.author | upper }}</div>
|
</div>
|
||||||
|
|
||||||
<!-- Rendered Markdown Content -->
|
<!-- Rendered Markdown Content -->
|
||||||
<div>
|
<div id="post-content">
|
||||||
{{ notice.render_markdown|safe }}
|
{{ notice.render_markdown|safe }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
{% if request.user == notice.author %}
|
{% if request.user == notice.author %}
|
||||||
@ -28,29 +31,68 @@
|
|||||||
|
|
||||||
<!-- Highlight.js Styles -->
|
<!-- Highlight.js Styles -->
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
|
||||||
|
|
||||||
<!-- Highlight.js Script -->
|
<!-- Highlight.js Script -->
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Initialize Highlight.js
|
// 문서 로드 후 동작
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
document
|
// 코드 블럭 하이라이트
|
||||||
.querySelectorAll("pre code")
|
document.querySelectorAll("pre code").forEach((block) => {
|
||||||
.forEach((block) => {
|
hljs.highlightElement(block);
|
||||||
hljs.highlightElement(block);
|
});
|
||||||
});
|
|
||||||
|
await updateImagesWithPresignedUrls();
|
||||||
});
|
});
|
||||||
</script>
|
|
||||||
<!-- Delete Notice -->
|
// 이미지 Presigned URL로 변환
|
||||||
<script>
|
async function updateImagesWithPresignedUrls() {
|
||||||
|
const contentDiv = document.getElementById("post-content");
|
||||||
|
const contentHtml = contentDiv.innerHTML;
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(contentHtml, "text/html");
|
||||||
|
const images = doc.querySelectorAll("img");
|
||||||
|
|
||||||
|
for (const img of images) {
|
||||||
|
const objectName = img.getAttribute("src");
|
||||||
|
try {
|
||||||
|
const response = await fetch("/obs_minio/get_presigned_url/", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ object_name: objectName })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
img.setAttribute("src", data.presigned_url);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching presigned URL:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 변경된 HTML 다시 적용
|
||||||
|
contentDiv.innerHTML = doc.body.innerHTML;
|
||||||
|
|
||||||
|
// 다시 하이라이트 적용
|
||||||
|
document.querySelectorAll("pre code").forEach((block) => {
|
||||||
|
hljs.highlightElement(block);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 버튼 클릭 이벤트
|
||||||
document
|
document
|
||||||
.getElementById("delete-button")
|
.getElementById("delete-button")
|
||||||
.addEventListener("click", function () {
|
.addEventListener("click", function () {
|
||||||
const confirmed = confirm("Are you sure you want to delete this Notice?");
|
const confirmed = confirm("Are you sure you want to delete this Notice?");
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
document
|
document
|
||||||
.getElementById("delete-form")
|
.getElementById("delete-form")
|
||||||
.submit();
|
.submit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{% extends "components/base.html" %}
|
{% extends "components/base.html" %}
|
||||||
{% block title %}Update Post{% endblock %}
|
{% block title %}notice edit{% endblock %}
|
||||||
|
|
||||||
{% block main_area %}
|
{% block main_area %}
|
||||||
<h1 class="pt-3">Update Post</h1>
|
<h1 class="pt-3">notice edit</h1>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row mt-3">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<form method="POST" id="post-form">
|
<form method="POST" id="post-form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
@ -26,10 +26,11 @@
|
|||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{{ form.contents }}
|
{{ form.contents }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 버튼 -->
|
<!-- 버튼 -->
|
||||||
<div class="d-flex justify-content-end mt-4">
|
<div class="d-flex justify-content-end mt-4">
|
||||||
<button type="submit" class="btn btn-primary me-2">Save Changes</button>
|
<button type="submit" class="btn btn-primary me-2">Save</button>
|
||||||
<a href="{% url 'blog:post_list' %}" class="btn btn-secondary">Cancel</a>
|
<a href="{% url 'board_notice:notice_list' %}" class="btn btn-secondary">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -40,18 +41,101 @@
|
|||||||
|
|
||||||
<!-- 마크다운 파서 및 스크립트 -->
|
<!-- 마크다운 파서 및 스크립트 -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/markdown-it/dist/markdown-it.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/markdown-it/dist/markdown-it.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// 마크다운 파서 초기화
|
const md = window.markdownit({
|
||||||
const md = window.markdownit();
|
highlight: function (str, lang) {
|
||||||
|
if (lang && hljs.getLanguage(lang)) {
|
||||||
|
try {
|
||||||
|
return hljs.highlight(str, { language: lang }).value;
|
||||||
|
} catch (__) {}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// content 필드와 미리보기 연결
|
|
||||||
const textarea = document.getElementById("markdown-editor");
|
const textarea = document.getElementById("markdown-editor");
|
||||||
const preview = document.getElementById("preview");
|
const preview = document.getElementById("preview");
|
||||||
|
|
||||||
// 실시간 미리보기 업데이트
|
async function updatePreview() {
|
||||||
textarea.addEventListener("input", function () {
|
const markdownContent = textarea.value;
|
||||||
const markdownContent = textarea.value; // textarea 내용 가져오기
|
const lines = markdownContent.split("\n");
|
||||||
preview.innerHTML = md.render(markdownContent); // 마크다운 -> HTML 변환
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const match = lines[i].match(/!\[Image\]\((.+)\)/);
|
||||||
|
if (match) {
|
||||||
|
const objectName = match[1];
|
||||||
|
try {
|
||||||
|
const response = await fetch("/obs_minio/get_presigned_url/", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ object_name: objectName })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
const presignedUrl = data.presigned_url;
|
||||||
|
lines[i] = ``;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching presigned URL:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
preview.innerHTML = md.render(lines.join("\n"));
|
||||||
|
|
||||||
|
// 코드 블록 하이라이트 적용
|
||||||
|
document.querySelectorAll("#preview pre code").forEach((block) => {
|
||||||
|
hljs.highlightElement(block);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 페이지 로드되자마자 초기 미리보기 렌더링
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
updatePreview();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 입력할 때마다 미리보기 업데이트
|
||||||
|
textarea.addEventListener("input", updatePreview);
|
||||||
|
|
||||||
|
// 이미지 붙여넣기
|
||||||
|
textarea.addEventListener("paste", async function (event) {
|
||||||
|
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
if (item.type.startsWith("image/")) {
|
||||||
|
const file = item.getAsFile();
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("image", file);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("/obs_minio/upload/", {
|
||||||
|
method: "POST",
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
const fullImageUrl = data.url;
|
||||||
|
const objectName = fullImageUrl.split("/").slice(-2).join("/");
|
||||||
|
|
||||||
|
const markdownImage = `\n`;
|
||||||
|
textarea.value += markdownImage;
|
||||||
|
|
||||||
|
updatePreview();
|
||||||
|
} else {
|
||||||
|
alert("Image upload failed. Please try again.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error uploading image:", error);
|
||||||
|
alert("An error occurred during image upload.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user