1
1
import type { MediaValueType } from '../../property-editors/upload-field/types.js' ;
2
+ import { getMimeTypeFromExtension } from './utils.js' ;
2
3
import { TemporaryFileStatus , UmbTemporaryFileManager } from '@umbraco-cms/backoffice/temporary-file' ;
3
4
import type { UmbTemporaryFileModel } from '@umbraco-cms/backoffice/temporary-file' ;
4
5
import { UmbId } from '@umbraco-cms/backoffice/id' ;
@@ -16,7 +17,6 @@ import type { UUIFileDropzoneElement, UUIFileDropzoneEvent } from '@umbraco-cms/
16
17
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element' ;
17
18
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event' ;
18
19
19
- import './input-upload-field-file.element.js' ;
20
20
import { UmbExtensionsManifestInitializer } from '@umbraco-cms/backoffice/extension-api' ;
21
21
import { type ManifestFileUploadPreview , umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry' ;
22
22
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api' ;
@@ -26,7 +26,7 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
26
26
@property ( { type : Object } )
27
27
set value ( value : MediaValueType ) {
28
28
if ( ! value ?. src ) return ;
29
- this . _src = value . src ;
29
+ this . src = value . src ;
30
30
}
31
31
get value ( ) : MediaValueType {
32
32
return ! this . temporaryFile ? { src : this . _src } : { temporaryFileId : this . temporaryFile . temporaryUnique } ;
@@ -48,12 +48,23 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
48
48
@state ( )
49
49
public temporaryFile ?: UmbTemporaryFileModel ;
50
50
51
+ public set src ( src : string ) {
52
+ this . _src = src ;
53
+ this . _previewAlias = this . #getPreviewElementAlias( ) ;
54
+ }
55
+ public get src ( ) {
56
+ return this . _src ;
57
+ }
58
+
51
59
@state ( )
52
60
private _src = '' ;
53
61
54
62
@state ( )
55
63
private _extensions ?: string [ ] ;
56
64
65
+ @state ( )
66
+ private _previewAlias = '' ;
67
+
57
68
@query ( '#dropzone' )
58
69
private _dropzone ?: UUIFileDropzoneElement ;
59
70
@@ -79,6 +90,41 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
79
90
this . _extensions = extensions ?. map ( ( extension ) => `.${ extension } ` ) ;
80
91
}
81
92
93
+ #getPreviewElementAlias( ) {
94
+ const previews = this . #previewers. getValue ( ) ;
95
+ const fallbackAlias = previews . find ( ( preview ) => ! preview . forMimeTypes ?. length ) ?. alias ?? '' ;
96
+
97
+ const mimeType = this . #getMimeTypeFromPath( this . _src ) ;
98
+ if ( ! mimeType ) return fallbackAlias ;
99
+
100
+ const manifest = previews . find ( ( preview ) => {
101
+ return preview . forMimeTypes ?. find ( ( type ) => {
102
+ if ( mimeType === type ) preview . alias ;
103
+
104
+ const snippet = type . replace ( '*' , '' ) ;
105
+ if ( mimeType . startsWith ( snippet ) ) return preview . alias ;
106
+ if ( mimeType . endsWith ( snippet ) ) return preview . alias ;
107
+ return undefined ;
108
+ } ) ;
109
+ } ) ;
110
+
111
+ if ( manifest ) return manifest . alias ;
112
+ return fallbackAlias ;
113
+ }
114
+
115
+ #getMimeTypeFromPath( path : string ) {
116
+ // Extract the the MIME type from the data url
117
+ if ( path . startsWith ( 'data:' ) ) {
118
+ const mimeType = path . substring ( 5 , path . indexOf ( ';' ) ) ;
119
+ return mimeType ;
120
+ }
121
+
122
+ // Extract the file extension from the path
123
+ const extension = path . split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
124
+ if ( ! extension ) return null ;
125
+ return getMimeTypeFromExtension ( '.' + extension ) ;
126
+ }
127
+
82
128
async #onUpload( e : UUIFileDropzoneEvent ) {
83
129
//Property Editor for Upload field will always only have one file.
84
130
const item : UmbTemporaryFileModel = {
@@ -90,7 +136,7 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
90
136
91
137
const reader = new FileReader ( ) ;
92
138
reader . onload = ( ) => {
93
- this . _src = reader . result as string ;
139
+ this . src = reader . result as string ;
94
140
} ;
95
141
reader . readAsDataURL ( item . file ) ;
96
142
@@ -108,7 +154,11 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
108
154
}
109
155
110
156
override render ( ) {
111
- return html `${ this . _src ? this . #renderFile( this . _src , this . temporaryFile ?. file ) : this . #renderDropzone( ) } ` ;
157
+ if ( this . src && this . _previewAlias ) {
158
+ return this . #renderFile( this . src , this . _previewAlias , this . temporaryFile ?. file ) ;
159
+ } else {
160
+ return this . #renderDropzone( ) ;
161
+ }
112
162
}
113
163
114
164
#renderDropzone( ) {
@@ -124,89 +174,23 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
124
174
` ;
125
175
}
126
176
127
- #renderFile( src : string , file ?: File ) {
128
- const extension = this . #getFileExtensionFromPath( src ) ;
129
- const element = this . #getElementFromFilePath( src ) ;
130
- console . log ( 'element' , element ) ;
131
-
177
+ #renderFile( src : string , previewAlias : string , file ?: File ) {
178
+ if ( ! previewAlias ) return 'An error occurred. No previewer found for the file type.' ;
132
179
return html `
133
180
<div id= "wrapper" >
134
181
<div style= "position:relative; display: flex; width: fit-content; max-width: 100%" >
135
- ${ getElementTemplate ( ) }
182
+ <umb- extension- slot
183
+ type= "fileUploadPreview"
184
+ .props = ${ { path : src , file : file } }
185
+ .filter = ${ ( manifest : ManifestFileUploadPreview ) => manifest . alias === previewAlias } >
186
+ </ umb- extension- slot>
136
187
${ this . temporaryFile ?. status === TemporaryFileStatus . WAITING
137
188
? html `<umb- tempor ary- file-badge> </ umb- tempor ary- file-badge> `
138
189
: nothing }
139
190
</ div>
140
191
</ div>
141
192
${ this . #renderButtonRemove( ) }
142
193
` ;
143
-
144
- /**
145
- * @returns {string } The template for the file extension.
146
- */
147
- function getElementTemplate ( ) {
148
- switch ( extension ) {
149
- case 'audio' :
150
- return html `<umb- input- upload- field- audio .path = ${ src } > </ umb- input- upload- field- audio> ` ;
151
- case 'video' :
152
- return html `<umb- input- upload- field- video .path = ${ src } > </ umb- input- upload- field- video> ` ;
153
- case 'image' :
154
- return html `<umb- input- upload- field- image .path = ${ src } > </ umb- input- upload- field- image> ` ;
155
- case 'svg' :
156
- return html `<umb- input- upload- field- svg .path = ${ src } > </ umb- input- upload- field- svg> ` ;
157
- default :
158
- return html `<umb- input- upload- field- file .path = ${ src } .file = ${ file } > </ umb- input- upload- field- file> ` ;
159
- }
160
- }
161
- }
162
-
163
- #getElementFromFilePath( path : string ) {
164
- const previews = this . #previewers. getValue ( ) ;
165
- const fallbackElement = previews . find ( ( preview ) => ! preview . forMimeTypes ?. length ) ?. element ;
166
-
167
- // Extract the the MIME type from the data url and get corresponding previewer.
168
- if ( path . startsWith ( 'data:' ) ) {
169
- const mimeType = path . substring ( 5 , path . indexOf ( ';' ) ) ;
170
-
171
- const manifest = previews . find ( ( preview ) => {
172
- return preview . forMimeTypes ?. find ( ( type ) => {
173
- const snippet = type . replace ( '*' , '' ) ;
174
- if ( mimeType . startsWith ( snippet ) ) return preview ;
175
- if ( mimeType . endsWith ( snippet ) ) return preview ;
176
- return undefined ;
177
- } ) ;
178
- } ) ;
179
-
180
- if ( manifest ) return manifest . element ;
181
- return fallbackElement ;
182
- }
183
-
184
- // Extract the file extension from the path
185
- const extension = path . split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
186
- if ( ! extension ) return fallbackElement ;
187
-
188
- return fallbackElement ;
189
- }
190
-
191
- #getFileExtensionFromPath( path : string ) : 'audio' | 'video' | 'image' | 'svg' | 'file' {
192
- // Extract the MIME type from the data URL
193
- if ( path . startsWith ( 'data:' ) ) {
194
- const mimeType = path . substring ( 5 , path . indexOf ( ';' ) ) ;
195
- if ( mimeType === 'image/svg+xml' ) return 'svg' ;
196
- if ( mimeType . startsWith ( 'image/' ) ) return 'image' ;
197
- if ( mimeType . startsWith ( 'audio/' ) ) return 'audio' ;
198
- if ( mimeType . startsWith ( 'video/' ) ) return 'video' ;
199
- }
200
-
201
- // Extract the file extension from the path
202
- const extension = path . split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
203
- if ( ! extension ) return 'file' ;
204
- if ( [ 'svg' ] . includes ( extension ) ) return 'svg' ;
205
- if ( [ 'mp3' , 'weba' , 'oga' , 'opus' ] . includes ( extension ) ) return 'audio' ;
206
- if ( [ 'mp4' , 'mov' , 'webm' , 'ogv' ] . includes ( extension ) ) return 'video' ;
207
- if ( [ 'jpg' , 'jpeg' , 'png' , 'gif' ] . includes ( extension ) ) return 'image' ;
208
-
209
- return 'file' ;
210
194
}
211
195
212
196
#renderButtonRemove( ) {
@@ -216,7 +200,7 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
216
200
}
217
201
218
202
#handleRemove( ) {
219
- this . _src = '' ;
203
+ this . src = '' ;
220
204
this . temporaryFile = undefined ;
221
205
this . dispatchEvent ( new UmbChangeEvent ( ) ) ;
222
206
}
0 commit comments