Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(statusbar)!: implement overlay and background color in iOS #2179

Merged
merged 5 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
78 changes: 61 additions & 17 deletions status-bar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ The status bar visibility defaults to visible and the style defaults to
`Style.Default`. You can change these defaults by adding
`UIStatusBarHidden` and/or `UIStatusBarStyle` in `Info.plist`.

`setBackgroundColor` and `setOverlaysWebView` are currently not supported on
iOS devices.

## Example

```typescript
Expand All @@ -33,7 +30,7 @@ window.addEventListener('statusTap', function () {
console.log('statusbar tapped');
});

// Display content under transparent status bar (Android only)
// Display content under transparent status bar
StatusBar.setOverlaysWebView({ overlay: true });

const setStatusBarStyleDark = async () => {
Expand All @@ -53,6 +50,57 @@ const showStatusBar = async () => {
};
```

## Configuration

<docgen-config>
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->

These config values are available:

| Prop | Type | Description | Default | Since |
| --------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------- | -------------------- | ----- |
| **`overlaysWebView`** | <code>boolean</code> | Whether the statusbar is overlaid or not. | <code>true</code> | 1.0.0 |
| **`style`** | <code>string</code> | <a href="#style">Style</a> of the text of the status bar. | <code>default</code> | 1.0.0 |
| **`backgroundColor`** | <code>string</code> | Color of the background of the statusbar in hex format, #RRGGBB. Doesn't work if `overlaysWebView` is true. | <code>#000000</code> | 1.0.0 |

### Examples

In `capacitor.config.json`:

```json
{
"plugins": {
"StatusBar": {
"overlaysWebView": false,
"style": "DARK",
"backgroundColor": "#ffffffff"
}
}
}
```

In `capacitor.config.ts`:

```ts
/// <reference types="@capacitor/status-bar" />

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
plugins: {
StatusBar: {
overlaysWebView: false,
style: "DARK",
backgroundColor: "#ffffffff",
},
},
};

export default config;
```

</docgen-config>

## API

<docgen-index>
Expand Down Expand Up @@ -96,8 +144,6 @@ setBackgroundColor(options: BackgroundColorOptions) => Promise<void>

Set the background color of the status bar.

This method is only supported on Android.

| Param | Type |
| ------------- | ------------------------------------------------------------------------- |
| **`options`** | <code><a href="#backgroundcoloroptions">BackgroundColorOptions</a></code> |
Expand Down Expand Up @@ -169,8 +215,6 @@ setOverlaysWebView(options: SetOverlaysWebViewOptions) => Promise<void>
Set whether or not the status bar should overlay the webview to allow usage
of the space underneath it.

This method is only supported on Android.

| Param | Type |
| ------------- | ------------------------------------------------------------------------------- |
| **`options`** | <code><a href="#setoverlayswebviewoptions">SetOverlaysWebViewOptions</a></code> |
Expand All @@ -192,9 +236,9 @@ This method is only supported on Android.

#### BackgroundColorOptions

| Prop | Type | Description | Since |
| ----------- | ------------------- | ------------------------------------------------------------------------------------------- | ----- |
| **`color`** | <code>string</code> | A hex color to which the status bar color is set. This option is only supported on Android. | 1.0.0 |
| Prop | Type | Description | Since |
| ----------- | ------------------- | ------------------------------------------------- | ----- |
| **`color`** | <code>string</code> | A hex color to which the status bar color is set. | 1.0.0 |


#### AnimationOptions
Expand All @@ -206,12 +250,12 @@ This method is only supported on Android.

#### StatusBarInfo

| Prop | Type | Description | Since |
| -------------- | --------------------------------------- | ----------------------------------------------------------------------------------- | ----- |
| **`visible`** | <code>boolean</code> | Whether the status bar is visible or not. | 1.0.0 |
| **`style`** | <code><a href="#style">Style</a></code> | The current status bar style. | 1.0.0 |
| **`color`** | <code>string</code> | The current status bar color. This option is only supported on Android. | 1.0.0 |
| **`overlays`** | <code>boolean</code> | Whether the statusbar is overlaid or not. This option is only supported on Android. | 1.0.0 |
| Prop | Type | Description | Since |
| -------------- | --------------------------------------- | ----------------------------------------- | ----- |
| **`visible`** | <code>boolean</code> | Whether the status bar is visible or not. | 1.0.0 |
| **`style`** | <code><a href="#style">Style</a></code> | The current status bar style. | 1.0.0 |
| **`color`** | <code>string</code> | The current status bar color. | 1.0.0 |
| **`overlays`** | <code>boolean</code> | Whether the statusbar is overlaid or not. | 1.0.0 |


#### SetOverlaysWebViewOptions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.capacitorjs.plugins.statusbar;

