Skip to content

Commit b4a4fed

Browse files
authored
feat: add option to disable screen view usage (#190)
1 parent 4b905cd commit b4a4fed

File tree

15 files changed

+176
-40
lines changed

15 files changed

+176
-40
lines changed

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ android {
5858
dependencies {
5959
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
6060
// Customer.io SDK
61-
def cioVersion = "4.4.1"
61+
def cioVersion = "4.5.0"
6262
implementation "io.customer.android:datapipelines:$cioVersion"
6363
implementation "io.customer.android:messaging-push-fcm:$cioVersion"
6464
implementation "io.customer.android:messaging-in-app:$cioVersion"

android/src/main/kotlin/io/customer/customer_io/CustomerIOPlugin.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import io.customer.customer_io.bridge.nativeNoArgs
99
import io.customer.customer_io.messaginginapp.CustomerIOInAppMessaging
1010
import io.customer.customer_io.messagingpush.CustomerIOPushMessaging
1111
import io.customer.customer_io.utils.getAs
12+
import io.customer.datapipelines.config.ScreenView
1213
import io.customer.sdk.CustomerIO
1314
import io.customer.sdk.CustomerIOBuilder
1415
import io.customer.sdk.core.di.SDKComponent
@@ -182,13 +183,15 @@ class CustomerIOPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
182183
val logLevelRawValue = args.getAs<String>("logLevel")
183184
val regionRawValue = args.getAs<String>("region")
184185
val givenRegion = regionRawValue.let { Region.getRegion(it) }
186+
val screenViewRawValue = args.getAs<String>("screenViewUse")
185187

186188
CustomerIOBuilder(
187189
applicationContext = application,
188190
cdpApiKey = cdpApiKey
189191
).apply {
190192
logLevelRawValue?.let { logLevel(CioLogLevel.getLogLevel(it)) }
191193
regionRawValue?.let { region(givenRegion) }
194+
screenViewRawValue?.let { screenViewUse(ScreenView.getScreenView(it)) }
192195

193196
args.getAs<String>("migrationSiteId")?.let(::migrationSiteId)
194197
args.getAs<Boolean>("autoTrackDeviceAttributes")?.let(::autoTrackDeviceAttributes)

apps/amiapp_flutter/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
*.swp
66
.DS_Store
77
.atom/
8+
.build/
89
.buildlog/
910
.history
1011
.svn/
12+
.swiftpm/
1113
migrate_working_dir/
1214
fastlane/report.xml
1315

apps/amiapp_flutter/ios/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -------------
22
# This code only used internally for Customer.io testing
33
require 'open-uri'
4-
IO.copy_stream(URI.open('https://raw.githubusercontent.com/customerio/customerio-ios/v2/scripts/cocoapods_override_sdk.rb'), "/tmp/override_cio_sdk.rb")
4+
IO.copy_stream(URI.open('https://raw.githubusercontent.com/customerio/customerio-ios/main/scripts/cocoapods_override_sdk.rb'), "/tmp/override_cio_sdk.rb")
55
load "/tmp/override_cio_sdk.rb"
66
# end of internal Customer.io testing code
77
# -------------

apps/amiapp_flutter/lib/src/customer_io.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class CustomerIOSDK extends ChangeNotifier {
7272
cdnHost: _sdkConfig?.cdnHost,
7373
flushAt: _sdkConfig?.flushAt,
7474
flushInterval: _sdkConfig?.flushInterval?.toInt(),
75+
screenViewUse: _sdkConfig?.screenViewUse,
7576
inAppConfig: inAppConfig,
7677
),
7778
);

apps/amiapp_flutter/lib/src/data/config.dart

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class CustomerIOSDKConfig {
1515
final String? cdnHost;
1616
final int? flushAt;
1717
final int? flushInterval;
18+
final ScreenView? screenViewUse;
1819
final InAppConfig? inAppConfig;
1920
final PushConfig pushConfig;
2021

@@ -29,6 +30,7 @@ class CustomerIOSDKConfig {
2930
this.cdnHost,
3031
this.flushAt,
3132
this.flushInterval,
33+
this.screenViewUse,
3234
this.inAppConfig,
3335
PushConfig? pushConfig,
3436
}) : pushConfig = pushConfig ?? PushConfig();
@@ -45,10 +47,11 @@ class CustomerIOSDKConfig {
4547
throw ArgumentError('cdpApiKey cannot be null');
4648
}
4749

48-
final region = prefs.getString(_PreferencesKey.region) != null
49-
? Region.values.firstWhere(
50-
(e) => e.name == prefs.getString(_PreferencesKey.region))
51-
: null;
50+
final region =
51+
prefs.getEnumValueFromPrefs(_PreferencesKey.region, Region.values);
52+
final screenViewUse = prefs.getEnumValueFromPrefs(
53+
_PreferencesKey.screenViewUse, ScreenView.values);
54+
5255
return CustomerIOSDKConfig(
5356
cdpApiKey: cdpApiKey,
5457
migrationSiteId: prefs.getString(_PreferencesKey.migrationSiteId),
@@ -63,27 +66,11 @@ class CustomerIOSDKConfig {
6366
cdnHost: prefs.getString(_PreferencesKey.cdnHost),
6467
flushAt: prefs.getInt(_PreferencesKey.flushAt),
6568
flushInterval: prefs.getInt(_PreferencesKey.flushInterval),
69+
screenViewUse: screenViewUse,
6670
inAppConfig: InAppConfig(
6771
siteId: prefs.getString(_PreferencesKey.migrationSiteId) ?? ""),
6872
);
6973
}
70-
71-
Map<String, dynamic> toMap() {
72-
return {
73-
'cdpApiKey': cdpApiKey,
74-
'migrationSiteId': migrationSiteId,
75-
'region': region?.name,
76-
'logLevel': debugModeEnabled,
77-
'screenTrackingEnabled': screenTrackingEnabled,
78-
'autoTrackDeviceAttributes': autoTrackDeviceAttributes,
79-
'apiHost': apiHost,
80-
'cdnHost': cdnHost,
81-
'flushAt': flushAt,
82-
'flushInterval': flushInterval,
83-
'inAppConfig': inAppConfig?.toMap(),
84-
'pushConfig': pushConfig.toMap(),
85-
};
86-
}
8774
}
8875

8976
extension ConfigurationPreferencesExtensions on SharedPreferences {
@@ -128,8 +115,18 @@ extension ConfigurationPreferencesExtensions on SharedPreferences {
128115
result = result &&
129116
await setOrRemoveInt(
130117
_PreferencesKey.flushInterval, config.flushInterval);
118+
result = result &&
119+
await setOrRemoveString(
120+
_PreferencesKey.screenViewUse, config.screenViewUse?.name);
131121
return result;
132122
}
123+
124+
T? getEnumValueFromPrefs<T extends Enum>(String key, List<T> values) {
125+
final storedValue = getString(key);
126+
if (storedValue == null) return null;
127+
128+
return values.firstWhere((e) => e.name == storedValue);
129+
}
133130
}
134131

135132
class _PreferencesKey {
@@ -143,4 +140,5 @@ class _PreferencesKey {
143140
static const cdnHost = 'CDN_HOST';
144141
static const flushAt = 'FLUSH_AT';
145142
static const flushInterval = 'FLUSH_INTERVAL';
143+
static const screenViewUse = 'SCREEN_VIEW_USE';
146144
}

apps/amiapp_flutter/lib/src/screens/settings.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:customer_io/config/in_app_config.dart';
22
import 'package:customer_io/customer_io.dart';
3+
import 'package:customer_io/customer_io_enums.dart';
34
import 'package:flutter/material.dart';
45
import 'package:flutter/services.dart';
56
import 'package:go_router/go_router.dart';
@@ -44,6 +45,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
4445
late final TextEditingController _flushAtValueController;
4546
late final TextEditingController _flushIntervalValueController;
4647

48+
late ScreenView _screenViewUse;
4749
late bool _featureTrackScreens;
4850
late bool _featureTrackDeviceAttributes;
4951
late bool _featureDebugMode;
@@ -65,6 +67,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
6567
TextEditingController(text: cioConfig?.flushAt?.toString());
6668
_flushIntervalValueController =
6769
TextEditingController(text: cioConfig?.flushInterval?.toString());
70+
_screenViewUse = cioConfig?.screenViewUse ?? ScreenView.all;
6871
_featureTrackScreens = cioConfig?.screenTrackingEnabled ?? true;
6972
_featureTrackDeviceAttributes =
7073
cioConfig?.autoTrackDeviceAttributes ?? true;
@@ -85,6 +88,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
8588
cdnHost: _cdnHostValueController.text.trim().nullIfEmpty(),
8689
flushAt: _flushAtValueController.text.trim().toIntOrNull(),
8790
flushInterval: _flushIntervalValueController.text.trim().toIntOrNull(),
91+
screenViewUse: _screenViewUse,
8892
screenTrackingEnabled: _featureTrackScreens,
8993
autoTrackDeviceAttributes: _featureTrackDeviceAttributes,
9094
debugModeEnabled: _featureDebugMode,
@@ -119,6 +123,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
119123
_flushAtValueController.text = defaultConfig.flushAt?.toString() ?? '';
120124
_flushIntervalValueController.text =
121125
defaultConfig.flushInterval?.toString() ?? '';
126+
_screenViewUse = defaultConfig.screenViewUse ?? ScreenView.all;
122127
_featureTrackScreens = defaultConfig.screenTrackingEnabled;
123128
_featureTrackDeviceAttributes =
124129
defaultConfig.autoTrackDeviceAttributes ?? true;
@@ -287,6 +292,18 @@ class _SettingsScreenState extends State<SettingsScreen> {
287292
updateState: ((value) =>
288293
setState(() => _featureDebugMode = value)),
289294
),
295+
const SizedBox(height: 8),
296+
ChoiceSettingsFormField<ScreenView>(
297+
labelText: 'ScreenView Use',
298+
semanticsLabel: 'ScreenView options',
299+
value: _screenViewUse,
300+
options: ScreenView.values,
301+
updateState: (ScreenView selected) {
302+
setState(() {
303+
_screenViewUse = selected;
304+
});
305+
},
306+
),
290307
],
291308
),
292309
),

