2727define ( function ( require , exports , module ) {
2828 const HTMLInstrumentation = require ( "LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation" ) ;
2929 const LiveDevMultiBrowser = require ( "LiveDevelopment/LiveDevMultiBrowser" ) ;
30+ const LiveDevelopment = require ( "LiveDevelopment/main" ) ;
3031 const CodeMirror = require ( "thirdparty/CodeMirror/lib/codemirror" ) ;
3132 const ProjectManager = require ( "project/ProjectManager" ) ;
3233 const FileSystem = require ( "filesystem/FileSystem" ) ;
@@ -41,6 +42,14 @@ define(function (require, exports, module) {
4142
4243 // state manager key, to save the download location of the image
4344 const IMAGE_DOWNLOAD_FOLDER_KEY = "imageGallery.downloadFolder" ;
45+ const IMAGE_DOWNLOAD_PERSIST_FOLDER_KEY = "imageGallery.persistFolder" ;
46+
47+ const DOWNLOAD_EVENTS = {
48+ STARTED : 'downloadStarted' ,
49+ COMPLETED : 'downloadCompleted' ,
50+ CANCELLED : 'downloadCancelled' ,
51+ ERROR : 'downloadError'
52+ } ;
4453
4554 const KernalModeTrust = window . KernalModeTrust ;
4655 if ( ! KernalModeTrust ) {
@@ -685,6 +694,32 @@ define(function (require, exports, module) {
685694 }
686695 }
687696
697+ function _sendDownloadStatusToBrowser ( eventType , data ) {
698+ const currLiveDoc = LiveDevMultiBrowser . getCurrentLiveDoc ( ) ;
699+ if ( currLiveDoc && currLiveDoc . protocol && currLiveDoc . protocol . evaluate ) {
700+ const dataJson = JSON . stringify ( data || { } ) ;
701+ const evalString = `_LD.handleDownloadEvent('${ eventType } ', ${ dataJson } )` ;
702+ currLiveDoc . protocol . evaluate ( evalString ) ;
703+ }
704+ }
705+
706+ function _handleDownloadError ( error , downloadId ) {
707+ console . error ( 'something went wrong while download the image. error:' , error ) ;
708+ if ( downloadId ) {
709+ _sendDownloadStatusToBrowser ( DOWNLOAD_EVENTS . ERROR , { downloadId : downloadId } ) ;
710+ }
711+ }
712+
713+ function _trackDownload ( downloadLocation ) {
714+ if ( ! downloadLocation ) {
715+ return ;
716+ }
717+ fetch ( `https://images.phcode.dev/api/images/download?download_location=${ encodeURIComponent ( downloadLocation ) } ` )
718+ . catch ( error => {
719+ console . error ( 'download tracking failed:' , error ) ;
720+ } ) ;
721+ }
722+
688723 /**
689724 * Helper function to update image src attribute and dismiss ribbon gallery
690725 *
@@ -716,16 +751,18 @@ define(function (require, exports, module) {
716751 * @param {Directory } projectRoot - the project root in which the image is to be saved
717752 */
718753 function _handleUseThisImageLocalFiles ( message , filename , projectRoot ) {
719- const { tagId, imageData } = message ;
754+ const { tagId, imageData, downloadLocation , downloadId } = message ;
720755
721756 const uint8Array = new Uint8Array ( imageData ) ;
722757 const targetPath = projectRoot . fullPath + filename ;
723758
724759 window . fs . writeFile ( targetPath , window . Filer . Buffer . from ( uint8Array ) ,
725760 { encoding : window . fs . BYTE_ARRAY_ENCODING } , ( err ) => {
726761 if ( err ) {
727- console . error ( 'Failed to save image:' , err ) ;
762+ _handleDownloadError ( err , downloadId ) ;
728763 } else {
764+ _trackDownload ( downloadLocation ) ;
765+ _sendDownloadStatusToBrowser ( DOWNLOAD_EVENTS . COMPLETED , { downloadId } ) ;
729766 _updateImageAndDismissRibbon ( tagId , targetPath , filename ) ;
730767 }
731768 } ) ;
@@ -738,7 +775,7 @@ define(function (require, exports, module) {
738775 * @param {Directory } projectRoot - the project root in which the image is to be saved
739776 */
740777 function _handleUseThisImageRemote ( message , filename , projectRoot ) {
741- const { imageUrl, tagId } = message ;
778+ const { imageUrl, tagId, downloadLocation , downloadId } = message ;
742779
743780 fetch ( imageUrl )
744781 . then ( response => {
@@ -754,14 +791,16 @@ define(function (require, exports, module) {
754791 window . fs . writeFile ( targetPath , window . Filer . Buffer . from ( uint8Array ) ,
755792 { encoding : window . fs . BYTE_ARRAY_ENCODING } , ( err ) => {
756793 if ( err ) {
757- console . error ( 'Failed to save image:' , err ) ;
794+ _handleDownloadError ( err , downloadId ) ;
758795 } else {
796+ _trackDownload ( downloadLocation ) ;
797+ _sendDownloadStatusToBrowser ( DOWNLOAD_EVENTS . COMPLETED , { downloadId } ) ;
759798 _updateImageAndDismissRibbon ( tagId , targetPath , filename ) ;
760799 }
761800 } ) ;
762801 } )
763802 . catch ( error => {
764- console . error ( 'Failed to fetch image:' , error ) ;
803+ _handleDownloadError ( error , downloadId ) ;
765804 } ) ;
766805 }
767806
@@ -778,6 +817,10 @@ define(function (require, exports, module) {
778817 return ;
779818 }
780819
820+ if ( message . downloadId ) {
821+ _sendDownloadStatusToBrowser ( DOWNLOAD_EVENTS . STARTED , { downloadId : message . downloadId } ) ;
822+ }
823+
781824 const filename = message . filename ;
782825 const extnName = message . extnName || "jpg" ;
783826
@@ -792,11 +835,17 @@ define(function (require, exports, module) {
792835 // the directory name that user wrote, first check if it exists or not
793836 // if it doesn't exist we create it and then download the image inside it
794837 targetDir . exists ( ( err , exists ) => {
795- if ( err ) { return ; }
838+ if ( err ) {
839+ _handleDownloadError ( err , message . downloadId ) ;
840+ return ;
841+ }
796842
797843 if ( ! exists ) {
798844 targetDir . create ( ( err ) => {
799- if ( err ) { return ; }
845+ if ( err ) {
846+ _handleDownloadError ( err , message . downloadId ) ;
847+ return ;
848+ }
800849 _downloadImageToDirectory ( message , filename , extnName , targetDir ) ;
801850 } ) ;
802851 } else {
@@ -1109,6 +1158,10 @@ define(function (require, exports, module) {
11091158 let rootFolders = [ ] ;
11101159 let stringMatcher = null ;
11111160
1161+ const persistFolder = StateManager . get ( IMAGE_DOWNLOAD_PERSIST_FOLDER_KEY , StateManager . PROJECT_CONTEXT ) ;
1162+ const shouldBeChecked = persistFolder !== false ;
1163+ $rememberCheckbox . prop ( 'checked' , shouldBeChecked ) ;
1164+
11121165 _scanRootDirectoriesOnly ( projectRoot , rootFolders ) . then ( ( ) => {
11131166 stringMatcher = new StringMatch . StringMatcher ( { segmentedSearch : true } ) ;
11141167 _renderFolderSuggestions ( rootFolders . slice ( 0 , 15 ) , $suggestions , $input ) ;
@@ -1134,14 +1187,22 @@ define(function (require, exports, module) {
11341187 const folderPath = $input . val ( ) . trim ( ) ;
11351188
11361189 // if the checkbox is checked, we save the folder preference for this project
1137- if ( $rememberCheckbox . is ( ':checked' ) ) {
1190+ const isChecked = $rememberCheckbox . is ( ':checked' ) ;
1191+ StateManager . set ( IMAGE_DOWNLOAD_PERSIST_FOLDER_KEY , isChecked , StateManager . PROJECT_CONTEXT ) ;
1192+ if ( isChecked ) {
11381193 StateManager . set ( IMAGE_DOWNLOAD_FOLDER_KEY , folderPath , StateManager . PROJECT_CONTEXT ) ;
1194+ } else {
1195+ StateManager . set ( IMAGE_DOWNLOAD_FOLDER_KEY , undefined , StateManager . PROJECT_CONTEXT ) ;
11391196 }
11401197
11411198 // if message is provided, download the image
11421199 if ( message ) {
11431200 _downloadToFolder ( message , folderPath ) ;
11441201 }
1202+ } else {
1203+ if ( message && message . downloadId ) {
1204+ _sendDownloadStatusToBrowser ( DOWNLOAD_EVENTS . CANCELLED , { downloadId : message . downloadId } ) ;
1205+ }
11451206 }
11461207 dialog . close ( ) ;
11471208 } ) ;
@@ -1187,7 +1248,7 @@ define(function (require, exports, module) {
11871248 _handleUseThisImageRemote ( message , uniqueFilename , targetDir ) ;
11881249 }
11891250 } ) . catch ( error => {
1190- console . error ( 'Something went wrong when trying to use this image' , error ) ;
1251+ _handleDownloadError ( error , message . downloadId ) ;
11911252 } ) ;
11921253 }
11931254
@@ -1234,6 +1295,12 @@ define(function (require, exports, module) {
12341295 return ;
12351296 }
12361297
1298+ // handle image gallery state change message
1299+ if ( message . type === "imageGalleryStateChange" ) {
1300+ LiveDevelopment . setImageGalleryState ( message . selected ) ;
1301+ return ;
1302+ }
1303+
12371304 // handle move(drag & drop)
12381305 if ( message . move && message . sourceId && message . targetId ) {
12391306 _moveElementInSource ( message . sourceId , message . targetId , message . insertAfter , message . insertInside ) ;
0 commit comments