Skip to content

Commit 8a37253

Browse files
committed
Theming support and images preloading
1 parent 18a68bd commit 8a37253

File tree

14 files changed

+111
-5
lines changed

14 files changed

+111
-5
lines changed

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ android {
5151

5252
dependencies {
5353
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
54-
implementation "io.qonversion:sandwich:7.3.1"
54+
implementation "io.qonversion:sandwich:7.4.0"
5555
implementation 'com.google.code.gson:gson:2.9.0'
5656
}

android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/NoCodesPlugin.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ class NoCodesPlugin(private val messenger: BinaryMessenger, private val context:
8181
val version = args["version"] as? String ?: return result.noNecessaryDataError()
8282
val source = args["source"] as? String ?: return result.noNecessaryDataError()
8383
val locale = args["locale"] as? String
84+
val theme = args["theme"] as? String
8485

8586
if (projectKey.isNotEmpty()) {
8687
// Initialize NoCodes Sandwich
8788
noCodesSandwich = NoCodesSandwich()
8889

8990
noCodesSandwich?.storeSdkInfo(context, source, version)
9091

91-
noCodesSandwich?.initialize(context, projectKey, null, null, null, locale)
92+
noCodesSandwich?.initialize(context, projectKey, null, null, null, locale, theme)
9293
noCodesSandwich?.setDelegate(this)
9394
result.success(null)
9495
} else {
@@ -124,6 +125,11 @@ class NoCodesPlugin(private val messenger: BinaryMessenger, private val context:
124125
result.success(null)
125126
}
126127

128+
fun setTheme(theme: String?, result: Result) {
129+
noCodesSandwich?.setTheme(theme)
130+
result.success(null)
131+
}
132+
127133
// MARK: - Purchase Delegate Methods
128134

129135
fun setPurchaseDelegate(result: Result) {

android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/QonversionPlugin.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class QonversionPlugin : MethodCallHandler, FlutterPlugin, ActivityAware {
154154
"setScreenPresentationConfig" -> noCodesPlugin?.setScreenPresentationConfig(args["config"] as? Map<String, Any>, args["contextKey"] as? String, result)
155155
"showNoCodesScreen" -> noCodesPlugin?.showNoCodesScreen(args["contextKey"] as? String, result)
156156
"setNoCodesLocale" -> noCodesPlugin?.setLocale(args["locale"] as? String, result)
157+
"setNoCodesTheme" -> noCodesPlugin?.setTheme(args["theme"] as? String, result)
157158
// NoCodes Purchase Delegate methods
158159
"delegatedPurchaseFailed" -> noCodesPlugin?.delegatedPurchaseFailed(args["errorMessage"] as? String, result)
159160
"delegatedRestoreFailed" -> noCodesPlugin?.delegatedRestoreFailed(args["errorMessage"] as? String, result)

example/lib/screens/no_codes_screen.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class _NoCodesScreenState extends State<NoCodesScreen> {
9292
bool _animated = true;
9393
bool _purchaseDelegateEnabled = false;
9494
SamplePurchaseDelegate? _purchaseDelegate;
95+
NoCodesTheme _selectedTheme = NoCodesTheme.auto;
9596

9697
@override
9798
void dispose() {
@@ -131,6 +132,8 @@ class _NoCodesScreenState extends State<NoCodesScreen> {
131132
const SizedBox(height: 16),
132133
_buildLocaleSection(),
133134
const SizedBox(height: 16),
135+
_buildThemeSection(),
136+
const SizedBox(height: 16),
134137
_buildActionsSection(),
135138
const SizedBox(height: 16),
136139
_buildEventsSection(appState),
@@ -346,6 +349,36 @@ class _NoCodesScreenState extends State<NoCodesScreen> {
346349
);
347350
}
348351

352+
Widget _buildThemeSection() {
353+
return SectionCard(
354+
title: 'Theme',
355+
child: Column(
356+
crossAxisAlignment: CrossAxisAlignment.stretch,
357+
children: [
358+
Text(
359+
'Select theme mode',
360+
style: TextStyle(
361+
fontSize: 13,
362+
fontWeight: FontWeight.w500,
363+
color: Colors.grey.shade700,
364+
),
365+
),
366+
const SizedBox(height: 8),
367+
...NoCodesTheme.values.map((theme) => _buildRadioTile(
368+
title: theme.name,
369+
value: theme,
370+
groupValue: _selectedTheme,
371+
onChanged: (value) {
372+
if (value != null) {
373+
_setTheme(value);
374+
}
375+
},
376+
)),
377+
],
378+
),
379+
);
380+
}
381+
349382
Widget _buildActionsSection() {
350383
return SectionCard(
351384
title: 'Actions',
@@ -507,6 +540,21 @@ class _NoCodesScreenState extends State<NoCodesScreen> {
507540
}
508541
}
509542

543+
void _setTheme(NoCodesTheme theme) async {
544+
try {
545+
debugPrint('🔄 [NoCodes] Setting theme: ${theme.name}');
546+
await NoCodes.getSharedInstance().setTheme(theme);
547+
setState(() {
548+
_selectedTheme = theme;
549+
});
550+
debugPrint('✅ [NoCodes] Theme set');
551+
_showSuccess('Theme set to: ${theme.name}');
552+
} catch (e) {
553+
debugPrint('❌ [NoCodes] Failed to set theme: $e');
554+
_showError('Failed to set theme: $e');
555+
}
556+
}
557+
510558
void _showSuccess(String message) {
511559
ScaffoldMessenger.of(context).showSnackBar(
512560
SnackBar(content: Text(message), backgroundColor: AppTheme.successColor),

ios/Classes/NoCodesPlugin.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ public class NoCodesPlugin: NSObject {
9090

9191
let proxyUrl = args["proxyUrl"] as? String
9292
let locale = args["locale"] as? String
93-
noCodesSandwich?.initialize(projectKey: projectKey, proxyUrl: proxyUrl, locale: locale)
93+
let theme = args["theme"] as? String
94+
noCodesSandwich?.initialize(projectKey: projectKey, proxyUrl: proxyUrl, locale: locale, theme: theme)
9495
result(nil)
9596
}
9697

@@ -126,6 +127,11 @@ public class NoCodesPlugin: NSObject {
126127
result(nil)
127128
}
128129

130+
public func setTheme(_ theme: String?, _ result: @escaping FlutterResult) {
131+
noCodesSandwich?.setTheme(theme)
132+
result(nil)
133+
}
134+
129135
// MARK: - Purchase Delegate Methods
130136

131137
public func setPurchaseDelegate(_ result: @escaping FlutterResult) {

ios/Classes/SwiftQonversionPlugin.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin {
185185
noCodesPlugin?.setLocale(args["locale"] as? String, result)
186186
return
187187

188+
case "setNoCodesTheme":
189+
noCodesPlugin?.setTheme(args["theme"] as? String, result)
190+
return
191+
188192
case "delegatedPurchaseFailed":
189193
noCodesPlugin?.delegatedPurchaseFailed(args, result)
190194
return

ios/qonversion_flutter.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
1616
s.source_files = 'Classes/**/*'
1717
s.dependency 'Flutter'
1818
s.platform = :ios, '13.0'
19-
s.dependency "QonversionSandwich", "7.3.1"
19+
s.dependency "QonversionSandwich", "7.4.0"
2020

2121
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
2222
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }

lib/qonversion_flutter.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export 'src/dto/entitlements_cache_lifetime.dart';
88
export 'src/dto/environment.dart';
99
export 'src/dto/launch_mode.dart';
1010
export 'src/dto/nocodes_events.dart';
11+
export 'src/dto/nocodes_theme.dart';
1112
export 'src/dto/offerings.dart';
1213
export 'src/dto/presentation_config.dart';
1314
export 'src/dto/product.dart';

lib/src/internal/constants.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Constants {
3737
static const kVersion = 'version';
3838
static const kSource = 'source';
3939
static const kLocale = 'locale';
40+
static const kTheme = 'theme';
4041

4142
// MethodChannel methods names
4243
static const mInitialize = 'initialize';
@@ -79,6 +80,7 @@ class Constants {
7980
static const mShowNoCodesScreen = 'showNoCodesScreen';
8081
static const mCloseNoCodes = 'closeNoCodes';
8182
static const mSetNoCodesLocale = 'setNoCodesLocale';
83+
static const mSetNoCodesTheme = 'setNoCodesTheme';
8284
static const mSetNoCodesPurchaseDelegate = 'setNoCodesPurchaseDelegate';
8385
static const mDelegatedPurchaseCompleted = 'delegatedPurchaseCompleted';
8486
static const mDelegatedPurchaseFailed = 'delegatedPurchaseFailed';

lib/src/internal/nocodes_internal.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:qonversion_flutter/src/internal/qonversion_internal.dart';
77
import '../dto/nocodes_events.dart';
88
import '../dto/presentation_config.dart';
99
import '../dto/product.dart';
10+
import '../dto/nocodes_theme.dart';
1011
import '../nocodes_config.dart';
1112
import '../nocodes.dart';
1213
import '../nocodes_purchase_delegate.dart';
@@ -48,6 +49,7 @@ class NoCodesInternal implements NoCodes {
4849
Constants.kSource: Constants.sdkSource,
4950
if (config.proxyUrl != null) Constants.kProxyUrl: config.proxyUrl,
5051
if (config.locale != null) Constants.kLocale: config.locale,
52+
if (config.theme != null) Constants.kTheme: config.theme!.name,
5153
};
5254
// Initialize is fire-and-forget, errors will be handled in subsequent calls
5355
_channel.invokeMethod(Constants.mInitializeNoCodes, args).catchError((error) {
@@ -191,6 +193,15 @@ class NoCodesInternal implements NoCodes {
191193
await _invokeMethod(Constants.mSetNoCodesLocale, {Constants.kLocale: locale});
192194
}
193195

196+
@override
197+
Future<void> setTheme(NoCodesTheme theme) async {
198+
if (Platform.isMacOS) {
199+
return;
200+
}
201+
202+
await _invokeMethod(Constants.mSetNoCodesTheme, {Constants.kTheme: theme.name});
203+
}
204+
194205
@override
195206
Future<void> setPurchaseDelegate(NoCodesPurchaseDelegate delegate) async {
196207
if (Platform.isMacOS) {

0 commit comments

Comments
 (0)