import android.graphics.Color;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
Expand All @@ -16,11 +17,15 @@ public class StatusBar {
private final AppCompatActivity activity;
private final String defaultStyle;

public StatusBar(AppCompatActivity activity) {
public StatusBar(AppCompatActivity activity, StatusBarConfig config) {
// save initial color of the status bar
this.activity = activity;
this.currentStatusBarColor = activity.getWindow().getStatusBarColor();
this.defaultStyle = getStyle();

setBackgroundColor(config.getBackgroundColor());
setStyle(config.getStyle());
setOverlaysWebView(config.isOverlaysWebView());
}

public void setStyle(String style) {
Expand Down Expand Up @@ -93,6 +98,7 @@ public StatusBarInfo getInfo() {
info.setOverlays(getIsOverlaid());
info.setVisible(isVisible);
info.setColor(String.format("#%06X", (0xFFFFFF & window.getStatusBarColor())));
info.setHeight(getStatusBarHeight());
return info;
}

Expand All @@ -105,4 +111,17 @@ private String getStyle() {
}
return style;
}

private int getStatusBarHeight() {
int statusbarHeight = 0;
int resourceId = activity.getApplicationContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusbarHeight = (int) activity.getApplicationContext().getResources().getDimension(resourceId);
}

DisplayMetrics metrics = activity.getApplicationContext().getResources().getDisplayMetrics();
float densityDpi = metrics.density;

return (int) (statusbarHeight / densityDpi);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.capacitorjs.plugins.statusbar;

import com.getcapacitor.util.WebColor;

public class StatusBarConfig {
theproducer marked this conversation as resolved.
Show resolved Hide resolved

private boolean overlaysWebView = true;
private Integer backgroundColor = WebColor.parseColor("#000000");
private String style = "DEFAULT";

public boolean isOverlaysWebView() {
return overlaysWebView;
}

public void setOverlaysWebView(boolean overlaysWebView) {
this.overlaysWebView = overlaysWebView;
}

public Integer getBackgroundColor() {
return backgroundColor;
}

public void setBackgroundColor(Integer backgroundColor) {
this.backgroundColor = backgroundColor;
}

public String getStyle() {
return style;
}

public void setStyle(String style) {
this.style = style;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.capacitorjs.plugins.statusbar;

public class StatusBarInfo {
import java.io.Serializable;

public class StatusBarInfo implements Serializable {

private boolean overlays;
private boolean visible;
private String style;
private String color;
private int height;

public boolean isOverlays() {
return overlays;
Expand Down Expand Up @@ -38,4 +41,12 @@ public String getColor() {
public void setColor(String color) {
this.color = color;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.capacitorjs.plugins.statusbar;

import com.getcapacitor.JSObject;
import com.getcapacitor.Logger;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
Expand All @@ -11,11 +12,44 @@
@CapacitorPlugin(name = "StatusBar")
public class StatusBarPlugin extends Plugin {

public static final String statusBarVisibilityChanged = "statusBarVisibilityChanged";
public static final String statusBarOverlayChanged = "statusBarOverlayChanged";

private StatusBar implementation;

@Override
public void load() {
implementation = new StatusBar(getActivity());
StatusBarConfig config = getStatusBarConfig();
implementation = new StatusBar(getActivity(), config);
}

private StatusBarConfig getStatusBarConfig() {
StatusBarConfig config = new StatusBarConfig();
String backgroundColor = getConfig().getString("backgroundColor");
if (backgroundColor != null) {
try {
config.setBackgroundColor(WebColor.parseColor(backgroundColor));
} catch (IllegalArgumentException ex) {
Logger.debug("Background color not applied");
}
}
config.setStyle(styleFromConfig(getConfig().getString("style", config.getStyle())));
config.setOverlaysWebView(getConfig().getBoolean("overlaysWebView", config.isOverlaysWebView()));
return config;
}

private String styleFromConfig(String style) {
switch (style.toLowerCase()) {
case "lightcontent":
case "dark":
return "DARK";
case "darkcontent":
case "light":
return "LIGHT";
case "default":
default:
return "DEFAULT";
}
}

@PluginMethod
Expand Down Expand Up @@ -64,6 +98,8 @@ public void hide(final PluginCall call) {
.executeOnMainThread(
() -> {
implementation.hide();
StatusBarInfo info = implementation.getInfo();
notifyListeners(statusBarVisibilityChanged, toJSObject(info));
call.resolve();
}
);
Expand All @@ -76,6 +112,8 @@ public void show(final PluginCall call) {
.executeOnMainThread(
() -> {
implementation.show();
StatusBarInfo info = implementation.getInfo();
notifyListeners(statusBarVisibilityChanged, toJSObject(info));
call.resolve();
}
);
Expand All @@ -84,13 +122,7 @@ public void show(final PluginCall call) {
@PluginMethod
public void getInfo(final PluginCall call) {
StatusBarInfo info = implementation.getInfo();

JSObject data = new JSObject();
data.put("visible", info.isVisible());
data.put("style", info.getStyle());
data.put("color", info.getColor());
data.put("overlays", info.isOverlays());
call.resolve(data);
call.resolve(toJSObject(info));
}

@PluginMethod
Expand All @@ -100,8 +132,20 @@ public void setOverlaysWebView(final PluginCall call) {
.executeOnMainThread(
() -> {
implementation.setOverlaysWebView(overlays);
StatusBarInfo info = implementation.getInfo();
notifyListeners(statusBarOverlayChanged, toJSObject(info));
call.resolve();
}
);
}

private JSObject toJSObject(StatusBarInfo info) {
JSObject data = new JSObject();
data.put("visible", info.isVisible());
data.put("style", info.getStyle());
data.put("color", info.getColor());
data.put("overlays", info.isOverlays());
data.put("height", info.getHeight());
return data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Capacitor

extension CAPBridgeViewController {

open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
NotificationCenter.default.post(Notification(name: .capacitorViewDidAppear))
}

open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
NotificationCenter.default.post(Notification(name: .capacitorViewWillTransition))
}
}
6 changes: 6 additions & 0 deletions status-bar/ios/Sources/StatusBarPlugin/CAPNotifications.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Capacitor

extension Notification.Name {
public static let capacitorViewDidAppear = Notification.Name(rawValue: "CapacitorViewDidAppear")
public static let capacitorViewWillTransition = Notification.Name(rawValue: "CapacitorViewWillTransition")
}
Loading
Loading