Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
# Changelog

## [15.0.2](https://github.com/Instabug/Instabug-Flutter/compare/v14.3.0...15.0.2) (Jul 7, 2025)
## [Unreleased](https://github.com/Instabug/Instabug-Flutter/compare/v15.0.2...dev)

### Added

- Add support for Advanced UI customization with comprehensive theming capabilities ([#599](https://github.com/Instabug/Instabug-Flutter/pull/599))
-
- Add support for App variant. ([#585](https://github.com/Instabug/Instabug-Flutter/pull/585))

### Changed

- **BREAKING** Remove deprecated APIs ([#614](https://github.com/Instabug/Instabug-Flutter/pull/614)). See migration guide for more details.


## [15.0.2](https://github.com/Instabug/Instabug-Flutter/compare/v14.3.0...15.0.2) (Jul 7, 2025)

### Added


- Add support for xCode 16. ([#574](https://github.com/Instabug/Instabug-Flutter/pull/574))

- Add support for BugReporting user consents. ([#573](https://github.com/Instabug/Instabug-Flutter/pull/573))
Expand Down
74 changes: 1 addition & 73 deletions android/src/main/java/com/instabug/flutter/modules/ApmApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.instabug.apm.InternalAPM;
import com.instabug.apm.configuration.cp.APMFeature;
import com.instabug.apm.configuration.cp.FeatureAvailabilityCallback;
import com.instabug.apm.model.ExecutionTrace;
import com.instabug.apm.networking.APMNetworkLogger;
import com.instabug.apm.networkinterception.cp.APMCPNetworkLog;
import com.instabug.flutter.generated.ApmPigeon;
Expand All @@ -26,7 +25,6 @@

public class ApmApi implements ApmPigeon.ApmHostApi {
private final String TAG = ApmApi.class.getName();
private final HashMap<String, ExecutionTrace> traces = new HashMap<>();

public static void init(BinaryMessenger messenger) {
final ApmApi api = new ApmApi();
Expand Down Expand Up @@ -98,45 +96,7 @@ public void setAutoUITraceEnabled(@NonNull Boolean isEnabled) {
*
* @deprecated see {@link #startFlow}
*/
@Override
public void startExecutionTrace(@NonNull String id, @NonNull String name, ApmPigeon.Result<String> result) {
ThreadManager.runOnBackground(
new Runnable() {
@Override
public void run() {
try {
ExecutionTrace trace = APM.startExecutionTrace(name);
if (trace != null) {
traces.put(id, trace);

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(id);
}
});
} else {
ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(null);
}
});
}
} catch (Exception e) {
e.printStackTrace();

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(null);
}
});
}
}
}
);
}


/**
* Starts an AppFlow with the specified name.
Expand Down Expand Up @@ -201,39 +161,7 @@ public void endFlow(@NonNull String name) {
}
}

/**
* Adds a new attribute to trace
*
* @param id String id of the trace.
* @param key attribute key
* @param value attribute value. Null to remove attribute
*
* @deprecated see {@link #setFlowAttribute}
*/
@Override
public void setExecutionTraceAttribute(@NonNull String id, @NonNull String key, @NonNull String value) {
try {
traces.get(id).setAttribute(key, value);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Ends a trace
*
* @param id string id of the trace.
*
* @deprecated see {@link #endFlow}
*/
@Override
public void endExecutionTrace(@NonNull String id) {
try {
traces.get(id).end();
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Starts a UI trace.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public void setCommentMinimumCharacterCount(@NonNull Long limit, @Nullable List<
reportTypesArray[i] = ArgsRegistry.reportTypes.get(key);
}
}
BugReporting.setCommentMinimumCharacterCount(limit.intValue(), reportTypesArray);
BugReporting.setCommentMinimumCharacterCountForBugReportType(limit.intValue(), reportTypesArray);
}

@Override
Expand Down
179 changes: 165 additions & 14 deletions android/src/main/java/com/instabug/flutter/modules/InstabugApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.graphics.Typeface;
import android.util.Log;

import androidx.annotation.NonNull;
Expand Down Expand Up @@ -196,7 +197,6 @@ public void setWelcomeMessageMode(@NonNull String mode) {

@Override
public void setPrimaryColor(@NonNull Long color) {
Instabug.setPrimaryColor(color.intValue());
}

@Override
Expand Down Expand Up @@ -248,20 +248,7 @@ public void run() {
);
}

@Override
public void addExperiments(@NonNull List<String> experiments) {
Instabug.addExperiments(experiments);
}

@Override
public void removeExperiments(@NonNull List<String> experiments) {
Instabug.removeExperiments(experiments);
}

@Override
public void clearAllExperiments() {
Instabug.clearAllExperiments();
}

@Override
public void addFeatureFlags(@NonNull Map<String, String> featureFlags) {
Expand Down Expand Up @@ -529,4 +516,168 @@ public void setNetworkLogBodyEnabled(@NonNull Boolean isEnabled) {
e.printStackTrace();
}
}

@Override
public void setTheme(@NonNull Map<String, Object> themeConfig) {
try {
Log.d(TAG, "setTheme called with config: " + themeConfig.toString());

com.instabug.library.model.IBGTheme.Builder builder = new com.instabug.library.model.IBGTheme.Builder();

if (themeConfig.containsKey("primaryColor")) {
builder.setPrimaryColor(getColor(themeConfig, "primaryColor"));
}
if (themeConfig.containsKey("secondaryTextColor")) {
builder.setSecondaryTextColor(getColor(themeConfig, "secondaryTextColor"));
}
if (themeConfig.containsKey("primaryTextColor")) {
builder.setPrimaryTextColor(getColor(themeConfig, "primaryTextColor"));
}
if (themeConfig.containsKey("titleTextColor")) {
builder.setTitleTextColor(getColor(themeConfig, "titleTextColor"));
}
if (themeConfig.containsKey("backgroundColor")) {
builder.setBackgroundColor(getColor(themeConfig, "backgroundColor"));
}

if (themeConfig.containsKey("primaryTextStyle")) {
builder.setPrimaryTextStyle(getTextStyle(themeConfig, "primaryTextStyle"));
}
if (themeConfig.containsKey("secondaryTextStyle")) {
builder.setSecondaryTextStyle(getTextStyle(themeConfig, "secondaryTextStyle"));
}
if (themeConfig.containsKey("ctaTextStyle")) {
builder.setCtaTextStyle(getTextStyle(themeConfig, "ctaTextStyle"));
}

setFontIfPresent(themeConfig, builder, "primaryFontPath", "primaryFontAsset", "primary");
setFontIfPresent(themeConfig, builder, "secondaryFontPath", "secondaryFontAsset", "secondary");
setFontIfPresent(themeConfig, builder, "ctaFontPath", "ctaFontAsset", "CTA");

com.instabug.library.model.IBGTheme theme = builder.build();
Instabug.setTheme(theme);
Log.d(TAG, "Theme applied successfully");

} catch (Exception e) {
Log.e(TAG, "Error in setTheme: " + e.getMessage());
e.printStackTrace();
}
}



/**
* Retrieves a color value from the Map.
*
* @param map The Map object.
* @param key The key to look for.
* @return The parsed color as an integer, or black if missing or invalid.
*/
private int getColor(Map<String, Object> map, String key) {
try {
if (map != null && map.containsKey(key) && map.get(key) != null) {
String colorString = (String) map.get(key);
return android.graphics.Color.parseColor(colorString);
}
} catch (Exception e) {
e.printStackTrace();
}
return android.graphics.Color.BLACK;
}

/**
* Retrieves a text style from the Map.
*
* @param map The Map object.
* @param key The key to look for.
* @return The corresponding Typeface style, or Typeface.NORMAL if missing or invalid.
*/
private int getTextStyle(Map<String, Object> map, String key) {
try {
if (map != null && map.containsKey(key) && map.get(key) != null) {
String style = (String) map.get(key);
switch (style.toLowerCase()) {
case "bold":
return Typeface.BOLD;
case "italic":
return Typeface.ITALIC;
case "bold_italic":
return Typeface.BOLD_ITALIC;
case "normal":
default:
return Typeface.NORMAL;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return Typeface.NORMAL;
}

/**
* Sets a font on the theme builder if the font configuration is present in the theme config.
*
* @param themeConfig The theme configuration map
* @param builder The theme builder
* @param fileKey The key for font file path
* @param assetKey The key for font asset path
* @param fontType The type of font (for logging purposes)
*/
private void setFontIfPresent(Map<String, Object> themeConfig, com.instabug.library.model.IBGTheme.Builder builder,
String fileKey, String assetKey, String fontType) {
if (themeConfig.containsKey(fileKey) || themeConfig.containsKey(assetKey)) {
Typeface typeface = getTypeface(themeConfig, fileKey, assetKey);
if (typeface != null) {
switch (fontType) {
case "primary":
builder.setPrimaryTextFont(typeface);
break;
case "secondary":
builder.setSecondaryTextFont(typeface);
break;
case "CTA":
builder.setCtaTextFont(typeface);
break;
}
}
}
}

private Typeface getTypeface(Map<String, Object> map, String fileKey, String assetKey) {
String fontName = null;

if (assetKey != null && map.containsKey(assetKey) && map.get(assetKey) != null) {
fontName = (String) map.get(assetKey);
} else if (fileKey != null && map.containsKey(fileKey) && map.get(fileKey) != null) {
fontName = (String) map.get(fileKey);
}

if (fontName == null) {
return Typeface.DEFAULT;
}

try {
String assetPath = "fonts/" + fontName;
return Typeface.createFromAsset(context.getAssets(), assetPath);
} catch (Exception e) {
try {
return Typeface.create(fontName, Typeface.NORMAL);
} catch (Exception e2) {
return Typeface.DEFAULT;
}
}
}
/**
* Enables or disables displaying in full-screen mode, hiding the status and navigation bars.
* @param isEnabled A boolean to enable/disable setFullscreen.
*/
@Override
public void setFullscreen(@NonNull final Boolean isEnabled) {
try {
Instabug.setFullscreen(isEnabled);
} catch (Exception e) {
e.printStackTrace();
}
}

}
Loading