@@ -419,7 +419,7 @@ function showEditModal(filename, id, downloads, expiry, password, unlimitedown,
419419 $ ( 'body' ) . append ( myClone ) ;
420420 } ) ;
421421
422- document . getElementById ( "m_filenamelabel" ) . innerHTML = filename ;
422+ document . getElementById ( "m_filenamelabel" ) . innerText = filename ;
423423 document . getElementById ( "mc_expiry" ) . setAttribute ( "data-timestamp" , expiry ) ;
424424 document . getElementById ( "mb_save" ) . setAttribute ( 'data-fileid' , id ) ;
425425 createCalendar ( expiry ) ;
@@ -562,14 +562,14 @@ function parseSseData(data) {
562562function setNewDownloadCount ( id , downloadCount , downloadsRemaining ) {
563563 let downloadCell = document . getElementById ( "cell-downloads-" + id ) ;
564564 if ( downloadCell != null ) {
565- downloadCell . innerHTML = downloadCount ;
565+ downloadCell . innerText = downloadCount ;
566566 downloadCell . classList . add ( "updatedDownloadCount" ) ;
567567 setTimeout ( ( ) => downloadCell . classList . remove ( "updatedDownloadCount" ) , 500 ) ;
568568 }
569569 if ( downloadsRemaining != - 1 ) {
570570 let downloadsRemainingCell = document . getElementById ( "cell-downloadsRemaining-" + id ) ;
571571 if ( downloadsRemainingCell != null ) {
572- downloadsRemainingCell . innerHTML = downloadsRemaining ;
572+ downloadsRemainingCell . innerText = downloadsRemaining ;
573573 downloadsRemainingCell . classList . add ( "updatedDownloadCount" ) ;
574574 setTimeout ( ( ) => downloadsRemainingCell . classList . remove ( "updatedDownloadCount" ) , 500 ) ;
575575 }
@@ -662,6 +662,7 @@ function removeFileStatus(chunkId) {
662662function addRow ( item ) {
663663 let table = document . getElementById ( "downloadtable" ) ;
664664 let row = table . insertRow ( 0 ) ;
665+ item . Id = sanitizeId ( item . Id ) ;
665666 row . id = "row-" + item . Id ;
666667 let cellFilename = row . insertCell ( 0 ) ;
667668 let cellFileSize = row . insertCell ( 1 ) ;
@@ -670,11 +671,7 @@ function addRow(item) {
670671 let cellDownloadCount = row . insertCell ( 4 ) ;
671672 let cellUrl = row . insertCell ( 5 ) ;
672673 let cellButtons = row . insertCell ( 6 ) ;
673- let lockIcon = "" ;
674674
675- if ( item . IsPasswordProtected === true ) {
676- lockIcon = ' <i title="Password protected" class="bi bi-key"></i>' ;
677- }
678675 cellFilename . innerText = item . Name ;
679676 cellFilename . id = "cell-name-" + item . Id ;
680677 cellDownloadCount . id = "cell-downloads-" + item . Id ;
@@ -691,19 +688,130 @@ function addRow(item) {
691688 cellStoredUntil . innerText = item . ExpireAtString ;
692689 }
693690 cellDownloadCount . innerText = item . DownloadCount ;
694- cellUrl . innerHTML = '<a target="_blank" style="color: inherit" id="url-href-' + item . Id + '" href="' + item . UrlDownload + '">' + item . Id + '</a>' + lockIcon ;
695691
696- let buttons = '<button type="button" onclick="showToast(1000)" id="url-button-' + item . Id + '" data-clipboard-text="' + item . UrlDownload + '" class="copyurl btn btn-outline-light btn-sm"><i class="bi bi-copy"></i> URL</button> ' ;
697- if ( item . UrlHotlink === "" ) {
698- buttons = buttons + '<button type="button"class="copyurl btn btn-outline-light btn-sm disabled"><i class="bi bi-copy"></i> Hotlink</button> ' ;
692+ // === URL Link ===
693+ const link = document . createElement ( 'a' ) ;
694+ link . href = item . UrlDownload ;
695+ link . target = '_blank' ;
696+ link . style . color = 'inherit' ;
697+ link . id = 'url-href-' + item . Id ;
698+ link . textContent = item . Id ;
699+
700+ cellUrl . appendChild ( link ) ;
701+
702+ if ( item . IsPasswordProtected === true ) {
703+ const icon = document . createElement ( 'i' ) ;
704+ icon . className = 'bi bi-key' ;
705+ icon . title = 'Password protected' ;
706+ cellUrl . appendChild ( document . createTextNode ( ' ' ) ) ;
707+ cellUrl . appendChild ( icon ) ;
708+ }
709+
710+ // === Button: Copy URL ===
711+ const copyUrlBtn = document . createElement ( 'button' ) ;
712+ copyUrlBtn . type = 'button' ;
713+ copyUrlBtn . className = 'copyurl btn btn-outline-light btn-sm' ;
714+ copyUrlBtn . dataset . clipboardText = item . UrlDownload ;
715+ copyUrlBtn . id = 'url-button-' + item . Id ;
716+ copyUrlBtn . title = 'Copy URL' ;
717+
718+ const copyIcon = document . createElement ( 'i' ) ;
719+ copyIcon . className = 'bi bi-copy' ;
720+ copyUrlBtn . appendChild ( copyIcon ) ;
721+ copyUrlBtn . appendChild ( document . createTextNode ( ' URL' ) ) ;
722+
723+ copyUrlBtn . addEventListener ( 'click' , ( ) => {
724+ showToast ( 1000 ) ;
725+ } ) ;
726+
727+ cellButtons . appendChild ( copyUrlBtn ) ;
728+ cellButtons . appendChild ( document . createTextNode ( ' ' ) ) ;
729+
730+ // === Button: Copy Hotlink ===
731+ const hotlinkBtn = document . createElement ( 'button' ) ;
732+ hotlinkBtn . type = 'button' ;
733+ hotlinkBtn . className = 'copyurl btn btn-outline-light btn-sm' ;
734+ hotlinkBtn . title = 'Copy Hotlink' ;
735+
736+ const hotlinkIcon = document . createElement ( 'i' ) ;
737+ hotlinkIcon . className = 'bi bi-copy' ;
738+ hotlinkBtn . appendChild ( hotlinkIcon ) ;
739+ hotlinkBtn . appendChild ( document . createTextNode ( ' Hotlink' ) ) ;
740+
741+ if ( item . UrlHotlink ) {
742+ hotlinkBtn . dataset . clipboardText = item . UrlHotlink ;
743+ hotlinkBtn . addEventListener ( 'click' , ( ) => {
744+ showToast ( 1000 ) ;
745+ } ) ;
699746 } else {
700- buttons = buttons + '<button type="button" onclick="showToast(1000)" data-clipboard-text="' + item . UrlHotlink + '" class="copyurl btn btn-outline-light btn-sm"><i class="bi bi-copy"></i> Hotlink</button> ' ;
747+ hotlinkBtn . disabled = true ;
701748 }
702- buttons = buttons + '<button type="button" id="qrcode-' + item . Id + '" title="QR Code" class="btn btn-outline-light btn-sm" onclick="showQrCode(\'' + item . UrlDownload + '\');"><i class="bi bi-qr-code"></i></button> ' ;
703- buttons = buttons + '<button type="button" title="Edit" class="btn btn-outline-light btn-sm" onclick="showEditModal(\'' + item . Name + '\',\'' + item . Id + '\', ' + item . DownloadsRemaining + ', ' + item . ExpireAt + ', ' + item . IsPasswordProtected + ', ' + item . UnlimitedDownloads + ', ' + item . UnlimitedTime + ', ' + item . IsEndToEndEncrypted + ', canReplaceOwnFiles);"><i class="bi bi-pencil"></i></button> ' ;
704- buttons = buttons + '<button type="button" id="button-delete-' + item . Id + '" title="Delete" class="btn btn-outline-danger btn-sm" onclick="deleteFile(\'' + item . Id + '\')"><i class="bi bi-trash3"></i></button>' ;
705749
706- cellButtons . innerHTML = buttons ;
750+ cellButtons . appendChild ( hotlinkBtn ) ;
751+ cellButtons . appendChild ( document . createTextNode ( ' ' ) ) ;
752+
753+ // === Button: QR Code ===
754+ const qrBtn = document . createElement ( 'button' ) ;
755+ qrBtn . type = 'button' ;
756+ qrBtn . className = 'btn btn-outline-light btn-sm' ;
757+ qrBtn . title = 'QR Code' ;
758+ qrBtn . id = 'qrcode-' + item . Id ;
759+
760+ const qrIcon = document . createElement ( 'i' ) ;
761+ qrIcon . className = 'bi bi-qr-code' ;
762+ qrBtn . appendChild ( qrIcon ) ;
763+
764+ qrBtn . addEventListener ( 'click' , ( ) => {
765+ showQrCode ( item . UrlDownload ) ;
766+ } ) ;
767+
768+ cellButtons . appendChild ( qrBtn ) ;
769+ cellButtons . appendChild ( document . createTextNode ( ' ' ) ) ;
770+
771+ // === Button: Edit ===
772+ const editBtn = document . createElement ( 'button' ) ;
773+ editBtn . type = 'button' ;
774+ editBtn . className = 'btn btn-outline-light btn-sm' ;
775+ editBtn . title = 'Edit' ;
776+
777+ const editIcon = document . createElement ( 'i' ) ;
778+ editIcon . className = 'bi bi-pencil' ;
779+ editBtn . appendChild ( editIcon ) ;
780+
781+ editBtn . addEventListener ( 'click' , ( ) => {
782+ showEditModal (
783+ item . Name ,
784+ item . Id ,
785+ item . DownloadsRemaining ,
786+ item . ExpireAt ,
787+ item . IsPasswordProtected ,
788+ item . UnlimitedDownloads ,
789+ item . UnlimitedTime ,
790+ item . IsEndToEndEncrypted ,
791+ canReplaceOwnFiles
792+ ) ;
793+ } ) ;
794+
795+ cellButtons . appendChild ( editBtn ) ;
796+ cellButtons . appendChild ( document . createTextNode ( ' ' ) ) ;
797+
798+ // === Button: Delete ===
799+ const deleteBtn = document . createElement ( 'button' ) ;
800+ deleteBtn . type = 'button' ;
801+ deleteBtn . className = 'btn btn-outline-danger btn-sm' ;
802+ deleteBtn . title = 'Delete' ;
803+ deleteBtn . id = 'button-delete-' + item . Id ;
804+
805+ const deleteIcon = document . createElement ( 'i' ) ;
806+ deleteIcon . className = 'bi bi-trash3' ;
807+ deleteBtn . appendChild ( deleteIcon ) ;
808+
809+ deleteBtn . addEventListener ( 'click' , ( ) => {
810+ deleteFile ( item . Id ) ;
811+ } ) ;
812+
813+ cellButtons . appendChild ( deleteBtn ) ;
814+
707815
708816 cellFilename . classList . add ( 'newItem' ) ;
709817 cellFileSize . classList . add ( 'newItem' ) ;
@@ -718,6 +826,10 @@ function addRow(item) {
718826 return item . Id ;
719827}
720828
829+ function sanitizeId ( str ) {
830+ return str . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '' ) ;
831+ }
832+
721833function changeRowCount ( add , row ) {
722834 let datatable = $ ( '#maintable' ) . DataTable ( ) ;
723835 if ( rowCount == - 1 ) {
0 commit comments