@uploadcare/file-uploader 1.15.0-alpha.13 → 1.15.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,21 +1,6 @@
1
- export class FileItem extends UploaderBlock {
2
- /** @private */
3
- private _entrySubs;
4
- /**
5
- * @private
6
- * @type {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData | null}
7
- */
8
- private _entry;
1
+ export class FileItem extends FileItemConfig {
9
2
  /** @private */
10
3
  private _renderedOnce;
11
- /**
12
- * @private
13
- * @template {any[]} A
14
- * @template {(entry: import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData, ...args: A) => any} T
15
- * @param {T} fn
16
- * @returns {(...args: A) => ReturnType<T>}
17
- */
18
- private _withEntry;
19
4
  init$: {
20
5
  uid: string;
21
6
  itemName: string;
@@ -62,12 +47,6 @@ export class FileItem extends UploaderBlock {
62
47
  private _calculateState;
63
48
  /** @private */
64
49
  private _debouncedCalculateState;
65
- /**
66
- * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
67
- * @param {K} prop_
68
- * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler_
69
- */
70
- _subEntry: (prop_: K, handler_: (value: import("../../abstract/uploadEntrySchema.js").UploadEntryData[K]) => void) => void;
71
50
  _updateHint: (...args: any[]) => void;
72
51
  /**
73
52
  * @private
@@ -92,5 +71,5 @@ export namespace FileItem {
92
71
  let template: string;
93
72
  let activeInstances: Set<any>;
94
73
  }
95
- import { UploaderBlock } from '../../abstract/UploaderBlock.js';
74
+ import { FileItemConfig } from './FileItemConfig.js';
96
75
  //# sourceMappingURL=FileItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileItem.d.ts","sourceRoot":"","sources":["FileItem.js"],"names":[],"mappings":"AAiBA;IAIE,eAAe;IACf,mBAAuB;IACvB;;;OAGG;IACH,eAAc;IAEd,eAAe;IACf,sBAAsB;IAEtB;;;;;;OAMG;IACH,mBAYC;IAKC;;;;;;;;;;;;;;;;;;;;;;;+CAvCS,gBAAU;mCAIjB,gBAAU;6BAImB,2BAA2B;;wCAS5C,wCACE;;;;;;MAoDf;IAGH,eAQC;IAED;;;OAGG;IACH,0BAUC;IAPC,qCAA2C;IAC3C,wCAA0C;IAQ5C,eAAe;IACf,wBAYG;IAEH,eAAe;IACf,iCAA0E;IAE1E;;;;OAIG;IACH,YAAa,OAHF,CAGO,EAAE,UAFT,CAAC,KAAK,EAAE,OAAO,qCAAqC,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAE5D,UAgBP;IAErB,sCAeE;IAEF;;;OAGG;IACH,uBAiCC;IAyDD,uCA+BE;IAaA,eAAe;IACf,kBAEE;IAUJ;;;MAEC;IAED;;;OAGG;IACH,uBAEC;IAED,0CAqGG;CACJ;;;;;8BAnb6B,iCAAiC"}
1
+ {"version":3,"file":"FileItem.d.ts","sourceRoot":"","sources":["FileItem.js"],"names":[],"mappings":"AAiBA;IAIE,eAAe;IACf,sBAAsB;IAKpB;;;;;;;;;;;;;;;;;;;;;;;+CAVoB,gBAAU;mCAIlB,gBACR;6BAMM,2BAET;;wCAMC,wCACK;;;;;;MAqBN;IAGH,eAQC;IAED;;;OAGG;IACH,0BAUC;IAPC,qCAA2C;IAC3C,wCAA0C;IAQ5C,eAAe;IACf,wBAYG;IAEH,eAAe;IACf,iCAA0E;IAE1E,sCAeE;IAEF;;;OAGG;IACH,uBAiCC;IAyDD,uCA+BE;IAaA,eAAe;IACf,kBAEE;IAUJ;;;MAEC;IAED;;;OAGG;IACH,uBAEC;IAED,0CAqGG;CACJ;;;;;+BA3X8B,qBAAqB"}
@@ -2,11 +2,11 @@
2
2
  import { shrinkFile } from '@uploadcare/image-shrink';
3
3
  import { CancelError, UploadcareError, uploadFile } from '@uploadcare/upload-client';
4
4
  import { ActivityBlock } from '../../abstract/ActivityBlock.js';
5
- import { UploaderBlock } from '../../abstract/UploaderBlock.js';
6
5
  import { debounce } from '../utils/debounce.js';
7
6
  import { parseShrink } from '../../utils/parseShrink.js';
8
7
  import { UploadSource } from '../utils/UploadSource.js';
9
8
  import { throttle } from '../utils/throttle.js';
9
+ import { FileItemConfig } from './FileItemConfig.js';
10
10
 
11
11
  const FileItemState = Object.freeze({
12
12
  FINISHED: Symbol('FINISHED'),
@@ -15,42 +15,13 @@ const FileItemState = Object.freeze({
15
15
  IDLE: Symbol('IDLE'),
16
16
  });
17
17
 
18
- export class FileItem extends UploaderBlock {
18
+ export class FileItem extends FileItemConfig {
19
19
  couldBeCtxOwner = true;
20
20
  pauseRender = true;
21
21
 
22
- /** @private */
23
- _entrySubs = new Set();
24
- /**
25
- * @private
26
- * @type {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData | null}
27
- */
28
- _entry = null;
29
-
30
22
  /** @private */
31
23
  _renderedOnce = false;
32
24
 
33
- /**
34
- * @private
35
- * @template {any[]} A
36
- * @template {(entry: import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData, ...args: A) => any} T
37
- * @param {T} fn
38
- * @returns {(...args: A) => ReturnType<T>}
39
- */
40
- _withEntry(fn) {
41
- const wrapperFn = /** @type {(...args: A) => ReturnType<T>} */ (
42
- (...args) => {
43
- const entry = this._entry;
44
- if (!entry) {
45
- console.warn('No entry found');
46
- return;
47
- }
48
- return fn(entry, ...args);
49
- }
50
- );
51
- return wrapperFn;
52
- }
53
-
54
25
  constructor() {
55
26
  super();
56
27
 
@@ -132,29 +103,6 @@ export class FileItem extends UploaderBlock {
132
103
  /** @private */
133
104
  _debouncedCalculateState = debounce(this._calculateState.bind(this), 100);
134
105
 
135
- /**
136
- * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
137
- * @param {K} prop_
138
- * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler_
139
- */
140
- _subEntry = (prop_, handler_) =>
141
- this._withEntry(
142
- /**
143
- * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
144
- * @param {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData} entry
145
- * @param {K} prop
146
- * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler
147
- */
148
- (entry, prop, handler) => {
149
- let sub = entry.subscribe(prop, (value) => {
150
- if (this.isConnected) {
151
- handler(value);
152
- }
153
- });
154
- this._entrySubs.add(sub);
155
- },
156
- )(prop_, handler_);
157
-
158
106
  _updateHint = this._withEntry(
159
107
  throttle((entry) => {
160
108
  const source = entry.getValue('source');
@@ -0,0 +1,26 @@
1
+ export class FileItemConfig extends UploaderBlock {
2
+ /** @protected */
3
+ protected _entrySubs: Set<any>;
4
+ /**
5
+ * @type {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData | null}
6
+ * @protected
7
+ */
8
+ protected _entry: import("../../abstract/uploadEntrySchema.js").UploadEntryTypedData | null;
9
+ /**
10
+ * @template {any[]} A
11
+ * @template {(entry: import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData, ...args: A) => any} T
12
+ * @param {T} fn
13
+ * @returns {(...args: A) => ReturnType<T>}
14
+ * @protected
15
+ */
16
+ protected _withEntry<A extends any[], T extends (entry: import("../../abstract/uploadEntrySchema.js").UploadEntryTypedData, ...args: A) => any>(fn: T): (...args: A) => ReturnType<T>;
17
+ /**
18
+ * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
19
+ * @param {K} prop_
20
+ * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler_
21
+ * @protected
22
+ */
23
+ protected _subEntry: (prop_: K, handler_: (value: import("../../abstract/uploadEntrySchema.js").UploadEntryData[K]) => void) => void;
24
+ }
25
+ import { UploaderBlock } from '../../abstract/UploaderBlock.js';
26
+ //# sourceMappingURL=FileItemConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileItemConfig.d.ts","sourceRoot":"","sources":["FileItemConfig.js"],"names":[],"mappings":"AAIA;IACE,iBAAiB;IACjB,+BAAuB;IAEvB;;;OAGG;IACH,kBAHU,OAAO,qCAAqC,EAAE,oBAAoB,GAAG,IAAI,CAGrE;IAEd;;;;;;OAMG;IACH,qBANqB,CAAC,SAAR,GAAG,EAAG,EAC0F,CAAC,SAAlG,CAAE,KAAK,EAAE,OAAO,qCAAqC,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,GAAI,MAClG,CAAC,GACC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAezC;IAED;;;;;OAKG;IACH,sBAAa,OAJF,CAIO,EAAE,UAHT,CAAC,KAAK,EAAE,OAAO,qCAAqC,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAG5D,UAgBP;CAMtB;8BA7D6B,iCAAiC"}
@@ -0,0 +1,64 @@
1
+ //@ts-check
2
+
3
+ import { UploaderBlock } from '../../abstract/UploaderBlock.js';
4
+
5
+ export class FileItemConfig extends UploaderBlock {
6
+ /** @protected */
7
+ _entrySubs = new Set();
8
+
9
+ /**
10
+ * @type {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData | null}
11
+ * @protected
12
+ */
13
+ _entry = null;
14
+
15
+ /**
16
+ * @template {any[]} A
17
+ * @template {(entry: import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData, ...args: A) => any} T
18
+ * @param {T} fn
19
+ * @returns {(...args: A) => ReturnType<T>}
20
+ * @protected
21
+ */
22
+ _withEntry(fn) {
23
+ const wrapperFn = /** @type {(...args: A) => ReturnType<T>} */ (
24
+ (...args) => {
25
+ const entry = this._entry;
26
+ if (!entry) {
27
+ console.warn('No entry found');
28
+ return;
29
+ }
30
+ return fn(entry, ...args);
31
+ }
32
+ );
33
+ return wrapperFn;
34
+ }
35
+
36
+ /**
37
+ * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
38
+ * @param {K} prop_
39
+ * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler_
40
+ * @protected
41
+ */
42
+ _subEntry = (prop_, handler_) =>
43
+ this._withEntry(
44
+ /**
45
+ * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
46
+ * @param {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData} entry
47
+ * @param {K} prop
48
+ * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler
49
+ */
50
+ (entry, prop, handler) => {
51
+ let sub = entry.subscribe(prop, (value) => {
52
+ if (this.isConnected) {
53
+ handler(value);
54
+ }
55
+ });
56
+ this._entrySubs.add(sub);
57
+ },
58
+ )(prop_, handler_);
59
+
60
+ disconnectedCallback() {
61
+ super.disconnectedCallback();
62
+ this._entrySubs = new Set();
63
+ }
64
+ }
@@ -1,31 +1,12 @@
1
- export class Thumb extends UploaderBlock {
1
+ export class Thumb extends FileItemConfig {
2
2
  /** @private */
3
- private _entrySubs;
4
- /**
5
- * @private
6
- * @type {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData | null}
7
- */
8
- private _entry;
3
+ private _renderedGridOnce;
9
4
  /**
10
5
  * @private
11
6
  * @type {IntersectionObserverEntry['boundingClientRect'] | null}
12
7
  */
13
8
  private _thumbRect;
14
9
  _isIntersecting: boolean;
15
- /**
16
- * @private
17
- * @template {any[]} A
18
- * @template {(entry: import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData, ...args: A) => any} T
19
- * @param {T} fn
20
- * @returns {(...args: A) => ReturnType<T>}
21
- */
22
- private _withEntry;
23
- /**
24
- * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
25
- * @param {K} prop_
26
- * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler_
27
- */
28
- _subEntry: (prop_: K, handler_: (value: import("../../abstract/uploadEntrySchema.js").UploadEntryData[K]) => void) => void;
29
10
  init$: {
30
11
  thumbUrl: string;
31
12
  badgeIcon: string;
@@ -44,7 +25,9 @@ export class Thumb extends UploaderBlock {
44
25
  '*historyBack': null;
45
26
  '*closeModal': () => void;
46
27
  };
47
- _calculateThumbSize(): number;
28
+ /** @param {string} imageUrl */
29
+ loadImage(imageUrl: string): Promise<any>;
30
+ _calculateThumbSize(force?: boolean): number;
48
31
  /** @private */
49
32
  private _generateThumbnail;
50
33
  _debouncedGenerateThumb: ((...args: any[]) => Promise<void>) & {
@@ -60,5 +43,5 @@ export class Thumb extends UploaderBlock {
60
43
  export namespace Thumb {
61
44
  let template: string;
62
45
  }
63
- import { UploaderBlock } from '../../abstract/UploaderBlock.js';
46
+ import { FileItemConfig } from '../FileItem/FileItemConfig.js';
64
47
  //# sourceMappingURL=Thumb.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Thumb.d.ts","sourceRoot":"","sources":["Thumb.js"],"names":[],"mappings":"AAQA;IACE,eAAe;IACf,mBAAuB;IAEvB;;;OAGG;IACH,eAAc;IAEd;;;OAGG;IACH,mBAAkB;IAElB,yBAAwB;IAExB;;;;;;OAMG;IACH,mBAYC;IAED;;;;OAIG;IACH,YAAa,OAHF,CAGO,EAAE,UAFT,CAAC,KAAK,EAAE,OAAO,qCAAqC,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAE5D,UAgBP;IAKnB;;;;;;;+CAnDI,gBAAU;mCAOf,gBAAQ;6BAAmF,2BACvF;;wCAI0C,wCAC3C;;;;;;MA2CD;IAGH,8BAYC;IAED,eAAe;IACf,2BAuCG;IAEH;;MAA4E;IAE5E;;;OAGG;IACH,0BAaC;IAqCC,4CAAuG;CAY1G;;;;8BA3M6B,iCAAiC"}
1
+ {"version":3,"file":"Thumb.d.ts","sourceRoot":"","sources":["Thumb.js"],"names":[],"mappings":"AAQA;IACE,eAAe;IACf,0BAA0B;IAE1B;;;OAGG;IACH,mBAAkB;IAElB,yBAAwB;IAKtB;;;;;;;+CAEU,gBACV;mCAMF,gBAAQ;6BAEa,2BACJ;;wCAKH,wCACD;;;;;;MAbV;IAGH,+BAA+B;IAC/B,oBADY,MAAM,gBAgBjB;IAED,6CAgBC;IAED,eAAe;IACf,2BA2CG;IAEH;;MAA4E;IAE5E;;;OAGG;IACH,0BAaC;IA4CC,4CAAuG;CAY1G;;;;+BAzL8B,+BAA+B"}
@@ -1,20 +1,14 @@
1
1
  //@ts-check
2
2
 
3
- import { UploaderBlock } from '../../abstract/UploaderBlock.js';
4
3
  import { createCdnUrl, createCdnUrlModifiers, createOriginalUrl } from '../../utils/cdn-utils.js';
4
+ import { FileItemConfig } from '../FileItem/FileItemConfig.js';
5
5
  import { fileCssBg } from '../svg-backgrounds/svg-backgrounds.js';
6
6
  import { debounce } from '../utils/debounce.js';
7
7
  import { generateThumb } from '../utils/resizeImage.js';
8
8
 
9
- export class Thumb extends UploaderBlock {
9
+ export class Thumb extends FileItemConfig {
10
10
  /** @private */
11
- _entrySubs = new Set();
12
-
13
- /**
14
- * @private
15
- * @type {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData | null}
16
- */
17
- _entry = null;
11
+ _renderedGridOnce = false;
18
12
 
19
13
  /**
20
14
  * @private
@@ -24,50 +18,6 @@ export class Thumb extends UploaderBlock {
24
18
 
25
19
  _isIntersecting = false;
26
20
 
27
- /**
28
- * @private
29
- * @template {any[]} A
30
- * @template {(entry: import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData, ...args: A) => any} T
31
- * @param {T} fn
32
- * @returns {(...args: A) => ReturnType<T>}
33
- */
34
- _withEntry(fn) {
35
- const wrapperFn = /** @type {(...args: A) => ReturnType<T>} */ (
36
- (...args) => {
37
- const entry = this._entry;
38
- if (!entry) {
39
- console.warn('No entry found');
40
- return;
41
- }
42
- return fn(entry, ...args);
43
- }
44
- );
45
- return wrapperFn;
46
- }
47
-
48
- /**
49
- * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
50
- * @param {K} prop_
51
- * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler_
52
- */
53
- _subEntry = (prop_, handler_) =>
54
- this._withEntry(
55
- /**
56
- * @template {import('../../abstract/uploadEntrySchema.js').UploadEntryKeys} K
57
- * @param {import('../../abstract/uploadEntrySchema.js').UploadEntryTypedData} entry
58
- * @param {K} prop
59
- * @param {(value: import('../../abstract/uploadEntrySchema.js').UploadEntryData[K]) => void} handler
60
- */
61
- (entry, prop, handler) => {
62
- let sub = entry.subscribe(prop, (value) => {
63
- if (this.isConnected) {
64
- handler(value);
65
- }
66
- });
67
- this._entrySubs.add(sub);
68
- },
69
- )(prop_, handler_);
70
-
71
21
  constructor() {
72
22
  super();
73
23
 
@@ -79,7 +29,29 @@ export class Thumb extends UploaderBlock {
79
29
  };
80
30
  }
81
31
 
82
- _calculateThumbSize() {
32
+ /** @param {string} imageUrl */
33
+ loadImage(imageUrl) {
34
+ return new Promise((resolve, reject) => {
35
+ const img = new Image();
36
+ img.onload = () => {
37
+ this.set$({ thumbUrl: `url(${imageUrl})` });
38
+ resolve(true);
39
+ img.remove();
40
+ };
41
+ img.onerror = () => {
42
+ console.error('Failed to load image:', imageUrl);
43
+ reject(new Error(`Failed to load image: ${imageUrl}`));
44
+ img.remove();
45
+ };
46
+ img.src = imageUrl;
47
+ });
48
+ }
49
+
50
+ _calculateThumbSize(force = false) {
51
+ if (force) {
52
+ this._thumbRect = this.getBoundingClientRect();
53
+ }
54
+
83
55
  let size = Math.max(
84
56
  parseInt(String(this?._thumbRect?.height || 0)),
85
57
  parseInt(String(this?._thumbRect?.width || 0)),
@@ -94,11 +66,11 @@ export class Thumb extends UploaderBlock {
94
66
  }
95
67
 
96
68
  /** @private */
97
- _generateThumbnail = this._withEntry(async (entry) => {
69
+ _generateThumbnail = this._withEntry(async (entry, force = false) => {
98
70
  const fileInfo = entry.getValue('fileInfo');
99
71
  const isImage = entry.getValue('isImage');
100
72
  const uuid = entry.getValue('uuid');
101
- let size = this._calculateThumbSize();
73
+ let size = this._calculateThumbSize(force);
102
74
 
103
75
  if (fileInfo && isImage && uuid) {
104
76
  let thumbUrl = await this.proxyUrl(
@@ -107,11 +79,15 @@ export class Thumb extends UploaderBlock {
107
79
  createCdnUrlModifiers(entry.getValue('cdnUrlModifiers'), `scale_crop/${size}x${size}/center`),
108
80
  ),
109
81
  );
110
- let currentThumbUrl = entry.getValue('thumbUrl');
111
- if (currentThumbUrl !== thumbUrl) {
112
- entry.setValue('thumbUrl', thumbUrl);
113
- currentThumbUrl?.startsWith('blob:') && URL.revokeObjectURL(currentThumbUrl);
114
- }
82
+
83
+ this.loadImage(thumbUrl).then(() => {
84
+ let currentThumbUrl = entry.getValue('thumbUrl');
85
+ if (currentThumbUrl !== thumbUrl) {
86
+ entry.setValue('thumbUrl', thumbUrl);
87
+ currentThumbUrl?.startsWith('blob:') && URL.revokeObjectURL(currentThumbUrl);
88
+ }
89
+ });
90
+
115
91
  return;
116
92
  }
117
93
 
@@ -185,6 +161,13 @@ export class Thumb extends UploaderBlock {
185
161
  }
186
162
  });
187
163
 
164
+ this.subConfigValue('filesViewMode', (viewMode) => {
165
+ if (!this._renderedGridOnce && viewMode === 'grid') {
166
+ this._debouncedGenerateThumb(true);
167
+ this._renderedGridOnce = true;
168
+ }
169
+ });
170
+
188
171
  this.setAttribute('role', 'img');
189
172
  }
190
173
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uploadcare/file-uploader",
3
- "version": "1.15.0-alpha.13",
3
+ "version": "1.15.0-alpha.15",
4
4
  "description": "Building blocks for Uploadcare products integration",
5
5
  "keywords": [
6
6
  "web components",