@@ -10,6 +10,7 @@ import { CID } from 'multiformats/cid'
1010import { useDrag } from 'react-dnd'
1111import { toString as fromUint8ArrayToString } from 'uint8arrays'
1212import Button from '../../components/button/button.tsx'
13+ import GlyphCancel from '../../icons/GlyphCancel.js'
1314
1415const maxPlainTextPreview = 1024 * 10 // only preview small part of huge files
1516
@@ -24,7 +25,7 @@ const Drag = ({ name, size, cid, path, children }) => {
2425}
2526
2627const Preview = ( props ) => {
27- const { t, name, cid, size, availableGatewayUrl, publicGateway, read, onDownload } = props
28+ const { t, name, cid, size, availableGatewayUrl, publicGateway, read, onDownload, onClose } = props
2829 const [ content , setContent ] = useState ( null )
2930 const [ hasMoreContent , setHasMoreContent ] = useState ( false )
3031 const [ buffer , setBuffer ] = useState ( null )
@@ -60,39 +61,64 @@ const Preview = (props) => {
6061 const src = `${ availableGatewayUrl } /ipfs/${ cid } ?filename=${ encodeURIComponent ( name ) } `
6162 const className = 'mw-100 mt3 bg-snow-muted pa2 br2 border-box'
6263
64+ // Close button header
65+ const closeButtonHeader = onClose != null && (
66+ < div className = "flex items-center justify-between mb3 pb2 bb b--light-gray" >
67+ < div className = "flex items-center" >
68+ < h2 className = "ma0 f4 charcoal truncate" > { name } </ h2 >
69+ </ div >
70+ < GlyphCancel
71+ onClick = { onClose }
72+ style = { { width : '44px' , height : '44px' , fill : '#244c5a' , cursor : 'pointer' } }
73+ />
74+ </ div >
75+ )
76+
6377 switch ( type ) {
6478 case 'audio' :
6579 return (
66- < Drag { ...props } >
67- { /* eslint-disable-next-line jsx-a11y/media-has-caption */ }
68- < audio width = '100%' controls >
69- < source src = { safeSubresourceGwUrl ( src ) } />
70- </ audio >
71- </ Drag >
80+ < div >
81+ { closeButtonHeader }
82+ < Drag { ...props } >
83+ { /* eslint-disable-next-line jsx-a11y/media-has-caption */ }
84+ < audio width = '100%' controls >
85+ < source src = { safeSubresourceGwUrl ( src ) } />
86+ </ audio >
87+ </ Drag >
88+ </ div >
7289 )
7390 case 'pdf' :
7491 return (
75- < Drag { ...props } >
76- < object className = "FilePreviewPDF w-100" data = { safeSubresourceGwUrl ( src ) } type = 'application/pdf' >
77- { t ( 'noPDFSupport' ) }
78- < a href = { src } download target = '_blank' rel = 'noopener noreferrer' className = 'underline-hover navy-muted' > { t ( 'downloadPDF' ) } </ a >
79- </ object >
80- </ Drag >
92+ < div >
93+ { closeButtonHeader }
94+ < Drag { ...props } >
95+ < object className = "FilePreviewPDF w-100" data = { safeSubresourceGwUrl ( src ) } type = 'application/pdf' >
96+ { t ( 'noPDFSupport' ) }
97+ < a href = { src } download target = '_blank' rel = 'noopener noreferrer' className = 'underline-hover navy-muted' > { t ( 'downloadPDF' ) } </ a >
98+ </ object >
99+ </ Drag >
100+ </ div >
81101 )
82102 case 'video' :
83103 return (
84- < Drag { ...props } >
85- { /* eslint-disable-next-line jsx-a11y/media-has-caption */ }
86- < video controls className = { className } >
87- < source src = { safeSubresourceGwUrl ( src ) } />
88- </ video >
89- </ Drag >
104+ < div >
105+ { closeButtonHeader }
106+ < Drag { ...props } >
107+ { /* eslint-disable-next-line jsx-a11y/media-has-caption */ }
108+ < video controls className = { className } >
109+ < source src = { safeSubresourceGwUrl ( src ) } />
110+ </ video >
111+ </ Drag >
112+ </ div >
90113 )
91114 case 'image' :
92115 return (
93- < Drag { ...props } >
94- < img className = { className } alt = { name } src = { safeSubresourceGwUrl ( src ) } />
95- </ Drag >
116+ < div >
117+ { closeButtonHeader }
118+ < Drag { ...props } >
119+ < img className = { className } alt = { name } src = { safeSubresourceGwUrl ( src ) } />
120+ </ Drag >
121+ </ div >
96122 )
97123 default : {
98124 const srcPublic = `${ publicGateway } /ipfs/${ cid } ?filename=${ encodeURIComponent ( name ) } `
@@ -114,31 +140,49 @@ const Preview = (props) => {
114140 )
115141
116142 if ( content === null ) {
117- return < ComponentLoader />
143+ return (
144+ < div >
145+ { closeButtonHeader }
146+ < ComponentLoader />
147+ </ div >
148+ )
118149 }
119150
120151 // a precaution to not render too much, in case we overread
121152 if ( content . length > maxPlainTextPreview ) {
122- return cantPreview
153+ return (
154+ < div >
155+ { closeButtonHeader }
156+ { cantPreview }
157+ </ div >
158+ )
123159 }
124160
125161 if ( isBinary ( name , content ) ) {
126- return cantPreview
162+ return (
163+ < div >
164+ { closeButtonHeader }
165+ { cantPreview }
166+ </ div >
167+ )
127168 }
128169
129- return < >
130- < pre className = { `${ className } overflow-auto monospace` } >
131- { content }
132- </ pre >
133- { hasMoreContent && < div className = "w-100 flex items-center justify-center" >
134- < p > < Trans i18nKey = 'previewLimitReached' t = { t } > This preview is limited to 10 KiB. Click the download button to access the full file.</ Trans > </ p >
135- < p >
136- < Button className = "mh2 lh-copy bn justify-center flex " onClick = { onDownload } >
137- { t ( 'app:actions.download' ) }
138- </ Button >
139- </ p >
140- </ div > }
141- </ >
170+ return (
171+ < div >
172+ { closeButtonHeader }
173+ < pre className = { `${ className } overflow-auto monospace` } >
174+ { content }
175+ </ pre >
176+ { hasMoreContent && < div className = "w-100 flex items-center justify-center" >
177+ < p > < Trans i18nKey = 'previewLimitReached' t = { t } > This preview is limited to 10 KiB. Click the download button to access the full file.</ Trans > </ p >
178+ < p >
179+ < Button className = "mh2 lh-copy bn justify-center flex " onClick = { onDownload } >
180+ { t ( 'app:actions.download' ) }
181+ </ Button >
182+ </ p >
183+ </ div > }
184+ </ div >
185+ )
142186 }
143187 }
144188}
@@ -151,7 +195,8 @@ Preview.propTypes = {
151195 read : PropTypes . func . isRequired ,
152196 content : PropTypes . object ,
153197 t : PropTypes . func . isRequired ,
154- tReady : PropTypes . bool . isRequired
198+ tReady : PropTypes . bool . isRequired ,
199+ onClose : PropTypes . func
155200}
156201
157202export default connect (
0 commit comments