SplashScreen not loading png file for pwa using ionic - ionic-framework

I used a png file for my splash screen for mac, but the image does not load. The app loads and works, it's the splashscreen with png file that's not working.
I have following on my index.js file :
if (useSplashScreen) {
splashScreen = new CapacitorSplashScreen(mainWindow, {
imageFileName: 'splash.png',
windowHeight: 800,
windowWidth: 600,
loadingText: 'Starting Pinpoint...',
backgroundColor: '#cc0099',
textPercentageFromTop: 85
});
splashScreen.init();
}

try to add splash screen in you config.xml for your browser.
<platform name="browser">
<preference name="SplashScreen" value="assets/img/loading_screen.svg" />
</platform>

Related

Ionic 5 / React: Use ion-icon to embed custom SVG

I have a React app in Ionic 5 and I want to add some custom SVGs to it.
This SO question is about Angular, but my question is about React.
My app folder structure looks like this:
src
assets
listen.svg
SvgListen.tsx
Here is SvgListen.tsx:
import React from 'react';
import { ReactComponent as ListenSvg } from './listen.svg';
import { IonIcon } from '#ionic/react';
const SvgListen = () => (
<>
<ListenSvg />
<IonIcon src="./listen.svg" font-size="48px" />
</>
);
export default SvgListen;
When testing the app in Chrome, I get this HTML:
<ion-icon src="./listen.svg" font-size="48px" role="img" class="ios hydrated"></ion-icon>
The <ListenSvg /> that I imported is displayed correctly; however, the ion-icon is not displayed. There is no error message, either.
I checked this blog post, but no luck with the approach outlined there, either.
How can I show a custom SVG using <IonIcon> in Ionic 5?
According do the Create React App docs you can import images to get their final path in the output bundle:
import React from 'react';
import { IonIcon } from '#ionic/react';
import listenSvg from './listen.svg';
const SvgListen = () => (
<IonIcon src={listenSvg} font-size="48px" />
);
export default SvgListen;

How to change default push notification icon to small icon in Onesignal in ionic 3?

