Fix WP Bouncing IBM MobileFirst 6.3 - windows-phone-8

I found the plugin to fix WP bouncing in cordova :
https://github.com/vilic/cordova-plugin-fix-wp-bouncing
I want to implement the plugin into my MFP project.
Native Code :
void border_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {
browser.InvokeScript("eval", "FixWPBouncing.onmanipulationcompleted()");
}
Javascript Code :
exports.onmanipulationcompleted = function () {
exports.target = null;
};
exports.fix = function (target) {
if (!POINTER_DOWN) { return; }
if (!(target instanceof HTMLElement) && target.length) {
target = target[0];
}
target.addEventListener(POINTER_DOWN, function () { exports.target = target; }, false); };
plugin.xml :
<js-module src="www/fix-wp-bouncing.js" name="fix-wp-bouncing">
<clobbers target="FixWPBouncing" />
</js-module>
<!-- windows phone 8 -->
<platform name="wp8">
<config-file target="config.xml" parent="/*">
<feature name="FixWPBouncing">
<param name="wp-package" value="FixWPBouncing"/>
<param name="onload" value="true" />
</feature>
</config-file>
How to call :
// call fix after deviceready.
var wrapper = document.getElementById('an-element-that-scrolls');
FixWPBouncing.fix(wrapper);
// I don’t have any idea where i must write this code below :
declare module FixWPBouncing {
/** when target is a JQuery, it process the first element only. */
export function fix(target: HTMLElement|JQuery): void;
}
From the code above, this is my explanation :
call FixWPBouncing.fix(wrapper); => it will call the javascript function exports.fix, The purpose of this function is adding the event listener when we touch the element.
The listener in the native code void border_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) will trigger the javascript code exports.onmanipulationcompleted
<param name="onload" value="true" /> => The purpose of this configuration, is autoload the Native Code, so i don’t need to call cordova.exec
Because of that, i think to integrate the javascript code and the native code, i will need :
<js-module src="www/fix-wp-bouncing.js" name="fix-wp-bouncing">
<clobbers target="FixWPBouncing" />
</js-module>
So the native code listener will always trigger the javascript code.
I feel confused to change the logic like : https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-6-3/adding-native-functionality/windows-phone-8-adding-native-functionality-hybrid-application-apache-cordova-plugin/
Because from that link, we call the native with cordova.exec.
Not with autoload and automatically trigger the javascript code.
Please correct me if i’m wrong.
Do you have any idea to implement : https://github.com/vilic/cordova-plugin-fix-wp-bouncing in the MFP project ?

If you are implementing a Cordova plug-in in a Hybrid application, you must follow the instructions as provided in the MobileFirst Platform Developer Center tutorial.
Implementing it based on other instructions is untested/supported.
Of course, you can always choose to use a "pure" Cordova application in MobileFirst Platform Foundation 7.1, negating the need to go through anything related to MPF and instead follow standard Cordova procedures.

Related

Why is CreateFileAsync() continuation not executed?

