Skip to content

Commit e14f29d

Browse files
a7medevHeshamMegid
authored andcommitted
[EP-354] Add Custom Logo API (#290)
1 parent 81991a4 commit e14f29d

File tree

7 files changed

+130
-0
lines changed

7 files changed

+130
-0
lines changed

android/src/main/java/com/instabug/flutter/modules/InstabugApi.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import android.app.Application;
44
import android.content.Context;
55
import android.graphics.Bitmap;
6+
import android.graphics.BitmapFactory;
67
import android.net.Uri;
78
import android.util.Log;
89

@@ -26,14 +27,18 @@
2627
import org.json.JSONObject;
2728

2829
import java.io.File;
30+
import java.io.IOException;
31+
import java.io.InputStream;
2932
import java.lang.reflect.Method;
3033
import java.util.HashMap;
3134
import java.util.List;
3235
import java.util.Locale;
3336
import java.util.Map;
3437
import java.util.concurrent.Callable;
3538

39+
import io.flutter.FlutterInjector;
3640
import io.flutter.plugin.common.BinaryMessenger;
41+
import io.flutter.embedding.engine.loader.FlutterLoader;
3742

3843
public class InstabugApi implements InstabugPigeon.InstabugHostApi {
3944
private final String TAG = InstabugApi.class.getName();
@@ -269,6 +274,43 @@ public void reportScreenChange(@NonNull String screenName) {
269274
}
270275
}
271276

277+
private Bitmap getBitmapForAsset(String assetName) {
278+
try {
279+
FlutterLoader loader = FlutterInjector.instance().flutterLoader();
280+
String key = loader.getLookupKeyForAsset(assetName);
281+
InputStream stream = context.getAssets().open(key);
282+
return BitmapFactory.decodeStream(stream);
283+
} catch (IOException exception) {
284+
return null;
285+
}
286+
}
287+
288+
@Override
289+
public void setCustomBrandingImage(@NonNull String light, @NonNull String dark) {
290+
try {
291+
Bitmap lightLogoVariant = getBitmapForAsset(light);
292+
Bitmap darkLogoVariant = getBitmapForAsset(dark);
293+
294+
if (lightLogoVariant == null) {
295+
lightLogoVariant = darkLogoVariant;
296+
}
297+
if (darkLogoVariant == null) {
298+
darkLogoVariant = lightLogoVariant;
299+
}
300+
if (lightLogoVariant == null) {
301+
throw new Exception("Couldn't find the light or dark logo images");
302+
}
303+
304+
Method method = Reflection.getMethod(Class.forName("com.instabug.library.Instabug"), "setCustomBrandingImage", Bitmap.class, Bitmap.class);
305+
306+
if (method != null) {
307+
method.invoke(null, lightLogoVariant, darkLogoVariant);
308+
}
309+
} catch (Exception e) {
310+
e.printStackTrace();
311+
}
312+
}
313+
272314
@Override
273315
public void addFileAttachmentWithURL(@NonNull String filePath, @NonNull String fileName) {
274316
final File file = new File(filePath);

example/ios/InstabugSampleTests/InstabugSampleTests.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,18 @@ - (void) testLogout {
1818
[[[mInstabug verify] classMethod] logOut];
1919
}
2020

21+
- (void) testSetCustomBrandingImage {
22+
id mInstabug = OCMClassMock([Instabug class]);
23+
InstabugApi *api = [[InstabugApi alloc] init];
24+
id mApi = OCMPartialMock(api);
25+
NSString *lightImage = @"images/light_logo.jpeg";
26+
NSString *darkImage = @"images/dark_logo.jpeg";
27+
FlutterError *error;
28+
29+
OCMStub([mApi getImageForAsset:[OCMArg isKindOfClass:[NSString class]]]).andReturn([UIImage new]);
30+
31+
[api setCustomBrandingImageLight:lightImage dark:darkImage error:&error];
32+
[[[mInstabug verify] classMethod] setCustomBrandingImage:[OCMArg isKindOfClass:[UIImageAsset class]]];
33+
}
34+
2135
@end

ios/Classes/Modules/InstabugApi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33
extern void InitInstabugApi(id<FlutterBinaryMessenger> messenger);
44

55
@interface InstabugApi : NSObject <InstabugHostApi>
6+
7+
- (UIImage *)getImageForAsset:(NSString *)assetName;
8+
69
@end

ios/Classes/Modules/InstabugApi.m

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,41 @@ - (void)setReproStepsModeMode:(NSString *)mode error:(FlutterError *_Nullable *_
148148
[Instabug setReproStepsMode:resolvedMode];
149149
}
150150

151+
- (UIImage *)getImageForAsset:(NSString *)assetName {
152+
NSString *key = [FlutterDartProject lookupKeyForAsset:assetName];
153+
NSString *path = [[NSBundle mainBundle] pathForResource:key ofType:nil];
154+
155+
return [UIImage imageWithContentsOfFile:path];
156+
}
157+
158+
- (void)setCustomBrandingImageLight:(NSString *)light dark:(NSString *)dark error:(FlutterError * _Nullable __autoreleasing *)error {
159+
UIImage *lightImage = [self getImageForAsset:light];
160+
UIImage *darkImage = [self getImageForAsset:dark];
161+
162+
if (!lightImage) {
163+
lightImage = darkImage;
164+
}
165+
if (!darkImage) {
166+
darkImage = lightImage;
167+
}
168+
169+
if (@available(iOS 12.0, *)) {
170+
UIImageAsset *imageAsset = [[UIImageAsset alloc] init];
171+
172+
[imageAsset registerImage:lightImage withTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
173+
[imageAsset registerImage:darkImage withTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]];
174+
175+
Instabug.customBrandingImage = imageAsset;
176+
} else {
177+
UIImage *defaultImage = lightImage;
178+
if (!lightImage) {
179+
defaultImage = darkImage;
180+
}
181+
182+
Instabug.customBrandingImage = defaultImage.imageAsset;
183+
}
184+
}
185+
151186
- (void)reportScreenChangeScreenName:(NSString *)screenName error:(FlutterError *_Nullable *_Nonnull)error {
152187
SEL setPrivateApiSEL = NSSelectorFromString(@"logViewDidAppearEvent:");
153188
if ([[Instabug class] respondsToSelector:setPrivateApiSEL]) {

lib/src/modules/instabug.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'dart:typed_data';
88
// ignore: unnecessary_import
99
import 'dart:ui';
1010

11+
import 'package:flutter/material.dart';
1112
import 'package:flutter/services.dart';
1213
import 'package:instabug_flutter/generated/instabug.api.g.dart';
1314
import 'package:instabug_flutter/instabug_flutter.dart';
@@ -346,6 +347,25 @@ class Instabug {
346347
return _host.setReproStepsMode(reproStepsMode.toString());
347348
}
348349

350+
/// Sets a custom branding image logo with [light] and [dark] images for different color modes.
351+
///
352+
/// If no [context] is passed, [asset variants](https://docs.flutter.dev/development/ui/assets-and-images#asset-variants) won't work as expected;
353+
/// if you have different variants of the [light] or [dark] image assets make sure to pass the [context] in order for the right variant to be picked up.
354+
static Future<void> setCustomBrandingImage({
355+
required AssetImage light,
356+
required AssetImage dark,
357+
BuildContext? context,
358+
}) async {
359+
var configuration = ImageConfiguration.empty;
360+
if (context != null) {
361+
configuration = createLocalImageConfiguration(context);
362+
}
363+
364+
final lightKey = await light.obtainKey(configuration);
365+
final darkKey = await dark.obtainKey(configuration);
366+
return _host.setCustomBrandingImage(lightKey.name, darkKey.name);
367+
}
368+
349369
/// Android Only
350370
/// Enables all Instabug functionality
351371
@Deprecated(

pigeons/instabug.api.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ abstract class InstabugHostApi {
4545
void setReproStepsMode(String mode);
4646
void reportScreenChange(String screenName);
4747

48+
void setCustomBrandingImage(String light, String dark);
49+
4850
void addFileAttachmentWithURL(String filePath, String fileName);
4951
void addFileAttachmentWithData(Uint8List data, String fileName);
5052
void clearFileAttachments();

test/instabug_test.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,20 @@ void main() {
301301
).called(1);
302302
});
303303

304+
test('[setCustomBrandingImage] should call host method', () async {
305+
const lightImage = 'images/light_logo.jpeg';
306+
const darkImage = 'images/dark_logo.jpeg';
307+
308+
await Instabug.setCustomBrandingImage(
309+
light: const AssetImage(lightImage),
310+
dark: const AssetImage(darkImage),
311+
);
312+
313+
verify(
314+
mHost.setCustomBrandingImage(lightImage, darkImage),
315+
).called(1);
316+
});
317+
304318
test('[reportScreenChange] should call host method', () async {
305319
const screen = "home";
306320

0 commit comments

Comments
 (0)