I have a problem to change small icon push notification Onesignal in ionic 3, I have tried this tutorial https://documentation.onesignal.com/docs/customize-notification-icons, https://ionicframework.com/docs/native/onesignal/ and https://github.com/OneSignal/OneSignal-Cordova-SDK/issues/341#issuecomment-382648188, but fail all, small icon in my push notification still default of onesignal.
This is my folder structure and my script :
My folder structure :
copy_android_notification_icons.js :
#!/usr/bin/env node
var fs = require('fs');
var path = require('path');
var rootDest = 'platforms/android/app/src/main/res';
var files = [{
'icon_onesignal/res/drawable-hdpi/ic_stat_onesignal_default.png':
path.join(rootDest, 'drawable-hdpi/ic_stat_onesignal_default.png')
}, {
'icon_onesignal/res/drawable-mdpi/ic_stat_onesignal_default.png':
path.join(rootDest, 'drawable-mdpi/ic_stat_onesignal_default.png')
}, {
'icon_onesignal/res/drawable-xhdpi/ic_stat_onesignal_default.png':
path.join(rootDest, 'drawable-xhdpi/ic_stat_onesignal_default.png')
}, {
'icon_onesignal/res/drawable-xxhdpi/ic_stat_onesignal_default.png':
path.join(rootDest, 'drawable-xxhdpi/ic_stat_onesignal_default.png')
}, {
'icon_onesignal/res/drawable-xxxhdpi/ic_stat_onesignal_default.png':
path.join(rootDest, 'drawable-xxxhdpi/ic_stat_onesignal_default.png')
}];
function createFolder(pathAbsolute) {
if (!fs.existsSync(pathAbsolute)) {
fs.mkdirSync(pathAbsolute);
}
console.log('Folder ready ', pathAbsolute);
}
module.exports = function(context) {
var root = context.opts.projectRoot;
createFolder(path.join(root, rootDest, 'drawable-hdpi'));
createFolder(path.join(root, rootDest, 'drawable-mdpi'));
createFolder(path.join(root, rootDest, 'drawable-xhdpi'));
createFolder(path.join(root, rootDest, 'drawable-xxhdpi'));
createFolder(path.join(root, rootDest, 'drawable-xxxhdpi'));
files.forEach(function(obj) {
Object.keys(obj).forEach(function(key) {
var src = path.join(root, key);
var dest = path.join(root, obj[key]);
if (fs.existsSync(src) && fs.existsSync(path.dirname(dest))) {
fs.createReadStream(src).pipe(fs.createWriteStream(dest));
console.log('Copied ' + src + ' to ' + dest);
}
});
});
};
app.components.ts
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HomePage } from '../pages/home/home';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
var notificationOpenedCallback = function(jsonData) {
console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData));
};
window["plugins"].OneSignal
.startInit("xxxx-yyyy-zzzz-123, "1234567")
.handleNotificationOpened(notificationOpenedCallback)
.endInit();
});
}
}
config.xml
<platform name="android">
<allow-intent href="market:*" />
<hook src="hooks/copy_android_notification_icons.js" type="after_prepare" />
</platform>
Please correct my folder or my script, maybe you find a mistake and please help to solve this problem.
Thanks.
You could follow below steps. Then you no need to touch your platform folder and manually add push notification icons.
Go to Android Asset Studio and generate icons using name
ic_stat_onesignal_default
Then copy those icons into android folder under resources. In my case
it looks like below.
Then in config.xml file add below code.
<!-- Add to your existing android platform sction -->
<platform name="android">
<resource-file src="resources/android/notification/drawable-mdpi/ic_stat_onesignal_default.png" target="app/src/main/res/drawable-mdpi/ic_stat_onesignal_default.png" />
<resource-file src="resources/android/notification/drawable-hdpi/ic_stat_onesignal_default.png" target="app/src/main/res/drawable-hdpi/ic_stat_onesignal_default.png" />
<resource-file src="resources/android/notification/drawable-xhdpi/ic_stat_onesignal_default.png" target="app/src/main/res/drawable-xhdpi/ic_stat_onesignal_default.png" />
<resource-file src="resources/android/notification/drawable-xxhdpi/ic_stat_onesignal_default.png" target="app/src/main/res/drawable-xxhdpi/ic_stat_onesignal_default.png" />
<resource-file src="resources/android/notification/drawable-xxxhdpi/ic_stat_onesignal_default.png" target="app/src/main/res/drawable-xxxhdpi/ic_stat_onesignal_default.png" />
</platform>
Build the project
again.
Now default push notification icon will replace with new one.
Find more details from OneSignal DOC
I was working in OneSignal last week and did the same as you. There are some specific sizes for the Notification.
Generate From Android Assets or online here.
Sizes must be set :
Small Notification Icon (mdpi)- 24x24
Small Notification Icon (hdpi)- 36x36
Small Notification Icon (xhdpi)- 48x48
Small Notification Icon (xxhdpi) - 72x72
Small Notification Icon (xxxhdpi)-96x96
Also, Remember you have to put all icons on the platform folder. For this go to - platform/android/app/src/main/res/ .
Create the drawable folder if not present there. Name should be like - drawable-mdpi, drawable-hdpi and so on.
Note the name you are using for the icon.
Now, From the onesignal panel use the name in small icon options. Example
Hope this will solve your issue.

$cordovaCamera.getPicture does not work in ios 11

I am using a ionic v1 app deployed on an ipad running on ios 11. When I try to run the app in ipad and click on the camera button , nothing happens. It stays as it is. I tried to look for issues mentioned similar to ios 10 and added relevant tags for info.plst file and also added the cross frame security bypass. I looked around but could not any solution to this. I have raised this question only after trying out all possible solutions that were specific for $cordovaCamera not working on ios 10. Even I tried to use the navigator.camera.getPicture() instead of $cordovaCamera.getPicture() but that didnt work either.
In my view I have
<a ng-click="takePicture()" style="color:#fff;">
In controller I have
$scope.takePicture = function (options) {
var options = {
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
quality: 100,
targetWidth: 300,
targetHeight: 300,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false,
correctOrientation:true
};
$cordovaCamera.getPicture(options).then(function(imageData) {
console.log('here');
$scope.pictureUrl = "data:image/jpeg;base64," + imageData;
console.log(imageData);
$scope.img_update = 1;
}, function(err) {
console.log(err);
});
};
In the controller I have also injected $cordovaCamera.
In index.html I have added
<meta http-equiv="Content-Security-Policy" content="default-src * gap://ready file:; script-src &apos;self&apos; &apos;unsafe-inline&apos; &apos;unsafe-eval&apos; *; style-src &apos;self&apos; &apos;unsafe-inline&apos; *">
In config.xml I have added these tags inside platform ios
<plugin name="cordova-plugin-camera" spec="~2.3.0">
<variable name="CAMERA_USAGE_DESCRIPTION" value="The app would like to access the camera when you attach photos to content." />
<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="The app would like to access the photo library when you attach images to content." />
</plugin>
<edit-config target="NSCameraUsageDescription" file="*-Info.plist" mode="merge">
<string>need camera access to take pictures</string>
</edit-config>
<edit-config target="NSPhotoLibraryUsageDescription" file="*-Info.plist" mode="merge">
<string>need to photo library access to get pictures from there</string>
</edit-config>
<edit-config target="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
<string>need location access to find things nearby</string>
</edit-config>
<edit-config target="NSPhotoLibraryAddUsageDescription" file="*-Info.plist" mode="merge">
<string>need to photo library access to save pictures there</string>
</edit-config>
Update latest ios and android version then start following steps.
Step 1) Run this command
ionic cordova plugin rm camera
ionic cordova plugin add cordova-plugin-camera --variable CAMERA_USAGE_DESCRIPTION="your usage message" --variable PHOTOLIBRARY_USAGE_DESCRIPTION="your usage message"
Step 2) Add Options like this
var options = {
// Size
quality: 80,
targetWidth: 1024,
targetHeight: 768,
// Actions
allowEdit: false,
correctOrientation: false,
saveToPhotoAlbum: false,
// iOS
popoverOptions: CameraPopoverOptions,
// Basic
encodingType: Camera.EncodingType.JPEG,
sourceType: Camera.PictureSourceType.CAMERA,
destinationType: this.platform.is('ios') ? Camera.DestinationType.FILE_URI : Camera.DestinationType.DATA_URL,
};
And you Done.