In the below code, the continuation of CreateFileAsync() neither prints nor accesses pdone. However, the zero-length file, Hello.txt, is created.
auto pdone = make_shared<bool>(false);
create_task(folderLocal->CreateFileAsync("Hello.txt", CreationCollisionOption::ReplaceExisting)).then([pdone](StorageFile ^file) {
OutputDebugString(L"In CreateFileAsync continuation!\n");
*pdone = true;
});
create_task([pdone]{
OutputDebugString(L"In my task!\n");
});
create_async([pdone]{
OutputDebugString(L"In my async!\n");
});
while (!*pdone) {}
OutputDebugString(L"Done!\n");
In the debugger:
In my task!
In my async!
I'm not very familiar with debugging WinRT threads yet, but I do not see any obvious exception or any reason the continuation to the async operation should not execute. The target platform is the Hololens emulator.
Any thoughts are appreciated.
Thanks!
Harry's comment above is most likely the culprit - if you initiated this on a UI thread then by default the C++ tasks library (PPL) will try to schedule the completion on the same thread. This will never happen if you are spinning the thread waiting for the completion to happen (classic deadlock).
If you must do this (although you really should try and avoid it) you need to use a "continuation context" to tell PPL to run the continuation somewhere else.
Here's an example. First, basic XAML (just paste inside the Grid of a blank C++ XAML project):
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Content="Hang the UI thread" Click="Hang"/>
<Button Content="Do not do this" Click="DoNotDoThis"/>
</StackPanel>
And the code (just paste after the MainPage constructor):
using namespace Windows::Storage;
using namespace concurrency;
void DoIt(task_continuation_context& context)
{
auto folder = ApplicationData::Current->LocalFolder;
auto done = std::make_shared<bool>(false);
create_task(folder->CreateFileAsync(L"x", CreationCollisionOption::ReplaceExisting))
.then([done](StorageFile^ file) mutable
{
OutputDebugString(L"Done creating file\n");
*done = true;
}, context);
OutputDebugString(L"Going to wait... DO NOT DO THIS IN PRODUCTION CODE!\n");
while (!*done)
;
OutputDebugString(L"Done waiting\n");
}
void MainPage::Hang(Platform::Object^ sender, RoutedEventArgs^ e)
{
OutputDebugString(L"Starting Hang\n");
// The default context == the UI thread (if called from UI)
DoIt(task_continuation_context::use_default());
OutputDebugString(L"Ending Hang\n");
}
void MainPage::DoNotDoThis(Platform::Object^ sender, RoutedEventArgs^ e)
{
OutputDebugString(L"Starting DoNotDoThis\n");
// An arbitrary context will pick another thread (not the UI)
DoIt(task_continuation_context::use_arbitrary());
OutputDebugString(L"Ending DoNotDoThis\n");
}
As noted, you shouldn't do this. If you need synchronous File I/O, and you're accessing files in your own package, use the Win32 API CreateFile2. If you need to access files outside of your package (eg, from a file picker or the photos library) you should use a fully-async programming approach.
I believe using task_continuation_context::use_arbitarty() is the correct way of doing this, however I think microsoft suggests using it slightly differently unless i have misunderstood this link (scroll all the way to the bottom): https://msdn.microsoft.com/en-us/library/hh750082.aspx
create_task(folderLocal->CreateFileAsync("Hello.txt", CreationCollisionOption::ReplaceExisting)).then([pdone](StorageFile ^file) {
OutputDebugString(L"In CreateFileAsync continuation!\n");
*pdone = true;
}, task_continuation_context::use_arbitrary());

Programmatically loading a ES6 module with Traceur in web page

I have been using Traceur to develop some projects in ES6. In my HTML page, I include local Traceur sources:
<script src="traceur.js"></script>
<script src="bootstrap.js"></script>
and if I have a module in the HTML afterwards like:
<script type="module" src="foo.js"></script>
Then Traceur loads in that module, compiles it and everything works great.
I now want to programmatically add an ES6 module to the page from within another ES6 module (reasons are somewhat complicated). Here was my first attempt:
var module = document.createElement('script');
module.setAttribute('type', 'module');
module.textContent = `
console.log('Inside the module now!');
`;
document.body.appendChild(module);
Unfortunately this doesn't work as Traceur does not monitor the page for every script tag added, I guess.
How can I get Traceur to compile and execute the script? I guess I need to invoke something on either 'traceur' or '$traceurRuntime' but I haven't found a good online source of documentation for that.
You can load other modules using ES6 import statements or TraceurLoader API for dynamic dependencies.
Example from Traceur Documentation
function getLoader() {
var LoaderHooks = traceur.runtime.LoaderHooks;
var loaderHooks = new LoaderHooks(new traceur.util.ErrorReporter(), './');
return new traceur.runtime.TraceurLoader(loaderHooks);
}
getLoader().import('../src/traceur.js',
function(mod) {
console.log('DONE');
},
function(error) {
console.error(error);
}
);
Also, System.js loader seems to be supported as well
window.System = new traceur.runtime.BrowserTraceurLoader();
System.import('./Greeter.js');
Dynamic module loading is a (not-yet-standardized) feature of System:
System.import('./repl-module.js').catch(function(ex) {
console.error('Internal Error ', ex.stack || ex);
});
To make this work you need to npm test then include BrowserSystem
<script src="../bin/BrowserSystem.js"></script>
You might also like to look into https://github.com/systemjs/systemjs as it has great support for browser loading.
BTW the System object may eventually be standardize (perhaps under a different name) in the WHATWG: http://whatwg.github.io/loader/#system-loader-instance

Windows Phone 8 Receiving raw Push Notification issue

