@uploadcare/file-uploader 1.10.0 → 1.11.0-alpha.0
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.
- package/blocks/CameraSource/CameraSource.d.ts.map +1 -1
- package/blocks/CameraSource/CameraSource.js +0 -2
- package/blocks/CameraSource/camera-source.css +4 -15
- package/blocks/CloudImageEditorActivity/index.css +3 -3
- package/blocks/Config/initialConfig.d.ts +1 -1
- package/blocks/Config/initialConfig.d.ts.map +1 -1
- package/blocks/Config/initialConfig.js +1 -1
- package/blocks/ExternalSource/ExternalSource.d.ts +20 -50
- package/blocks/ExternalSource/ExternalSource.d.ts.map +1 -1
- package/blocks/ExternalSource/ExternalSource.js +96 -99
- package/blocks/ExternalSource/MessageBridge.d.ts +20 -0
- package/blocks/ExternalSource/MessageBridge.d.ts.map +1 -0
- package/blocks/ExternalSource/MessageBridge.js +71 -0
- package/blocks/ExternalSource/buildThemeDefinition.d.ts +3 -0
- package/blocks/ExternalSource/buildThemeDefinition.d.ts.map +1 -0
- package/blocks/ExternalSource/buildThemeDefinition.js +47 -0
- package/blocks/ExternalSource/external-source.css +37 -22
- package/blocks/ExternalSource/types.d.ts +113 -0
- package/blocks/ExternalSource/types.d.ts.map +1 -0
- package/blocks/ExternalSource/types.js +143 -0
- package/blocks/Modal/Modal.d.ts.map +1 -1
- package/blocks/Modal/Modal.js +4 -11
- package/blocks/Modal/modal.css +3 -54
- package/blocks/StartFrom/start-from.css +2 -6
- package/blocks/UploadList/upload-list.css +1 -11
- package/blocks/UrlSource/url-source.css +0 -8
- package/blocks/themes/uc-basic/theme.css +3 -3
- package/env.d.ts +1 -1
- package/env.d.ts.map +1 -1
- package/env.js +1 -1
- package/index.ssr.d.ts +1 -1
- package/index.ssr.d.ts.map +1 -1
- package/index.ssr.js +7 -11
- package/locales/file-uploader/en.d.ts +2 -0
- package/locales/file-uploader/en.js +3 -1
- package/package.json +4 -2
- package/web/file-uploader.iife.min.js +4 -4
- package/web/file-uploader.min.js +4 -4
- package/web/uc-basic.min.css +1 -1
- package/web/uc-cloud-image-editor.min.css +1 -1
- package/web/uc-cloud-image-editor.min.js +1 -1
- package/web/uc-file-uploader-inline.min.css +1 -1
- package/web/uc-file-uploader-inline.min.js +4 -4
- package/web/uc-file-uploader-minimal.min.css +1 -1
- package/web/uc-file-uploader-minimal.min.js +2 -2
- package/web/uc-file-uploader-regular.min.css +1 -1
- package/web/uc-file-uploader-regular.min.js +4 -4
- package/web/uc-img.min.js +1 -1
- package/blocks/ExternalSource/buildStyles.d.ts +0 -27
- package/blocks/ExternalSource/buildStyles.d.ts.map +0 -1
- package/blocks/ExternalSource/buildStyles.js +0 -133
- package/blocks/ExternalSource/messages.d.ts +0 -3
- package/blocks/ExternalSource/messages.d.ts.map +0 -1
- package/blocks/ExternalSource/messages.js +0 -35
- package/locales/file-uploader/fi.d.ts +0 -120
- package/locales/file-uploader/fi.d.ts.map +0 -1
- package/locales/file-uploader/fi.js +0 -120
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CameraSource.d.ts","sourceRoot":"","sources":["CameraSource.js"],"names":[],"mappings":"AAMA;IAEE,uBAA+C;IAE/C,eAAe;IACf,0BAAyB;IAEzB,WA0BE;IAbE,qBAAqB;IACrB,sCAAuC;IAc3C,eAAe;IACf,oBAKE;IAEF,eAAe;IACf,sBAME;IAEF,eAAe;IACf,iCAEE;IAEF;;;OAGG;IACH,
|
|
1
|
+
{"version":3,"file":"CameraSource.d.ts","sourceRoot":"","sources":["CameraSource.js"],"names":[],"mappings":"AAMA;IAEE,uBAA+C;IAE/C,eAAe;IACf,0BAAyB;IAEzB,WA0BE;IAbE,qBAAqB;IACrB,sCAAuC;IAc3C,eAAe;IACf,oBAKE;IAEF,eAAe;IACf,sBAME;IAEF,eAAe;IACf,iCAEE;IAEF;;;OAGG;IACH,6BAyBQ;IAER,eAAe;IACf,8BASC;IAED,eAAe;IACf,iBAuCC;IAnBC,eAAe;IACf,gBAA+C;IAC/C,eAAe;IACf,aAAyC;IASvC,eAAe;IACf,mBAAsB;IAQ1B,eAAe;IACf,qBAMC;IAED,eAAe;IACf,cAkBC;IAED,8BAgCC;CACF;;;;8BAnN6B,iCAAiC"}
|
|
@@ -66,8 +66,6 @@ export class CameraSource extends UploaderBlock {
|
|
|
66
66
|
* @param {'granted' | 'denied' | 'prompt'} state
|
|
67
67
|
*/
|
|
68
68
|
_setPermissionsState = debounce((state) => {
|
|
69
|
-
this.classList.toggle('uc-initialized', state === 'granted');
|
|
70
|
-
|
|
71
69
|
if (state === 'granted') {
|
|
72
70
|
this.set$({
|
|
73
71
|
videoHidden: false,
|
|
@@ -10,21 +10,9 @@ uc-camera-source {
|
|
|
10
10
|
border-radius: var(--uc-radius);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
[uc-modal] uc-camera-source {
|
|
14
|
-
width:
|
|
15
|
-
height:
|
|
16
|
-
max-height: var(--modal-max-content-height);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
uc-camera-source.uc-initialized {
|
|
20
|
-
height: max-content;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
@media only screen and (max-width: 430px) {
|
|
24
|
-
uc-camera-source {
|
|
25
|
-
width: calc(100vw - var(--uc-padding) * 2);
|
|
26
|
-
height: var(--modal-content-height-fill, 100%);
|
|
27
|
-
}
|
|
13
|
+
[uc-modal] > dialog:has(uc-camera-source[active]) {
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 100%;
|
|
28
16
|
}
|
|
29
17
|
|
|
30
18
|
uc-camera-source video {
|
|
@@ -52,6 +40,7 @@ uc-camera-source .uc-content {
|
|
|
52
40
|
flex: 1;
|
|
53
41
|
justify-content: center;
|
|
54
42
|
width: 100%;
|
|
43
|
+
height: 100%;
|
|
55
44
|
padding: var(--uc-padding);
|
|
56
45
|
padding-top: 0;
|
|
57
46
|
overflow: hidden;
|
|
@@ -7,7 +7,7 @@ uc-cloud-image-editor-activity {
|
|
|
7
7
|
background-color: var(--uc-background);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
[uc-modal] uc-cloud-image-editor-activity {
|
|
11
|
-
width:
|
|
12
|
-
height:
|
|
10
|
+
[uc-modal] > dialog:has(uc-cloud-image-editor-activity[active]) {
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
13
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const DEFAULT_CDN_CNAME: "https://ucarecdn.com";
|
|
2
2
|
export const DEFAULT_BASE_URL: "https://upload.uploadcare.com";
|
|
3
|
-
export const DEFAULT_SOCIAL_BASE_URL: "https://social.uploadcare.com";
|
|
3
|
+
export const DEFAULT_SOCIAL_BASE_URL: "https://social.staging0.uploadcare.com";
|
|
4
4
|
/** @type {import('../../types/exported').ConfigType} */
|
|
5
5
|
export const initialConfig: import('../../types/exported').ConfigType;
|
|
6
6
|
//# sourceMappingURL=initialConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialConfig.d.ts","sourceRoot":"","sources":["initialConfig.js"],"names":[],"mappings":"AAKA,uDAAwD;AACxD,+DAAgE;AAChE
|
|
1
|
+
{"version":3,"file":"initialConfig.d.ts","sourceRoot":"","sources":["initialConfig.js"],"names":[],"mappings":"AAKA,uDAAwD;AACxD,+DAAgE;AAChE,+EAAgF;AAEhF,wDAAwD;AACxD,4BADW,OAAO,sBAAsB,EAAE,UAAU,CA2DlD"}
|
|
@@ -5,7 +5,7 @@ import { serializeCsv } from '../utils/comma-separated.js';
|
|
|
5
5
|
|
|
6
6
|
export const DEFAULT_CDN_CNAME = 'https://ucarecdn.com';
|
|
7
7
|
export const DEFAULT_BASE_URL = 'https://upload.uploadcare.com';
|
|
8
|
-
export const DEFAULT_SOCIAL_BASE_URL = 'https://social.uploadcare.com';
|
|
8
|
+
export const DEFAULT_SOCIAL_BASE_URL = 'https://social.staging0.uploadcare.com';
|
|
9
9
|
|
|
10
10
|
/** @type {import('../../types/exported').ConfigType} */
|
|
11
11
|
export const initialConfig = {
|
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
/** @typedef {{ externalSourceType: string }} ActivityParams */
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {{
|
|
4
|
-
* type: 'file-selected';
|
|
5
|
-
* obj_type: 'selected_file';
|
|
6
|
-
* filename: string;
|
|
7
|
-
* url: string;
|
|
8
|
-
* alternatives?: Record<string, string>;
|
|
9
|
-
* }} SelectedFileMessage
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* @typedef {{
|
|
13
|
-
* type: 'embed-css';
|
|
14
|
-
* style: string;
|
|
15
|
-
* }} EmbedCssMessage
|
|
16
|
-
*/
|
|
17
|
-
/** @typedef {SelectedFileMessage | EmbedCssMessage} Message */
|
|
18
2
|
export class ExternalSource extends UploaderBlock {
|
|
19
3
|
activityType: "external";
|
|
20
4
|
init$: {
|
|
21
5
|
activityIcon: string;
|
|
22
6
|
activityCaption: string;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
7
|
+
/** @type {import('./types.js').InputMessageMap['selected-files-change']['selectedFiles']} */
|
|
8
|
+
selectedList: import('./types.js').InputMessageMap['selected-files-change']['selectedFiles'];
|
|
9
|
+
total: number;
|
|
10
|
+
isSelectionReady: boolean;
|
|
11
|
+
couldSelectAll: boolean;
|
|
12
|
+
couldDeselectAll: boolean;
|
|
13
|
+
showSelectionStatus: boolean;
|
|
14
|
+
counterText: string;
|
|
26
15
|
onDone: () => void;
|
|
27
16
|
onCancel: () => void;
|
|
17
|
+
onSelectAll: () => void;
|
|
18
|
+
onDeselectAll: () => void;
|
|
28
19
|
'*commonProgress': number;
|
|
29
20
|
'*uploadList': never[];
|
|
30
21
|
'*uploadQueue': import("@uploadcare/upload-client").Queue;
|
|
@@ -43,39 +34,30 @@ export class ExternalSource extends UploaderBlock {
|
|
|
43
34
|
get activityParams(): ActivityParams;
|
|
44
35
|
/**
|
|
45
36
|
* @private
|
|
46
|
-
* @
|
|
37
|
+
* @param {NonNullable<import('./types.js').InputMessageMap['selected-files-change']['selectedFiles']>[number]} selectedFile
|
|
47
38
|
*/
|
|
48
|
-
private
|
|
39
|
+
private extractUrlFromSelectedFile;
|
|
49
40
|
/**
|
|
50
41
|
* @private
|
|
51
|
-
* @param {
|
|
42
|
+
* @param {import('./types.js').InputMessageMap['selected-files-change']} message
|
|
52
43
|
*/
|
|
53
|
-
private
|
|
54
|
-
/**
|
|
55
|
-
* @private
|
|
56
|
-
* @param {Message} message
|
|
57
|
-
*/
|
|
58
|
-
private sendMessage;
|
|
59
|
-
/**
|
|
60
|
-
* @private
|
|
61
|
-
* @param {SelectedFileMessage} message
|
|
62
|
-
*/
|
|
63
|
-
private handleFileSelected;
|
|
44
|
+
private handleSelectedFilesChange;
|
|
64
45
|
/** @private */
|
|
65
46
|
private handleIframeLoad;
|
|
66
|
-
/**
|
|
67
|
-
* @private
|
|
68
|
-
* @param {string} propName
|
|
69
|
-
*/
|
|
70
|
-
private getCssValue;
|
|
71
47
|
/** @private */
|
|
72
48
|
private applyStyles;
|
|
73
49
|
/** @private */
|
|
50
|
+
private setupL10n;
|
|
51
|
+
/** @private */
|
|
74
52
|
private remoteUrl;
|
|
75
53
|
/** @private */
|
|
76
54
|
private mountIframe;
|
|
77
55
|
/** @private */
|
|
56
|
+
private _messageBridge;
|
|
57
|
+
/** @private */
|
|
78
58
|
private unmountIframe;
|
|
59
|
+
/** @private */
|
|
60
|
+
private resetSelectionStatus;
|
|
79
61
|
}
|
|
80
62
|
export namespace ExternalSource {
|
|
81
63
|
let template: string;
|
|
@@ -83,17 +65,5 @@ export namespace ExternalSource {
|
|
|
83
65
|
export type ActivityParams = {
|
|
84
66
|
externalSourceType: string;
|
|
85
67
|
};
|
|
86
|
-
export type SelectedFileMessage = {
|
|
87
|
-
type: 'file-selected';
|
|
88
|
-
obj_type: 'selected_file';
|
|
89
|
-
filename: string;
|
|
90
|
-
url: string;
|
|
91
|
-
alternatives?: Record<string, string>;
|
|
92
|
-
};
|
|
93
|
-
export type EmbedCssMessage = {
|
|
94
|
-
type: 'embed-css';
|
|
95
|
-
style: string;
|
|
96
|
-
};
|
|
97
|
-
export type Message = SelectedFileMessage | EmbedCssMessage;
|
|
98
68
|
import { UploaderBlock } from '../../abstract/UploaderBlock.js';
|
|
99
69
|
//# sourceMappingURL=ExternalSource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExternalSource.d.ts","sourceRoot":"","sources":["ExternalSource.js"],"names":[],"mappings":"AAWA,+DAA+D;AAE/D
|
|
1
|
+
{"version":3,"file":"ExternalSource.d.ts","sourceRoot":"","sources":["ExternalSource.js"],"names":[],"mappings":"AAWA,+DAA+D;AAE/D;IAEE,yBAAiD;IAK/C;;;QAKE,6FAA6F;sBAAlF,OAAO,YAAY,EAAE,eAAe,CAAC,uBAAuB,CAAC,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;MA+B1F;IAGH,6BAA6B;IAC7B,qCAMC;IA4CD;;;OAGG;IACH,mCAcC;IAED;;;OAGG;IACH,kCAoBC;IAED,eAAe;IACf,yBAGC;IAED,eAAe;IACf,oBAKC;IAED,eAAe;IACf,kBAKC;IAED,eAAe;IACf,kBAeC;IAED,eAAe;IACf,oBA6BC;IALC,eAAe;IACf,uBAA6D;IAM/D,eAAe;IACf,sBAMC;IAED,eAAe;IACf,6BASC;CACF;;;;6BA7Oa;IAAE,kBAAkB,EAAE,MAAM,CAAA;CAAE;8BAPd,iCAAiC"}
|
|
@@ -5,31 +5,12 @@ import { ActivityBlock } from '../../abstract/ActivityBlock.js';
|
|
|
5
5
|
import { UploaderBlock } from '../../abstract/UploaderBlock.js';
|
|
6
6
|
import { stringToArray } from '../../utils/stringToArray.js';
|
|
7
7
|
import { wildcardRegexp } from '../../utils/wildcardRegexp.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { buildThemeDefinition } from './buildThemeDefinition.js';
|
|
9
|
+
import { MessageBridge } from './MessageBridge.js';
|
|
10
10
|
import { queryString } from './query-string.js';
|
|
11
11
|
|
|
12
12
|
/** @typedef {{ externalSourceType: string }} ActivityParams */
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* @typedef {{
|
|
16
|
-
* type: 'file-selected';
|
|
17
|
-
* obj_type: 'selected_file';
|
|
18
|
-
* filename: string;
|
|
19
|
-
* url: string;
|
|
20
|
-
* alternatives?: Record<string, string>;
|
|
21
|
-
* }} SelectedFileMessage
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @typedef {{
|
|
26
|
-
* type: 'embed-css';
|
|
27
|
-
* style: string;
|
|
28
|
-
* }} EmbedCssMessage
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/** @typedef {SelectedFileMessage | EmbedCssMessage} Message */
|
|
32
|
-
|
|
33
14
|
export class ExternalSource extends UploaderBlock {
|
|
34
15
|
couldBeCtxOwner = true;
|
|
35
16
|
activityType = ActivityBlock.activities.EXTERNAL;
|
|
@@ -41,12 +22,20 @@ export class ExternalSource extends UploaderBlock {
|
|
|
41
22
|
...this.init$,
|
|
42
23
|
activityIcon: '',
|
|
43
24
|
activityCaption: '',
|
|
25
|
+
|
|
26
|
+
/** @type {import('./types.js').InputMessageMap['selected-files-change']['selectedFiles']} */
|
|
44
27
|
selectedList: [],
|
|
45
|
-
|
|
46
|
-
|
|
28
|
+
total: 0,
|
|
29
|
+
|
|
30
|
+
isSelectionReady: false,
|
|
31
|
+
couldSelectAll: false,
|
|
32
|
+
couldDeselectAll: false,
|
|
33
|
+
showSelectionStatus: false,
|
|
34
|
+
counterText: '',
|
|
35
|
+
|
|
47
36
|
onDone: () => {
|
|
48
37
|
for (const message of this.$.selectedList) {
|
|
49
|
-
const url = this.
|
|
38
|
+
const url = this.extractUrlFromSelectedFile(message);
|
|
50
39
|
const { filename } = message;
|
|
51
40
|
const { externalSourceType } = this.activityParams;
|
|
52
41
|
this.api.addFileFromUrl(url, { fileName: filename, source: externalSourceType });
|
|
@@ -57,6 +46,14 @@ export class ExternalSource extends UploaderBlock {
|
|
|
57
46
|
onCancel: () => {
|
|
58
47
|
this.historyBack();
|
|
59
48
|
},
|
|
49
|
+
|
|
50
|
+
onSelectAll: () => {
|
|
51
|
+
this._messageBridge?.send({ type: 'select-all' });
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
onDeselectAll: () => {
|
|
55
|
+
this._messageBridge?.send({ type: 'deselect-all' });
|
|
56
|
+
},
|
|
60
57
|
};
|
|
61
58
|
}
|
|
62
59
|
|
|
@@ -69,12 +66,6 @@ export class ExternalSource extends UploaderBlock {
|
|
|
69
66
|
throw new Error(`External Source activity params not found`);
|
|
70
67
|
}
|
|
71
68
|
|
|
72
|
-
/**
|
|
73
|
-
* @private
|
|
74
|
-
* @type {HTMLIFrameElement | null}
|
|
75
|
-
*/
|
|
76
|
-
_iframe = null;
|
|
77
|
-
|
|
78
69
|
initCallback() {
|
|
79
70
|
super.initCallback();
|
|
80
71
|
this.registerActivity(this.activityType, {
|
|
@@ -108,24 +99,25 @@ export class ExternalSource extends UploaderBlock {
|
|
|
108
99
|
this.unmountIframe();
|
|
109
100
|
}
|
|
110
101
|
});
|
|
111
|
-
this.sub('selectedList', (list) => {
|
|
112
|
-
this.$.counter = list.length;
|
|
113
|
-
});
|
|
114
102
|
this.subConfigValue('multiple', (multiple) => {
|
|
115
|
-
this.$.
|
|
103
|
+
this.$.showSelectionStatus = multiple;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
this.subConfigValue('localeName', (val) => {
|
|
107
|
+
this.setupL10n();
|
|
116
108
|
});
|
|
117
109
|
}
|
|
118
110
|
|
|
119
111
|
/**
|
|
120
112
|
* @private
|
|
121
|
-
* @param {
|
|
113
|
+
* @param {NonNullable<import('./types.js').InputMessageMap['selected-files-change']['selectedFiles']>[number]} selectedFile
|
|
122
114
|
*/
|
|
123
|
-
|
|
124
|
-
if (
|
|
115
|
+
extractUrlFromSelectedFile(selectedFile) {
|
|
116
|
+
if (selectedFile.alternatives) {
|
|
125
117
|
const preferredTypes = stringToArray(this.cfg.externalSourcesPreferredTypes);
|
|
126
118
|
for (const preferredType of preferredTypes) {
|
|
127
119
|
const regexp = wildcardRegexp(preferredType);
|
|
128
|
-
for (const [type, typeUrl] of Object.entries(
|
|
120
|
+
for (const [type, typeUrl] of Object.entries(selectedFile.alternatives)) {
|
|
129
121
|
if (regexp.test(type)) {
|
|
130
122
|
return typeUrl;
|
|
131
123
|
}
|
|
@@ -133,81 +125,71 @@ export class ExternalSource extends UploaderBlock {
|
|
|
133
125
|
}
|
|
134
126
|
}
|
|
135
127
|
|
|
136
|
-
return
|
|
128
|
+
return selectedFile.url;
|
|
137
129
|
}
|
|
138
130
|
|
|
139
131
|
/**
|
|
140
132
|
* @private
|
|
141
|
-
* @param {
|
|
133
|
+
* @param {import('./types.js').InputMessageMap['selected-files-change']} message
|
|
142
134
|
*/
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* @private
|
|
149
|
-
* @param {SelectedFileMessage} message
|
|
150
|
-
*/
|
|
151
|
-
async handleFileSelected(message) {
|
|
152
|
-
if (!this.$.multiple && this.$.selectedList.length) {
|
|
135
|
+
async handleSelectedFilesChange(message) {
|
|
136
|
+
if (this.cfg.multiple !== message.isMultipleMode) {
|
|
137
|
+
console.error('Multiple mode mismatch');
|
|
153
138
|
return;
|
|
154
139
|
}
|
|
155
140
|
|
|
156
|
-
this
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
141
|
+
this.bindL10n('counterText', () =>
|
|
142
|
+
this.l10n('selected-count', {
|
|
143
|
+
count: message.selectedCount,
|
|
144
|
+
total: message.total,
|
|
145
|
+
}),
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
this.set$({
|
|
149
|
+
isSelectionReady: message.isReady,
|
|
150
|
+
showSelectionStatus: message.isMultipleMode && message.total > 0,
|
|
151
|
+
couldSelectAll: message.selectedCount < message.total,
|
|
152
|
+
couldDeselectAll: message.selectedCount === message.total,
|
|
153
|
+
selectedList: message.selectedFiles,
|
|
154
|
+
});
|
|
161
155
|
}
|
|
162
156
|
|
|
163
157
|
/** @private */
|
|
164
158
|
handleIframeLoad() {
|
|
165
159
|
this.applyStyles();
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* @private
|
|
170
|
-
* @param {string} propName
|
|
171
|
-
*/
|
|
172
|
-
getCssValue(propName) {
|
|
173
|
-
let style = window.getComputedStyle(this);
|
|
174
|
-
return style.getPropertyValue(propName).trim();
|
|
160
|
+
this.setupL10n();
|
|
175
161
|
}
|
|
176
162
|
|
|
177
163
|
/** @private */
|
|
178
164
|
applyStyles() {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
secondaryForegroundColor: this.getCssValue('--uc-secondary-foreground'),
|
|
185
|
-
secondaryHover: this.getCssValue('--uc-secondary-hover'),
|
|
186
|
-
linkColor: this.getCssValue('--uc-primary'),
|
|
187
|
-
linkColorHover: this.getCssValue('--uc-primary-hover'),
|
|
188
|
-
fontFamily: this.getCssValue('--uc-font-family'),
|
|
189
|
-
fontSize: this.getCssValue('--uc-font-size'),
|
|
190
|
-
};
|
|
165
|
+
this._messageBridge?.send({
|
|
166
|
+
type: 'set-theme-definition',
|
|
167
|
+
theme: buildThemeDefinition(this),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
191
170
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
171
|
+
/** @private */
|
|
172
|
+
setupL10n() {
|
|
173
|
+
this._messageBridge?.send({
|
|
174
|
+
type: 'set-locale-definition',
|
|
175
|
+
localeDefinition: this.cfg.localeName,
|
|
195
176
|
});
|
|
196
177
|
}
|
|
197
178
|
|
|
198
179
|
/** @private */
|
|
199
180
|
remoteUrl() {
|
|
200
|
-
const { pubkey, remoteTabSessionKey, socialBaseUrl } = this.cfg;
|
|
181
|
+
const { pubkey, remoteTabSessionKey, socialBaseUrl, multiple } = this.cfg;
|
|
201
182
|
const { externalSourceType } = this.activityParams;
|
|
202
183
|
const lang = this.l10n('social-source-lang')?.split('-')?.[0] || 'en';
|
|
203
184
|
const params = {
|
|
204
185
|
lang,
|
|
205
186
|
public_key: pubkey,
|
|
206
187
|
images_only: false.toString(),
|
|
207
|
-
pass_window_open: false,
|
|
208
188
|
session_key: remoteTabSessionKey,
|
|
189
|
+
wait_for_theme: true,
|
|
190
|
+
multiple: multiple.toString(),
|
|
209
191
|
};
|
|
210
|
-
const url = new URL(`/
|
|
192
|
+
const url = new URL(`/window4/${externalSourceType}`, socialBaseUrl);
|
|
211
193
|
url.search = queryString(params);
|
|
212
194
|
return url.toString();
|
|
213
195
|
}
|
|
@@ -231,31 +213,43 @@ export class ExternalSource extends UploaderBlock {
|
|
|
231
213
|
this.ref.iframeWrapper.innerHTML = '';
|
|
232
214
|
this.ref.iframeWrapper.appendChild(iframe);
|
|
233
215
|
|
|
234
|
-
|
|
216
|
+
if (!iframe.contentWindow) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
this._messageBridge?.destroy();
|
|
221
|
+
|
|
222
|
+
/** @private */
|
|
223
|
+
this._messageBridge = new MessageBridge(iframe.contentWindow);
|
|
224
|
+
this._messageBridge.on('selected-files-change', this.handleSelectedFilesChange.bind(this));
|
|
235
225
|
|
|
236
|
-
this.
|
|
237
|
-
this.$.selectedList = [];
|
|
226
|
+
this.resetSelectionStatus();
|
|
238
227
|
}
|
|
239
228
|
|
|
240
229
|
/** @private */
|
|
241
230
|
unmountIframe() {
|
|
242
|
-
this.
|
|
231
|
+
this._messageBridge?.destroy();
|
|
232
|
+
this._messageBridge = undefined;
|
|
243
233
|
this.ref.iframeWrapper.innerHTML = '';
|
|
244
|
-
|
|
245
|
-
this
|
|
246
|
-
|
|
234
|
+
|
|
235
|
+
this.resetSelectionStatus();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** @private */
|
|
239
|
+
resetSelectionStatus() {
|
|
240
|
+
this.set$({
|
|
241
|
+
selectedList: [],
|
|
242
|
+
total: 0,
|
|
243
|
+
isSelectionReady: false,
|
|
244
|
+
couldSelectAll: false,
|
|
245
|
+
couldDeselectAll: false,
|
|
246
|
+
showSelectionStatus: false,
|
|
247
|
+
});
|
|
247
248
|
}
|
|
248
249
|
}
|
|
249
250
|
|
|
250
251
|
ExternalSource.template = /* HTML */ `
|
|
251
252
|
<uc-activity-header>
|
|
252
|
-
<button type="button" class="uc-mini-btn" set="onclick: *historyBack" l10n="@title:back">
|
|
253
|
-
<uc-icon name="back"></uc-icon>
|
|
254
|
-
</button>
|
|
255
|
-
<div>
|
|
256
|
-
<uc-icon set="@name: activityIcon"></uc-icon>
|
|
257
|
-
<span>{{activityCaption}}</span>
|
|
258
|
-
</div>
|
|
259
253
|
<button
|
|
260
254
|
type="button"
|
|
261
255
|
class="uc-mini-btn uc-close-btn"
|
|
@@ -269,12 +263,15 @@ ExternalSource.template = /* HTML */ `
|
|
|
269
263
|
<div ref="iframeWrapper" class="uc-iframe-wrapper"></div>
|
|
270
264
|
<div class="uc-toolbar">
|
|
271
265
|
<button type="button" class="uc-cancel-btn uc-secondary-btn" set="onclick: onCancel" l10n="cancel"></button>
|
|
272
|
-
<div
|
|
273
|
-
|
|
266
|
+
<div set="@hidden: !showSelectionStatus" class="uc-selection-status-box">
|
|
267
|
+
<span>{{counterText}}</span>
|
|
268
|
+
<button type="button" set="onclick: onSelectAll; @hidden: !couldSelectAll" l10n="select-all"></button>
|
|
269
|
+
<button type="button" set="onclick: onDeselectAll; @hidden: !couldDeselectAll" l10n="deselect-all"></button>
|
|
270
|
+
</div>
|
|
274
271
|
<button
|
|
275
272
|
type="button"
|
|
276
273
|
class="uc-done-btn uc-primary-btn"
|
|
277
|
-
set="onclick: onDone; @disabled: !
|
|
274
|
+
set="onclick: onDone; @disabled: !isSelectionReady"
|
|
278
275
|
l10n="done"
|
|
279
276
|
></button>
|
|
280
277
|
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class MessageBridge {
|
|
2
|
+
/** @param {Window} context */
|
|
3
|
+
constructor(context: Window);
|
|
4
|
+
/** @type {Map<string, Set<import('./types').InputMessageHandler<import('./types').InputMessageType>>>} */
|
|
5
|
+
_handlerMap: Map<string, Set<import('./types').InputMessageHandler<import('./types').InputMessageType>>>;
|
|
6
|
+
/** @type {Window} */
|
|
7
|
+
_context: Window;
|
|
8
|
+
/** @param {MessageEvent} e */
|
|
9
|
+
_handleMessage: (e: MessageEvent) => void;
|
|
10
|
+
/**
|
|
11
|
+
* @template {import('./types').InputMessageType} T
|
|
12
|
+
* @param {T} type
|
|
13
|
+
* @param {import('./types').InputMessageHandler<T>} handler
|
|
14
|
+
*/
|
|
15
|
+
on<T extends "selected-files-change">(type: T, handler: import("./types").InputMessageHandler<T>): void;
|
|
16
|
+
/** @param {import('./types').OutputMessage} message */
|
|
17
|
+
send(message: import('./types').OutputMessage): void;
|
|
18
|
+
destroy(): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=MessageBridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageBridge.d.ts","sourceRoot":"","sources":["MessageBridge.js"],"names":[],"mappings":"AAgBA;IAOE,8BAA8B;IAC9B,qBADY,MAAM,EAKjB;IAXD,0GAA0G;IAC1G,aADW,IAAI,MAAM,EAAE,IAAI,OAAO,SAAS,EAAE,mBAAmB,CAAC,OAAO,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAC9E;IAExB,qBAAqB;IACrB,UADW,MAAM,CACR;IAST,8BAA8B;IAC9B,oBADY,YAAY,UAgBtB;IAEF;;;;OAIG;IACH,wGAOC;IAED,uDAAuD;IACvD,cADY,OAAO,SAAS,EAAE,aAAa,QAG1C;IAED,gBAEC;CACF"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** @type {import('./types').InputMessageType[]} */
|
|
2
|
+
const MESSAGE_TYPE_WHITELIST = ['selected-files-change'];
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {unknown} message
|
|
6
|
+
* @returns {message is import("./types").InputMessageMap[import("./types").InputMessageType]}
|
|
7
|
+
*/
|
|
8
|
+
const isWhitelistedMessage = (message) => {
|
|
9
|
+
if (!message) return false;
|
|
10
|
+
if (typeof message !== 'object') return false;
|
|
11
|
+
return (
|
|
12
|
+
'type' in message &&
|
|
13
|
+
MESSAGE_TYPE_WHITELIST.includes(/** @type {import('./types').InputMessageType} */ (message.type))
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class MessageBridge {
|
|
18
|
+
/** @type {Map<string, Set<import('./types').InputMessageHandler<import('./types').InputMessageType>>>} */
|
|
19
|
+
_handlerMap = new Map();
|
|
20
|
+
|
|
21
|
+
/** @type {Window} */
|
|
22
|
+
_context;
|
|
23
|
+
|
|
24
|
+
/** @param {Window} context */
|
|
25
|
+
constructor(context) {
|
|
26
|
+
this._context = context;
|
|
27
|
+
|
|
28
|
+
window.addEventListener('message', this._handleMessage);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** @param {MessageEvent} e */
|
|
32
|
+
_handleMessage = (e) => {
|
|
33
|
+
if (e.source !== this._context) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const message = e.data;
|
|
37
|
+
if (!isWhitelistedMessage(message)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const handlers = this._handlerMap.get(message.type);
|
|
42
|
+
if (handlers) {
|
|
43
|
+
for (const handler of handlers) {
|
|
44
|
+
handler(message);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @template {import('./types').InputMessageType} T
|
|
51
|
+
* @param {T} type
|
|
52
|
+
* @param {import('./types').InputMessageHandler<T>} handler
|
|
53
|
+
*/
|
|
54
|
+
on(type, handler) {
|
|
55
|
+
const handlers = this._handlerMap.get(type) ?? new Set();
|
|
56
|
+
if (!this._handlerMap.has(type)) {
|
|
57
|
+
this._handlerMap.set(type, handlers);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
handlers.add(/** @type {import('./types').InputMessageHandler<import('./types').InputMessageType>} */ (handler));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @param {import('./types').OutputMessage} message */
|
|
64
|
+
send(message) {
|
|
65
|
+
this._context.postMessage(message, '*');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
destroy() {
|
|
69
|
+
window.removeEventListener('message', this._handleMessage);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildThemeDefinition.d.ts","sourceRoot":"","sources":["buildThemeDefinition.js"],"names":[],"mappings":"AAqCA,mCAAmC;AACnC,8CADY,WAAW,8DAStB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {HTMLElement} element
|
|
5
|
+
* @param {string} propName
|
|
6
|
+
*/
|
|
7
|
+
function getCssValue(element, propName) {
|
|
8
|
+
let style = window.getComputedStyle(element);
|
|
9
|
+
return style.getPropertyValue(propName).trim();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const ucCustomProperties = /** @type {(keyof import('./types.js').ThemeDefinition)[]} */ ([
|
|
13
|
+
'--uc-font-family',
|
|
14
|
+
'--uc-font-size',
|
|
15
|
+
'--uc-line-height',
|
|
16
|
+
'--uc-button-size',
|
|
17
|
+
'--uc-preview-size',
|
|
18
|
+
'--uc-input-size',
|
|
19
|
+
'--uc-padding',
|
|
20
|
+
'--uc-radius',
|
|
21
|
+
'--uc-transition',
|
|
22
|
+
'--uc-background',
|
|
23
|
+
'--uc-foreground',
|
|
24
|
+
'--uc-primary',
|
|
25
|
+
'--uc-primary-hover',
|
|
26
|
+
'--uc-primary-transparent',
|
|
27
|
+
'--uc-primary-foreground',
|
|
28
|
+
'--uc-secondary',
|
|
29
|
+
'--uc-secondary-hover',
|
|
30
|
+
'--uc-secondary-foreground',
|
|
31
|
+
'--uc-muted',
|
|
32
|
+
'--uc-muted-foreground',
|
|
33
|
+
'--uc-destructive',
|
|
34
|
+
'--uc-destructive-foreground',
|
|
35
|
+
'--uc-border',
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
/** @param {HTMLElement} element */
|
|
39
|
+
export function buildThemeDefinition(element) {
|
|
40
|
+
return ucCustomProperties.reduce((acc, prop) => {
|
|
41
|
+
const value = getCssValue(element, prop);
|
|
42
|
+
if (value) {
|
|
43
|
+
acc[prop] = value;
|
|
44
|
+
}
|
|
45
|
+
return acc;
|
|
46
|
+
}, /** @type {Record<keyof import('./types.js').ThemeDefinition, string>} */ ({}));
|
|
47
|
+
}
|