@cookieinformation/react-native-sdk 0.5.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/LICENSE +21 -0
- package/README.md +353 -0
- package/android/build.gradle +67 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/expo/modules/mobileconsentssdk/CookieInformationRNSDKModule.kt +455 -0
- package/android/src/main/java/expo/modules/mobileconsentssdk/UiParsing.kt +84 -0
- package/build/CookieInformationRNSDKModule.d.ts +106 -0
- package/build/CookieInformationRNSDKModule.d.ts.map +1 -0
- package/build/CookieInformationRNSDKModule.js +14 -0
- package/build/CookieInformationRNSDKModule.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +6 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +17 -0
- package/ios/CookieInformationRNSDK.podspec +30 -0
- package/ios/CookieInformationRNSDKModule.swift +235 -0
- package/ios/UiParsing.swift +58 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CookieInformation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# Cookie Information React Native SDK
|
|
2
|
+
|
|
3
|
+
React Native wrapper for the Cookie Information Mobile Consents SDKs.
|
|
4
|
+
|
|
5
|
+
Native SDKs:
|
|
6
|
+
- Android: https://github.com/cookie-information/android-release
|
|
7
|
+
- iOS: https://github.com/cookie-information/ios-release
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @cookieinformation/react-native-sdk
|
|
13
|
+
# or
|
|
14
|
+
yarn add @cookieinformation/react-native-sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
# Using the SDK
|
|
18
|
+
|
|
19
|
+
## Initializing
|
|
20
|
+
|
|
21
|
+
Initialize the SDK before calling any other method. You can initialize with or without UI customization.
|
|
22
|
+
SDK credentials can be fetched from the Cookie Information platform: https://go.cookieinformation.com/login
|
|
23
|
+
|
|
24
|
+
The SDK uses the `languageCode` you pass during initialization for all UI components and ignores the system language. If `languageCode` is not set, the SDK uses the device locale. You must ensure the selected language is configured in the Cookie Information platform and that content is provided for that language.
|
|
25
|
+
|
|
26
|
+
Recommended flow: initialize once, then call `showPrivacyPopUpIfNeeded` when needed (typically on app start).
|
|
27
|
+
|
|
28
|
+
Minimum required data for initialization:
|
|
29
|
+
- `clientId`
|
|
30
|
+
- `clientSecret`
|
|
31
|
+
- `solutionId`
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import MobileConsent from '@cookieinformation/react-native-sdk';
|
|
35
|
+
|
|
36
|
+
await MobileConsent.initialize({
|
|
37
|
+
clientId: 'YOUR_CLIENT_ID',
|
|
38
|
+
clientSecret: 'YOUR_CLIENT_SECRET',
|
|
39
|
+
solutionId: 'YOUR_SOLUTION_ID',
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Here is an example of all the arguments and data that support the SDK:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
await MobileConsent.initialize({
|
|
47
|
+
clientId: 'YOUR_CLIENT_ID',
|
|
48
|
+
clientSecret: 'YOUR_CLIENT_SECRET',
|
|
49
|
+
solutionId: 'YOUR_SOLUTION_ID',
|
|
50
|
+
languageCode: 'EN', // optional
|
|
51
|
+
enableNetworkLogger: false, // iOS only
|
|
52
|
+
ui: {
|
|
53
|
+
ios: {
|
|
54
|
+
accentColor: '#2E5BFF',
|
|
55
|
+
fontSet: {
|
|
56
|
+
largeTitle: { size: 34, weight: 'bold' },
|
|
57
|
+
body: { size: 14, weight: 'regular' },
|
|
58
|
+
bold: { size: 14, weight: 'bold' },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
android: {
|
|
62
|
+
lightColorScheme: {
|
|
63
|
+
primary: '#FF0000',
|
|
64
|
+
secondary: '#FFFF00',
|
|
65
|
+
tertiary: '#FFC0CB',
|
|
66
|
+
},
|
|
67
|
+
darkColorScheme: {
|
|
68
|
+
primary: '#00FF00',
|
|
69
|
+
secondary: '#008000',
|
|
70
|
+
tertiary: '#000000',
|
|
71
|
+
},
|
|
72
|
+
typography: {
|
|
73
|
+
bodyMedium: { font: 'inter_regular', size: 14 },
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Notes:
|
|
81
|
+
- Android `font` is a resource name under `android/app/src/main/res/font`.
|
|
82
|
+
- Colors accept `#RRGGBB` or `#AARRGGBB`.
|
|
83
|
+
- iOS uses system fonts if `name` is omitted.
|
|
84
|
+
|
|
85
|
+
## Using built-in mobile consents UI
|
|
86
|
+
|
|
87
|
+
SDK contains built-in screens for managing consents. Please ensure you set the correct language code you expect the consents to use, and that it has been fully configured in the Cookie Information platform.
|
|
88
|
+
|
|
89
|
+
| iOS | Android |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
|  |  |
|
|
92
|
+
|
|
93
|
+
## Privacy Pop-Up
|
|
94
|
+
|
|
95
|
+
### Standard flows
|
|
96
|
+
|
|
97
|
+
#### Presenting the privacy pop-up
|
|
98
|
+
|
|
99
|
+
To show the Privacy Pop Up screen regardless of state, use `showPrivacyPopUp` (typically used in settings to allow modification of consent). To show the Privacy Pop Up screen only when the user has not consented to the latest version, use `showPrivacyPopUpIfNeeded` (typically used at startup to present the privacy screen conditionally; see more below).
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
showPrivacyPopUp(): Promise<TrackingConsents>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
const consents = await MobileConsent.showPrivacyPopUp();
|
|
107
|
+
|
|
108
|
+
// Return type: TrackingConsents (Record<string, boolean | undefined>)
|
|
109
|
+
// TrackingConsents is a map of consent choices keyed by purpose/category:
|
|
110
|
+
// - keys: necessary, functional, statistical, marketing, custom (plus any custom keys)
|
|
111
|
+
// - values: boolean (true/false) or undefined
|
|
112
|
+
// Example return shape:
|
|
113
|
+
// {
|
|
114
|
+
// necessary: true,
|
|
115
|
+
// functional: false,
|
|
116
|
+
// statistical: true,
|
|
117
|
+
// marketing: false,
|
|
118
|
+
// custom: true
|
|
119
|
+
// }
|
|
120
|
+
|
|
121
|
+
if (consents.marketing) {
|
|
122
|
+
// enable marketing SDKs
|
|
123
|
+
} else {
|
|
124
|
+
// disable marketing SDKs
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The above function resolves with the user’s selections (a key/value map of consent categories to booleans). Use this result to enable or disable third‑party SDKs based on consent.
|
|
129
|
+
|
|
130
|
+
### Presenting the privacy pop-up conditionally
|
|
131
|
+
|
|
132
|
+
`showPrivacyPopUpIfNeeded` is typically used to present the popup after app start (or at a point you choose). The method checks if a valid consent is already saved locally on the device and also checks if there are any updates on the Cookie Information server. If there is no consent saved or the consent version is different from the one available on the server, the popup is presented; otherwise it resolves immediately with the current consent data. Use `ignoreVersionChanges` to ignore consent version changes coming from the server (iOS only).
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
showPrivacyPopUpIfNeeded(
|
|
136
|
+
options?: { ignoreVersionChanges?: boolean; userId?: string | null }
|
|
137
|
+
): Promise<TrackingConsents>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
const consents = await MobileConsent.showPrivacyPopUpIfNeeded();
|
|
142
|
+
|
|
143
|
+
// Use the result to enable/disable SDKs
|
|
144
|
+
if (consents.marketing) {
|
|
145
|
+
// enable marketing SDKs
|
|
146
|
+
} else {
|
|
147
|
+
// disable marketing SDKs
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
With options (Android `userId`, iOS `ignoreVersionChanges`):
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const consents = await MobileConsent.showPrivacyPopUpIfNeeded({
|
|
155
|
+
ignoreVersionChanges: true, // iOS only
|
|
156
|
+
userId: 'user_123', // optional on Android
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Example: read custom keys or localized titles
|
|
160
|
+
if (consents['Age Consent']) {
|
|
161
|
+
// handle custom consent item
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Handling errors
|
|
166
|
+
|
|
167
|
+
Both `showPrivacyPopUp` and `showPrivacyPopUpIfNeeded` reject on error. If an error happens, the selection is still persisted locally and an attempt is made the next time `showPrivacyPopUpIfNeeded` or `synchronizeIfNeeded` is called.
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
try {
|
|
171
|
+
await MobileConsent.showPrivacyPopUpIfNeeded();
|
|
172
|
+
} catch (e) {
|
|
173
|
+
console.warn('Consent UI failed, retry later:', e);
|
|
174
|
+
// You can call showPrivacyPopUpIfNeeded() again later (e.g. next app start).
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Custom view
|
|
179
|
+
|
|
180
|
+
If the default consent UI does not fit your product, you can build your own custom view. Use the methods below to fetch the consent solution and submit the user’s choices.
|
|
181
|
+
|
|
182
|
+
All methods return Promises and must be called after `initialize()`.
|
|
183
|
+
|
|
184
|
+
### initialize
|
|
185
|
+
Initialize the native SDKs before calling any other method.
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
initialize(options: InitializeOptions): Promise<void>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### cacheConsentSolution
|
|
192
|
+
|
|
193
|
+
Fetches the latest consent solution from the server. On iOS, it also returns `consentSolutionVersionId` which you must pass to `saveConsents` when sending consents manually. Use the returned `consentItems` to build your own UI if needed.
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
cacheConsentSolution(): Promise<{ consentItems: ConsentItem[]; consentSolutionVersionId?: string }>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
const { consentItems, consentSolutionVersionId } =
|
|
201
|
+
await MobileConsent.cacheConsentSolution();
|
|
202
|
+
|
|
203
|
+
// Example usage: build your own UI from consentItems
|
|
204
|
+
const itemsForUi = consentItems.map((item) => ({
|
|
205
|
+
id: item.id,
|
|
206
|
+
title: item.title,
|
|
207
|
+
required: item.required,
|
|
208
|
+
accepted: item.accepted,
|
|
209
|
+
}));
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### saveConsents
|
|
213
|
+
|
|
214
|
+
Submits the selected consent items to the server and stores them locally. On iOS, you must pass `consentSolutionVersionId` from `cacheConsentSolution` (or a known version). On Android, `consentSolutionVersionId` is ignored.
|
|
215
|
+
|
|
216
|
+
Parameters:
|
|
217
|
+
- `consentItems`: List of consent items to save.
|
|
218
|
+
- `customData`: Optional custom data (e.g. email, device_id).
|
|
219
|
+
- `userId`: Android only, optional user id; omit or pass `null` for anonymous user. Ignored on iOS.
|
|
220
|
+
- `consentSolutionVersionId`: iOS only, optional version id override when already known.
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
saveConsents(
|
|
224
|
+
consentItems: ConsentItem[],
|
|
225
|
+
customData?: Record<string, string> | null,
|
|
226
|
+
userId?: string | null,
|
|
227
|
+
consentSolutionVersionId?: string | null
|
|
228
|
+
): Promise<SaveConsentsResponse>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
const { consentItems, consentSolutionVersionId } =
|
|
233
|
+
await MobileConsent.cacheConsentSolution();
|
|
234
|
+
|
|
235
|
+
await MobileConsent.saveConsents(
|
|
236
|
+
consentItems,
|
|
237
|
+
{ device_id: 'example-device' },
|
|
238
|
+
'user_123', // optional userId on Android
|
|
239
|
+
consentSolutionVersionId
|
|
240
|
+
);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Notes:
|
|
244
|
+
- On iOS, `consentSolutionVersionId` is required and can be obtained from `cacheConsentSolution()` or passed explicitly.
|
|
245
|
+
- On Android, `consentSolutionVersionId` is ignored.
|
|
246
|
+
- `userId` is optional on Android; pass `null` or omit for anonymous user.
|
|
247
|
+
|
|
248
|
+
### getSavedConsents
|
|
249
|
+
|
|
250
|
+
`getSavedConsents` returns consent items stored on the device.
|
|
251
|
+
- Android: Returns items from the local DB (cached solution + user choices). Items may exist after `cacheConsentSolution` even before the user selects anything.
|
|
252
|
+
- iOS: Returns only consents that were saved when the user submitted choices (e.g. via the consent dialog or `saveConsents`). Empty until the user completes the flow at least once.
|
|
253
|
+
|
|
254
|
+
Parameters:
|
|
255
|
+
- `userId`: Android only, optional user id; omit or pass `null` for anonymous user. Ignored on iOS.
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
getSavedConsents(userId?: string | null): Promise<{ consentItems: ConsentItem[] }>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
const { consentItems } = await MobileConsent.getSavedConsents();
|
|
263
|
+
// Return type: { consentItems: ConsentItem[] }
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### acceptAllConsents
|
|
267
|
+
Fetches the solution and saves “accept all” consents.
|
|
268
|
+
|
|
269
|
+
Parameters:
|
|
270
|
+
- `userId`: Android only, optional user id; omit or pass `null` for anonymous user. Ignored on iOS.
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
acceptAllConsents(userId?: string | null): Promise<AcceptAllConsentsResponse>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### removeStoredConsents
|
|
277
|
+
Deletes stored consents on the device (does not delete server data).
|
|
278
|
+
|
|
279
|
+
Parameters:
|
|
280
|
+
- `userId`: Android only, optional user id; omit or pass `null` for anonymous user. Ignored on iOS.
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
removeStoredConsents(userId?: string | null): Promise<void>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### synchronizeIfNeeded
|
|
287
|
+
Retries failed consent uploads.
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
synchronizeIfNeeded(): Promise<void>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Types (summary)
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
type TrackingConsents = Record<string, boolean | undefined>;
|
|
297
|
+
|
|
298
|
+
interface ConsentItem {
|
|
299
|
+
id: number;
|
|
300
|
+
universalId: string;
|
|
301
|
+
title: string;
|
|
302
|
+
description: string;
|
|
303
|
+
required: boolean;
|
|
304
|
+
type: string;
|
|
305
|
+
accepted: boolean;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
interface SaveConsentsResponse {
|
|
309
|
+
success: true;
|
|
310
|
+
savedCount: number;
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Logging
|
|
315
|
+
|
|
316
|
+
Enable network logging on iOS via `enableNetworkLogger: true` in `initialize()`.
|
|
317
|
+
|
|
318
|
+
## Running the example app
|
|
319
|
+
|
|
320
|
+
The example app lives in `example/` and requires a native build (Expo Go is not supported).
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# from repo root
|
|
324
|
+
npm install
|
|
325
|
+
cd example
|
|
326
|
+
npm install
|
|
327
|
+
|
|
328
|
+
# generate native projects (first time or after native changes)
|
|
329
|
+
npx expo prebuild --clean
|
|
330
|
+
|
|
331
|
+
# run on device/simulator
|
|
332
|
+
npx expo run:ios
|
|
333
|
+
# or
|
|
334
|
+
npx expo run:android
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Notes:
|
|
338
|
+
- Update the credentials in `example/App.tsx` before running.
|
|
339
|
+
|
|
340
|
+
## Notes
|
|
341
|
+
|
|
342
|
+
- Call `initialize()` before any other method.
|
|
343
|
+
|
|
344
|
+
## Implementation
|
|
345
|
+
|
|
346
|
+
For additional customization options within MobileConsentsSDK, please contact our support team.
|
|
347
|
+
|
|
348
|
+
If something is missing or you want to change something, let us know.
|
|
349
|
+
|
|
350
|
+
## Release automation
|
|
351
|
+
|
|
352
|
+
- GitHub Actions publish requires `NPM_TOKEN` repository secret.
|
|
353
|
+
- Release tags must match the `package.json` version (format `X.Y.Z`).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
apply plugin: 'com.android.library'
|
|
2
|
+
|
|
3
|
+
group = 'expo.modules.mobileconsentssdk'
|
|
4
|
+
version = '0.1.0'
|
|
5
|
+
|
|
6
|
+
def nodeBinary = (findProperty("NODE_BINARY") ?: System.getenv("NODE_BINARY") ?: "node")
|
|
7
|
+
|
|
8
|
+
// Dynamic resolution for Expo modules core plugin (monorepo compatible)
|
|
9
|
+
def expoModulesCorePluginFile = new File(
|
|
10
|
+
providers.exec {
|
|
11
|
+
workingDir(rootDir)
|
|
12
|
+
commandLine(nodeBinary, "--print", "require.resolve('expo-modules-core/package.json')")
|
|
13
|
+
}.standardOutput.asText.get().trim(),
|
|
14
|
+
"../android/ExpoModulesCorePlugin.gradle"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
apply from: expoModulesCorePluginFile
|
|
18
|
+
applyKotlinExpoModulesCorePlugin()
|
|
19
|
+
useCoreDependencies()
|
|
20
|
+
useExpoPublishing()
|
|
21
|
+
|
|
22
|
+
// If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
|
|
23
|
+
// The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
|
|
24
|
+
// Most of the time, you may like to manage the Android SDK versions yourself.
|
|
25
|
+
def useManagedAndroidSdkVersions = false
|
|
26
|
+
if (useManagedAndroidSdkVersions) {
|
|
27
|
+
useDefaultAndroidSdkVersions()
|
|
28
|
+
} else {
|
|
29
|
+
buildscript {
|
|
30
|
+
// Simple helper that allows the root project to override versions declared by this library.
|
|
31
|
+
ext.safeExtGet = { prop, fallback ->
|
|
32
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
project.android {
|
|
36
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 34)
|
|
37
|
+
defaultConfig {
|
|
38
|
+
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
39
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 34)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
android {
|
|
45
|
+
namespace "expo.modules.mobileconsentssdk"
|
|
46
|
+
defaultConfig {
|
|
47
|
+
versionCode 1
|
|
48
|
+
versionName "0.1.0"
|
|
49
|
+
}
|
|
50
|
+
lintOptions {
|
|
51
|
+
abortOnError false
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
dependencies {
|
|
56
|
+
implementation 'androidx.activity:activity-compose:1.8.2'
|
|
57
|
+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
|
|
58
|
+
|
|
59
|
+
// Cannot upgrade further as the latest architecture (3.0.x) does not expose the ability to accept all consents.
|
|
60
|
+
implementation "com.cookieinformation:mobileconsents:3.0.1"
|
|
61
|
+
implementation "com.cookieinformation:core:0.0.13"
|
|
62
|
+
|
|
63
|
+
// Add these Compose Material3 dependencies
|
|
64
|
+
implementation "androidx.compose.material3:material3:1.1.2"
|
|
65
|
+
implementation "androidx.compose.material3:material3-window-size-class:1.1.2"
|
|
66
|
+
implementation "androidx.compose.ui:ui:1.4.3"
|
|
67
|
+
}
|