I am unable to receive raw notification on my WindowsPhone8.
Followed :https://github.com/barryvdh/PushPlugin/#uccb-wp8-only
Able to get toast notification. In my app toggle is happening like below.
Case 1: If I comment ecb able to get both raw and toast but not
channel uri.
Case 2: If I won't comment ecb able to get toast and channel uri but
not raw
My code as follows:
if (device.platform == "Win32NT") {
console.log("called");
pushNotification.register(
channelHandler,
errorHandler,
{
"channelName": "channelName",
"ecb": onNotificationWP8,
"uccb": channelHandler,
"errcb": jsonErrorHandler
});
}
else {
console.log("not called");
}
}
function channelHandler(event) {
var uri = event.uri;
console.log("UUUUURRRRRRRRRRRIIIIIIIII :" + uri);
}
function errorHandler(e) {
}
function jsonErrorHandler(error) {
$("#app-status-ul").append('<li style="color:red;">error:' + error.code + '</li>');
$("#app-status-ul").append('<li style="color:red;">error:' + error.message + '</li>');
}
function onNotificationWP8(e) {
console.log("notification called");
if (e.type == "toast" && e.jsonContent){
pushNotification.showToastNotification(successHandler, errorHandler,
{
"Title": e.jsonContent["wp:Text1"], "Subtitle": e.jsonContent["wp:Text2"], "NavigationUri": e.jsonContent["wp:Param"]
});
}
if (e.type == "raw" && e.jsonContent) {
alert(e.jsonContent.Body);
}
}
Tried with error and trail methods. Please suggest what might went wrong.
The issue observed does not appear to be related to Worklight at all. From the description and the code snippet, you are bypassing Worklight client SDK and server completely , and using a custom Cordova Push plugin. The custom plugin's working in your application should be analyzed to understand the variance in behaviour.
Since you are not using Worklight Push at all, you can try disabling it and check if this helps your case.
To do this, navigate to the config.xml . This will be located in apps/YourAppName/WindowsPhone8/native/Resources folder.
Look for :
<feature name="Push">
<param name="wp-package" value="Push" />
</feature>
Change this to:
<feature name="Push">
<param name="wp-package" value="Push" />
<param name="onload" value="false" />
</feature>
On the query regarding Worklight API:
There are no Worklight APIs that return Channel URI. When using Worklight SDK for Push, all this is done automatically and hidden from the user. Even with a Push Adapter in place, it is not possible to obtain the channel URI as there no APIs published to obtain this information.
Finally it got solved by adding Coding4Fun.Toolkit.Controls.dll
And some code updation in PushPlugin.cs
using Coding4Fun.Toolkit.Controls;
using System.Windows.Threading;
void PushChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
string msg = string.Empty;
foreach (var item in e.Collection)
{
if (item.Key == "wp:Text1")
{
msg = item.Value;
}
}
MessageBox.Show(msg, "Notification", MessageBoxButton.OK);
});
}
My heart-full thanks to Rajith who helped me to make it happen.

Phaser HTML5 app cannot play sound after porting by Phonegap Cloud Build

