I'm working with react navigation 5 :
I created MainStackScreen and AuthStackScreen,
const AuthStack = createStackNavigator();
function AuthStackScreen() {
return (
<AuthStack.Navigator headerMode="none">
<AuthStack.Screen name="Main" component={Main} />
<AuthStack.Screen name="Login" component={Login} />
<AuthStack.Screen name="Registration" component={Registration} />
<AuthStack.Screen name="Home" component={DrawerNavigator} />
<AuthStack.Screen name="Notifications" component={Notifications} />
<AuthStack.Screen name="SmsValidation" component={SmsValidation} />
<AuthStack.Screen name="MoreRegistrationInfo" component={MoreRegistrationInfo} />
</AuthStack.Navigator>
);
}
MainStackScreen :
const MainScreen = createStackNavigator();
function MainStackScreen({navigation}) {
return (
<MainScreen.Navigator>
<MainScreen.Screen name="Main" component={Main} />
<MainScreen.Screen name="SmsValidation" component={SmsValidation} />
<MainScreen.Screen name="MoreRegistrationInfo" component={MoreRegistrationInfo} />
</MainScreen.Navigator>
);
}
I want to prevent IOS swipe action back between Login my screens
You can set gestureEnabled to false in a screen like:
<AuthStack.Screen
name="Login"
component={Login}
options={{gestureEnabled: false}}
/>
Or the whole navigator like:
<AuthStack.Navigator screenOptions={{gestureEnabled: false}}>
...
</AuthStack.Navigator>
/* -------------------------------------------------------------------------- */
/* AUTH STACK */
/* -------------------------------------------------------------------------- */
const AuthStack = createStackNavigator();
function AuthStackScreen() {
return (
<AuthStack.Navigator headerMode="none">
<AuthStack.Screen name="Main" component={Main} />
<AuthStack.Screen name="Login" component={Login} options={{gestureEnabled: false}} />
<AuthStack.Screen
name="Registration"
component={Registration}
options={{gestureEnabled: false}}
/>
<AuthStack.Screen name="Home" component={DrawerNavigator} options={{gestureEnabled: false}} />
<AuthStack.Screen
name="Notifications"
component={Notifications}
options={{gestureEnabled: false}}
/>
<AuthStack.Screen
name="SmsValidation"
component={SmsValidation}
options={{gestureEnabled: false}}
/>
<AuthStack.Screen
name="MoreRegistrationInfo"
component={MoreRegistrationInfo}
options={{gestureEnabled: false}}
/>
</AuthStack.Navigator>
);
}
You can set a beforeRemove listener to prevent going back.
React Navigation Docs
Related
I am required to intergrate Push notifications for both android and IOS using angular Firebase.
I am currently using the video and article:
https://angularfirebase.com/lessons/ionic-native-with-firebase-fcm-push-notifications-ios-android/#Step-3-Broadcast-Messages
Right now, I am having difficulty receiving the notifications on my IOS device.
So far, Android works perfectly. However, when I use the firebase console to push to my iPhone, nothing happens.
Both android and iOS store tokens in firestore.
All the bundle IDs are correct and I followed the steps precicesly to ensure that the right certificates are set up.
Is there anything that I am doing wrong?
+---------------------------------------------------------------------------------+
My steps:
1)
ionic start projectname
2) blank project
3) chose not to use ionic 4
4) chose "y" (yes) for android and iOS integration
5) cd ./projectname
6)
ionic cordova plugin add cordova-plugin-firebase
npm install --save #ionic-native/firebase
7)
npm install --save angularfire2 firebase
8) Adjusted the typescript files accordingly using the tutorial
9) Install rxjs to fix "Object(...)" error
npm i rxjs#^6.0 rxjs-compat
import rxjs-compact to file
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';
import { Observable } from 'rxjs-compat';
import { map } from 'rxjs-compat/operators';
https://stackoverflow.com/a/50447449/6567753
10) Placed GoogleService-Info.plist and google services into the root folder of the project (Where config.xml is)
11) Built Android (works great)
ionic cordova run android -l -c
12) Added IOS and sorted certificates and provisional profiles using: https://medium.com/#felipepucinelli/how-to-add-push-notifications-in-your-cordova-application-using-firebase-69fac067e821
ionic cordova platform add ios
13) Using the firebase console and database, both apps store tokens.
At this point Android pushes - IOS does not
+---------------------------------------------------------------------------------+
app.components.ts below
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';
import { FcmProvider } from '../providers/fcm/fcm';
import { ToastController } from 'ionic-angular';
import { Subject } from 'rxjs/Subject';
import { tap } from 'rxjs/operators';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen,fcm: FcmProvider, toastCtrl: ToastController) {
platform.ready().then(() => {
// Get a FCM token
fcm.getToken()
// Listen to incoming messages
fcm.listenToNotifications().pipe(
tap(msg => {
// show a toast
const toast = toastCtrl.create({
message: msg.body,
duration: 3000
});
toast.present();
})
)
.subscribe()
// 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();
});
}
}
app.module.ts below
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '#ionic-native/splash-screen';
import { StatusBar } from '#ionic-native/status-bar';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { Firebase } from '#ionic-native/firebase';
import { AngularFireModule } from 'angularfire2';
import { AngularFirestoreModule } from 'angularfire2/firestore';
import { FcmProvider } from '../providers/fcm/fcm';
import { HttpClient, HttpClientModule } from '#angular/common/http';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';
import { Observable } from 'rxjs-compat';
const firebase = {
apiKey: "AIzaSyBoxPRJt3_i0UFnIBc4MZGFqq7daVy6t_o",
authDomain: "b13webwrapper.firebaseio.com",
databaseURL: "https://b13webwrapper.firebaseio.com",
projectId: "b13webwrapper",
storageBucket: "b13webwrapper.appspot.com",
messagingSenderId: "456561976577"
// your firebase web config
}
#NgModule({
declarations: [
MyApp,
HomePage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
AngularFireModule.initializeApp(firebase),
AngularFirestoreModule,
HttpClientModule,
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage
],
providers: [
StatusBar,
SplashScreen,
Firebase,
{provide: ErrorHandler, useClass: IonicErrorHandler},
FcmProvider
]
})
export class AppModule {}
home.ts below
For some reason Android will not push without reusing "fcm.getToken()" block in home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { ToastController } from 'ionic-angular';
import { Subject } from 'rxjs/Subject';
import { tap } from 'rxjs/operators';
import { FcmProvider } from '../../providers/fcm/fcm';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController,public fcm: FcmProvider,public toastCtrl: ToastController) {
}
ionViewDidLoad(){
// Get a FCM token
this.fcm.getToken()
// Listen to incoming messages
this.fcm.listenToNotifications().pipe(
tap(msg => {
// show a toast
const toast = this.toastCtrl.create({
message: msg.body,
duration: 3000
});
toast.present();
})
)
.subscribe()
}
}
fcm.ts below
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Firebase } from '#ionic-native/firebase';
import { Platform } from 'ionic-angular';
import { AngularFirestore } from 'angularfire2/firestore';
/*
Generated class for the FcmProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
#Injectable()
export class FcmProvider {
constructor(public http: HttpClient,public firebaseNative: Firebase,
public afs: AngularFirestore,
private platform: Platform) {
console.log('Hello FcmProvider Provider');
}
async getToken() {
let token;
if (this.platform.is('android')) {
token = await this.firebaseNative.getToken()
}
if (this.platform.is('ios')) {
token = await this.firebaseNative.getToken();
await this.firebaseNative.grantPermission();
}
return this.saveTokenToFirestore(token)
}
private saveTokenToFirestore(token) {
if (!token) return;
const devicesRef = this.afs.collection('devices')
const docData = {
token,
userId: 'testUser',
}
return devicesRef.doc(token).set(docData)
}
listenToNotifications() {
return this.firebaseNative.onNotificationOpen()
}
}
config.xml below
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.webwrapper.theapp" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>B13Wrapper</name>
<description>An awesome Ionic/Cordova app.</description>
<author email="hi#ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="ScrollEnabled" value="false" />
<preference name="android-minSdkVersion" value="19" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<preference name="SplashShowOnlyFirstTime" value="false" />
<preference name="SplashScreen" value="screen" />
<preference name="SplashScreenDelay" value="3000" />
<platform name="android">
<allow-intent href="market:*" />
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
<icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
<icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
<icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
<icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
<icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
<splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
<splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
<splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
<splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
<splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
<splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
<splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
<splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
<splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
<splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
<splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
<splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<icon height="57" src="resources/ios/icon/icon.png" width="57" />
<icon height="114" src="resources/ios/icon/icon#2x.png" width="114" />
<icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
<icon height="80" src="resources/ios/icon/icon-40#2x.png" width="80" />
<icon height="120" src="resources/ios/icon/icon-40#3x.png" width="120" />
<icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
<icon height="100" src="resources/ios/icon/icon-50#2x.png" width="100" />
<icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
<icon height="120" src="resources/ios/icon/icon-60#2x.png" width="120" />
<icon height="180" src="resources/ios/icon/icon-60#3x.png" width="180" />
<icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
<icon height="144" src="resources/ios/icon/icon-72#2x.png" width="144" />
<icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
<icon height="152" src="resources/ios/icon/icon-76#2x.png" width="152" />
<icon height="167" src="resources/ios/icon/icon-83.5#2x.png" width="167" />
<icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
<icon height="58" src="resources/ios/icon/icon-small#2x.png" width="58" />
<icon height="87" src="resources/ios/icon/icon-small#3x.png" width="87" />
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
<splash height="1136" src="resources/ios/splash/Default-568h#2x~iphone.png" width="640" />
<splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
<splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
<splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
<splash height="1536" src="resources/ios/splash/Default-Landscape#2x~ipad.png" width="2048" />
<splash height="2048" src="resources/ios/splash/Default-Landscape#~ipadpro.png" width="2732" />
<splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
<splash height="2048" src="resources/ios/splash/Default-Portrait#2x~ipad.png" width="1536" />
<splash height="2732" src="resources/ios/splash/Default-Portrait#~ipadpro.png" width="2048" />
<splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
<splash height="960" src="resources/ios/splash/Default#2x~iphone.png" width="640" />
<splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
<splash height="2732" src="resources/ios/splash/Default#2x~universal~anyany.png" width="2732" />
</platform>
<plugin name="cordova-plugin-whitelist" spec="1.3.3" />
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
<plugin name="cordova-plugin-device" spec="2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
<plugin name="cordova-plugin-ionic-webview" spec="^2.0.0" />
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
<plugin name="cordova-plugin-firebase" spec="2.0.5" />
<allow-navigation href="http://172.16.13.85:8100" sessionid="4a721959" />
<engine name="android" spec="7.1.1" />
<engine name="ios" spec="~4.5.5" />
</widget>
My ( cordova ) app shall download an image from remote, store it persistent on local filesystem and display it. Downloading and storing is no problem. The images are created an the source attributes are set. But what type of URL I ever will use, the image is not displayed. I try to get this work for IOS in a native device.
index.html:
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html> <!--<![endif]-->
<head>
<title>The App</title>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: cdvfile: https://ssl.gstatic.com 'unsafe-eval' https://www.adomain.de; style-src 'self' 'unsafe-inline' https://www.adomain.de; media-src *; script-src 'self' 'unsafe-eval' https://adomain.de; connect-src 'self' https://www.adomain.de; font-src 'self' data: https://www.adomain.de; img-src * filesystem: data: cdvfile:">
</head>
<body>
<div id="links"></div>
<script type="text/javascript" src="public/js/test/test.js"></script>
<script type="text/javascript" src="cordova.js"></script>
</body>
</html>
test.js:
var oRessources = {
ressourcesDir:false,
init:function(){
function initFS(success){
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.PERSISTENT, 0, function (fs) {
success();
});
}
initFS(oRessources.createRessourcesDir);
},
createRessourcesDir:function(){
resolveLocalFileSystemURL(cordova.file.dataDirectory, function(dirEntry){
console.log('datadirectory');
console.log(dirEntry);
dirEntry.getDirectory(
'ressources/',
{create:true},
function(dirEntry){
oRessources.ressourcesDir = dirEntry;
oRessources.download();
},
function(error){
console.log('error');
console.log(error)
}
);
},
function(dirEntry){
console.log('error');
}
);
},
download:function(){
var target = "e44498f0b0964152632bd0c82342914b859c543e.jpeg"
oRessources.ressourcesDir.getFile(
target,
{ create: true, exclusive: false },
function (fileEntry) {
console.log('file created');
console.log(fileEntry);
var oReq = new XMLHttpRequest();
oReq.open("GET", "https://www.adomain.de/api/public/content_images/"+target, true);
oReq.responseType = "blob";
oReq.onload = function (oEvent) {
var blob = oReq.response;
if (blob) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function (e) {
fileEntry.getMetadata(function(meta){
console.log(meta);
}, function(error){
});
var link = document.createElement("A");
link.appendChild(document.createTextNode(fileEntry.toInternalURL()));
link.href = fileEntry.toInternalURL();
document.getElementById('links').appendChild(link);
var image = document.createElement("IMG");
image.src = fileEntry.toInternalURL();
document.getElementById('links').appendChild(image);
var link2 = document.createElement("A");
link2.appendChild(document.createTextNode(fileEntry.toURL()));
link2.href = fileEntry.toURL();
document.getElementById('links').appendChild(link2);
var image2 = document.createElement("IMG");
image2.src = fileEntry.toURL();
document.getElementById('links').appendChild(image2);
var link3 = document.createElement("a");
link3.appendChild(document.createTextNode(fileEntry.toURL().replace("///", "//") ));
link3.href = fileEntry.toURL().replace("///", "//");
document.getElementById('links').appendChild(link3);
var image3 = document.createElement("IMG");
image3.src = fileEntry.toURL().replace("///", "//");
document.getElementById('links').appendChild(image3);
link4 = document.createElement("A");
link4.appendChild(document.createTextNode(fileEntry.fullPath ));
link4.href = fileEntry.fullPath;
document.getElementById('links').appendChild(link4);
var image4 = document.createElement("IMG");
image4.src = fileEntry.fullPath;
document.getElementById('links').appendChild(image4);
console.log(blob);
link5 = document.createElement("A");
link5.appendChild(document.createTextNode(window.URL.createObjectURL(blob) ));
link5.href = window.URL.createObjectURL(blob);
document.getElementById('links').appendChild(link5);
var image5 = document.createElement("IMG");
image5.src = window.URL.createObjectURL(blob);
document.getElementById('links').appendChild(image5);
var readerBlob = new FileReader();
readerBlob.onload = function(event){
console.log('dataURL2');
//console.log(readerBlob.result);
var image6 = document.createElement("IMG");
image6.src = readerBlob.result;
document.getElementById('links').appendChild(image6);
};
console.log('dataURL1');
readerBlob.readAsDataURL(blob);
};
fileWriter.onerror = function (e) {
// you could hook this up with our global error handler, or pass in an error callback
console.log('Write failed: ' + e.toString());
};
fileWriter.write(blob);
});
} else console.error('we didnt get an XHR response!');
};
oReq.onerror = function (oEvent) {
if(oRessources.loadingStack.length > 0){
//oRessources.download();
}else{
oRessources.loading = false;
}
}
oReq.send(null);
},
function (error) {
console.log('error creating file');
console.log(error);
}
);
}
};
document.addEventListener("deviceready", function(){
console.log('DEVICE READY');
oRessources.init();
}, false);
window.onerror = function(message, url, lineNumber){
console.log('Error: '+message+' in '+ url + ' at line '+lineNumber);
}
config.xml:
<?xml version='1.0' encoding='utf-8'?>
<widget id="de.app.app" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>App</name>
<description>
App
</description>
<author email="mail#nils-fett.de" href="http://www.adomain.de">
Nils Fett
</author>
<content src="index.html" />
<access origin="*" />
<access origin="cdvfile://*" />
<access origin="file://*/*" />
<access origin="file:///*/*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<allow-intent href="file://*/*" />
<allow-intent href="file:///*/*" />
<allow-intent href="cdvfile:*" />
<allow-navigation href="*" />
<allow-navigation href="file://*/*" />
<allow-navigation href="file:///*/*" />
<allow-navigation href="cdvfile:*" />
<allow-origin href="file://*/*" />
<allow-origin href="file:///*/*" />
<allow-origin href="cdvfile:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<access origin="*" />
<access origin="cdvfile://*" />
<access origin="file://*/*" />
<access origin="file:///*/*" />
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<allow-intent href="file://*/*" />
<allow-intent href="file:///*/*" />
<allow-intent href="cdvfile:*" />
<allow-navigation href="file://*/*" />
<allow-navigation href="file:///*/*" />
<allow-navigation href="cdvfile:*" />
<allow-origin href="file://*/*" />
<allow-origin href="file:///*/*" />
<allow-origin href="cdvfile:*" />
<splash height="1024" src="lobbe-logo-768x1024.png" width="768" />
<splash height="2048" src="lobbe-logo-1536x2048.png" width="1536" />
<splash height="1536" src="lobbe-logo-2048x1536.png" width="2048" />
</platform>
<preference name="DisallowOverscroll" value="true" />
<preference name="Orientation" value="default" />
<preference name="BackupWebStorage" value="local" />
<preference name="iosPersistentFileLocation" value="library" />
<preference name="AutoHideSplashScreen" value="true" />
<feature name="File">
<param name="ios-package" value="CDVFile" />
</feature>
<feature name="FileTransfer">
<param name="ios-package" value="CDVFileTransfer" />
</feature>
<icon src="lobbe.png" />
<plugin name="cordova-plugin-console" spec="~1.1.0" />
<plugin name="cordova-plugin-device" spec="~2.0.1" />
<plugin name="cordova-plugin-email-composer" spec="~0.8.11" />
<plugin name="cordova-plugin-file" spec="~6.0.1" />
<plugin name="cordova-plugin-inappbrowser" spec="~2.0.1" />
<plugin name="cordova-plugin-network-information" spec="~2.0.1" />
<plugin name="cordova-plugin-splashscreen" spec="~5.0.1" />
<plugin name="cordova-plugin-webserver" spec="~1.0.3" />
<plugin name="cordova-plugin-whitelist" spec="~1.3.3" />
<engine name="ios" spec="~4.2.1" />
</widget>
I think its a kind of restriction added in a newer IOS Version. I heard of a issue of the WKWebView, but threads read that this problem should be solved. Any ideas?
UPDATE:
So sorry, there was no problem with cordova or iOS or filesystem. The problem was, that the image URL were redirected to a html page. So I downloaded HTML and tried to dispay it as image. The code works. toInternalURL, toURL, createObjectURL and readAsDataURL work perfect.
So sorry, there was no problem with cordova or iOS or filesystem. The problem was, that the image URL were redirected to a html page. So I downloaded HTML and tried to dispay it as image. The code works. toInternalURL, toURL, createObjectURL and readAsDataURL work perfect.
I have my code below, basically to print out an image.
private async void imageControl_PrintButtonClick(object sender, RoutedEventArgs e)
{
var createBitmapTask = Task.Run(async () =>
{
var stream = await provider.OpenEntryAsRandomAccessStreamAsync(currentImageFile);
var decoder = await BitmapDecoder.CreateAsync(stream);
return await decoder.GetSoftwareBitmapAsync(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied);
});
var printHelper = new PrintHelper(printPanel);
printHelper.OnPreviewPagesCreated += PrintHelper_OnPreviewPagesCreated;
printPanel.Opacity = 1.0;
var source = new SoftwareBitmapSource();
var bitmap = await createBitmapTask;
await source.SetBitmapAsync(bitmap);
printImage.Source = source;
printFileName.Text = "Hello";
printImage.Height = bitmap.PixelHeight;
printImage.Width = bitmap.PixelWidth;
await printHelper.ShowPrintUIAsync("ZipPicView - " + currentImageFile.ExtractFilename(), true);
printPanel.Opacity = 0;
}
private void PrintHelper_OnPreviewPagesCreated(List<FrameworkElement> obj)
{
ContentDialog dialog = new ContentDialog();
}
However, the print preview shows an empty page. When I print it out, the printer does nothing.
I've tried changing the opacity of the printPanel (which is a Grid object) to non-zero, and the image does display on the screen. Still, the print has nothing on the output page.
I did notice that, on the OnPreviewPagesCreated, its obj parameter has a new object everytime it's called. The first call has one object with both Width and Height as NaN. My guess is because the container has no size, it cannot determine the content size.
Below is the XAML file.
<Page x:Name="page"
x:Class="ZipPicViewUWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ZipPicViewUWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"
mc:Ignorable="d" KeyUp="page_KeyUp" Loaded="page_Loaded" SizeChanged="page_SizeChanged">
<Canvas x:Name="canvas" SizeChanged="canvas_SizeChanged">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Height="1019" Width="1920">
<Grid x:Name="printPanel" Opacity="0">
<StackPanel x:Name="printContent"
Margin="0,0"
Orientation="Vertical">
<TextBlock x:Name="printFileName" />
<Image x:Name="printImage"
Stretch="Fill" />
</StackPanel>
</Grid>
<SplitView x:Name="splitView" DisplayMode="CompactOverlay" PanePlacement="Left" CompactPaneLength="50" OpenPaneLength="300">
<SplitView.Content>
<GridView x:Name="thumbnailGrid" />
</SplitView.Content>
<SplitView.Pane>
<Grid Background="{StaticResource SidebarBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Button x:Name="subFolderButton" Width="50" Height="50" Background="Transparent" Click="subFolderButton_Click">
<SymbolIcon Symbol="List" />
</Button>
<TextBlock VerticalAlignment="Center" Margin="0,15">Folders</TextBlock>
</StackPanel>
<ScrollViewer Grid.Row="1">
<ListView x:Name="subFolderListCtrl" SelectionChanged="subFolderList_SelectionChanged" DataFetchSize="2" Margin="-10,0,0,0" />
</ScrollViewer>
<ProgressRing x:Name="thumbProgress" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="2" Margin="10,0,0,10" />
</Grid>
</SplitView.Pane>
</SplitView>
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="BlurBehavior" Duration="500" AutomaticallyStart="False" />
</interactivity:Interaction.Behaviors>
</Grid>
<Border x:Name="imageBorder" Visibility="Collapsed">
<Image x:Name="image" ManipulationMode="TranslateX" ManipulationCompleted="image_ManipulationCompleted" Tapped="image_Tapped">
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="ImageTransitionBehavior" Duration="500" AutomaticallyStart="False" />
</interactivity:Interaction.Behaviors>
</Image>
</Border>
<local:ViewerControl x:Name="imageControl" Visibility="Collapsed" CloseButtonClick="imageControl_CloseButtonClick" NextButtonClick="imageControl_NextButtonClick" PrevButtonClick="imageControl_PrevButtonClick" SaveButtonClick="imageControl_SaveButtonClick" PrintButtonClick="imageControl_PrintButtonClick" />
<Border x:Name="loadingBorder" Visibility="Collapsed">
<ProgressRing IsActive="True" Width="100" Height="100" />
</Border>
</Canvas>
<Page.TopAppBar>
<CommandBar VerticalContentAlignment="Center" VerticalAlignment="Center">
<CommandBar.Content>
<TextBlock Margin="10,0,0,0" x:Name="filenameTextBlock" Text="<None>" UseLayoutRounding="True" />
</CommandBar.Content>
<AppBarToggleButton x:Name="fullscreenButton" Icon="FullScreen" Label="FullScreen" Checked="fullscreenButton_Checked" Unchecked="fullscreenButton_Unchecked" />
<AppBarSeparator />
<AppBarButton x:Name="openFileButton" Icon="OpenFile" Label="Open File" Click="openFileButton_Click" />
<AppBarButton x:Name="openFolderButton" Icon="Folder" Label="Open Folder" Click="openFolderButton_Click" />
</CommandBar>
</Page.TopAppBar>
</Page>
And the source code is here : https://github.com/wutipong/ZipPicViewCS/tree/master/ZipPicViewUWP
I'm using gxt 3.0.1 and gwt 2.5.1.
I’ve created FramedPanel and Widget with UiBinder and it works fine. Widget inherits from Composite. After adding Widget to FramedPanel it doesn't show up.
Before:
After:
Main View:
<ui:with type="com.sencha.gxt.core.client.util.Margins" field="centerMargins">
<ui:attributes top="4" right="4" bottom="0" left="4" />
</ui:with>
<ui:with type="com.sencha.gxt.widget.core.client.container.MarginData" field="centerData">
<ui:attributes margins="{centerMargins}" />
</ui:with>
<ui:with type="com.sencha.gxt.core.client.util.Margins" field="middleMargins">
<ui:attributes top="5" right="0" bottom="5" left="0" />
</ui:with>
<ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData" field="middleData">
<ui:attributes margins="{middleMargins}" width="1" height="-1" />
</ui:with>
<ui:with type="com.sencha.gxt.widget.core.client.container.BorderLayoutContainer.BorderLayoutData" field="eastData">
<ui:attributes minSize="200" maxSize="1000" size="400" margins="{eastMargins}" collapsible="true" split="true" />
</ui:with>
<ui:with type="com.sencha.gxt.core.client.util.Margins" field="eastMargins">
<ui:attributes top="0" right="1" bottom="0" left="5" />
</ui:with>
<core:FramedPanel headerVisible="false">
<c:BorderLayoutContainer borders="false">
<c:center layoutData="{centerData}">
<c:VerticalLayoutContainer ui:field="mainVerContainer">
<c:child layoutData="{middleData}">
<p:PanView />
</c:child>
</c:VerticalLayoutContainer>
</c:center>
<c:east layoutData="{eastData}">
<core:ContentPanel headingText="" />
</c:east>
</c:BorderLayoutContainer>
</core:FramedPanel>
Widget's View:
<ui:with type="com.sencha.gxt.widget.core.client.grid.ColumnModel" field="columnModel" />
<ui:with type="com.sencha.gxt.data.shared.ListStore" field="store" />
<ui:with type="com.sencha.gxt.widget.core.client.grid.GridView" field="view">
<ui:attributes stripeRows="true" columnLines="true" />
</ui:with>
<ui:with type="com.sencha.gxt.widget.core.client.container.MarginData" field="centerData">
<ui:attributes margins="{centerMargins}" />
</ui:with>
<ui:with type="com.sencha.gxt.core.client.util.Margins" field="centerMargins">
<ui:attributes top="0" right="0" bottom="0" left="0" />
</ui:with>
<ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData" field="topData">
<ui:attributes width="1" height="30" />
</ui:with>
<ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData" field="middleData">
<ui:attributes width="1" height="1" />
</ui:with>
<ui:with type="com.sencha.gxt.core.client.util.Margins" field="southMargins">
<ui:attributes top="1" right="1" bottom="5" left="1" />
</ui:with>
<ui:with type="com.sencha.gxt.widget.core.client.container.BorderLayoutContainer.BorderLayoutData" field="southData">
<ui:attributes size=".5f" minSize="200" maxSize="1000" margins="{southMargins}" collapsible="true" split="true" />
</ui:with>
<core:ContentPanel headerVisible="false" ui:field="mainPanel" borders="false">
<c:BorderLayoutContainer borders="false">
<c:center layoutData="{centerData}">
<core:ContentPanel headingText="Grid" collapsible="false" ui:field="documentPanel">
<c:VerticalLayoutContainer borders="false">
<c:child layoutData="{topData}">
<t:ToolBar ui:field="topToolBar">
<b:TextButton ui:field="toPreviousPackageButton" toolTip="Up" />
<t:SeparatorToolItem />
</t:ToolBar>
</c:child>
<c:child layoutData="{middleData}">
<grid:Grid cm="{columnModel}" store="{store}" view="{view}" loadMask="true" columnReordering="true" borders="false" />
</c:child>
</c:VerticalLayoutContainer>
</core:ContentPanel>
</c:center>
<c:south layoutData="{southData}">
<core:ContentPanel ui:field="propertiesPanel" headingText="Properties" />
</c:south>
</c:BorderLayoutContainer>
</core:ContentPanel>
I'm trying to understand how to use Facebook Connect (login) with jQuery Mobile and Phonegap Build, but as more I search about this information, more I get confused.
I have already my app created on Facebook, and I have API number.
I don't know if the best way is to call a PHP page (via ajax) where validates EMAIL + PASS via Facebook PHP SDK or Facebook SDK Javascript. For SDK JS I don't understand how to integrate it in my code (and I don't know if it's possible to test it by localhost).
If someone could help me with this question...
Update
I tried #Dom suggestion, but when I click in the button, any action happens.
Below my HTML code:
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, maximum-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>Test</title>
<!-- CSS -->
<link rel="stylesheet" href="css/jquery.mobile-1.3.1.min.css">
<link rel="stylesheet" href="css/codiqa.ext.css">
<!-- jQuery and jQuery Mobile -->
<script type="text/javascript" src="phonegap.js"></script>
<script src="js/jquery-1.9.0.js"></script>
<script src="js/utf8.js"></script>
<script src="js/cdv-plugin-fb-connect.js"></script>
<script src="js/facebook-js-sdk.js"></script>
<script src="js/jquery.mobile-1.3.1.min.js"></script>
<script>
<!-- These are the notifications that are displayed to the user through pop-ups if the above JS files does not exist in the same directory-->
if ((typeof cordova == 'undefined') && (typeof Cordova == 'undefined')) alert('Cordova variable does not exist. Check that you have included cordova.js correctly');
if (typeof CDV == 'undefined') alert('CDV variable does not exist. Check that you have included cdv-plugin-fb-connect.js correctly');
if (typeof FB == 'undefined') alert('FB variable does not exist. Check that you have included the Facebook JS SDK file.');
FB.Event.subscribe('auth.login', function(response) {
alert('auth.login event');
});
FB.Event.subscribe('auth.logout', function(response) {
alert('auth.logout event');
});
FB.Event.subscribe('auth.sessionChange', function(response) {
alert('auth.sessionChange event');
});
FB.Event.subscribe('auth.statusChange', function(response) {
alert('auth.statusChange event');
});
/*function getSession() {
alert("session: " + JSON.stringify(FB.getSession()));
}
*/
function getLoginStatus() {
FB.getLoginStatus(function(response) {
if (response.status == 'connected') {
alert('logged in');
} else {
alert('not logged in');
}
});
}
var friendIDs = [];
var fdata;
function me() {
FB.api('/me/friends', { fields: 'id, name, picture' }, function(response) {
if (response.error) {
alert(JSON.stringify(response.error));
} else {
var data = document.getElementById('data');
fdata=response.data;
console.log("fdata: "+fdata);
response.data.forEach(function(item) {
var d = document.createElement('div');
d.innerHTML = "<img src="+item.picture+"/>"+item.name;
data.appendChild(d);
});
}
var friends = response.data;
console.log(friends.length);
for (var k = 0; k < friends.length && k < 200; k++) {
var friend = friends[k];
var index = 1;
friendIDs[k] = friend.id;
//friendsInfo[k] = friend;
}
console.log("friendId's: "+friendIDs);
});
}
function logout() {
FB.logout(function(response) {
alert('logged out');
});
}
function login() {
FB.login(
function(response) {
if (response.session) {
alert('logged in');
} else {
alert('not logged in');
}
},
{ scope: "email" }
);
}
function facebookWallPost() {
console.log('Debug 1');
var params = {
method: 'feed',
name: 'Facebook Dialogs',
link: 'https://developers.facebook.com/docs/reference/dialogs/',
picture: 'http://fbrell.com/f8.jpg',
caption: 'Reference Documentation',
description: 'Dialogs provide a simple, consistent interface for applications to interface with users.'
};
console.log(params);
FB.ui(params, function(obj) { console.log(obj);});
}
function publishStoryFriend() {
randNum = Math.floor ( Math.random() * friendIDs.length );
var friendID = friendIDs[randNum];
if (friendID == undefined){
alert('please click the me button to get a list of friends first');
}else{
console.log("friend id: " + friendID );
console.log('Opening a dialog for friendID: ', friendID);
var params = {
method: 'feed',
to: friendID.toString(),
name: 'Facebook Dialogs',
link: 'https://developers.facebook.com/docs/reference/dialogs/',
picture: 'http://fbrell.com/f8.jpg',
caption: 'Reference Documentation',
description: 'Dialogs provide a simple, consistent interface for applications to interface with users.'
};
FB.ui(params, function(obj) { console.log(obj);});
}
}
document.addEventListener('deviceready', function() {
try {
alert('Device is ready! Make sure you set your app_id below this alert.');
FB.init({ appId: "appid", nativeInterface: CDV.FB, useCachedDialogs: false });
document.getElementById('data').innerHTML = "";
} catch (e) {
alert(e);
}
}, false);
</script>
</head>
<body>
<div data-role="page" id="page_login">
<div data-role="content" id="content-login">
<div id="content">
Login Facebook
Me
Get Login Status
facebookWallPost
friendstory
</div>
</div>
</div>
</body>
</html>
XML code:
<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns = "http://www.w3.org/ns/widgets"
xmlns:gap = "http://phonegap.com/ns/1.0"
id = "br.com.test"
version = "1.0.0">
<name>Test</name>
<!-- FB Connect Section -->
<gap:plugin name="com.phonegap.plugins.facebookconnect">
<param name="APP_ID" value="XXXXXXXXXX...." /> <!-- FB App ID-->
<param name="APP_NAME" value="test" /> <!-- FB App Namespace-->
</gap:plugin>
<description>
Test
</description>
<author href="http://test.com.br" email="atendimento#test.com.br">
Test
</author>
<gap:plugin name="com.phonegap.plugins.barcodescanner" />
<feature name="http://api.phonegap.com/1.0/device" />
<preference name="phonegap-version" value="2.9.0" />
<preference name="orientation" value="default" />
<preference name="target-device" value="universal" />
<preference name="fullscreen" value="false" />
<preference name="webviewbounce" value="true" />
<icon src="icon.png" />
<icon src="res/icon/android/icon-36-ldpi.png" gap:platform="android" gap:density="ldpi" />
<icon src="res/icon/android/icon-48-mdpi.png" gap:platform="android" gap:density="mdpi" />
<icon src="res/icon/android/icon-72-hdpi.png" gap:platform="android" gap:density="hdpi" />
<icon src="res/icon/android/icon-96-xhdpi.png" gap:platform="android" gap:density="xhdpi" />
<icon src="res/icon/blackberry/icon-80.png" gap:platform="blackberry" />
<icon src="res/icon/blackberry/icon-80.png" gap:platform="blackberry" gap:state="hover"/>
<icon src="res/icon/ios/icon-57.png" gap:platform="ios" width="57" height="57" />
<icon src="res/icon/ios/icon-72.png" gap:platform="ios" width="72" height="72" />
<icon src="res/icon/ios/icon-57-2x.png" gap:platform="ios" width="114" height="114" />
<icon src="res/icon/ios/icon-72-2x.png" gap:platform="ios" width="144" height="144" />
<icon src="res/icon/webos/icon-64.png" gap:platform="webos" />
<icon src="res/icon/windows-phone/icon-48.png" gap:platform="winphone" />
<icon src="res/icon/windows-phone/icon-173.png" gap:platform="winphone" gap:role="background" />
<gap:splash src="res/screen/android/screen-ldpi-portrait.png" gap:platform="android" gap:density="ldpi" />
<gap:splash src="res/screen/android/screen-mdpi-portrait.png" gap:platform="android" gap:density="mdpi" />
<gap:splash src="res/screen/android/screen-hdpi-portrait.png" gap:platform="android" gap:density="hdpi" />
<gap:splash src="res/screen/android/screen-xhdpi-portrait.png" gap:platform="android" gap:density="xhdpi" />
<gap:splash src="res/screen/blackberry/screen-225.png" gap:platform="blackberry" />
<gap:splash src="res/screen/ios/screen-iphone-portrait.png" gap:platform="ios" width="320" height="480" />
<gap:splash src="res/screen/ios/screen-iphone-portrait-2x.png" gap:platform="ios" width="640" height="960" />
<gap:splash src="res/screen/ios/screen-ipad-portrait.png" gap:platform="ios" width="768" height="1024" />
<gap:splash src="res/screen/ios/screen-ipad-landscape.png" gap:platform="ios" width="1024" height="768" />
<gap:splash src="res/screen/windows-phone/screen-portrait.jpg" gap:platform="winphone" />
</widget>
Take a look at the plugin documentation located here.
Ensure you have the below in the <head> of your index.html:
<script src="cdv-plugin-fb-connect.js"></script>
<script src="facebook-js-sdk.js"></script>
Ensure your config.xml contains the below:
<gap:plugin name="com.phonegap.plugins.facebookconnect">
<param name="APP_ID" value="..." />
<param name="APP_NAME" value="..." />
</gap:plugin>
Finally, review the "Simple Sample" on how to use the plugin located here
Hope this helps. If you are still having issues, post some code you are using for us to take a look at.