capacitor-extended-dialog 0.0.13 → 0.0.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.
- package/CapacitorExtendedDialog.podspec +2 -1
- package/Package.swift +4 -2
- package/README.md +75 -77
- package/android/build.gradle +10 -9
- package/android/src/main/java/com/albermonte/extendeddialog/SheetBottomDialogFragment.java +19 -14
- package/android/src/main/java/com/albermonte/extendeddialog/SvgImageLoader.java +90 -0
- package/dist/docs.json +74 -74
- package/dist/esm/definitions.d.ts +16 -4
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.js.map +1 -1
- package/ios/Sources/ExtendedDialogPlugin/FullScreenDialogViewController.swift +22 -17
- package/ios/Sources/ExtendedDialogPlugin/SvgImageLoader.swift +70 -0
- package/package.json +12 -12
|
@@ -11,7 +11,8 @@ Pod::Spec.new do |s|
|
|
|
11
11
|
s.author = package['author']
|
|
12
12
|
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
13
|
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
-
s.ios.deployment_target = '
|
|
14
|
+
s.ios.deployment_target = '15.0'
|
|
15
15
|
s.dependency 'Capacitor'
|
|
16
|
+
s.dependency 'SVGKit', '~> 3.0'
|
|
16
17
|
s.swift_version = '5.1'
|
|
17
18
|
end
|
package/Package.swift
CHANGED
|
@@ -10,14 +10,16 @@ let package = Package(
|
|
|
10
10
|
targets: ["ExtendedDialogPlugin"])
|
|
11
11
|
],
|
|
12
12
|
dependencies: [
|
|
13
|
-
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
|
|
13
|
+
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0"),
|
|
14
|
+
.package(url: "https://github.com/SVGKit/SVGKit.git", from: "3.0.0")
|
|
14
15
|
],
|
|
15
16
|
targets: [
|
|
16
17
|
.target(
|
|
17
18
|
name: "ExtendedDialogPlugin",
|
|
18
19
|
dependencies: [
|
|
19
20
|
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
|
20
|
-
.product(name: "Cordova", package: "capacitor-swift-pm")
|
|
21
|
+
.product(name: "Cordova", package: "capacitor-swift-pm"),
|
|
22
|
+
.product(name: "SVGKit", package: "SVGKit")
|
|
21
23
|
],
|
|
22
24
|
path: "ios/Sources/ExtendedDialogPlugin"),
|
|
23
25
|
.testTarget(
|
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ npx cap sync
|
|
|
38
38
|
### alert(...)
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
|
-
alert(options: AlertOptions) =>
|
|
41
|
+
alert(options: AlertOptions) => Promise<void>
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Show an alert dialog with a single dismiss button.
|
|
@@ -47,15 +47,13 @@ Show an alert dialog with a single dismiss button.
|
|
|
47
47
|
| ------------- | ----------------------------------------------------- | ------------------------------ |
|
|
48
48
|
| **`options`** | <code><a href="#alertoptions">AlertOptions</a></code> | - Alert configuration options. |
|
|
49
49
|
|
|
50
|
-
**Returns:** <code>any</code>
|
|
51
|
-
|
|
52
50
|
--------------------
|
|
53
51
|
|
|
54
52
|
|
|
55
53
|
### confirm(...)
|
|
56
54
|
|
|
57
55
|
```typescript
|
|
58
|
-
confirm(options: ConfirmOptions) =>
|
|
56
|
+
confirm(options: ConfirmOptions) => Promise<ConfirmResult>
|
|
59
57
|
```
|
|
60
58
|
|
|
61
59
|
Show a confirmation dialog with OK and Cancel buttons.
|
|
@@ -64,7 +62,7 @@ Show a confirmation dialog with OK and Cancel buttons.
|
|
|
64
62
|
| ------------- | --------------------------------------------------------- | -------------------------------- |
|
|
65
63
|
| **`options`** | <code><a href="#confirmoptions">ConfirmOptions</a></code> | - Confirm configuration options. |
|
|
66
64
|
|
|
67
|
-
**Returns:** <code>
|
|
65
|
+
**Returns:** <code>Promise<<a href="#confirmresult">ConfirmResult</a>></code>
|
|
68
66
|
|
|
69
67
|
--------------------
|
|
70
68
|
|
|
@@ -72,7 +70,7 @@ Show a confirmation dialog with OK and Cancel buttons.
|
|
|
72
70
|
### prompt(...)
|
|
73
71
|
|
|
74
72
|
```typescript
|
|
75
|
-
prompt(options: PromptOptions) =>
|
|
73
|
+
prompt(options: PromptOptions) => Promise<PromptResult>
|
|
76
74
|
```
|
|
77
75
|
|
|
78
76
|
Show a prompt dialog with a text input field.
|
|
@@ -81,7 +79,7 @@ Show a prompt dialog with a text input field.
|
|
|
81
79
|
| ------------- | ------------------------------------------------------- | ------------------------------- |
|
|
82
80
|
| **`options`** | <code><a href="#promptoptions">PromptOptions</a></code> | - Prompt configuration options. |
|
|
83
81
|
|
|
84
|
-
**Returns:** <code>
|
|
82
|
+
**Returns:** <code>Promise<<a href="#promptresult">PromptResult</a>></code>
|
|
85
83
|
|
|
86
84
|
--------------------
|
|
87
85
|
|
|
@@ -89,7 +87,7 @@ Show a prompt dialog with a text input field.
|
|
|
89
87
|
### singleSelect(...)
|
|
90
88
|
|
|
91
89
|
```typescript
|
|
92
|
-
singleSelect(options: SingleSelectOptions) =>
|
|
90
|
+
singleSelect(options: SingleSelectOptions) => Promise<SingleSelectResult>
|
|
93
91
|
```
|
|
94
92
|
|
|
95
93
|
Show a single-select dialog where the user picks one option.
|
|
@@ -98,7 +96,7 @@ Show a single-select dialog where the user picks one option.
|
|
|
98
96
|
| ------------- | ------------------------------------------------------------------- | -------------------------------------- |
|
|
99
97
|
| **`options`** | <code><a href="#singleselectoptions">SingleSelectOptions</a></code> | - Single select configuration options. |
|
|
100
98
|
|
|
101
|
-
**Returns:** <code>
|
|
99
|
+
**Returns:** <code>Promise<<a href="#singleselectresult">SingleSelectResult</a>></code>
|
|
102
100
|
|
|
103
101
|
--------------------
|
|
104
102
|
|
|
@@ -106,7 +104,7 @@ Show a single-select dialog where the user picks one option.
|
|
|
106
104
|
### multiSelect(...)
|
|
107
105
|
|
|
108
106
|
```typescript
|
|
109
|
-
multiSelect(options: MultiSelectOptions) =>
|
|
107
|
+
multiSelect(options: MultiSelectOptions) => Promise<MultiSelectResult>
|
|
110
108
|
```
|
|
111
109
|
|
|
112
110
|
Show a multi-select dialog where the user picks one or more options.
|
|
@@ -115,7 +113,7 @@ Show a multi-select dialog where the user picks one or more options.
|
|
|
115
113
|
| ------------- | ----------------------------------------------------------------- | ------------------------------------- |
|
|
116
114
|
| **`options`** | <code><a href="#multiselectoptions">MultiSelectOptions</a></code> | - Multi select configuration options. |
|
|
117
115
|
|
|
118
|
-
**Returns:** <code>
|
|
116
|
+
**Returns:** <code>Promise<<a href="#multiselectresult">MultiSelectResult</a>></code>
|
|
119
117
|
|
|
120
118
|
--------------------
|
|
121
119
|
|
|
@@ -123,7 +121,7 @@ Show a multi-select dialog where the user picks one or more options.
|
|
|
123
121
|
### sheet(...)
|
|
124
122
|
|
|
125
123
|
```typescript
|
|
126
|
-
sheet(options: SheetOptions) =>
|
|
124
|
+
sheet(options: SheetOptions) => Promise<SheetResult>
|
|
127
125
|
```
|
|
128
126
|
|
|
129
127
|
Show a sheet dialog with a header, title, and structured data rows.
|
|
@@ -132,7 +130,7 @@ Show a sheet dialog with a header, title, and structured data rows.
|
|
|
132
130
|
| ------------- | ----------------------------------------------------- | ------------------------------ |
|
|
133
131
|
| **`options`** | <code><a href="#sheetoptions">SheetOptions</a></code> | - Sheet configuration options. |
|
|
134
132
|
|
|
135
|
-
**Returns:** <code>
|
|
133
|
+
**Returns:** <code>Promise<<a href="#sheetresult">SheetResult</a>></code>
|
|
136
134
|
|
|
137
135
|
--------------------
|
|
138
136
|
|
|
@@ -140,7 +138,7 @@ Show a sheet dialog with a header, title, and structured data rows.
|
|
|
140
138
|
### messageSheet(...)
|
|
141
139
|
|
|
142
140
|
```typescript
|
|
143
|
-
messageSheet(options: MessageSheetOptions) =>
|
|
141
|
+
messageSheet(options: MessageSheetOptions) => Promise<MessageSheetResult>
|
|
144
142
|
```
|
|
145
143
|
|
|
146
144
|
Show a message sheet dialog with an optional header logo, title, and message.
|
|
@@ -149,7 +147,7 @@ Show a message sheet dialog with an optional header logo, title, and message.
|
|
|
149
147
|
| ------------- | ------------------------------------------------------------------- | -------------------------------------- |
|
|
150
148
|
| **`options`** | <code><a href="#messagesheetoptions">MessageSheetOptions</a></code> | - Message sheet configuration options. |
|
|
151
149
|
|
|
152
|
-
**Returns:** <code>
|
|
150
|
+
**Returns:** <code>Promise<<a href="#messagesheetresult">MessageSheetResult</a>></code>
|
|
153
151
|
|
|
154
152
|
--------------------
|
|
155
153
|
|
|
@@ -164,6 +162,13 @@ Show a message sheet dialog with an optional header logo, title, and message.
|
|
|
164
162
|
| **`buttonTitle`** | <code>string</code> | Title for the dismiss button. | <code>"OK"</code> |
|
|
165
163
|
|
|
166
164
|
|
|
165
|
+
#### ConfirmResult
|
|
166
|
+
|
|
167
|
+
| Prop | Type | Description |
|
|
168
|
+
| ----------- | -------------------- | ----------------------------------------------------------- |
|
|
169
|
+
| **`value`** | <code>boolean</code> | Whether the user confirmed (`true`) or cancelled (`false`). |
|
|
170
|
+
|
|
171
|
+
|
|
167
172
|
#### ConfirmOptions
|
|
168
173
|
|
|
169
174
|
| Prop | Type | Description | Default |
|
|
@@ -172,11 +177,12 @@ Show a message sheet dialog with an optional header logo, title, and message.
|
|
|
172
177
|
| **`cancelButtonTitle`** | <code>string</code> | Title for the cancel button. | <code>"Cancel"</code> |
|
|
173
178
|
|
|
174
179
|
|
|
175
|
-
####
|
|
180
|
+
#### PromptResult
|
|
176
181
|
|
|
177
|
-
| Prop
|
|
178
|
-
|
|
|
179
|
-
| **`value`**
|
|
182
|
+
| Prop | Type | Description |
|
|
183
|
+
| --------------- | -------------------- | -------------------------------------------------------- |
|
|
184
|
+
| **`value`** | <code>string</code> | The text entered by the user. Empty string if cancelled. |
|
|
185
|
+
| **`cancelled`** | <code>boolean</code> | Whether the user cancelled the dialog. |
|
|
180
186
|
|
|
181
187
|
|
|
182
188
|
#### PromptOptions
|
|
@@ -190,22 +196,22 @@ Show a message sheet dialog with an optional header logo, title, and message.
|
|
|
190
196
|
| **`focusInput`** | <code>boolean</code> | Whether to automatically focus the input field and open the keyboard when the dialog appears. Note: On iOS, basic (non-fullscreen) dialogs always auto-focus the input field due to UIAlertController's built-in behavior. This option only takes effect on iOS when using fullscreen mode (`mode: 'fullscreen'`). On Android and web, this works for all modes. | <code>false</code> |
|
|
191
197
|
|
|
192
198
|
|
|
193
|
-
####
|
|
199
|
+
#### SingleSelectResult
|
|
194
200
|
|
|
195
|
-
| Prop | Type
|
|
196
|
-
| --------------- |
|
|
197
|
-
| **`value`** | <code>string</code>
|
|
198
|
-
| **`cancelled`** | <code>boolean</code>
|
|
201
|
+
| Prop | Type | Description |
|
|
202
|
+
| --------------- | --------------------------- | --------------------------------------------------------- |
|
|
203
|
+
| **`value`** | <code>string \| null</code> | The value of the selected option, or `null` if cancelled. |
|
|
204
|
+
| **`cancelled`** | <code>boolean</code> | Whether the user cancelled the dialog. |
|
|
199
205
|
|
|
200
206
|
|
|
201
207
|
#### SingleSelectOptions
|
|
202
208
|
|
|
203
|
-
| Prop | Type
|
|
204
|
-
| ----------------------- |
|
|
205
|
-
| **`options`** | <code>
|
|
206
|
-
| **`selectedValue`** | <code>string</code>
|
|
207
|
-
| **`okButtonTitle`** | <code>string</code>
|
|
208
|
-
| **`cancelButtonTitle`** | <code>string</code>
|
|
209
|
+
| Prop | Type | Description | Default |
|
|
210
|
+
| ----------------------- | --------------------------- | ----------------------------------------- | --------------------- |
|
|
211
|
+
| **`options`** | <code>SelectOption[]</code> | List of options to display for selection. | |
|
|
212
|
+
| **`selectedValue`** | <code>string</code> | Value of the initially selected option. | |
|
|
213
|
+
| **`okButtonTitle`** | <code>string</code> | Title for the confirmation button. | <code>"OK"</code> |
|
|
214
|
+
| **`cancelButtonTitle`** | <code>string</code> | Title for the cancel button. | <code>"Cancel"</code> |
|
|
209
215
|
|
|
210
216
|
|
|
211
217
|
#### SelectOption
|
|
@@ -216,55 +222,54 @@ Show a message sheet dialog with an optional header logo, title, and message.
|
|
|
216
222
|
| **`value`** | <code>string</code> | Value returned when the option is selected. |
|
|
217
223
|
|
|
218
224
|
|
|
219
|
-
####
|
|
225
|
+
#### MultiSelectResult
|
|
220
226
|
|
|
221
|
-
| Prop | Type
|
|
222
|
-
| --------------- |
|
|
223
|
-
| **`
|
|
224
|
-
| **`cancelled`** | <code>boolean</code>
|
|
227
|
+
| Prop | Type | Description |
|
|
228
|
+
| --------------- | --------------------- | ------------------------------------------------------------- |
|
|
229
|
+
| **`values`** | <code>string[]</code> | The values of the selected options. Empty array if cancelled. |
|
|
230
|
+
| **`cancelled`** | <code>boolean</code> | Whether the user cancelled the dialog. |
|
|
225
231
|
|
|
226
232
|
|
|
227
233
|
#### MultiSelectOptions
|
|
228
234
|
|
|
229
|
-
| Prop | Type
|
|
230
|
-
| ----------------------- |
|
|
231
|
-
| **`options`** | <code>
|
|
232
|
-
| **`selectedValues`** | <code>
|
|
233
|
-
| **`okButtonTitle`** | <code>string</code>
|
|
234
|
-
| **`cancelButtonTitle`** | <code>string</code>
|
|
235
|
+
| Prop | Type | Description | Default |
|
|
236
|
+
| ----------------------- | --------------------------- | ----------------------------------------- | --------------------- |
|
|
237
|
+
| **`options`** | <code>SelectOption[]</code> | List of options to display for selection. | |
|
|
238
|
+
| **`selectedValues`** | <code>string[]</code> | Values of the initially selected options. | |
|
|
239
|
+
| **`okButtonTitle`** | <code>string</code> | Title for the confirmation button. | <code>"OK"</code> |
|
|
240
|
+
| **`cancelButtonTitle`** | <code>string</code> | Title for the cancel button. | <code>"Cancel"</code> |
|
|
235
241
|
|
|
236
242
|
|
|
237
|
-
####
|
|
243
|
+
#### SheetResult
|
|
238
244
|
|
|
239
|
-
| Prop | Type | Description
|
|
240
|
-
| --------------- | -------------------- |
|
|
241
|
-
| **`
|
|
242
|
-
| **`cancelled`** | <code>boolean</code> | Whether the user cancelled the dialog. |
|
|
245
|
+
| Prop | Type | Description |
|
|
246
|
+
| --------------- | -------------------- | ------------------------------------- |
|
|
247
|
+
| **`confirmed`** | <code>boolean</code> | True if confirmed, false if cancelled |
|
|
243
248
|
|
|
244
249
|
|
|
245
250
|
#### SheetOptions
|
|
246
251
|
|
|
247
|
-
| Prop | Type | Description
|
|
248
|
-
| ------------------------ | ------------------------------------------------- |
|
|
249
|
-
| **`headerLogo`** | <code>string</code> | Header logo -
|
|
250
|
-
| **`title`** | <code>string</code> | Sheet title
|
|
251
|
-
| **`subtitle`** | <code>string</code> | Optional subtitle displayed between title and rows
|
|
252
|
-
| **`rows`** | <code>
|
|
253
|
-
| **`confirmButtonTitle`** | <code>string</code> | Confirm button title
|
|
254
|
-
| **`cancelButtonTitle`** | <code>string</code> | Cancel button title
|
|
255
|
-
| **`mode`** | <code><a href="#dialogmode">DialogMode</a></code> | Dialog mode
|
|
252
|
+
| Prop | Type | Description |
|
|
253
|
+
| ------------------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
254
|
+
| **`headerLogo`** | <code>string</code> | Header logo. Supports: - PNG/JPEG/WebP/GIF as base64 data URL or HTTP/HTTPS URL - SVG as `data:image/svg+xml;base64,...`, `data:image/svg+xml,<svg ...>...` (URL-encoded or plain), or any HTTP/HTTPS URL ending in `.svg` |
|
|
255
|
+
| **`title`** | <code>string</code> | Sheet title |
|
|
256
|
+
| **`subtitle`** | <code>string</code> | Optional subtitle displayed between title and rows |
|
|
257
|
+
| **`rows`** | <code>SheetRow[]</code> | Description rows |
|
|
258
|
+
| **`confirmButtonTitle`** | <code>string</code> | Confirm button title |
|
|
259
|
+
| **`cancelButtonTitle`** | <code>string</code> | Cancel button title |
|
|
260
|
+
| **`mode`** | <code><a href="#dialogmode">DialogMode</a></code> | Dialog mode |
|
|
256
261
|
|
|
257
262
|
|
|
258
263
|
#### SheetRow
|
|
259
264
|
|
|
260
|
-
| Prop | Type | Description
|
|
261
|
-
| ----------- | ------------------- |
|
|
262
|
-
| **`title`** | <code>string</code> | Row title (required)
|
|
263
|
-
| **`logo`** | <code>string</code> | Optional logo/icon -
|
|
264
|
-
| **`value`** | <code>string</code> | Optional value displayed on the right
|
|
265
|
+
| Prop | Type | Description |
|
|
266
|
+
| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
267
|
+
| **`title`** | <code>string</code> | Row title (required) |
|
|
268
|
+
| **`logo`** | <code>string</code> | Optional logo/icon. Supports: - PNG/JPEG/WebP/GIF as base64 data URL or HTTP/HTTPS URL - SVG as `data:image/svg+xml;base64,...`, `data:image/svg+xml,<svg ...>...` (URL-encoded or plain), or any HTTP/HTTPS URL ending in `.svg` |
|
|
269
|
+
| **`value`** | <code>string</code> | Optional value displayed on the right |
|
|
265
270
|
|
|
266
271
|
|
|
267
|
-
####
|
|
272
|
+
#### MessageSheetResult
|
|
268
273
|
|
|
269
274
|
| Prop | Type | Description |
|
|
270
275
|
| --------------- | -------------------- | ------------------------------------- |
|
|
@@ -273,22 +278,15 @@ Show a message sheet dialog with an optional header logo, title, and message.
|
|
|
273
278
|
|
|
274
279
|
#### MessageSheetOptions
|
|
275
280
|
|
|
276
|
-
| Prop | Type | Description
|
|
277
|
-
| ------------------------ | ------------------------------------------------- |
|
|
278
|
-
| **`headerLogo`** | <code>string</code> | Header logo -
|
|
279
|
-
| **`title`** | <code>string</code> | Sheet title
|
|
280
|
-
| **`subtitle`** | <code>string</code> | Optional subtitle displayed between title and message
|
|
281
|
-
| **`message`** | <code>string</code> | Message body displayed in the sheet
|
|
282
|
-
| **`confirmButtonTitle`** | <code>string</code> | Confirm button title
|
|
283
|
-
| **`cancelButtonTitle`** | <code>string</code> | Cancel button title
|
|
284
|
-
| **`mode`** | <code><a href="#dialogmode">DialogMode</a></code> | Dialog mode
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
#### MessageSheetResult
|
|
288
|
-
|
|
289
|
-
| Prop | Type | Description |
|
|
290
|
-
| --------------- | -------------------- | ------------------------------------- |
|
|
291
|
-
| **`confirmed`** | <code>boolean</code> | True if confirmed, false if cancelled |
|
|
281
|
+
| Prop | Type | Description |
|
|
282
|
+
| ------------------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
283
|
+
| **`headerLogo`** | <code>string</code> | Header logo. Supports: - PNG/JPEG/WebP/GIF as base64 data URL or HTTP/HTTPS URL - SVG as `data:image/svg+xml;base64,...`, `data:image/svg+xml,<svg ...>...` (URL-encoded or plain), or any HTTP/HTTPS URL ending in `.svg` |
|
|
284
|
+
| **`title`** | <code>string</code> | Sheet title |
|
|
285
|
+
| **`subtitle`** | <code>string</code> | Optional subtitle displayed between title and message |
|
|
286
|
+
| **`message`** | <code>string</code> | Message body displayed in the sheet |
|
|
287
|
+
| **`confirmButtonTitle`** | <code>string</code> | Confirm button title |
|
|
288
|
+
| **`cancelButtonTitle`** | <code>string</code> | Cancel button title |
|
|
289
|
+
| **`mode`** | <code><a href="#dialogmode">DialogMode</a></code> | Dialog mode |
|
|
292
290
|
|
|
293
291
|
|
|
294
292
|
### Type Aliases
|
package/android/build.gradle
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
ext {
|
|
2
2
|
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
-
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.
|
|
4
|
-
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.
|
|
5
|
-
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
|
|
4
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
|
|
5
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
@@ -11,18 +11,18 @@ buildscript {
|
|
|
11
11
|
mavenCentral()
|
|
12
12
|
}
|
|
13
13
|
dependencies {
|
|
14
|
-
classpath 'com.android.tools.build:gradle:8.
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.13.0'
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
apply plugin: 'com.android.library'
|
|
19
19
|
|
|
20
20
|
android {
|
|
21
|
-
namespace "com.albermonte.extendeddialog"
|
|
22
|
-
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion :
|
|
21
|
+
namespace = "com.albermonte.extendeddialog"
|
|
22
|
+
compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
|
|
23
23
|
defaultConfig {
|
|
24
|
-
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion :
|
|
25
|
-
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion :
|
|
24
|
+
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
|
|
25
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
|
|
26
26
|
versionCode 1
|
|
27
27
|
versionName "1.0"
|
|
28
28
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
@@ -34,7 +34,7 @@ android {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
lintOptions {
|
|
37
|
-
abortOnError false
|
|
37
|
+
abortOnError = false
|
|
38
38
|
}
|
|
39
39
|
compileOptions {
|
|
40
40
|
sourceCompatibility JavaVersion.VERSION_21
|
|
@@ -53,6 +53,7 @@ dependencies {
|
|
|
53
53
|
implementation project(':capacitor-android')
|
|
54
54
|
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
55
55
|
implementation 'com.google.android.material:material:1.12.0'
|
|
56
|
+
implementation 'com.caverock:androidsvg-aar:1.4'
|
|
56
57
|
testImplementation "junit:junit:$junitVersion"
|
|
57
58
|
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
58
59
|
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
@@ -7,7 +7,6 @@ import android.content.res.ColorStateList;
|
|
|
7
7
|
import android.graphics.Bitmap;
|
|
8
8
|
import android.graphics.BitmapFactory;
|
|
9
9
|
import android.os.Bundle;
|
|
10
|
-
import android.util.Base64;
|
|
11
10
|
import android.util.TypedValue;
|
|
12
11
|
import android.view.ContextThemeWrapper;
|
|
13
12
|
import android.view.Gravity;
|
|
@@ -52,6 +51,8 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
52
51
|
private static final String ARG_SUBTITLE = "subtitle";
|
|
53
52
|
private static final String ARG_IS_MESSAGE_SHEET = "isMessageSheet";
|
|
54
53
|
|
|
54
|
+
private static final Executor IMAGE_EXECUTOR = Executors.newCachedThreadPool();
|
|
55
|
+
|
|
55
56
|
private ExtendedDialog.SheetCallback sheetCallback;
|
|
56
57
|
private boolean dismissed = false;
|
|
57
58
|
private Context themedContext;
|
|
@@ -706,28 +707,32 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
706
707
|
}
|
|
707
708
|
|
|
708
709
|
private void loadImageAsync(ImageView imageView, String imageUrl) {
|
|
709
|
-
|
|
710
|
-
|
|
710
|
+
if (imageUrl == null || imageUrl.isEmpty()) return;
|
|
711
|
+
IMAGE_EXECUTOR.execute(() -> {
|
|
711
712
|
try {
|
|
712
|
-
Bitmap bitmap;
|
|
713
|
-
if (imageUrl.startsWith("data:")) {
|
|
714
|
-
String base64Data = imageUrl.substring(imageUrl.indexOf(",") + 1);
|
|
715
|
-
byte[] decodedBytes = Base64.decode(base64Data, Base64.DEFAULT);
|
|
716
|
-
bitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
|
|
717
|
-
} else {
|
|
718
|
-
InputStream inputStream = new URL(imageUrl).openStream();
|
|
719
|
-
bitmap = BitmapFactory.decodeStream(inputStream);
|
|
720
|
-
inputStream.close();
|
|
721
|
-
}
|
|
713
|
+
Bitmap bitmap = decodeImage(imageUrl, imageView);
|
|
722
714
|
if (bitmap != null) {
|
|
723
715
|
imageView.post(() -> imageView.setImageBitmap(bitmap));
|
|
724
716
|
}
|
|
725
717
|
} catch (Exception e) {
|
|
726
|
-
|
|
718
|
+
android.util.Log.w("ExtendedDialog", "Failed to load image: " + e.getMessage());
|
|
727
719
|
}
|
|
728
720
|
});
|
|
729
721
|
}
|
|
730
722
|
|
|
723
|
+
private static Bitmap decodeImage(String imageUrl, ImageView imageView) throws Exception {
|
|
724
|
+
if (SvgImageLoader.isSvgSource(imageUrl)) {
|
|
725
|
+
return SvgImageLoader.render(imageUrl, imageView);
|
|
726
|
+
}
|
|
727
|
+
if (SvgImageLoader.isDataUrl(imageUrl)) {
|
|
728
|
+
byte[] decodedBytes = SvgImageLoader.decodeDataUrl(imageUrl);
|
|
729
|
+
return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
|
|
730
|
+
}
|
|
731
|
+
try (InputStream inputStream = new URL(imageUrl).openStream()) {
|
|
732
|
+
return BitmapFactory.decodeStream(inputStream);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
731
736
|
private void handleConfirm() {
|
|
732
737
|
if (dismissed) return;
|
|
733
738
|
dismissed = true;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
package com.albermonte.extendeddialog;
|
|
2
|
+
|
|
3
|
+
import android.graphics.Bitmap;
|
|
4
|
+
import android.graphics.Canvas;
|
|
5
|
+
import android.net.Uri;
|
|
6
|
+
import android.util.Base64;
|
|
7
|
+
import android.view.ViewGroup;
|
|
8
|
+
import android.widget.ImageView;
|
|
9
|
+
import com.caverock.androidsvg.SVG;
|
|
10
|
+
import com.caverock.androidsvg.SVGParseException;
|
|
11
|
+
import java.io.ByteArrayInputStream;
|
|
12
|
+
import java.io.IOException;
|
|
13
|
+
import java.io.InputStream;
|
|
14
|
+
import java.net.URL;
|
|
15
|
+
import java.net.URLDecoder;
|
|
16
|
+
import java.nio.charset.StandardCharsets;
|
|
17
|
+
import java.util.Locale;
|
|
18
|
+
|
|
19
|
+
final class SvgImageLoader {
|
|
20
|
+
|
|
21
|
+
private static final String SVG_DATA_URL_PREFIX = "data:image/svg+xml";
|
|
22
|
+
private static final String DATA_URL_PREFIX = "data:";
|
|
23
|
+
private static final String SVG_SUFFIX = ".svg";
|
|
24
|
+
|
|
25
|
+
private SvgImageLoader() {}
|
|
26
|
+
|
|
27
|
+
static boolean isDataUrl(String source) {
|
|
28
|
+
return source != null && source.regionMatches(true, 0, DATA_URL_PREFIX, 0, DATA_URL_PREFIX.length());
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static boolean isSvgSource(String source) {
|
|
32
|
+
if (source == null) return false;
|
|
33
|
+
if (source.regionMatches(true, 0, SVG_DATA_URL_PREFIX, 0, SVG_DATA_URL_PREFIX.length())) return true;
|
|
34
|
+
Uri uri = Uri.parse(source);
|
|
35
|
+
String scheme = uri.getScheme();
|
|
36
|
+
if (scheme == null || (!scheme.equalsIgnoreCase("http") && !scheme.equalsIgnoreCase("https"))) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
String path = uri.getPath();
|
|
40
|
+
return path != null && path.toLowerCase(Locale.ROOT).endsWith(SVG_SUFFIX);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Supports `;base64` and percent-encoded payloads. */
|
|
44
|
+
static byte[] decodeDataUrl(String source) throws IOException {
|
|
45
|
+
int comma = source.indexOf(',');
|
|
46
|
+
if (comma < 0) throw new IOException("Malformed data URL");
|
|
47
|
+
String header = source.substring(0, comma);
|
|
48
|
+
String payload = source.substring(comma + 1);
|
|
49
|
+
if (header.toLowerCase(Locale.ROOT).contains(";base64")) {
|
|
50
|
+
return Base64.decode(payload, Base64.DEFAULT);
|
|
51
|
+
}
|
|
52
|
+
return URLDecoder.decode(payload, StandardCharsets.UTF_8.name()).getBytes(StandardCharsets.UTF_8);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Sizes Bitmap to {@code targetView}'s layout params (or 64dp default). */
|
|
56
|
+
static Bitmap render(String source, ImageView targetView) throws SVGParseException, IOException {
|
|
57
|
+
SVG svg = parse(source);
|
|
58
|
+
ViewGroup.LayoutParams params = targetView.getLayoutParams();
|
|
59
|
+
int width = params != null ? params.width : 0;
|
|
60
|
+
int height = params != null ? params.height : 0;
|
|
61
|
+
if (width <= 0 || height <= 0) {
|
|
62
|
+
float density = targetView.getResources().getDisplayMetrics().density;
|
|
63
|
+
int fallback = (int) (64 * density);
|
|
64
|
+
if (width <= 0) width = fallback;
|
|
65
|
+
if (height <= 0) height = fallback;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Rescale via viewBox + preserveAspectRatio so small-viewport SVGs
|
|
69
|
+
// (e.g. width="20") aren't rendered tiny in the top-left corner.
|
|
70
|
+
svg.setDocumentWidth(width);
|
|
71
|
+
svg.setDocumentHeight(height);
|
|
72
|
+
|
|
73
|
+
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
74
|
+
Canvas canvas = new Canvas(bitmap);
|
|
75
|
+
svg.renderToCanvas(canvas);
|
|
76
|
+
return bitmap;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private static SVG parse(String source) throws SVGParseException, IOException {
|
|
80
|
+
if (isDataUrl(source)) {
|
|
81
|
+
byte[] bytes = decodeDataUrl(source);
|
|
82
|
+
try (InputStream in = new ByteArrayInputStream(bytes)) {
|
|
83
|
+
return SVG.getFromInputStream(in);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
try (InputStream in = new URL(source).openStream()) {
|
|
87
|
+
return SVG.getFromInputStream(in);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|