Massive re-factor to forum code (at least the first half)
This commit is contained in:
parent
24e517b299
commit
f500846975
@ -384,6 +384,16 @@
|
|||||||
background-color: rgba(0, 0, 0, 0.8); /* Black w/ opacity */
|
background-color: rgba(0, 0, 0, 0.8); /* Black w/ opacity */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remove-image-button {
|
||||||
|
background-color: #0f4c41;
|
||||||
|
color: #ffffff;
|
||||||
|
border: dotted;
|
||||||
|
border-radius: 1vh;
|
||||||
|
padding: 0.3vh 0.6vh;
|
||||||
|
margin-top: 1px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -494,7 +494,7 @@ const toggleComments = async (cardIdentifier) => {
|
|||||||
const createModal = async () => {
|
const createModal = async () => {
|
||||||
const modalHTML = `
|
const modalHTML = `
|
||||||
<div id="modal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); z-index: 1000;">
|
<div id="modal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); z-index: 1000;">
|
||||||
<div style="position: relative; margin: 5% auto; width: 90%; height: 90%; background: white; border-radius: 10px; overflow: hidden;">
|
<div style="position: relative; margin: 10% auto; width: 95%; height: 80%; background: white; border-radius: 10px; overflow: hidden;">
|
||||||
<iframe id="modalContent" src="" style="width: 100%; height: 100%; border: none;"></iframe>
|
<iframe id="modalContent" src="" style="width: 100%; height: 100%; border: none;"></iframe>
|
||||||
<button onclick="closeModal()" style="position: absolute; top: 10px; right: 10px; background: red; color: white; border: none; padding: 5px 10px; border-radius: 5px;">Close</button>
|
<button onclick="closeModal()" style="position: absolute; top: 10px; right: 10px; background: red; color: white; border: none; padding: 5px 10px; border-radius: 5px;">Close</button>
|
||||||
</div>
|
</div>
|
||||||
@ -522,9 +522,16 @@ const closeModal = async () => {
|
|||||||
|
|
||||||
const processLink = async (link) => {
|
const processLink = async (link) => {
|
||||||
if (link.startsWith('qortal://')) {
|
if (link.startsWith('qortal://')) {
|
||||||
return link.replace('qortal://', '/render/')
|
const match = link.match(/^qortal:\/\/([^/]+)(\/.*)?$/);
|
||||||
|
if (match) {
|
||||||
|
const firstParam = match[1].toUpperCase(); // Convert to uppercase
|
||||||
|
const remainingPath = match[2] || ""; // Rest of the URL
|
||||||
|
// Perform any asynchronous operation if necessary
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 10)); // Simulating async operation
|
||||||
|
return `http://localhost:12391/render/${firstParam}${remainingPath}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return link // Return the link unchanged if it doesn't start with `qortal://`
|
return link; // Return unchanged if not a Qortal link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,311 +137,282 @@ const renderPaginationControls = async(room, totalMessages, limit) => {
|
|||||||
// Main function to load the full content of the room, along with all main functionality -----------------------------------
|
// Main function to load the full content of the room, along with all main functionality -----------------------------------
|
||||||
const loadRoomContent = async (room) => {
|
const loadRoomContent = async (room) => {
|
||||||
const forumContent = document.getElementById("forum-content");
|
const forumContent = document.getElementById("forum-content");
|
||||||
if (forumContent) {
|
|
||||||
forumContent.innerHTML = `
|
if (!forumContent) {
|
||||||
<div class="room-content">
|
console.error("Forum content container not found!");
|
||||||
<h3 class="room-title" style="color: lightblue;">${room.charAt(0).toUpperCase() + room.slice(1)} Room</h3>
|
return;
|
||||||
<div id="messages-container" class="messages-container"></div>
|
}
|
||||||
<div id="pagination-container" class="pagination-container" style="margin-top: 20px; text-align: center;"></div>
|
|
||||||
<div class="message-input-section">
|
// Set initial content
|
||||||
<div id="toolbar" class="message-toolbar"></div>
|
forumContent.innerHTML = `
|
||||||
<div id="editor" class="message-input"></div>
|
<div class="room-content">
|
||||||
<div class="attachment-section">
|
<h3 class="room-title" style="color: lightblue;">${room.charAt(0).toUpperCase() + room.slice(1)} Room</h3>
|
||||||
<input type="file" id="file-input" class="file-input" multiple>
|
<div id="messages-container" class="messages-container"></div>
|
||||||
<label for="file-input" class="custom-file-input-button">Select Files</label>
|
<div id="pagination-container" class="pagination-container" style="margin-top: 20px; text-align: center;"></div>
|
||||||
<input type="file" id="image-input" class="image-input" multiple accept="image/*">
|
<div class="message-input-section">
|
||||||
<label for="image-input" class="custom-image-input-button">Select IMAGES w/Preview</label>
|
<div id="toolbar" class="message-toolbar"></div>
|
||||||
<button id="add-images-to-publish-button" disabled>Add Images to Multi-Publish</button>
|
<div id="editor" class="message-input"></div>
|
||||||
<div id="preview-container" style="display: flex; flex-wrap: wrap; gap: 10px;"></div>
|
<div class="attachment-section">
|
||||||
</div>
|
<input type="file" id="file-input" class="file-input" multiple>
|
||||||
<button id="send-button" class="send-button">Publish</button>
|
<label for="file-input" class="custom-file-input-button">Select Files</label>
|
||||||
|
<input type="file" id="image-input" class="image-input" multiple accept="image/*">
|
||||||
|
<label for="image-input" class="custom-image-input-button">Select IMAGES w/Preview</label>
|
||||||
|
<button id="add-images-to-publish-button" disabled>Add Images to Multi-Publish</button>
|
||||||
|
<div id="preview-container" style="display: flex; flex-wrap: wrap; gap: 10px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<button id="send-button" class="send-button">Publish</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
const imageModalHTML = `
|
// Add modal for image preview
|
||||||
<div id="image-modal" class="image-modal">
|
forumContent.insertAdjacentHTML(
|
||||||
<span id="close-modal" class="close">×</span>
|
'beforeend',
|
||||||
<img id="modal-image" class="modal-content">
|
`
|
||||||
<div id="caption" class="caption"></div>
|
<div id="image-modal" class="image-modal">
|
||||||
<button id="download-button" class="download-button">Download</button>
|
<span id="close-modal" class="close">×</span>
|
||||||
</div>
|
<img id="modal-image" class="modal-content">
|
||||||
`;
|
<div id="caption" class="caption"></div>
|
||||||
forumContent.insertAdjacentHTML('beforeend', imageModalHTML);
|
<button id="download-button" class="download-button">Download</button>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
// Initialize Quill editor for rich text input
|
initializeQuillEditor();
|
||||||
const quill = new Quill('#editor', {
|
setupModalHandlers();
|
||||||
theme: 'snow',
|
setupFileInputs(room);
|
||||||
modules: {
|
await loadMessagesFromQDN(room, currentPage);
|
||||||
toolbar: [
|
};
|
||||||
[{ 'font': [] }], // Add font family options
|
|
||||||
[{ 'size': ['small', false, 'large', 'huge'] }], // Add font size options
|
|
||||||
[{ 'header': [1, 2, false] }],
|
|
||||||
['bold', 'italic', 'underline'], // Text formatting options
|
|
||||||
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
|
||||||
['link', 'blockquote', 'code-block'],
|
|
||||||
[{ 'color': [] }, { 'background': [] }], // Text color and background color options
|
|
||||||
[{ 'align': [] }], // Text alignment
|
|
||||||
['clean'] // Remove formatting button
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load messages from QDN for the selected room
|
// Initialize Quill editor
|
||||||
await loadMessagesFromQDN(room, currentPage);
|
const initializeQuillEditor = () => {
|
||||||
|
new Quill('#editor', {
|
||||||
|
theme: 'snow',
|
||||||
|
modules: {
|
||||||
|
toolbar: [
|
||||||
|
[{ 'font': [] }],
|
||||||
|
[{ 'size': ['small', false, 'large', 'huge'] }],
|
||||||
|
[{ 'header': [1, 2, false] }],
|
||||||
|
['bold', 'italic', 'underline'],
|
||||||
|
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
||||||
|
['link', 'blockquote', 'code-block'],
|
||||||
|
[{ 'color': [] }, { 'background': [] }],
|
||||||
|
[{ 'align': [] }],
|
||||||
|
['clean']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
document.addEventListener("click", async (event) => {
|
// Set up modal behavior
|
||||||
if (event.target.classList.contains("inline-image")) {
|
const setupModalHandlers = () => {
|
||||||
const modal = document.getElementById("image-modal");
|
document.addEventListener("click", (event) => {
|
||||||
const modalImage = document.getElementById("modal-image");
|
if (event.target.classList.contains("inline-image")) {
|
||||||
const caption = document.getElementById("caption");
|
|
||||||
// const downloadButton = document.getElementById("download-button");
|
|
||||||
|
|
||||||
// Set the modal content
|
|
||||||
modalImage.src = event.target.src;
|
|
||||||
caption.textContent = event.target.alt;
|
|
||||||
|
|
||||||
// Show the modal
|
|
||||||
modal.style.display = "block";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Close the modal
|
|
||||||
document.getElementById("close-modal").addEventListener("click", async () => {
|
|
||||||
document.getElementById("image-modal").style.display = "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
// Hide the modal when clicking outside of the image or close button
|
|
||||||
window.addEventListener("click", async (event) => {
|
|
||||||
const modal = document.getElementById("image-modal");
|
const modal = document.getElementById("image-modal");
|
||||||
if (!event.target == modal) {
|
const modalImage = document.getElementById("modal-image");
|
||||||
modal.style.display = "none";
|
const caption = document.getElementById("caption");
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
let selectedFiles = [];
|
modalImage.src = event.target.src;
|
||||||
let selectedImages = [];
|
caption.textContent = event.target.alt;
|
||||||
let attachmentIdentifiers = [];
|
modal.style.display = "block";
|
||||||
let multiResource = []
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const imageFileInput = document.getElementById('image-input');
|
document.getElementById("close-modal").addEventListener("click", () => {
|
||||||
const previewContainer = document.getElementById('preview-container');
|
document.getElementById("image-modal").style.display = "none";
|
||||||
const addToPublishButton = document.getElementById('add-images-to-publish-button')
|
});
|
||||||
const randomID = await uid();
|
|
||||||
const attachmentID = `${messageAttachmentIdentifierPrefix}-${room}-${randomID}`;
|
|
||||||
|
|
||||||
imageFileInput.addEventListener('change', async (event) => {
|
window.addEventListener("click", (event) => {
|
||||||
// Clear previous previews to prepare for preview generation
|
const modal = document.getElementById("image-modal");
|
||||||
previewContainer.innerHTML = '';
|
if (event.target === modal) {
|
||||||
selectedImages = Array.from(event.target.files);
|
modal.style.display = "none";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if (selectedImages.length > 0) {
|
let selectedImages = [];
|
||||||
addToPublishButton.disabled = false;
|
let selectedFiles = [];
|
||||||
}
|
let multiResource = [];
|
||||||
|
let attachmentIdentifiers = [];
|
||||||
|
|
||||||
selectedImages.forEach((file, index) => {
|
// Set up file input handling
|
||||||
const reader = new FileReader();
|
const setupFileInputs = (room) => {
|
||||||
reader.onload = () => {
|
const imageFileInput = document.getElementById('image-input');
|
||||||
const img = document.createElement('img');
|
const previewContainer = document.getElementById('preview-container');
|
||||||
img.src = reader.result;
|
const addToPublishButton = document.getElementById('add-images-to-publish-button');
|
||||||
img.alt = file.name;
|
const fileInput = document.getElementById('file-input');
|
||||||
img.style.width = '100px';
|
const sendButton = document.getElementById('send-button');
|
||||||
img.style.height = '100px';
|
|
||||||
img.style.objectFit = 'cover';
|
|
||||||
img.style.border = '1px solid #ccc';
|
|
||||||
img.style.borderRadius = '5px';
|
|
||||||
|
|
||||||
// Add remove button
|
const attachmentID = generateAttachmentID(room);
|
||||||
const removeButton = document.createElement('button');
|
|
||||||
removeButton.innerText = 'Remove';
|
|
||||||
removeButton.style.marginTop = '5px';
|
|
||||||
removeButton.onclick = () => {
|
|
||||||
selectedImages.splice(index, 1);
|
|
||||||
img.remove();
|
|
||||||
removeButton.remove();
|
|
||||||
if (selectedImages.length === 0) {
|
|
||||||
addToPublishButton.disabled = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const container = document.createElement('div');
|
imageFileInput.addEventListener('change', (event) => {
|
||||||
container.style.display = 'flex';
|
previewContainer.innerHTML = '';
|
||||||
container.style.flexDirection = 'column';
|
selectedImages = [...event.target.files];
|
||||||
container.style.alignItems = 'center';
|
|
||||||
container.style.margin = '5px';
|
addToPublishButton.disabled = selectedImages.length === 0;
|
||||||
container.appendChild(img);
|
|
||||||
container.appendChild(removeButton);
|
selectedImages.forEach((file, index) => {
|
||||||
previewContainer.appendChild(container);
|
const reader = new FileReader();
|
||||||
|
reader.onload = () => {
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = reader.result;
|
||||||
|
img.alt = file.name;
|
||||||
|
img.style = "width: 100px; height: 100px; object-fit: cover; border: 1px solid #ccc; border-radius: 5px;";
|
||||||
|
|
||||||
|
const removeButton = document.createElement('button');
|
||||||
|
removeButton.innerText = 'Remove';
|
||||||
|
removeButton.classList.add('remove-image-button');
|
||||||
|
removeButton.onclick = () => {
|
||||||
|
selectedImages.splice(index, 1);
|
||||||
|
img.remove();
|
||||||
|
removeButton.remove();
|
||||||
|
addToPublishButton.disabled = selectedImages.length === 0;
|
||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
|
||||||
});
|
const container = document.createElement('div');
|
||||||
|
container.style = "display: flex; flex-direction: column; align-items: center; margin: 5px;";
|
||||||
|
container.append(img, removeButton);
|
||||||
|
previewContainer.append(container);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
addToPublishButton.addEventListener('click', async () => {
|
addToPublishButton.addEventListener('click', () => {
|
||||||
await addImagesToMultiPublish()
|
processSelectedImages(selectedImages, multiResource, room);
|
||||||
})
|
selectedImages = [];
|
||||||
|
addToPublishButton.disabled = true;
|
||||||
|
});
|
||||||
|
|
||||||
// Function to add images in the preview to the multi-publish object --------------------------
|
fileInput.addEventListener('change', (event) => {
|
||||||
const addImagesToMultiPublish = async () => {
|
selectedFiles = [...event.target.files];
|
||||||
console.log('Adding Images to multi-publish:', selectedImages);
|
});
|
||||||
for (let i = 0; i < selectedImages.length; i++) {
|
|
||||||
const file = selectedImages[i];
|
sendButton.addEventListener('click', async () => {
|
||||||
try {
|
const quill = new Quill('#editor');
|
||||||
multiResource.push({
|
const messageHtml = quill.root.innerHTML.trim();
|
||||||
name: userState.accountName,
|
|
||||||
service: "FILE",
|
if (messageHtml || selectedFiles.length > 0 || selectedImages.length > 0) {
|
||||||
identifier: attachmentID,
|
await handleSendMessage(room, messageHtml, selectedFiles, selectedImages, multiResource);
|
||||||
file: file,
|
}
|
||||||
});
|
});
|
||||||
|
};
|
||||||
attachmentIdentifiers.push({
|
|
||||||
name: userState.accountName,
|
// Process selected images
|
||||||
service: "FILE",
|
const processSelectedImages = async (selectedImages, multiResource, room) => {
|
||||||
identifier: attachmentID,
|
|
||||||
filename: file.name,
|
for (const file of selectedImages) {
|
||||||
mimeType: file.type
|
let attachmentID = generateAttachmentID(room, selectedImages.indexOf(file))
|
||||||
});
|
try {
|
||||||
|
multiResource.push({
|
||||||
console.log(`Attachment ${file.name} placed into multiResource with attachmentID: ${attachmentID}`);
|
name: userState.accountName,
|
||||||
|
service: "FILE",
|
||||||
// Remove the processed file
|
identifier: attachmentID,
|
||||||
selectedImages.splice(i, 1);
|
file
|
||||||
i--; // Adjust the index since we removed an item
|
});
|
||||||
|
attachmentIdentifiers.push({
|
||||||
} catch (error) {
|
name: userState.accountName,
|
||||||
console.error(`Error processing attachment ${file.name}:`, error);
|
service: "FILE",
|
||||||
}
|
identifier: attachmentID,
|
||||||
}
|
filename: file.name,
|
||||||
selectedImages = []
|
mimeType: file.type
|
||||||
addToPublishButton.disabled = true
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error processing image ${file.name}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle send message
|
||||||
|
const handleSendMessage = async (room, messageHtml, selectedFiles, selectedImages, multiResource) => {
|
||||||
|
const messageIdentifier = `${messageIdentifierPrefix}-${room}-${Date.now()}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (selectedImages.length > 0) {
|
||||||
|
await processSelectedImages(selectedImages, multiResource, room);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add event listener to handle file selection
|
for (const file of selectedFiles) {
|
||||||
document.getElementById('file-input').addEventListener('change', async (event) => {
|
let attachmentID = generateAttachmentID(room, selectedFiles.indexOf(file))
|
||||||
selectedFiles = Array.from(event.target.files);
|
multiResource.push({
|
||||||
|
name: userState.accountName,
|
||||||
|
service: "FILE",
|
||||||
|
identifier: attachmentID,
|
||||||
|
file
|
||||||
|
});
|
||||||
|
attachmentIdentifiers.push({
|
||||||
|
name: userState.accountName,
|
||||||
|
service: "FILE",
|
||||||
|
identifier: attachmentID,
|
||||||
|
filename: file.name,
|
||||||
|
mimeType: file.type
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageObject = {
|
||||||
|
messageHtml,
|
||||||
|
hasAttachment: multiResource.length > 0,
|
||||||
|
attachments: attachmentIdentifiers,
|
||||||
|
replyTo: replyToMessageIdentifier || null // Add replyTo
|
||||||
|
};
|
||||||
|
|
||||||
|
const base64Message = btoa(JSON.stringify(messageObject));
|
||||||
|
|
||||||
|
multiResource.push({
|
||||||
|
name: userState.accountName,
|
||||||
|
service: "BLOG_POST",
|
||||||
|
identifier: messageIdentifier,
|
||||||
|
data64: base64Message
|
||||||
});
|
});
|
||||||
// Add event listener for the PUBLISH button
|
|
||||||
document.getElementById("send-button").addEventListener("click", async () => {
|
|
||||||
const messageHtml = quill.root.innerHTML.trim();
|
|
||||||
if (messageHtml !== "" || selectedFiles.length > 0 || selectedImages.length > 0) {
|
|
||||||
const messageIdentifier = `${messageIdentifierPrefix}-${room}-${randomID}`;
|
|
||||||
|
|
||||||
if (selectedImages.length > 0) {
|
await publishMultipleResources(multiResource);
|
||||||
await addImagesToMultiPublish()
|
|
||||||
}
|
|
||||||
if (selectedFiles.length === 1) {
|
|
||||||
console.log(`single file has been detected, attaching single file...`)
|
|
||||||
const singleAttachment = selectedFiles[0]
|
|
||||||
|
|
||||||
multiResource.push({
|
|
||||||
name: userState.accountName,
|
|
||||||
service: "FILE",
|
|
||||||
identifier: attachmentID,
|
|
||||||
file: singleAttachment
|
|
||||||
})
|
|
||||||
|
|
||||||
attachmentIdentifiers.push({
|
clearInputs();
|
||||||
name: userState.accountName,
|
showSuccessNotification();
|
||||||
service: "FILE",
|
} catch (error) {
|
||||||
identifier: attachmentID,
|
console.error("Error sending message:", error);
|
||||||
filename: singleAttachment.name,
|
|
||||||
filetype: singleAttachement.type
|
|
||||||
})
|
|
||||||
// Clear selectedFiles as we do not need them anymore.
|
|
||||||
document.getElementById('file-input').value = "";
|
|
||||||
selectedFiles = [];
|
|
||||||
|
|
||||||
}else if (selectedFiles.length >= 2) {
|
|
||||||
console.log(`selected files found: ${selectedFiles.length}, adding multiple files to multi-publish resource...`)
|
|
||||||
// Handle Multiple attachements utilizing multi-publish
|
|
||||||
for (let i = 0; i < selectedFiles.length; i++) {
|
|
||||||
const file = selectedFiles[i];
|
|
||||||
try {
|
|
||||||
multiResource.push({
|
|
||||||
name: userState.accountName,
|
|
||||||
service: "FILE",
|
|
||||||
identifier: attachmentID,
|
|
||||||
file: file,
|
|
||||||
});
|
|
||||||
|
|
||||||
attachmentIdentifiers.push({
|
|
||||||
name: userState.accountName,
|
|
||||||
service: "FILE",
|
|
||||||
identifier: attachmentID,
|
|
||||||
filename: file.name,
|
|
||||||
mimeType: file.type
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`Attachment ${file.name} placed into multiResource with attachmentID: ${attachmentID}`);
|
|
||||||
|
|
||||||
// Remove the processed file
|
|
||||||
selectedFiles.splice(i, 1);
|
|
||||||
i--; // Adjust the index since we removed an item
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error processing attachment ${file.name}:`, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create message object with unique identifier, HTML content, and attachments
|
|
||||||
const messageObject = {
|
|
||||||
messageHtml: messageHtml,
|
|
||||||
hasAttachment: attachmentIdentifiers.length > 0,
|
|
||||||
attachments: attachmentIdentifiers,
|
|
||||||
replyTo: replyToMessageIdentifier
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Convert message object to base64
|
|
||||||
let base64Message = await objectToBase64(messageObject);
|
|
||||||
if (!base64Message) {
|
|
||||||
console.log(`initial object creation with object failed, using btoa...`);
|
|
||||||
base64Message = btoa(JSON.stringify(messageObject));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put the message into the multiResource for batch-publishing.
|
|
||||||
multiResource.push({
|
|
||||||
name: userState.accountName,
|
|
||||||
service: "BLOG_POST",
|
|
||||||
identifier: messageIdentifier,
|
|
||||||
data64: base64Message
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Message added to multi-publish resource successfully, attempting multi-publish... ");
|
|
||||||
|
|
||||||
await publishMultipleResources(multiResource)
|
|
||||||
|
|
||||||
// Clear the editor after sending the message, including any potential attached files and replies.
|
|
||||||
quill.root.innerHTML = "";
|
|
||||||
document.getElementById('file-input').value = "";
|
|
||||||
selectedFiles = [];
|
|
||||||
selectedImages = [];
|
|
||||||
multiResource = [];
|
|
||||||
replyToMessageIdentifier = null;
|
|
||||||
const replyContainer = document.querySelector(".reply-container");
|
|
||||||
if (replyContainer) {
|
|
||||||
replyContainer.remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show success notification
|
|
||||||
const notification = document.createElement('div');
|
|
||||||
notification.innerText = "Message published successfully! Message will take a confirmation to show, please be patient...";
|
|
||||||
notification.style.color = "green";
|
|
||||||
notification.style.marginTop = "1em";
|
|
||||||
document.querySelector(".message-input-section").appendChild(notification);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
notification.remove();
|
|
||||||
}, 10000);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error publishing message:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// Modify clearInputs to reset replyTo
|
||||||
|
const clearInputs = () => {
|
||||||
|
const quill = new Quill('#editor');
|
||||||
|
quill.root.innerHTML = "";
|
||||||
|
document.getElementById('file-input').value = "";
|
||||||
|
document.getElementById('image-input').value = "";
|
||||||
|
document.getElementById('preview-container').innerHTML = "";
|
||||||
|
replyToMessageIdentifier = null;
|
||||||
|
multiResource = [];
|
||||||
|
attachmentIdentifiers = [];
|
||||||
|
selectedImages = []
|
||||||
|
selectedFiles = []
|
||||||
|
|
||||||
|
const replyContainer = document.querySelector(".reply-container");
|
||||||
|
if (replyContainer) {
|
||||||
|
replyContainer.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Show success notification
|
||||||
|
const showSuccessNotification = () => {
|
||||||
|
const notification = document.createElement('div');
|
||||||
|
notification.innerText = "Message published successfully! Please wait for confirmation.";
|
||||||
|
notification.style.color = "green";
|
||||||
|
notification.style.marginTop = "1em";
|
||||||
|
document.querySelector(".message-input-section").appendChild(notification);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.remove();
|
||||||
|
}, 10000);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generate unique attachment ID
|
||||||
|
const generateAttachmentID = (room, fileIndex = null) => {
|
||||||
|
const baseID = `${messageAttachmentIdentifierPrefix}-${room}-${Date.now()}`;
|
||||||
|
return fileIndex !== null ? `${baseID}-${fileIndex}` : baseID;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const loadMessagesFromQDN = async (room, page, isPolling = false) => {
|
const loadMessagesFromQDN = async (room, page, isPolling = false) => {
|
||||||
try {
|
try {
|
||||||
@ -534,17 +505,17 @@ const loadMessagesFromQDN = async (room, page, isPolling = false) => {
|
|||||||
let attachmentHtml = "";
|
let attachmentHtml = "";
|
||||||
if (message.attachments && message.attachments.length > 0) {
|
if (message.attachments && message.attachments.length > 0) {
|
||||||
for (const attachment of message.attachments) {
|
for (const attachment of message.attachments) {
|
||||||
if (attachment.mimeType.startsWith('image/')) {
|
if (attachment.mimeType && attachment.mimeType.startsWith('image/')) {
|
||||||
try {
|
try {
|
||||||
// OTHER METHOD NOT BEING USED HERE. WE CAN LOAD THE IMAGE DIRECTLY SINCE IT WILL BE PUBLISHED UNENCRYPTED/UNENCODED.
|
// Construct the image URL
|
||||||
// const imageHtml = await loadImageHtml(attachment.service, attachment.name, attachment.identifier, attachment.filename, attachment.mimeType);
|
|
||||||
const imageUrl = `/arbitrary/${attachment.service}/${attachment.name}/${attachment.identifier}`;
|
const imageUrl = `/arbitrary/${attachment.service}/${attachment.name}/${attachment.identifier}`;
|
||||||
|
|
||||||
// Add the image HTML with the direct URL
|
// Add the image HTML with the direct URL
|
||||||
attachmentHtml += `<div class="attachment">
|
attachmentHtml += `<div class="attachment">
|
||||||
<img src="${imageUrl}" alt="${attachment.filename}" class="inline-image"/>
|
<img src="${imageUrl}" alt="${attachment.filename}" class="inline-image"/>
|
||||||
</div>`;
|
</div>`;
|
||||||
// Add the modal download button details as well, in order to pass correct information to the modal
|
|
||||||
|
// Set up the modal download button
|
||||||
const downloadButton = document.getElementById("download-button");
|
const downloadButton = document.getElementById("download-button");
|
||||||
downloadButton.onclick = () => {
|
downloadButton.onclick = () => {
|
||||||
fetchAndSaveAttachment(
|
fetchAndSaveAttachment(
|
||||||
@ -555,19 +526,18 @@ const loadMessagesFromQDN = async (room, page, isPolling = false) => {
|
|||||||
attachment.mimeType
|
attachment.mimeType
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
// FOR OTHER METHOD NO LONGER USED
|
|
||||||
// attachmentHtml += imageHtml;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to fetch attachment ${attachment.filename}:`, error);
|
console.error(`Failed to fetch attachment ${attachment.filename}:`, error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Display a button to download other attachments
|
// Display a button to download non-image attachments
|
||||||
attachmentHtml += `<div class="attachment">
|
attachmentHtml += `<div class="attachment">
|
||||||
<button onclick="fetchAndSaveAttachment('${attachment.service}', '${attachment.name}', '${attachment.identifier}', '${attachment.filename}', '${attachment.mimeType}')">Download ${attachment.filename}</button>
|
<button onclick="fetchAndSaveAttachment('${attachment.service}', '${attachment.name}', '${attachment.identifier}', '${attachment.filename}', '${attachment.mimeType}')">Download ${attachment.filename}</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const avatarUrl = `/arbitrary/THUMBNAIL/${message.name}/qortal_avatar`;
|
const avatarUrl = `/arbitrary/THUMBNAIL/${message.name}/qortal_avatar`;
|
||||||
const messageHTML = `
|
const messageHTML = `
|
||||||
|
Loading…
Reference in New Issue
Block a user