2024-12-11 22:40:32 +00:00
const messageIdentifierPrefix = ` mintership-forum-message ` ;
const messageAttachmentIdentifierPrefix = ` mintership-forum-attachment ` ;
// NOTE - SET adminGroups in QortalApi.js to enable admin access to forum for specific groups. Minter Admins will be fetched automatically.
let replyToMessageIdentifier = null ;
let latestMessageIdentifiers = { } ; // To keep track of the latest message in each room
let currentPage = 0 ; // Track current pagination page
let existingIdentifiers = new Set ( ) ; // Keep track of existing identifiers to not pull them more than once.
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
let messagesById = { }
let messageOrder = [ ]
const MAX _MESSAGES = 2000
// Key = message.identifier
// Value = { ...the message object with timestamp, name, content, etc. }
2024-12-11 22:40:32 +00:00
// If there is a previous latest message identifiers, use them. Otherwise, use an empty.
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
const storeMessageInMap = ( msg ) => {
if ( ! msg ? . identifier || ! msg || ! msg ? . timestamp ) return
messagesById [ msg . identifier ] = msg
// We will keep an array 'messageOrder' to store the messages and limit the size they take
messageOrder . push ( { identifier : msg . identifier , timestamp : msg . timestamp } )
messageOrder . sort ( ( a , b ) => a . timestamp - b . timestamp ) ;
while ( messageOrder . length > MAX _MESSAGES ) {
// Remove oldest from the front
const oldest = messageOrder . shift ( ) ;
// Delete from the map as well
delete messagesById [ oldest . identifier ] ;
}
}
function saveMessagesToLocalStorage ( ) {
try {
const data = { messagesById , messageOrder } ;
localStorage . setItem ( "forumMessages" , JSON . stringify ( data ) ) ;
console . log ( "Saved messages to localStorage. Count:" , messageOrder . length ) ;
} catch ( error ) {
console . error ( "Error saving to localStorage:" , error ) ;
}
}
function loadMessagesFromLocalStorage ( ) {
try {
const stored = localStorage . getItem ( "forumMessages" ) ;
if ( ! stored ) {
console . log ( "No saved messages in localStorage." ) ;
return ;
}
const parsed = JSON . parse ( stored ) ;
if ( parsed . messagesById && parsed . messageOrder ) {
messagesById = parsed . messagesById ;
messageOrder = parsed . messageOrder ;
console . log ( ` Loaded ${ messageOrder . length } messages from localStorage. ` ) ;
}
} catch ( error ) {
console . error ( "Error loading messages from localStorage:" , error ) ;
}
}
2024-12-11 22:40:32 +00:00
if ( localStorage . getItem ( "latestMessageIdentifiers" ) ) {
latestMessageIdentifiers = JSON . parse ( localStorage . getItem ( "latestMessageIdentifiers" ) ) ;
}
document . addEventListener ( "DOMContentLoaded" , async ( ) => {
2024-12-18 06:24:40 +00:00
console . log ( "DOMContentLoaded fired!" ) ;
2024-12-11 22:40:32 +00:00
2024-12-18 06:24:40 +00:00
// --- GENERAL LINKS (MINTERSHIP-FORUM and MINTER-BOARD) ---
const mintershipForumLinks = document . querySelectorAll ( 'a[href="MINTERSHIP-FORUM"]' ) ;
2024-12-11 22:40:32 +00:00
mintershipForumLinks . forEach ( link => {
link . addEventListener ( 'click' , async ( event ) => {
event . preventDefault ( ) ;
if ( ! userState . isLoggedIn ) {
await login ( ) ;
}
await loadForumPage ( ) ;
2024-12-18 06:24:40 +00:00
loadRoomContent ( "general" ) ;
startPollingForNewMessages ( ) ;
} ) ;
} ) ;
const minterBoardLinks = document . querySelectorAll ( 'a[href="MINTER-BOARD"], a[href="MINTERS"]' ) ;
minterBoardLinks . forEach ( link => {
link . addEventListener ( "click" , async ( event ) => {
event . preventDefault ( ) ;
if ( ! userState . isLoggedIn ) {
await login ( ) ;
}
if ( typeof loadMinterBoardPage === "undefined" ) {
console . log ( "loadMinterBoardPage not found, loading script dynamically..." ) ;
await loadScript ( "./assets/js/MinterBoard.js" ) ;
}
await loadMinterBoardPage ( ) ;
2024-12-11 22:40:32 +00:00
} ) ;
} ) ;
2024-12-18 06:24:40 +00:00
// --- ADMIN CHECK ---
await verifyUserIsAdmin ( ) ;
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
if ( userState . isAdmin && ( localStorage . getItem ( 'savedAdminData' ) ) ) {
console . log ( 'saved admin data found (Q-Mintership.js), loading...' )
const adminData = localStorage . getItem ( 'savedAdminData' )
const parsedAdminData = JSON . parse ( adminData )
if ( ! adminPublicKeys || adminPublicKeys . length === 0 || ! Array . isArray ( adminPublicKeys ) ) {
console . log ( 'no adminPublicKey variable data found and/or data did not pass checks, using fetched localStorage data...' , adminPublicKeys )
if ( parsedAdminData . publicKeys . length === 0 || ! parsedAdminData . publicKeys || ! Array . isArray ( parsedAdminData . publicKeys ) ) {
console . log ( 'loaded data from localStorage also did not pass checks... fetching from API...' , parsedAdminData . publicKeys )
adminPublicKeys = await fetchAdminGroupsMembersPublicKeys ( )
} else {
adminPublicKeys = parsedAdminData . publicKeys
}
}
}
2024-12-18 06:24:40 +00:00
if ( userState . isAdmin ) {
console . log ( ` User is an Admin. Admin-specific buttons will remain visible. ` ) ;
// DATA-BOARD Links for Admins
const minterDataBoardLinks = document . querySelectorAll ( 'a[href="ADMINBOARD"]' ) ;
minterDataBoardLinks . forEach ( link => {
link . addEventListener ( "click" , async ( event ) => {
event . preventDefault ( ) ;
if ( ! userState . isLoggedIn ) {
await login ( ) ;
}
if ( typeof loadAdminBoardPage === "undefined" ) {
console . log ( "loadAdminBoardPage function not found, loading script dynamically..." ) ;
await loadScript ( "./assets/js/AdminBoard.js" ) ;
}
await loadAdminBoardPage ( ) ;
} ) ;
} ) ;
// TOOLS Links for Admins
const toolsLinks = document . querySelectorAll ( 'a[href="TOOLS"]' ) ;
toolsLinks . forEach ( link => {
link . addEventListener ( 'click' , async ( event ) => {
event . preventDefault ( ) ;
if ( ! userState . isLoggedIn ) {
await login ( ) ;
}
if ( typeof loadMinterAdminToolsPage === "undefined" ) {
console . log ( "loadMinterAdminToolsPage function not found, loading script dynamically..." ) ;
await loadScript ( "./assets/js/AdminTools.js" ) ;
}
await loadMinterAdminToolsPage ( ) ;
} ) ;
} ) ;
} else {
console . log ( "User is NOT an Admin. Removing admin-specific links." ) ;
// Remove all admin-specific links and their parents
2024-12-19 01:33:09 +00:00
const toolsLinks = document . querySelectorAll ( 'a[href="TOOLS"], a[href="ADMINBOARD"]' ) ;
2024-12-18 06:24:40 +00:00
toolsLinks . forEach ( link => {
const buttonParent = link . closest ( 'button' ) ;
if ( buttonParent ) buttonParent . remove ( ) ;
const cardParent = link . closest ( '.item.features-image' ) ;
if ( cardParent ) cardParent . remove ( ) ;
link . remove ( ) ;
} ) ;
// Center the remaining card if it exists
const remainingCard = document . querySelector ( '.features7 .row .item.features-image' ) ;
if ( remainingCard ) {
remainingCard . classList . remove ( 'col-lg-6' , 'col-md-6' ) ;
remainingCard . classList . add ( 'col-12' , 'text-center' ) ;
}
}
console . log ( "All DOMContentLoaded tasks completed." ) ;
2024-12-11 22:40:32 +00:00
} ) ;
2024-12-18 06:24:40 +00:00
async function loadScript ( src ) {
return new Promise ( ( resolve , reject ) => {
const script = document . createElement ( "script" ) ;
script . src = src ;
script . onload = resolve ;
script . onerror = reject ;
document . head . appendChild ( script ) ;
} ) ;
}
2024-12-13 01:23:34 +00:00
// Main load function to clear existing HTML and load the forum page -----------------------------------------------------
const loadForumPage = async ( ) => {
// remove everything that isn't the menu from the body to use js to generate page content.
2024-12-11 22:40:32 +00:00
const bodyChildren = document . body . children ;
for ( let i = bodyChildren . length - 1 ; i >= 0 ; i -- ) {
const child = bodyChildren [ i ] ;
if ( ! child . classList . contains ( 'menu' ) ) {
child . remove ( ) ;
}
}
2024-12-24 08:27:17 +00:00
if ( ( typeof userState . isAdmin === 'undefined' ) || ( ! userState . isAdmin ) ) {
2024-12-15 03:40:31 +00:00
try {
// Fetch and verify the admin status asynchronously
userState . isAdmin = await verifyUserIsAdmin ( ) ;
} catch ( error ) {
console . error ( 'Error verifying admin status:' , error ) ;
userState . isAdmin = false ; // Default to non-admin if there's an issue
}
}
2024-12-11 22:40:32 +00:00
const avatarUrl = ` /arbitrary/THUMBNAIL/ ${ userState . accountName } /qortal_avatar ` ;
2024-12-15 03:40:31 +00:00
const isAdmin = userState . isAdmin ;
2024-12-11 22:40:32 +00:00
2024-12-15 03:40:31 +00:00
// Create the forum layout, including a header, sub-menu, and keeping the original background image: style="background-image: url('/assets/images/background.jpg');">
2024-12-11 22:40:32 +00:00
const mainContent = document . createElement ( 'div' ) ;
mainContent . innerHTML = `
< div class = "forum-main mbr-parallax-background cid-ttRnlSkg2R" >
< div class = "forum-header" style = "color: lightblue; display: flex; justify-content: center; align-items: center; padding: 10px;" >
2024-12-15 03:40:31 +00:00
< div class = "user-info" style = "border: 1px solid lightblue; padding: 5px; color: white; display: flex; align-items: center; justify-content: center;" >
2024-12-11 22:40:32 +00:00
< img src = "${avatarUrl}" alt = "User Avatar" class = "user-avatar" style = "width: 50px; height: 50px; border-radius: 50%; margin-right: 10px;" >
< span > $ { userState . accountName || 'Guest' } < / s p a n >
< / d i v >
< / d i v >
< div class = "forum-submenu" >
< div class = "forum-rooms" >
< button class = "room-button" id = "minters-room" > Minters Room < / b u t t o n >
2024-12-15 03:40:31 +00:00
$ { isAdmin ? '<button class="room-button" id="admins-room">Admins Room</button>' : '' }
2024-12-11 22:40:32 +00:00
< button class = "room-button" id = "general-room" > General Room < / b u t t o n >
< / d i v >
< / d i v >
< div id = "forum-content" class = "forum-content" > < / d i v >
< / d i v >
` ;
document . body . appendChild ( mainContent ) ;
// Add event listeners to room buttons
document . getElementById ( "minters-room" ) . addEventListener ( "click" , ( ) => {
currentPage = 0 ;
loadRoomContent ( "minters" ) ;
} ) ;
if ( userState . isAdmin ) {
document . getElementById ( "admins-room" ) . addEventListener ( "click" , ( ) => {
currentPage = 0 ;
loadRoomContent ( "admins" ) ;
} ) ;
}
document . getElementById ( "general-room" ) . addEventListener ( "click" , ( ) => {
currentPage = 0 ;
loadRoomContent ( "general" ) ;
} ) ;
}
2024-12-13 01:23:34 +00:00
// Function to add the pagination buttons and related control mechanisms ------------------------
2024-12-15 03:40:31 +00:00
const renderPaginationControls = ( room , totalMessages , limit ) => {
2024-12-11 22:40:32 +00:00
const paginationContainer = document . getElementById ( "pagination-container" ) ;
if ( ! paginationContainer ) return ;
paginationContainer . innerHTML = "" ; // Clear existing buttons
const totalPages = Math . ceil ( totalMessages / limit ) ;
// Add "Previous" button
if ( currentPage > 0 ) {
const prevButton = document . createElement ( "button" ) ;
prevButton . innerText = "Previous" ;
prevButton . addEventListener ( "click" , ( ) => {
if ( currentPage > 0 ) {
currentPage -- ;
loadMessagesFromQDN ( room , currentPage , false ) ;
}
} ) ;
paginationContainer . appendChild ( prevButton ) ;
}
// Add numbered page buttons
for ( let i = 0 ; i < totalPages ; i ++ ) {
const pageButton = document . createElement ( "button" ) ;
pageButton . innerText = i + 1 ;
pageButton . className = i === currentPage ? "active-page" : "" ;
pageButton . addEventListener ( "click" , ( ) => {
if ( i !== currentPage ) {
currentPage = i ;
loadMessagesFromQDN ( room , currentPage , false ) ;
}
} ) ;
paginationContainer . appendChild ( pageButton ) ;
}
// Add "Next" button
if ( currentPage < totalPages - 1 ) {
const nextButton = document . createElement ( "button" ) ;
nextButton . innerText = "Next" ;
nextButton . addEventListener ( "click" , ( ) => {
if ( currentPage < totalPages - 1 ) {
currentPage ++ ;
loadMessagesFromQDN ( room , currentPage , false ) ;
}
} ) ;
paginationContainer . appendChild ( nextButton ) ;
}
}
2024-12-13 01:23:34 +00:00
// Main function to load the full content of the room, along with all main functionality -----------------------------------
const loadRoomContent = async ( room ) => {
2024-12-11 22:40:32 +00:00
const forumContent = document . getElementById ( "forum-content" ) ;
2024-12-13 05:49:14 +00:00
if ( ! forumContent ) {
console . error ( "Forum content container not found!" ) ;
return ;
}
2024-12-24 08:27:17 +00:00
if ( userState . isAdmin ) {
await loadOrFetchAdminGroupsData ( )
}
2024-12-13 05:49:14 +00:00
// Set initial content
forumContent . innerHTML = `
< div class = "room-content" >
< h3 class = "room-title" style = "color: lightblue;" > $ { room . charAt ( 0 ) . toUpperCase ( ) + room . slice ( 1 ) } Room < / h 3 >
< div id = "messages-container" class = "messages-container" > < / d i v >
< div id = "pagination-container" class = "pagination-container" style = "margin-top: 20px; text-align: center;" > < / d i v >
< div class = "message-input-section" >
< div id = "toolbar" class = "message-toolbar" > < / d i v >
< div id = "editor" class = "message-input" > < / d i v >
< div class = "attachment-section" >
< input type = "file" id = "file-input" class = "file-input" multiple >
< label for = "file-input" class = "custom-file-input-button" > Select Files < / l a b e l >
< 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 < / l a b e l >
2024-12-24 08:27:17 +00:00
< button id = "add-images-to-publish-button" style = "display: none" disabled > Add Images to Multi - Publish < / b u t t o n >
2024-12-13 05:49:14 +00:00
< div id = "preview-container" style = "display: flex; flex-wrap: wrap; gap: 10px;" > < / d i v >
2024-12-11 22:40:32 +00:00
< / d i v >
2024-12-13 05:49:14 +00:00
< button id = "send-button" class = "send-button" > Publish < / b u t t o n >
2024-12-11 22:40:32 +00:00
< / d i v >
2024-12-13 05:49:14 +00:00
< / d i v >
` ;
2024-12-11 22:40:32 +00:00
2024-12-13 05:49:14 +00:00
// Add modal for image preview
forumContent . insertAdjacentHTML (
'beforeend' ,
`
< div id = "image-modal" class = "image-modal" >
< span id = "close-modal" class = "close" > & times ; < / s p a n >
< img id = "modal-image" class = "modal-content" >
< div id = "caption" class = "caption" > < / d i v >
< button id = "download-button" class = "download-button" > Download < / b u t t o n >
< / d i v >
` );
initializeQuillEditor ( ) ;
setupModalHandlers ( ) ;
setupFileInputs ( room ) ;
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
//TODO - maybe turn this into its own function and put it as a button? But for now it's fine to just load the latest message's position by default I think.
const latestId = latestMessageIdentifiers [ room ] ? . latestIdentifier ;
if ( latestId ) {
const page = await findMessagePage ( room , latestId , 10 )
currentPage = page ;
await loadMessagesFromQDN ( room , currentPage )
scrollToMessage ( latestId . latestIdentifier )
} else {
await loadMessagesFromQDN ( room , currentPage )
}
;
2024-12-13 05:49:14 +00:00
} ;
// Initialize Quill editor
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' ]
]
}
} ) ;
} ;
// Set up modal behavior
const setupModalHandlers = ( ) => {
document . addEventListener ( "click" , ( event ) => {
if ( event . target . classList . contains ( "inline-image" ) ) {
2024-12-11 22:40:32 +00:00
const modal = document . getElementById ( "image-modal" ) ;
2024-12-13 05:49:14 +00:00
const modalImage = document . getElementById ( "modal-image" ) ;
const caption = document . getElementById ( "caption" ) ;
modalImage . src = event . target . src ;
caption . textContent = event . target . alt ;
modal . style . display = "block" ;
}
} ) ;
document . getElementById ( "close-modal" ) . addEventListener ( "click" , ( ) => {
document . getElementById ( "image-modal" ) . style . display = "none" ;
} ) ;
window . addEventListener ( "click" , ( event ) => {
const modal = document . getElementById ( "image-modal" ) ;
if ( event . target === modal ) {
modal . style . display = "none" ;
}
} ) ;
} ;
let selectedImages = [ ] ;
let selectedFiles = [ ] ;
let multiResource = [ ] ;
let attachmentIdentifiers = [ ] ;
// Set up file input handling
const setupFileInputs = ( room ) => {
const imageFileInput = document . getElementById ( 'image-input' ) ;
const previewContainer = document . getElementById ( 'preview-container' ) ;
const addToPublishButton = document . getElementById ( 'add-images-to-publish-button' ) ;
const fileInput = document . getElementById ( 'file-input' ) ;
const sendButton = document . getElementById ( 'send-button' ) ;
const attachmentID = generateAttachmentID ( room ) ;
imageFileInput . addEventListener ( 'change' , ( event ) => {
previewContainer . innerHTML = '' ;
selectedImages = [ ... event . target . files ] ;
addToPublishButton . disabled = selectedImages . length === 0 ;
selectedImages . forEach ( ( file , index ) => {
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 ;
} ;
2024-12-31 05:39:18 +00:00
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 )
} )
} )
2024-12-11 22:40:32 +00:00
2024-12-13 05:49:14 +00:00
addToPublishButton . addEventListener ( 'click' , ( ) => {
2024-12-31 05:39:18 +00:00
processSelectedImages ( selectedImages , multiResource , room )
selectedImages = [ ]
imageFileInput . value = ""
addToPublishButton . disabled = true
} )
2024-12-13 01:23:34 +00:00
2024-12-13 05:49:14 +00:00
fileInput . addEventListener ( 'change' , ( event ) => {
2024-12-31 05:39:18 +00:00
selectedFiles = [ ... event . target . files ]
} )
2024-12-13 01:23:34 +00:00
2024-12-13 05:49:14 +00:00
sendButton . addEventListener ( 'click' , async ( ) => {
2024-12-31 05:39:18 +00:00
const quill = new Quill ( '#editor' )
const messageHtml = quill . root . innerHTML . trim ( )
2024-12-13 01:23:34 +00:00
2024-12-13 05:49:14 +00:00
if ( messageHtml || selectedFiles . length > 0 || selectedImages . length > 0 ) {
2024-12-31 05:39:18 +00:00
await handleSendMessage ( room , messageHtml , selectedFiles , selectedImages , multiResource )
2024-12-13 05:49:14 +00:00
}
2024-12-31 05:39:18 +00:00
} )
}
2024-12-13 01:23:34 +00:00
2024-12-13 05:49:14 +00:00
// Process selected images
const processSelectedImages = async ( selectedImages , multiResource , room ) => {
for ( const file of selectedImages ) {
2024-12-31 05:39:18 +00:00
const attachmentID = generateAttachmentID ( room , selectedImages . indexOf ( file ) )
2024-12-15 03:40:31 +00:00
multiResource . push ( {
name : userState . accountName ,
service : room === "admins" ? "FILE_PRIVATE" : "FILE" ,
identifier : attachmentID ,
file : file , // Use encrypted file for admins
2024-12-31 05:39:18 +00:00
} )
2024-12-15 03:40:31 +00:00
attachmentIdentifiers . push ( {
name : userState . accountName ,
service : room === "admins" ? "FILE_PRIVATE" : "FILE" ,
identifier : attachmentID ,
filename : file . name ,
mimeType : file . type ,
2024-12-31 05:39:18 +00:00
} )
2024-12-13 05:49:14 +00:00
}
2024-12-31 05:39:18 +00:00
}
2024-12-13 01:23:34 +00:00
2024-12-13 05:49:14 +00:00
// Handle send message
const handleSendMessage = async ( room , messageHtml , selectedFiles , selectedImages , multiResource ) => {
2024-12-15 03:40:31 +00:00
const messageIdentifier = room === "admins"
2024-12-24 08:27:17 +00:00
? ` ${ messageIdentifierPrefix } - ${ room } -e- ${ randomID ( ) } `
2024-12-31 05:39:18 +00:00
: ` ${ messageIdentifierPrefix } - ${ room } - ${ randomID ( ) } `
2024-12-13 05:49:14 +00:00
try {
2024-12-15 03:40:31 +00:00
// Process selected images
2024-12-13 05:49:14 +00:00
if ( selectedImages . length > 0 ) {
2024-12-31 05:39:18 +00:00
await processSelectedImages ( selectedImages , multiResource , room )
2024-12-13 01:23:34 +00:00
}
2024-12-15 03:40:31 +00:00
// Process selected files
if ( selectedFiles && selectedFiles . length > 0 ) {
for ( const file of selectedFiles ) {
2024-12-31 05:39:18 +00:00
const attachmentID = generateAttachmentID ( room , selectedFiles . indexOf ( file ) )
2024-12-15 03:40:31 +00:00
multiResource . push ( {
name : userState . accountName ,
service : room === "admins" ? "FILE_PRIVATE" : "FILE" ,
identifier : attachmentID ,
file : file , // Use encrypted file for admins
2024-12-31 05:39:18 +00:00
} )
2024-12-15 03:40:31 +00:00
attachmentIdentifiers . push ( {
name : userState . accountName ,
service : room === "admins" ? "FILE_PRIVATE" : "FILE" ,
identifier : attachmentID ,
filename : file . name ,
mimeType : file . type ,
2024-12-31 05:39:18 +00:00
} )
2024-12-15 03:40:31 +00:00
}
2024-12-13 05:49:14 +00:00
}
2024-12-11 22:40:32 +00:00
2024-12-15 03:40:31 +00:00
// Build the message object
2024-12-13 05:49:14 +00:00
const messageObject = {
messageHtml ,
hasAttachment : multiResource . length > 0 ,
attachments : attachmentIdentifiers ,
2024-12-15 03:40:31 +00:00
replyTo : replyToMessageIdentifier || null , // Include replyTo if applicable
2024-12-31 05:39:18 +00:00
}
2024-12-11 22:40:32 +00:00
2024-12-15 03:40:31 +00:00
// Encode the message object
2024-12-31 05:39:18 +00:00
let base64Message = await objectToBase64 ( messageObject )
2024-12-15 03:40:31 +00:00
if ( ! base64Message ) {
2024-12-31 05:39:18 +00:00
base64Message = btoa ( JSON . stringify ( messageObject ) )
2024-12-15 03:40:31 +00:00
}
2024-12-11 22:40:32 +00:00
2024-12-15 03:40:31 +00:00
if ( room === "admins" && userState . isAdmin ) {
2024-12-31 05:39:18 +00:00
console . log ( "Encrypting message for admins..." )
2024-12-15 03:40:31 +00:00
multiResource . push ( {
name : userState . accountName ,
service : "MAIL_PRIVATE" ,
identifier : messageIdentifier ,
data64 : base64Message ,
2024-12-24 08:27:17 +00:00
} )
2024-12-15 03:40:31 +00:00
} else {
multiResource . push ( {
name : userState . accountName ,
service : "BLOG_POST" ,
identifier : messageIdentifier ,
data64 : base64Message ,
2024-12-24 08:27:17 +00:00
} )
2024-12-15 03:40:31 +00:00
}
2024-12-13 05:49:14 +00:00
2024-12-15 03:40:31 +00:00
// Publish resources
if ( room === "admins" ) {
2024-12-24 08:27:17 +00:00
if ( ! userState . isAdmin ) {
2024-12-31 05:39:18 +00:00
console . error ( "User is not an admin or no admin public keys found. Aborting publish." )
window . alert ( "You are not authorized to post in the Admin room." )
return
2024-12-15 03:40:31 +00:00
}
2024-12-31 05:39:18 +00:00
console . log ( "Publishing encrypted resources for Admin room..." )
await publishMultipleResources ( multiResource , adminPublicKeys , true )
2024-12-15 03:40:31 +00:00
} else {
2024-12-31 05:39:18 +00:00
console . log ( "Publishing resources for non-admin room..." )
await publishMultipleResources ( multiResource )
2024-12-15 03:40:31 +00:00
}
2024-12-13 05:49:14 +00:00
2024-12-15 03:40:31 +00:00
// Clear inputs and show success notification
2024-12-31 05:39:18 +00:00
clearInputs ( )
showSuccessNotification ( )
2024-12-13 05:49:14 +00:00
} catch ( error ) {
2024-12-31 05:39:18 +00:00
console . error ( "Error sending message:" , error )
2024-12-11 22:40:32 +00:00
}
2024-12-31 05:39:18 +00:00
}
2024-12-15 03:40:31 +00:00
2024-12-31 05:39:18 +00:00
function clearInputs ( ) {
2024-12-13 05:49:14 +00:00
const quill = new Quill ( '#editor' ) ;
2024-12-31 05:39:18 +00:00
// Properly reset Quill editor to ensure formatting options don't linger across messages
quill . setContents ( [ ] ) ;
quill . setSelection ( 0 , 0 ) ;
// clear the local file input arrays
2024-12-13 05:49:14 +00:00
document . getElementById ( 'file-input' ) . value = "" ;
document . getElementById ( 'image-input' ) . value = "" ;
document . getElementById ( 'preview-container' ) . innerHTML = "" ;
2024-12-31 05:39:18 +00:00
2024-12-13 05:49:14 +00:00
replyToMessageIdentifier = null ;
multiResource = [ ] ;
attachmentIdentifiers = [ ] ;
2024-12-31 05:39:18 +00:00
selectedImages = [ ] ;
selectedFiles = [ ] ;
2024-12-13 05:49:14 +00:00
2024-12-31 05:39:18 +00:00
// Remove the reply containers
2024-12-13 05:49:14 +00:00
const replyContainer = document . querySelector ( ".reply-container" ) ;
if ( replyContainer ) {
replyContainer . remove ( ) ;
}
2024-12-31 05:39:18 +00:00
}
2024-12-13 05:49:14 +00:00
// Show success notification
const showSuccessNotification = ( ) => {
2024-12-31 05:39:18 +00:00
const notification = document . createElement ( 'div' )
notification . innerText = "Message published successfully! Please wait for confirmation."
notification . style . color = "green"
notification . style . marginTop = "1em"
2024-12-13 05:49:14 +00:00
document . querySelector ( ".message-input-section" ) . appendChild ( notification ) ;
2024-12-18 06:24:40 +00:00
alert ( ` Successfully Published! Please note that messages will not display until after they are CONFIRMED, be patient! ` )
2024-12-13 05:49:14 +00:00
setTimeout ( ( ) => {
2024-12-31 05:39:18 +00:00
notification . remove ( )
} , 10000 )
}
2024-12-13 05:49:14 +00:00
// Generate unique attachment ID
const generateAttachmentID = ( room , fileIndex = null ) => {
2024-12-31 05:39:18 +00:00
const baseID = room === "admins" ? ` ${ messageAttachmentIdentifierPrefix } - ${ room } -e- ${ randomID ( ) } ` : ` ${ messageAttachmentIdentifierPrefix } - ${ room } - ${ randomID ( ) } `
return fileIndex !== null ? ` ${ baseID } - ${ fileIndex } ` : baseID
}
2024-12-20 05:28:36 +00:00
// --- REFACTORED LOAD MESSAGES AND HELPER FUNCTIONS ---
2024-12-11 22:40:32 +00:00
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
const findMessagePage = async ( room , identifier , limit ) => {
const { service , query } = getServiceAndQuery ( room )
2024-12-28 07:04:16 +00:00
//TODO check that searchSimple change worked.
const allMessages = await searchSimple ( service , query , '' , 0 , 0 , room , 'false' )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
2024-12-31 05:39:18 +00:00
const idx = allMessages . findIndex ( msg => msg . identifier === identifier )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
if ( idx === - 1 ) {
// Not found, default to last page or page=0
2024-12-31 05:39:18 +00:00
return 0
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
}
return Math . floor ( idx / limit )
}
2024-12-13 01:23:34 +00:00
const loadMessagesFromQDN = async ( room , page , isPolling = false ) => {
2024-12-11 22:40:32 +00:00
try {
2024-12-31 05:39:18 +00:00
const limit = 10
const offset = page * limit
console . log ( ` Loading messages from QDN: room= ${ room } , page= ${ page } , offset= ${ offset } , limit= ${ limit } ` )
2024-12-11 22:40:32 +00:00
2024-12-31 05:39:18 +00:00
const messagesContainer = document . querySelector ( "#messages-container" )
if ( ! messagesContainer ) return
2024-12-11 22:40:32 +00:00
2024-12-31 05:39:18 +00:00
prepareMessageContainer ( messagesContainer , isPolling )
2024-12-11 22:40:32 +00:00
2024-12-31 05:39:18 +00:00
const { service , query } = getServiceAndQuery ( room )
const response = await fetchResourceList ( service , query , limit , offset , room )
2024-12-11 22:40:32 +00:00
2024-12-31 05:39:18 +00:00
console . log ( ` Fetched ${ response . length } message(s) for page ${ page } . ` )
2024-12-11 22:40:32 +00:00
2024-12-20 05:28:36 +00:00
if ( handleNoMessagesScenario ( isPolling , page , response , messagesContainer ) ) {
2024-12-31 05:39:18 +00:00
return
2024-12-11 22:40:32 +00:00
}
2024-12-20 05:28:36 +00:00
// Re-establish existing identifiers after preparing container
existingIdentifiers = new Set (
Array . from ( messagesContainer . querySelectorAll ( '.message-item' ) )
. map ( item => item . dataset . identifier )
2024-12-31 05:39:18 +00:00
)
2024-12-11 22:40:32 +00:00
2024-12-31 05:39:18 +00:00
let mostRecentMessage = getCurrentMostRecentMessage ( room )
2024-12-11 22:40:32 +00:00
2024-12-31 05:39:18 +00:00
const fetchMessages = await fetchAllMessages ( response , service , room )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
for ( const msg of fetchMessages ) {
2024-12-31 05:39:18 +00:00
if ( ! msg ) continue
storeMessageInMap ( msg )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
}
2024-12-24 08:27:17 +00:00
const { firstNewMessageIdentifier , updatedMostRecentMessage } = await renderNewMessages (
2024-12-20 05:28:36 +00:00
fetchMessages ,
existingIdentifiers ,
messagesContainer ,
room ,
mostRecentMessage
2024-12-31 05:39:18 +00:00
)
2024-12-11 22:40:32 +00:00
2024-12-20 05:28:36 +00:00
if ( firstNewMessageIdentifier && ! isPolling ) {
2024-12-31 05:39:18 +00:00
scrollToNewMessages ( firstNewMessageIdentifier )
2024-12-11 22:40:32 +00:00
}
2024-12-20 05:28:36 +00:00
if ( updatedMostRecentMessage ) {
2024-12-31 05:39:18 +00:00
updateLatestMessageIdentifiers ( room , updatedMostRecentMessage )
2024-12-20 05:28:36 +00:00
}
2024-12-31 05:39:18 +00:00
handleReplyLogic ( fetchMessages )
2024-12-20 05:28:36 +00:00
2024-12-31 05:39:18 +00:00
await updatePaginationControls ( room , limit )
2024-12-20 05:28:36 +00:00
} catch ( error ) {
2024-12-31 05:39:18 +00:00
console . error ( 'Error loading messages from QDN:' , error )
2024-12-20 05:28:36 +00:00
}
2024-12-31 05:39:18 +00:00
}
2024-12-20 05:28:36 +00:00
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
function scrollToMessage ( identifier ) {
2024-12-31 05:39:18 +00:00
const targetElement = document . querySelector ( ` .message-item[data-identifier=" ${ identifier } "] ` )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
if ( targetElement ) {
2024-12-31 05:39:18 +00:00
targetElement . scrollIntoView ( { behavior : 'smooth' , block : 'center' } )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
}
}
2024-12-20 05:28:36 +00:00
/** Helper Functions (Arrow Functions) **/
const prepareMessageContainer = ( messagesContainer , isPolling ) => {
if ( ! isPolling ) {
2024-12-31 05:39:18 +00:00
messagesContainer . innerHTML = ""
existingIdentifiers . clear ( )
2024-12-20 05:28:36 +00:00
}
2024-12-31 05:39:18 +00:00
}
2024-12-20 05:28:36 +00:00
const getServiceAndQuery = ( room ) => {
2024-12-31 05:39:18 +00:00
const service = ( room === "admins" ) ? "MAIL_PRIVATE" : "BLOG_POST"
2024-12-20 05:28:36 +00:00
const query = ( room === "admins" )
? ` ${ messageIdentifierPrefix } - ${ room } -e `
2024-12-31 05:39:18 +00:00
: ` ${ messageIdentifierPrefix } - ${ room } `
return { service , query }
}
2024-12-20 05:28:36 +00:00
const fetchResourceList = async ( service , query , limit , offset , room ) => {
2024-12-28 07:04:16 +00:00
//TODO check
2024-12-31 05:39:18 +00:00
return await searchSimple ( service , query , '' , limit , offset , room , 'false' )
}
2024-12-20 05:28:36 +00:00
const handleNoMessagesScenario = ( isPolling , page , response , messagesContainer ) => {
if ( response . length === 0 ) {
if ( page === 0 && ! isPolling ) {
2024-12-31 05:39:18 +00:00
messagesContainer . innerHTML = ` <p>No messages found. Be the first to post!</p> `
2024-12-15 03:40:31 +00:00
}
2024-12-31 05:39:18 +00:00
return true
2024-12-20 05:28:36 +00:00
}
2024-12-31 05:39:18 +00:00
return false
}
2024-12-20 05:28:36 +00:00
const getCurrentMostRecentMessage = ( room ) => {
2024-12-31 05:39:18 +00:00
return latestMessageIdentifiers [ room ] ? . latestTimestamp ? latestMessageIdentifiers [ room ] : null
}
2024-12-20 05:28:36 +00:00
2024-12-24 08:27:17 +00:00
// 1) Convert fetchAllMessages to fully async
2024-12-20 05:28:36 +00:00
const fetchAllMessages = async ( response , service , room ) => {
2024-12-24 08:27:17 +00:00
// Instead of returning Promise.all(...) directly,
// we explicitly map each resource to a try/catch block.
const messages = await Promise . all (
response . map ( async ( resource ) => {
try {
2024-12-31 05:39:18 +00:00
const msg = await fetchFullMessage ( resource , service , room )
2024-12-24 08:27:17 +00:00
return msg ; // This might be null if you do that check in fetchFullMessage
} catch ( err ) {
2024-12-31 05:39:18 +00:00
console . error ( ` Skipping resource ${ resource . identifier } due to error: ` , err )
2024-12-24 08:27:17 +00:00
// Return null so it doesn't break everything
2024-12-31 05:39:18 +00:00
return null
2024-12-24 08:27:17 +00:00
}
} )
2024-12-31 05:39:18 +00:00
)
2024-12-24 08:27:17 +00:00
// Filter out any that are null/undefined (missing or errored)
2024-12-31 05:39:18 +00:00
return messages . filter ( Boolean )
}
2024-12-15 03:40:31 +00:00
2024-12-24 08:27:17 +00:00
// 2) fetchFullMessage is already async. We keep it async/await-based
2024-12-20 05:28:36 +00:00
const fetchFullMessage = async ( resource , service , room ) => {
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
// 1) Skip if we already have it in memory
if ( messagesById [ resource . identifier ] ) {
// Possibly also check if the local data is "up to date," //TODO when adding 'edit' ability to messages, will also need to verify timestamp in saved data.
// but if you trust your local data, skip the fetch entirely.
2024-12-31 05:39:18 +00:00
console . log ( ` Skipping fetch. Found in local store: ${ resource . identifier } ` )
return messagesById [ resource . identifier ]
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
}
2024-12-20 05:28:36 +00:00
try {
// Skip if already displayed
if ( existingIdentifiers . has ( resource . identifier ) ) {
2024-12-31 05:39:18 +00:00
return null
2024-12-11 22:40:32 +00:00
}
2024-12-31 05:39:18 +00:00
console . log ( ` Fetching message with identifier: ${ resource . identifier } ` )
2024-12-20 05:28:36 +00:00
const messageResponse = await qortalRequest ( {
action : "FETCH_QDN_RESOURCE" ,
name : resource . name ,
service ,
identifier : resource . identifier ,
... ( room === "admins" ? { encoding : "base64" } : { } ) ,
2024-12-31 05:39:18 +00:00
} )
2024-12-11 22:40:32 +00:00
2024-12-31 05:39:18 +00:00
const timestamp = resource . updated || resource . created
const formattedTimestamp = await timestampToHumanReadableDate ( timestamp )
const messageObject = await processMessageObject ( messageResponse , room )
2024-12-20 05:28:36 +00:00
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
const builtMsg = {
2024-12-20 05:28:36 +00:00
name : resource . name ,
content : messageObject ? . messageHtml || "<em>Message content missing</em>" ,
date : formattedTimestamp ,
identifier : resource . identifier ,
replyTo : messageObject ? . replyTo || null ,
timestamp ,
attachments : messageObject ? . attachments || [ ] ,
2024-12-31 05:39:18 +00:00
}
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
// 3) Store it in the map so we skip future fetches
2024-12-31 05:39:18 +00:00
storeMessageInMap ( builtMsg )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
2024-12-31 05:39:18 +00:00
return builtMsg
2024-12-11 22:40:32 +00:00
} catch ( error ) {
2024-12-31 05:39:18 +00:00
console . error ( ` Failed to fetch message ${ resource . identifier } : ${ error . message } ` )
2024-12-20 05:28:36 +00:00
return {
name : resource . name ,
content : "<em>Error loading message</em>" ,
date : "Unknown" ,
identifier : resource . identifier ,
replyTo : null ,
timestamp : resource . updated || resource . created ,
attachments : [ ] ,
2024-12-31 05:39:18 +00:00
}
2024-12-11 22:40:32 +00:00
}
2024-12-31 05:39:18 +00:00
}
2024-12-20 05:28:36 +00:00
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
const fetchReplyData = async ( service , name , identifier , room , replyTimestamp ) => {
try {
2024-12-31 05:39:18 +00:00
console . log ( ` Fetching message with identifier: ${ identifier } ` )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
const messageResponse = await qortalRequest ( {
action : "FETCH_QDN_RESOURCE" ,
name ,
service ,
identifier ,
... ( room === "admins" ? { encoding : "base64" } : { } ) ,
} )
console . log ( 'reply response' , messageResponse )
const messageObject = await processMessageObject ( messageResponse , room )
console . log ( 'reply message object' , messageObject )
const formattedTimestamp = await timestampToHumanReadableDate ( replyTimestamp )
return {
name ,
content : messageObject ? . messageHtml || "<em>Message content missing</em>" ,
date : formattedTimestamp ,
identifier ,
replyTo : messageObject ? . replyTo || null ,
timestamp : replyTimestamp ,
attachments : messageObject ? . attachments || [ ] ,
2024-12-31 05:39:18 +00:00
}
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
} catch ( error ) {
console . error ( ` Failed to fetch message ${ identifier } : ${ error . message } ` )
return {
name ,
content : "<em>Error loading message</em>" ,
date : "Unknown" ,
identifier ,
replyTo : null ,
timestamp : null ,
attachments : [ ] ,
}
}
}
2024-12-24 08:27:17 +00:00
2024-12-20 05:28:36 +00:00
const processMessageObject = async ( messageResponse , room ) => {
if ( room !== "admins" ) {
return messageResponse ;
}
try {
const decryptedData = await decryptAndParseObject ( messageResponse ) ;
return decryptedData
} catch ( error ) {
console . error ( ` Failed to decrypt admin message: ${ error . message } ` ) ;
return null ;
}
} ;
2024-12-24 08:27:17 +00:00
const renderNewMessages = async ( fetchMessages , existingIdentifiers , messagesContainer , room , mostRecentMessage ) => {
2024-12-31 05:39:18 +00:00
let firstNewMessageIdentifier = null
let updatedMostRecentMessage = mostRecentMessage
2024-12-20 05:28:36 +00:00
for ( const message of fetchMessages ) {
if ( message && ! existingIdentifiers . has ( message . identifier ) ) {
2024-12-31 05:39:18 +00:00
const isNewMessage = isMessageNew ( message , mostRecentMessage )
2024-12-20 05:28:36 +00:00
if ( isNewMessage && ! firstNewMessageIdentifier ) {
2024-12-31 05:39:18 +00:00
firstNewMessageIdentifier = message . identifier
2024-12-20 05:28:36 +00:00
}
2024-12-31 05:39:18 +00:00
const messageHTML = await buildMessageHTML ( message , fetchMessages , room , isNewMessage )
messagesContainer . insertAdjacentHTML ( 'beforeend' , messageHTML )
2024-12-20 05:28:36 +00:00
if ( ! updatedMostRecentMessage || new Date ( message . timestamp ) > new Date ( updatedMostRecentMessage ? . latestTimestamp || 0 ) ) {
updatedMostRecentMessage = {
latestIdentifier : message . identifier ,
latestTimestamp : message . timestamp ,
2024-12-31 05:39:18 +00:00
}
2024-12-20 05:28:36 +00:00
}
2024-12-31 05:39:18 +00:00
existingIdentifiers . add ( message . identifier )
2024-12-20 05:28:36 +00:00
}
}
2024-12-31 05:39:18 +00:00
return { firstNewMessageIdentifier , updatedMostRecentMessage }
}
2024-12-20 05:28:36 +00:00
const isMessageNew = ( message , mostRecentMessage ) => {
2024-12-31 05:39:18 +00:00
return ! mostRecentMessage || new Date ( message . timestamp ) > new Date ( mostRecentMessage ? . latestTimestamp )
}
2024-12-20 05:28:36 +00:00
2024-12-24 08:27:17 +00:00
const buildMessageHTML = async ( message , fetchMessages , room , isNewMessage ) => {
2024-12-31 05:39:18 +00:00
const replyHtml = await buildReplyHtml ( message , room )
const attachmentHtml = await buildAttachmentHtml ( message , room )
const avatarUrl = ` /arbitrary/THUMBNAIL/ ${ message . name } /qortal_avatar `
2024-12-20 05:28:36 +00:00
return `
< div class = "message-item" data - identifier = "${message.identifier}" >
< div class = "message-header" style = "display: flex; align-items: center; justify-content: space-between;" >
< div style = "display: flex; align-items: center;" >
< img src = "${avatarUrl}" alt = "Avatar" class = "user-avatar" style = "width: 30px; height: 30px; border-radius: 50%; margin-right: 10px;" >
< span class = "username" > $ { message . name } < / s p a n >
$ { isNewMessage ? ` <span class="new-indicator" style="margin-left: 10px; color: red; font-weight: bold;">NEW</span> ` : '' }
< / d i v >
< span class = "timestamp" > $ { message . date } < / s p a n >
< / d i v >
$ { replyHtml }
< div class = "message-text" > $ { message . content } < / d i v >
< div class = "attachments-gallery" >
$ { attachmentHtml }
< / d i v >
< button class = "reply-button" data - message - identifier = "${message.identifier}" > Reply < / b u t t o n >
< / d i v >
2024-12-21 06:07:18 +00:00
`
}
2024-12-20 05:28:36 +00:00
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
const buildReplyHtml = async ( message , room ) => {
2024-12-27 19:49:07 +00:00
// 1) If no replyTo, skip
2024-12-31 05:39:18 +00:00
if ( ! message . replyTo ) return ""
2024-12-27 19:49:07 +00:00
// 2) Decide which QDN service for this room
2024-12-31 05:39:18 +00:00
const replyService = ( room === "admins" ) ? "MAIL_PRIVATE" : "BLOG_POST"
const replyIdentifier = message . replyTo
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
2024-12-27 19:49:07 +00:00
// 3) Check if we already have a *saved* message
2024-12-31 05:39:18 +00:00
const savedRepliedToMessage = messagesById [ replyIdentifier ]
console . log ( "savedRepliedToMessage" , savedRepliedToMessage )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
2024-12-27 19:49:07 +00:00
// 4) If we do, try to process/decrypt it
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
if ( savedRepliedToMessage ) {
2024-12-27 19:49:07 +00:00
if ( savedRepliedToMessage ) {
// We successfully processed the cached message
2024-12-31 05:39:18 +00:00
console . log ( "Using saved message data for reply:" , savedRepliedToMessage )
2024-12-27 19:49:07 +00:00
return `
< div class = "reply-message" style = "border-left: 2px solid #ccc; margin-bottom: 0.5vh; padding-left: 1vh;" >
< div class = "reply-header" >
In reply to : < span class = "reply-username" > $ { savedRepliedToMessage . name } < / s p a n >
< span class = "reply-timestamp" > $ { savedRepliedToMessage . date } < / s p a n >
< / d i v >
< div class = "reply-content" > $ { savedRepliedToMessage . content } < / d i v >
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
< / d i v >
2024-12-31 05:39:18 +00:00
`
2024-12-27 19:49:07 +00:00
} else {
// The cached message is invalid
2024-12-31 05:39:18 +00:00
console . log ( "Saved message found but processMessageObject returned null. Falling back..." )
2024-12-27 19:49:07 +00:00
}
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
}
2024-12-20 05:28:36 +00:00
2024-12-27 19:49:07 +00:00
// 5) Fallback approach: If we don't have it in memory OR the cached version was invalid
try {
2024-12-31 05:39:18 +00:00
const replyData = await searchSimple ( replyService , replyIdentifier , "" , 1 )
2024-12-27 19:49:07 +00:00
if ( ! replyData || ! replyData . name ) {
2024-12-31 05:39:18 +00:00
console . log ( "No data found via searchSimple. Skipping reply rendering." )
return ""
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
}
2024-12-20 05:28:36 +00:00
2024-12-27 19:49:07 +00:00
// We'll use replyData to fetch the actual message from QDN
2024-12-31 05:39:18 +00:00
const replyName = replyData . name
const replyTimestamp = replyData . updated || replyData . created
console . log ( "message not found in workable form, using searchSimple result =>" , replyData )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
2024-12-27 19:49:07 +00:00
// This fetches and decrypts the actual message
2024-12-31 05:39:18 +00:00
const repliedMessage = await fetchReplyData ( replyService , replyName , replyIdentifier , room , replyTimestamp )
if ( ! repliedMessage ) return ""
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
2024-12-27 19:49:07 +00:00
// Now store the final message in the map for next time
2024-12-31 05:39:18 +00:00
storeMessageInMap ( repliedMessage )
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
2024-12-27 19:49:07 +00:00
// Return final HTML
return `
< div class = "reply-message" style = "border-left: 2px solid #ccc; margin-bottom: 0.5vh; padding-left: 1vh;" >
< div class = "reply-header" >
In reply to : < span class = "reply-username" > $ { repliedMessage . name } < / s p a n > < s p a n c l a s s = " r e p l y - t i m e s t a m p " > $ { r e p l i e d M e s s a g e . d a t e } < / s p a n >
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
< / d i v >
2024-12-27 19:49:07 +00:00
< div class = "reply-content" > $ { repliedMessage . content } < / d i v >
< / d i v >
2024-12-31 05:39:18 +00:00
`
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
} catch ( error ) {
2024-12-31 05:39:18 +00:00
throw error
This version includes many changes and performance improvements. Further performance improvements will be coming soon. This change includes a cache for the published data on the forum. Messages of up to 2000 in number, will be stored locally in browser storage, that way if the message has already been loaded by that computer, it will not have to pull the data again from QDN. It will be stored in encrypted format for the Admin room. This same caching will be applied to the Minter and Admin boards in the future. Also, reply issues that were present before should be resolved, all replies, regardless of when they were published, will now show their previews in the message pane as they are supposed to. Previously if a reply was on another page, it would not load this preview. The encrypted portions of the app now include a method of caching the admin public keys, for faster publishing. The Minter and Admin boards have a new comment loading display when the comments button is clicked to let users know that data is being loaded, on top of the existing comment count. Other new features and additional performance improvements are in planning. Also, the issue preventing comments from those that had not already loaded the forum, in the Admin Board, has been resolved as well.
2024-12-27 04:06:51 +00:00
}
2024-12-31 05:39:18 +00:00
}
2024-12-20 05:28:36 +00:00
2024-12-24 08:27:17 +00:00
const buildAttachmentHtml = async ( message , room ) => {
if ( ! message . attachments || message . attachments . length === 0 ) {
2024-12-31 05:39:18 +00:00
return ""
2024-12-24 08:27:17 +00:00
}
2024-12-20 05:28:36 +00:00
2024-12-24 08:27:17 +00:00
// Map over attachments -> array of Promises
const attachmentsHtmlPromises = message . attachments . map ( attachment =>
buildSingleAttachmentHtml ( attachment , room )
2024-12-31 05:39:18 +00:00
)
2024-12-24 08:27:17 +00:00
// Wait for all Promises to resolve -> array of HTML strings
2024-12-31 05:39:18 +00:00
const attachmentsHtmlArray = await Promise . all ( attachmentsHtmlPromises )
2024-12-24 08:27:17 +00:00
// Join them into a single string
2024-12-31 05:39:18 +00:00
return attachmentsHtmlArray . join ( "" )
}
2024-12-20 05:28:36 +00:00
2024-12-24 08:27:17 +00:00
const buildSingleAttachmentHtml = async ( attachment , room ) => {
2024-12-20 05:28:36 +00:00
if ( room !== "admins" && attachment . mimeType && attachment . mimeType . startsWith ( 'image/' ) ) {
2024-12-21 06:07:18 +00:00
const imageUrl = ` /arbitrary/ ${ attachment . service } / ${ attachment . name } / ${ attachment . identifier } `
2024-12-20 05:28:36 +00:00
return `
< div class = "attachment" >
< img src = "${imageUrl}" alt = "${attachment.filename}" class = "inline-image" / >
2024-12-24 08:27:17 +00:00
< button onclick = "fetchAndSaveAttachment('${attachment.service}', '${attachment.name}', '${attachment.identifier}', '${attachment.filename}', '${attachment.mimeType}')" >
Save $ { attachment . filename }
< / b u t t o n >
2024-12-20 05:28:36 +00:00
< / d i v >
2024-12-21 06:07:18 +00:00
`
} else if
( room === "admins" && attachment . mimeType && attachment . mimeType . startsWith ( 'image/' ) ) {
2024-12-24 08:27:17 +00:00
// const imageUrl = `/arbitrary/${attachment.service}/${attachment.name}/${attachment.identifier}`;
const decryptedBase64 = await fetchEncryptedImageBase64 ( attachment . service , attachment . name , attachment . identifier , attachment . mimeType )
2024-12-31 05:39:18 +00:00
const dataUrl = ` data:image/ ${ attachment . mimeType } ;base64, ${ decryptedBase64 } `
2024-12-24 08:27:17 +00:00
return `
< div class = "attachment" >
< img src = "${dataUrl}" alt = "${attachment.filename}" class = "inline-image" / >
< button onclick = "fetchAndSaveAttachment('${attachment.service}', '${attachment.name}', '${attachment.identifier}', '${attachment.filename}', '${attachment.mimeType}')" >
Save $ { attachment . filename }
< / b u t t o n >
< / d i v >
2024-12-31 05:39:18 +00:00
`
2024-12-21 06:07:18 +00:00
2024-12-20 05:28:36 +00:00
} else {
return `
< div class = "attachment" >
< button onclick = "fetchAndSaveAttachment('${attachment.service}', '${attachment.name}', '${attachment.identifier}', '${attachment.filename}', '${attachment.mimeType}')" >
Download $ { attachment . filename }
< / b u t t o n >
< / d i v >
2024-12-21 06:07:18 +00:00
`
2024-12-20 05:28:36 +00:00
}
2024-12-21 06:07:18 +00:00
}
2024-12-20 05:28:36 +00:00
const scrollToNewMessages = ( firstNewMessageIdentifier ) => {
2024-12-21 06:07:18 +00:00
const newMessageElement = document . querySelector ( ` .message-item[data-identifier=" ${ firstNewMessageIdentifier } "] ` )
2024-12-20 05:28:36 +00:00
if ( newMessageElement ) {
2024-12-21 06:07:18 +00:00
newMessageElement . scrollIntoView ( { behavior : 'smooth' , block : 'center' } )
2024-12-20 05:28:36 +00:00
}
2024-12-21 06:07:18 +00:00
}
2024-12-20 05:28:36 +00:00
const updateLatestMessageIdentifiers = ( room , mostRecentMessage ) => {
2024-12-21 06:07:18 +00:00
latestMessageIdentifiers [ room ] = mostRecentMessage
localStorage . setItem ( "latestMessageIdentifiers" , JSON . stringify ( latestMessageIdentifiers ) )
}
2024-12-20 05:28:36 +00:00
const handleReplyLogic = ( fetchMessages ) => {
2024-12-21 06:07:18 +00:00
const replyButtons = document . querySelectorAll ( ".reply-button" )
2024-12-20 05:28:36 +00:00
replyButtons . forEach ( button => {
button . addEventListener ( "click" , ( ) => {
2024-12-21 06:07:18 +00:00
const replyToMessageIdentifier = button . dataset . messageIdentifier
const repliedMessage = fetchMessages . find ( m => m && m . identifier === replyToMessageIdentifier )
2024-12-20 05:28:36 +00:00
if ( repliedMessage ) {
2024-12-21 06:07:18 +00:00
showReplyPreview ( repliedMessage )
2024-12-20 05:28:36 +00:00
}
2024-12-21 06:07:18 +00:00
} )
} )
}
2024-12-20 05:28:36 +00:00
const showReplyPreview = ( repliedMessage ) => {
2024-12-21 06:07:18 +00:00
replyToMessageIdentifier = repliedMessage . identifier
2024-12-20 05:28:36 +00:00
2024-12-21 06:07:18 +00:00
const replyContainer = document . createElement ( "div" )
replyContainer . className = "reply-container"
2024-12-20 05:28:36 +00:00
replyContainer . innerHTML = `
< div class = "reply-preview" style = "border: 1px solid #ccc; padding: 1vh; margin-bottom: 1vh; background-color: black; color: white;" >
< strong > Replying to : < / s t r o n g > $ { r e p l i e d M e s s a g e . c o n t e n t }
< button id = "cancel-reply" style = "float: right; color: red; background-color: black; font-weight: bold;" > Cancel < / b u t t o n >
< / d i v >
2024-12-21 06:07:18 +00:00
`
2024-12-20 05:28:36 +00:00
if ( ! document . querySelector ( ".reply-container" ) ) {
2024-12-21 06:07:18 +00:00
const messageInputSection = document . querySelector ( ".message-input-section" )
2024-12-20 05:28:36 +00:00
if ( messageInputSection ) {
2024-12-21 06:07:18 +00:00
messageInputSection . insertBefore ( replyContainer , messageInputSection . firstChild )
2024-12-20 05:28:36 +00:00
document . getElementById ( "cancel-reply" ) . addEventListener ( "click" , ( ) => {
2024-12-21 06:07:18 +00:00
replyToMessageIdentifier = null
replyContainer . remove ( )
} )
2024-12-20 05:28:36 +00:00
}
}
2024-12-21 06:07:18 +00:00
const messageInputSection = document . querySelector ( ".message-input-section" )
const editor = document . querySelector ( ".ql-editor" )
2024-12-20 05:28:36 +00:00
if ( messageInputSection ) {
2024-12-21 06:07:18 +00:00
messageInputSection . scrollIntoView ( { behavior : 'smooth' , block : 'center' } )
2024-12-20 05:28:36 +00:00
}
if ( editor ) {
2024-12-21 06:07:18 +00:00
editor . focus ( )
2024-12-20 05:28:36 +00:00
}
2024-12-21 06:07:18 +00:00
}
2024-12-20 05:28:36 +00:00
const updatePaginationControls = async ( room , limit ) => {
2024-12-21 06:07:18 +00:00
const totalMessages = room === "admins" ? await searchAllCountOnly ( ` ${ messageIdentifierPrefix } - ${ room } -e ` , room ) : await searchAllCountOnly ( ` ${ messageIdentifierPrefix } - ${ room } ` , room )
renderPaginationControls ( room , totalMessages , limit )
}
2024-12-20 05:28:36 +00:00
2024-12-11 22:40:32 +00:00
// Polling function to check for new messages without clearing existing ones
function startPollingForNewMessages ( ) {
setInterval ( async ( ) => {
2024-12-21 06:07:18 +00:00
const activeRoom = document . querySelector ( '.room-title' ) ? . innerText . toLowerCase ( ) . split ( " " ) [ 0 ]
2024-12-11 22:40:32 +00:00
if ( activeRoom ) {
2024-12-21 06:07:18 +00:00
await loadMessagesFromQDN ( activeRoom , currentPage , true )
2024-12-11 22:40:32 +00:00
}
2024-12-21 06:07:18 +00:00
} , 40000 )
2024-12-11 22:40:32 +00:00
}