Ionic View - Status bar overlap [duplicate]

How do I avoid ionic header from getting behind ios status bar like this?
I created the header with following code:
<ion-view title="{{title}}" hide-nav-bar="false">
From: http://www.sitepoint.com/5-ionic-app-development-tips-tricks/
Ionic has specific classes to deal with this – platform-ios and platform-cordova. Ionic’s pre-built elements target those classes and add in 20px top margin to the buttons in your header to make up for these situations. To get my own custom elements to do the same, I follow the same pattern. For my .search-bar above, I add a margin if we’ve got a .platform-ios.platform-cordova:not(.fullscreen) body class. Example:
.platform-ios.platform-cordova:not(.fullscreen) .search-bar {
margin-top: 20px;
}
This should be the correct answer.
I have been stuck on the same problem for a long time and none of the above solutions worked for me. Finally, to get the status bar from overlapping on the app's view, I added the following preference to my config.xml file and viola:
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarBackgroundColor" value="#000000" />
<preference name="StatusBarStyle" value="lightcontent" />
This ofcourse requires the plugin: cordova-plugin-statusbar "StatusBar".
Hope this helps.
The solution with StatusBar.styleDefault(); did not work for me, but calling StatusBar.overlaysWebView(false) did the job.
First screenshot is UI of the app before calling StatusBar.overlaysWebView(false), you can see that the iOS status bar is over the app and user cannot click the whole area of menu button:
Now when I call StatusBar.overlaysWebView(false), the iOS status bar is no longer over the menu button:
Finally the problem is solved.
in app.js
$ionicPlatform.ready(function() {
if (window.cordova && $cordovaKeyboard) {
$cordovaKeyboard.hideAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
}
and, if that doesn't solve the problem yet. In index.html, cordova.js should be imported on the very last.
<head>
...
<script src="cordova.js"></script>
</head>
This solve my problem.
adding margin won't work exactly. It will only create an empty space at the bottom of your screen.
The fix is to make sure you have viewport-fit = cover in your app's meta tag.
Try this for Ionic 5.x, just put index.html inside
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
This code is working for me with ionic 3 (3.7.1)
Open App.scss in app folder then add this code:
.platform-ios
{
page-home { // replaced by your page HERE
top: 20px !important;
}
}
Just a quick reminder,
If this issue only happens in some of the subpages, you probably used nav.push() inside a modal(this is depreciated).
To fix this issue, in your modal
import { App, ViewController } from 'ionic-angular';
constructor(
public viewCtrl: ViewController
public app: App
) {}
replace push() with below
//this.navCtrl.push(nextPage);
this.viewCtrl.dismiss();
this.appCtrl.getRootNav().push(nextPage);
I found a better option to do this. In AppModule.ts make change to IonicModule.forRoot(MyApp, {statusbarPadding: true}), and from app.component.ts remove or comment statusBar.overlaysWebView(true); it will fix your problem for IOS.
Add following code in config.xml
<preference name="SplashShowOnlyFirstTime" value="false" /><br>
<preference name="SplashScreen" value="screen" /><br>
<preference name="SplashScreenDelay" value="3000" /><br>
App.component.ts<br>
Inside constructor<br>
this.statusBar.overlaysWebView(false);<br>
this.statusBar.styleLightContent()
#Ferdy-Fauzi's answer did the trick; however, since the index.html gets overwritten on every build here my usage of ionic hooks to apply the changes after every build.
Add hooks in your ionic.config.json file
{
"name": "xxxx",
"integrations": {
"capacitor": {}
},
"type": "vue",
"id": "xxxxx",
"hooks": {
"build:after": "./deploy/after-build.js"
}
}
and then in your project folder (top level) create folder deploy with file after-build.js with following content:
var fs = require('fs')
module.exports = (ctx) => {
const index = `${ctx.project.dir}/dist/index.html`;
fs.readFile(index , 'utf8', (err, html) => {
const meta = '<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />';
html = html.replace(/<meta name="viewport".*?">/, meta);
fs.writeFile(index, html, 'utf8', err => err && console.log( err ));
});
};

Ionic ion-view header behind ios status bar

How do I avoid ionic header from getting behind ios status bar like this?
I created the header with following code:
<ion-view title="{{title}}" hide-nav-bar="false">
From: http://www.sitepoint.com/5-ionic-app-development-tips-tricks/
Ionic has specific classes to deal with this – platform-ios and platform-cordova. Ionic’s pre-built elements target those classes and add in 20px top margin to the buttons in your header to make up for these situations. To get my own custom elements to do the same, I follow the same pattern. For my .search-bar above, I add a margin if we’ve got a .platform-ios.platform-cordova:not(.fullscreen) body class. Example:
.platform-ios.platform-cordova:not(.fullscreen) .search-bar {
margin-top: 20px;
}
This should be the correct answer.
I have been stuck on the same problem for a long time and none of the above solutions worked for me. Finally, to get the status bar from overlapping on the app's view, I added the following preference to my config.xml file and viola:
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarBackgroundColor" value="#000000" />
<preference name="StatusBarStyle" value="lightcontent" />
This ofcourse requires the plugin: cordova-plugin-statusbar "StatusBar".
Hope this helps.
The solution with StatusBar.styleDefault(); did not work for me, but calling StatusBar.overlaysWebView(false) did the job.
First screenshot is UI of the app before calling StatusBar.overlaysWebView(false), you can see that the iOS status bar is over the app and user cannot click the whole area of menu button:
Now when I call StatusBar.overlaysWebView(false), the iOS status bar is no longer over the menu button:
Finally the problem is solved.
in app.js
$ionicPlatform.ready(function() {
if (window.cordova && $cordovaKeyboard) {
$cordovaKeyboard.hideAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
}
and, if that doesn't solve the problem yet. In index.html, cordova.js should be imported on the very last.
<head>
...
<script src="cordova.js"></script>
</head>
This solve my problem.
adding margin won't work exactly. It will only create an empty space at the bottom of your screen.
The fix is to make sure you have viewport-fit = cover in your app's meta tag.
Try this for Ionic 5.x, just put index.html inside
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
This code is working for me with ionic 3 (3.7.1)
Open App.scss in app folder then add this code:
.platform-ios
{
page-home { // replaced by your page HERE
top: 20px !important;
}
}
Just a quick reminder,
If this issue only happens in some of the subpages, you probably used nav.push() inside a modal(this is depreciated).
To fix this issue, in your modal
import { App, ViewController } from 'ionic-angular';
constructor(
public viewCtrl: ViewController
public app: App
) {}
replace push() with below
//this.navCtrl.push(nextPage);
this.viewCtrl.dismiss();
this.appCtrl.getRootNav().push(nextPage);
I found a better option to do this. In AppModule.ts make change to IonicModule.forRoot(MyApp, {statusbarPadding: true}), and from app.component.ts remove or comment statusBar.overlaysWebView(true); it will fix your problem for IOS.
Add following code in config.xml
<preference name="SplashShowOnlyFirstTime" value="false" /><br>
<preference name="SplashScreen" value="screen" /><br>
<preference name="SplashScreenDelay" value="3000" /><br>
App.component.ts<br>
Inside constructor<br>
this.statusBar.overlaysWebView(false);<br>
this.statusBar.styleLightContent()
#Ferdy-Fauzi's answer did the trick; however, since the index.html gets overwritten on every build here my usage of ionic hooks to apply the changes after every build.
Add hooks in your ionic.config.json file
{
"name": "xxxx",
"integrations": {
"capacitor": {}
},
"type": "vue",
"id": "xxxxx",
"hooks": {
"build:after": "./deploy/after-build.js"
}
}
and then in your project folder (top level) create folder deploy with file after-build.js with following content:
var fs = require('fs')
module.exports = (ctx) => {
const index = `${ctx.project.dir}/dist/index.html`;
fs.readFile(index , 'utf8', (err, html) => {
const meta = '<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />';
html = html.replace(/<meta name="viewport".*?">/, meta);
fs.writeFile(index, html, 'utf8', err => err && console.log( err ));
});
};