This's a simple Phaser audio example. It works well on my Android web browser. However, it's muted after porting to Android app by Phonegap cloud build.
I know how to play sound (and loop) in Phonegap app (How to loop a audio in phonegap?) but don't know how to apply it into the Phaser JS framework.
Here's the ported app. I can install and run it but without sound. Do I miss something or Phonegap Cloud Build does support the WebAudio in Phaser JS?
https://build.phonegap.com/apps/1783695/
My config.xml is:
<?xml version="1.0" encoding="UTF-8" ?>
<widget id="com.phaser.phasersound" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
<name>Phaser sound complete</name>
<description>
Phaser sound phonegap
</description>
<gap:plugin name="org.apache.cordova.media" />
<icon src="icon.png" />
<preference name="splash-screen-duration" value="1"/>
<!--
If you do not want any permissions to be added to your app, add the
following tag to your config.xml; you will still have the INTERNET
permission on your app, which PhoneGap requires.
-->
<preference name="permissions" value="none"/>
</widget>
The source code is: (I changed the local audio files from local to github links to run on code snippet)
var game = new Phaser.Game(600, 800, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });
function preload() {
game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
//have the game centered horizontally
game.scale.pageAlignHorizontally = true;
game.scale.pageAlignVertically = true;
game.stage.backgroundColor = '#414040';
// I changed the local audio files from local to github links to run on code snippet
/*
game.load.audio('explosion', 'assets/audio/SoundEffects/explosion.mp3');
game.load.audio('sword', 'assets/audio/SoundEffects/sword.mp3');
game.load.audio('blaster', 'assets/audio/SoundEffects/blaster.mp3');
*/
game.load.audio('explosion', 'https://raw.githubusercontent.com/nguoianphu/phaser-sound-complete-phonegap/master/www/assets/audio/SoundEffects/explosion.mp3');
game.load.audio('sword', 'https://raw.githubusercontent.com/nguoianphu/phaser-sound-complete-phonegap/master/www/assets/audio/SoundEffects/sword.mp3');
game.load.audio('blaster', 'https://raw.githubusercontent.com/nguoianphu/phaser-sound-complete-phonegap/master/www/assets/audio/SoundEffects/blaster.mp3');
}
var explosion;
var sword;
var blaster;
var text;
var text1;
var text2;
var text3;
function create() {
var style = { font: "65px Arial", fill: "#52bace", align: "center" };
text = game.add.text(game.world.centerX, 100, "decoding", style);
text.anchor.set(0.5);
explosion = game.add.audio('explosion');
sword = game.add.audio('sword');
blaster = game.add.audio('blaster');
// Being mp3 files these take time to decode, so we can't play them instantly
// Using setDecodedCallback we can be notified when they're ALL ready for use.
// The audio files could decode in ANY order, we can never be sure which it'll be.
game.sound.setDecodedCallback([ explosion, sword, blaster ], start, this);
}
var keys;
function start() {
text.text = 'Press 1, 2 or 3';
var style = { font: "48px Arial", fill: "#cdba52", align: "center" };
text1 = game.add.text(game.world.centerX, 250, "Blaster: Stopped", style);
text1.anchor.set(0.5);
text2 = game.add.text(game.world.centerX, 350, "Explosion: Stopped", style);
text2.anchor.set(0.5);
text3 = game.add.text(game.world.centerX, 450, "Sword: Stopped", style);
text3.anchor.set(0.5);
explosion.onStop.add(soundStopped, this);
sword.onStop.add(soundStopped, this);
blaster.onStop.add(soundStopped, this);
keys = game.input.keyboard.addKeys({ blaster: Phaser.Keyboard.ONE, explosion: Phaser.Keyboard.TWO, sword: Phaser.Keyboard.THREE });
keys.blaster.onDown.add(playFx, this);
keys.explosion.onDown.add(playFx, this);
keys.sword.onDown.add(playFx, this);
// And for touch devices you can also press the top, middle or bottom of the screen
game.input.onDown.add(onTouch, this);
}
function onTouch(pointer) {
var b = game.height / 3;
if (pointer.y < b)
{
playFx(keys.blaster);
}
else if (pointer.y > b * 2)
{
playFx(keys.sword);
}
else
{
playFx(keys.explosion);
}
}
function playFx(key) {
switch (key.keyCode)
{
case Phaser.Keyboard.ONE:
text1.text = "Blaster: Playing";
blaster.play();
break;
case Phaser.Keyboard.TWO:
text2.text = "Explosion: Playing";
explosion.play();
break;
case Phaser.Keyboard.THREE:
text3.text = "Sword: Playing";
sword.play();
break;
}
}
function soundStopped(sound) {
if (sound === blaster)
{
text1.text = "Blaster: Complete";
}
else if (sound === explosion)
{
text2.text = "Explosion: Complete";
}
else if (sound === sword)
{
text3.text = "Sword: Complete";
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/2.4.4/phaser.js"></script>
UPDATE 2015-12-01
Here is my completed source code. It has both .mp3 and .ogg sound files. You can play them on Android native browser (tested on 4.4.4 Samsung E5).
Source: https://github.com/nguoianphu/phaser-sound-complete-phonegap
Here is the ported app on Phonegap. It can display the screen but can't play sounds.
https://build.phonegap.com/apps/1783695/builds
You are trying to play the audio with the webview library. It is likely using the HTML5 API for audio or webaudio. If it is neither of these, then you need to ask the author.
Next, it is not best practice to use external source (http:). Your assests (javascript, css, audio files, etc) should live on the device. If you load files from the web, then the sound quality could be poor (or the audio may not play at all - see whitelist below). Load from the device.
Android 4.4.4 is Kitkat. The standard webview library was exchanged for the chromium version. This means your audio library might be confused about this or you need to give the library knowledge about this library. This also means your code may not work on devices before 4.4.4. (Mostly, because you cannot test it.)
The link you point to is likely using the core media plugin, even though they dont say so. In addition, the post is over 3 years old. Many thing have changed since them. NOTE: you have installed the media plugin in your config.xml. This is likely why your loop works.
You should start over. You've made many errors. In addition, to all that you have, You will need to implement the whitelist plugin (if you are going to import files, or talk to the network).
FIRST TRY this sample app - example plays on Android and iOS. You can download the Android version and test it. The iOS version requires I have your UUID compiled in.
There are 16 audio plugins you can choose from. I know a few do real time audio playback and have better control than the "core" plugin.
You should read:
Top Mistakes by Developers new to Cordova/Phonegap - read the bold sentences.
HOW TO apply the Cordova/Phonegap the whitelist system
HOWTO Core Plugins Setup
Phonegap--Generic-Boilerplate7 - just wrote this. It works.
Phonegap Demo Apps
Phonegap-Media-Test - source code for the example that plays on Android and iOS. You can download the Android version and test it.
UPDATE: 2015-12-01 - 2am Previously, I had forgotten to add a wild-card (*) to the CSP meta tag. I am now including this. This meta tag should be added to the header of the index.html file that is playing the audio.
NOTE YOUR APP IS NOW INSECURE. IT IS UP TO YOU TO SECURE YOUR APP.
<meta http-equiv="Content-Security-Policy"
content="default-src *;
style-src * 'self' 'unsafe-inline' 'unsafe-eval';
script-src * 'self' 'unsafe-inline' 'unsafe-eval';">
UPDATE: 2015-12-01 - 3pm
#Tuan, I've applied all the fixes as outlined in
HOW TO apply the Cordova/Phonegap the whitelist system
HOWTO Core Plugins Setup
Phonegap--Generic-Boilerplate7 - just wrote this. It works.
The audio is now working on my Android LG Leon/Android 5.1.1
Truthfully, I would never do this on my own, but your code had enough working that after I tested it on my firefox(v34) browser, I was fairly certain it would work.
UPDATE: 2016-04-15
The code has been removed. Ask in the comments, if you need code.
There should be enough code in place for you to work off of.
- Code
- Working Android App
- Phonegap Build Documentation

How do I allow an MIME extension map in ASP.NET vNext?

Background
I have a piece of LESS code that needs to be compiled at runtime with Less.js -- it calculates some things via JavaScript -- so I can't use the task runner, etc.
In my index.html, I have:
<head>
...
<link rel="stylesheet/less" href="assets/less/DynamicHeight.less" />
...
<script type="text/javascript" src="lib/less/less.js"></script>
...
</head>
Problem
Less.js appears unable to find the file:
And when I try to access the file directly, I see:
Question
How can I add the configuration that will allow this less file to be downloaded? Am I still able to use web.config files with vNext, or do I need to do something with config.json instead?
Lead 1: Should I use Owin?
Thinking this might be the right path but I'm pretty unfamiliar.
I see a number of tutorials out there, such as K. Scott Allen's, which reference code such as:
public void Configuration(IAppBuilder app)
{
var options = new StaticFileOptions
{
ContentTypeProvider = new FileExtensionContentTypeProvider()
};
((FileExtensionContentTypeProvider)options.ContentTypeProvider).Mappings.Add(
new KeyValuePair<string, string>(".less", "text/css"));
app.UseStaticFiles(options);
}
However, it appears that in its current version, asp.net is looking for a signature of Configure(IApplicationBuilder app) instead.
The IApplicationBuilder class doesn't have a method along the lines of UseStaticFiles -- it only has a signature of IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware).
I have a feeling that this is likely the right path to solve the issue -- I just can't find out how to propertly configure the IAppliationBuilder to map the MIME extension.
Okay, I believe I figured it out.
Step 1: Add the appropriate library for static files
In ASP.NET vNext, this is Microsoft.Aspnet.StaticFiles.
In your project.json file, add the following under "dependencies":
"Microsoft.AspNet.StaticFiles": "1.0.0-beta2"
This adds the static middleware method that you can use later.
Step 2: Configure the app to use Static Files
Add the using statement at the top:
using Microsoft.AspNet.StaticFiles;
At this point, the app.UseStaticFiles method will be available, so your Configure method can look as follows:
public void Configure(IApplicationBuilder app)
{
var options = new StaticFileOptions
{
ContentTypeProvider = new FileExtensionContentTypeProvider()
};
((FileExtensionContentTypeProvider)options.ContentTypeProvider).Mappings.Add(
new KeyValuePair<string, string>(".less", "text/css"));
app.UseStaticFiles(options);
}
And voila! I get text when browsing to .less files, and no more error is appearing from LessJS.
In .NET Core 1.0.1, SeanKileen answer is still good. The following is a simple code rewrite:
public void Configure(IApplicationBuilder app, ...)
var contentTypeProvider = new FileExtensionContentTypeProvider();
contentTypeProvider.Mappings[".map"] = "application/javascript";
contentTypeProvider.Mappings[".less"] = "text/css";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = contentTypeProvider
});
The above code EXTENDS the default mapping list (see the source), which already has ~370 mappings.
Avoid using the FileExtensionContentTypeProvider constructor overload that takes a dictionary (as suggested by JHo) if you want those 370 default mappings.
SeanKilleen's answer is right on, and still works ASP.NET Core RC1. My only improvement is to write the exact same code using collection initializers to make it cleaner.
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = new FileExtensionContentTypeProvider(new Dictionary<string, string>
{
{ ".less", "text/css" },
{ ".babylon", "text/json" },
// ....
})
});