@@ -933,7 +933,7 @@ const PrinterService = {
933933 cursor: pointer;
934934 min-width: 140px;
935935 ` ;
936- downloadBtn . onclick = ( ) => {
936+ downloadBtn . onclick = async ( ) => {
937937 // Create a new canvas with padding
938938 const padding = 20 ;
939939 const paddedCanvas = document . createElement ( 'canvas' ) ;
@@ -946,10 +946,42 @@ const PrinterService = {
946946 paddedCtx . drawImage ( canvas , padding , padding ) ;
947947
948948 const billType = billData . isPurchase ? 'purchase' : 'sale' ;
949- const link = document . createElement ( 'a' ) ;
950- link . download = `${ billType } _bill_${ billData . id || Date . now ( ) } .png` ;
951- link . href = paddedCanvas . toDataURL ( 'image/png' ) ;
952- link . click ( ) ;
949+ const filename = `${ billType } _bill_${ billData . id || Date . now ( ) } .png` ;
950+
951+ // Convert canvas to blob for better mobile support
952+ paddedCanvas . toBlob ( async ( blob ) => {
953+ if ( ! blob ) {
954+ UIManager . showToast ( 'Failed to generate image' , 'error' ) ;
955+ return ;
956+ }
957+
958+ // Try Web Share API for mobile (allows saving to gallery)
959+ if ( navigator . share && navigator . canShare && navigator . canShare ( { files : [ new File ( [ blob ] , filename , { type : 'image/png' } ) ] } ) ) {
960+ try {
961+ const file = new File ( [ blob ] , filename , { type : 'image/png' } ) ;
962+ await navigator . share ( {
963+ files : [ file ] ,
964+ title : 'Bill'
965+ } ) ;
966+ return ;
967+ } catch ( e ) {
968+ // User cancelled or share failed, fall through to download
969+ if ( e . name !== 'AbortError' ) {
970+ console . log ( 'Share failed, trying download:' , e ) ;
971+ }
972+ }
973+ }
974+
975+ // Fallback: Create blob URL and download
976+ const url = URL . createObjectURL ( blob ) ;
977+ const link = document . createElement ( 'a' ) ;
978+ link . href = url ;
979+ link . download = filename ;
980+ document . body . appendChild ( link ) ;
981+ link . click ( ) ;
982+ document . body . removeChild ( link ) ;
983+ URL . revokeObjectURL ( url ) ;
984+ } , 'image/png' ) ;
953985 } ;
954986
955987 const closeBtn = document . createElement ( 'button' ) ;
@@ -1056,7 +1088,7 @@ const PrinterService = {
10561088 cursor: pointer;
10571089 min-width: 140px;
10581090 ` ;
1059- downloadBtn . onclick = ( ) => {
1091+ downloadBtn . onclick = async ( ) => {
10601092 // Create a new canvas with padding
10611093 const padding = 20 ;
10621094 const paddedCanvas = document . createElement ( 'canvas' ) ;
@@ -1068,10 +1100,42 @@ const PrinterService = {
10681100 paddedCtx . fillRect ( 0 , 0 , paddedCanvas . width , paddedCanvas . height ) ;
10691101 paddedCtx . drawImage ( canvas , padding , padding ) ;
10701102
1071- const link = document . createElement ( 'a' ) ;
1072- link . download = `expense_${ expense . id || Date . now ( ) } .png` ;
1073- link . href = paddedCanvas . toDataURL ( 'image/png' ) ;
1074- link . click ( ) ;
1103+ const filename = `expense_${ expense . id || Date . now ( ) } .png` ;
1104+
1105+ // Convert canvas to blob for better mobile support
1106+ paddedCanvas . toBlob ( async ( blob ) => {
1107+ if ( ! blob ) {
1108+ UIManager . showToast ( 'Failed to generate image' , 'error' ) ;
1109+ return ;
1110+ }
1111+
1112+ // Try Web Share API for mobile (allows saving to gallery)
1113+ if ( navigator . share && navigator . canShare && navigator . canShare ( { files : [ new File ( [ blob ] , filename , { type : 'image/png' } ) ] } ) ) {
1114+ try {
1115+ const file = new File ( [ blob ] , filename , { type : 'image/png' } ) ;
1116+ await navigator . share ( {
1117+ files : [ file ] ,
1118+ title : 'Expense'
1119+ } ) ;
1120+ return ;
1121+ } catch ( e ) {
1122+ // User cancelled or share failed, fall through to download
1123+ if ( e . name !== 'AbortError' ) {
1124+ console . log ( 'Share failed, trying download:' , e ) ;
1125+ }
1126+ }
1127+ }
1128+
1129+ // Fallback: Create blob URL and download
1130+ const url = URL . createObjectURL ( blob ) ;
1131+ const link = document . createElement ( 'a' ) ;
1132+ link . href = url ;
1133+ link . download = filename ;
1134+ document . body . appendChild ( link ) ;
1135+ link . click ( ) ;
1136+ document . body . removeChild ( link ) ;
1137+ URL . revokeObjectURL ( url ) ;
1138+ } , 'image/png' ) ;
10751139 } ;
10761140
10771141 const closeBtn = document . createElement ( 'button' ) ;
0 commit comments