apps/amiapp_flutter/lib/src/utils/extensions.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ extension AmiAppStringExtensions on String {
106106
(min == null || value >= min) &&
107107
(max == null || value <= max);
108108
}
109+
110+
String capitalize() {
111+
return '${this[0].toUpperCase()}${substring(1)}';
112+
}
109113
}
110114

111115
extension LocationExtensions on GoRouter {

apps/amiapp_flutter/lib/src/widgets/settings_form_field.dart

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/material.dart';
22

33
import '../components/text_field_label.dart';
4+
import '../utils/extensions.dart';
45

56
class TextSettingsFormField extends StatelessWidget {
67
const TextSettingsFormField({
@@ -121,3 +122,98 @@ class SwitchSettingsFormField extends StatelessWidget {
121122
);
122123
}
123124
}
125+
126+
class ChoiceSettingsFormField<T> extends StatelessWidget {
127+
const ChoiceSettingsFormField({
128+
super.key,
129+
required this.labelText,
130+
required this.semanticsLabel,
131+
required this.value,
132+
required this.updateState,
133+
required this.options,
134+
this.enabled = true,
135+
});
136+
137+
final String labelText;
138+
final String semanticsLabel;
139+
final T value;
140+
final List<T> options;
141+
final void Function(T) updateState;
142+
final bool enabled;
143+
144+
@override
145+
Widget build(BuildContext context) {
146+
const double defaultBorderRadius = 8.0;
147+
148+
return UnmanagedRestorationScope(
149+
child: Column(
150+
crossAxisAlignment: CrossAxisAlignment.start,
151+
children: [
152+
Text(
153+
labelText,
154+
style: Theme.of(context).textTheme.bodyMedium,
155+
),
156+
const SizedBox(height: 12),
157+
Container(
158+
decoration: BoxDecoration(
159+
color: enabled
160+
? Theme.of(context).colorScheme.surface
161+
: Theme.of(context)
162+
.colorScheme
163+
.onSurface
164+
.withValues(alpha: 0.12),
165+
borderRadius: BorderRadius.circular(defaultBorderRadius),
166+
),
167+
child: Row(
168+
children: options.map((option) {
169+
final bool isSelected = option == value;
170+
return Expanded(
171+
child: GestureDetector(
172+
onTap: enabled
173+
? () {
174+
updateState(option);
175+
}
176+
: null,
177+
child: Container(
178+
padding: const EdgeInsets.symmetric(vertical: 12.0),
179+
decoration: BoxDecoration(
180+
color: isSelected
181+
? Theme.of(context).colorScheme.primary
182+
: Theme.of(context)
183+
.colorScheme
184+
.surfaceContainerHighest,
185+
borderRadius: BorderRadius.only(
186+
topLeft: option == options.first
187+
? const Radius.circular(defaultBorderRadius)
188+
: Radius.zero,
189+
bottomLeft: option == options.first
190+
? const Radius.circular(defaultBorderRadius)
191+
: Radius.zero,
192+
topRight: option == options.last
193+
? const Radius.circular(defaultBorderRadius)
194+
: Radius.zero,
195+
bottomRight: option == options.last
196+
? const Radius.circular(defaultBorderRadius)
197+
: Radius.zero,
198+
),
199+
),
200+
child: Text(
201+
option.toString().split('.').last.capitalize(),
202+
textAlign: TextAlign.center,
203+
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
204+
color: isSelected
205+
? Theme.of(context).colorScheme.onPrimary
206+
: Theme.of(context).colorScheme.onSurface,
207+
),
208+
),
209+
),
210+
),
211+
);
212+
}).toList(),
213+
),
214+
),
215+
],
216+
),
217+
);
218+
}
219+
}

0 commit comments

Comments
 (0)