We have an app published in the Teams App Store which uses task module and tabs.
On Task/Tab pages we use Teams API lib to work with media (camera/gallery). Camera and gallery API works fine if we limit users to only one image to pick.
On Android everything works great (doesn't matter how many media files you pick).
Strange things happen when we let IOS users to pick/make more than one image at a time.
There are two possible scenarios on IOS devices:
Teams App crashes.
Teams API returns attachments.length !== blobs.length.
I did some tests on different IOS Devices. Both have issues. I've updated the app to the latest and it got even worse (started to crash more often):
iPhone Xs (IOS 15.1).
iPhone 11 Pro Max (IOS 15.1).
Steps to reproduce blob issue:
Create an HTML page and load it into Task module.
Trigger microsoftTeams.media.selectMedia with maxMediaCount: 10.
Pick up to 10 small size images.
Save received attachments.length.
Request a blob for each attachment.
Calculate how many blobs and attachments you've got.
Expected: blobs.length === attachments.length.
Result: blobs.length !== attachments.length.
The issue described above appears randomly, sometimes you get expected values, sometimes you don't, sometimes it crashes even with small images.
How to crash IOS Teams App, Steps to reproduce:
Create an HTML page and load it into Task module.
Trigger microsoftTeams.media.selectMedia with maxMediaCount: 10.
Pick up to 10 big size images.
Expected: "Error 10000, Selected file is too big".
Result: Teams App crashes.
My code:
const MEDIA_MAX_FILES = 10;
const imageProp: microsoftTeams.media.ImageProps = {
sources: [microsoftTeams.media.Source.Gallery],
startMode: microsoftTeams.media.CameraStartMode.Photo,
ink: false,
cameraSwitcher: true,
textSticker: true,
enableFilter: true,
};
const mediaInput: microsoftTeams.media.MediaInputs = {
mediaType: microsoftTeams.media.MediaType.Image,
maxMediaCount: MEDIA_MAX_FILES,
imageProps: imageProp
};
const attachementsList = [];
const blobs = [];
microsoftTeams.media.selectMedia(mediaInput,(error: microsoftTeams.SdkError,
attachments: microsoftTeams.media.Media[]) => {
if (error) { /* block is truncated */ return; }
if (attachments) {
attachementsList.push(...attachments);
for (const attachment of attachments) {
attachment.getMedia((attachmentError: SdkError,
blob: Blob) => {
if (blob) {
blobs.push(blob);
}
});
}
}
});
Teams App build versions. Dev Preview is turned on on both devices:
iPhone Xs: 3.20.77.2021202701/1121
iPhone 11 Max Pro: 3.20.77.2021202701/1121
Is this a bug ? Or am I doing something wrong ? Thanks in advance.
I want to crop 3 images then upload them cropped using Angular 2.
I integrated Angular 2 Image Cropper "ng2-img-cropper" but I didn't get it to work.
When I run the application and go the page where the cropper is implemented I only see a small image square and nothing happens when I click or drag it and there is no errors in the console.
Figure : Empty image square
I am using "ng2-img-cropper#4.6".
This is how I proceeded for the implementation.
I referred to this Github link https://github.com/cstefanache/angular2-img-cropper
I added this into the HTML
<div>
<img-cropper [image]="data" [settings]="cropperSettings"></img-cropper><br>
<img [src]="data.image" [width]="cropperSettings.croppedWidth" [height]="cropperSettings.croppedHeight">
</div>
And this into the class
import {ImageCropperComponent, CropperSettings} from 'ng2-img-cropper';
data: any; cropperSettings: CropperSettings;
constructor() {
this.cropperSettings = new CropperSettings();
this.cropperSettings.width = 100;
this.cropperSettings.height = 100;
this.cropperSettings.croppedWidth =100;
this.cropperSettings.croppedHeight = 100;
this.cropperSettings.canvasWidth = 400;
this.cropperSettings.canvasHeight = 300;
this.data = {};
}
Thank you.
Link to the issue Issue
Basically there are two reasons by which your component is not showing first one either your are not listing
your component in the list or directives or either your are not binding properly of src in img. otherwise angular2 image cropper is
working fine for me see here.
https://embed.plnkr.co/V91mKCNkBQZB5QO2MUP4/
see here also
https://stackoverflow.com/a/39096831/5043867
if still you have any error kindly reproduce your error in attached plunker.
I have a problem loading images
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
alert('it loaded');
bgReady = true;
};
bgImage.src = "images/background.png";
the alert does not appear when the websocket server is running.
The alert will appear if I remove the socket code and turn the server off.
I have already placed alerts throughout the code to see how far it will run without breaking.
Nothing seems to be breaking except the image does not seem to want to load.
any suggestions will be helpful.
I was accessing files from a different port so thats why they were not loading
The code below works well with IE7, but when I switch to run with Firefox (from 3.0 to 3.6) I could not get the the Dialog. It raise error on line: DiaglogHandler.WaitUntilExists(10) "Dialog not available within 10 seconds." even though the dialog is there. I'm using the final WatiN release.
string url = "https://www.xxx.com"
Settings.AutoStartDialogWatcher = true;
Settings.AutoCloseDialogs = false;
//var browser = new IE();
var browser = new FireFox();
browser.GoTo(url);
Image theButton = browser.Image(Find.By("id", "button"));
AlertDialogHandler DiaglogHandler = new AlertDialogHandler();
DialogWatcher theDialogWatcher = new DialogWatcher(new WatiN.Core.Native.Windows.Window(browser.hWnd));
theDialogWatcher.Add(DiaglogHandler);
theDialogWatcher.CloseUnhandledDialogs = false;
theButton.ClickNoWait();
DiaglogHandler.WaitUntilExists(10);
Console.WriteLine(DiaglogHandler.Message);
Console.WriteLine("Done");
Console.ReadLine();
Afaik WatiN does not deal well with Dialogs yet, though it is on the horizon.
It is possible to get around them, say passing an Enter to the browser or other javascript interaction.
I've had similar issues with Authentication Required Dialogs in FireFox
I have protocol (like http) with scheme managed with 3rd party App registered in Mac OS X.
I.e, x-someapp://someaction or something like that.
How can I open this URL with Google Chrome?
By default, Chrome starts searching in Google engine instead launching App and passing URL handling to it...
Safari launches some registered App. And it is right thing.
Firefox and Opera asks what to do... and I can launch App also.
But Chrome... Doesn't ask.
I even tried to write some HTML page with JavaScript inside to send XHttpRequest:
function _httpExecuteCallback()
{
if (httpRequestCallbackFunction != null) {
if (httpRequest.readyState == 4) {
if (httpRequest.status == 200) {
httpRequestCallbackFunction();
httpRequestCallbackFunction = null;
}
}
}
}
function _httpGet(url, callbackFunction)
{
httpRequest = false;
httpRequestCallbackFunction = callbackFunction;
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = _httpExecuteCallback;
httpRequest.open('GET', url, true);
httpRequest.send(null);
}
_httpGet('x-someapp://test',function(){})
No results also...
The current accepted solution has a problem with Chrome for SSL https. Watching the console log, Chrome blocks the request because it thinks the custom url protocol is not secure:
[blocked] The page at reports blah blah ran insecure content from customproto//blah blah
Here is a solution (this took me a few days to research):
<input type='button' value='Test Custom Url' onclick='exec()'>
<script>
function submitRequest(buttonId) {
var d = (window.parent)?window.parent.document:window.document
if (d.getElementById(buttonId) == null || d.getElementById(buttonId) == undefined) return;
if (d.getElementById(buttonId).dispatchEvent) {
var e = d.createEvent("MouseEvents");
e.initEvent("click", true, true);
d.getElementById(buttonId).dispatchEvent(e);
}
else {
d.getElementById(buttonId).click();
}
}
function exec(){
var d = (window.parent)?window.parent.document:window.document
var f = d.getElementById('customUrlLink')
if (f ) {f.parentNode.removeChild(f);}
var a = d.createElement('a');
a.href = 'mycustomproto://arg1';
a.innerHTML = "Link"
a.setAttribute('id', 'customUrlLink');
a.setAttribute("style", "display:none; ");
d.body.appendChild(a);
submitRequest("customUrlLink");
}
</script>
This code will not work for IE. I've found using this technique IE limits the argument of the custom protocol to less than 1000 where as using the iFrame technique IE will allow 2083 chars.
The only way to overcome the url limit in javascript is chuck the data and call multiple times. If anyone wants to take a stab at that, please let me know how it goes. I would like to use it.
To handle long urls in the executing app, pass a token into the app and have it go get the data from a url GET.
So for right now I am using one function for Chrome/FF and another function for IE.
These links helped me develop this solution:
https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page
Simulating a click in jQuery/JavaScript on a link
(wish I had known this a few days ago....hope this helps someone)
==================================================
Update: (8hr later)
==================================================
Jake posted a great solution for chrome: https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page
This works in chrome only:
window.location.assign("customprotocol://");
It will fail in an iframe so this is working:
var w = (window.parent)?window.parent:window
w.location.assign(service + '://' + data)
==================================================
Update: (weeks later)
==================================================
All of the examples of opening the custom protocol, including my own, have a "://" in the url. And this is what is causing the SSL warnings.
Turns out the solution is to change "://" to ":"
so do this:
src="x-myproto:query" .....
and the SSL warnings will go away.
==================================================
Follow: (after months of production use)
==================================================
This has been working well for chorme. Detect the browser and if chrome do this:
var w = (window.parent)?window.parent:window
w.location.assign('myproto://xyzabcdefetc')
For IE and other browsers I do something slightly different.
Note that browsers do impose a limit on how much data you can put in custom url protocol. As long as your string is under 800 chars this seems to be the magic number for which works in all browsers.
It looks like it's Google's locationbar parsing which is getting in the way.
The browser, however, does seem to handle custom URL schemes properly. Try this in your locationbar:
javascript:document.location = 'myscheme://whatever'
Any link on your page that uses the custom scheme should also do the right thing.
I found the solution that works with Chrome.
I use the IFRAME-way.
Example (with JQuery):
$("body").append('<span id="__protoProxy"></span>');
function queryWord(aWord)
{
var protoProxy = document.getElementById('__protoProxy');
if (protoProxy)
{
var word = aWord.replace('"','\"');
protoProxy.innerHTML = '<div style="display:none;"><iframe src="x-myproto://query?' + word + '"></iframe></div>';
}
}
queryWord('hello');
Here's a solution that also includes a redirect to the App Store / Play Store if the user doesn't have the app. It uses a setTimeout for this. It also makes use of an iframe to support more browsers. So this works on Chrome, and any other mobile browser. We use this as my company, Branch. Just modify the two links below to correspond to your URI and App Store link.
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
window.onload = function() {
// Deep link to your app goes here
document.getElementById("l").src = "my_app://somepath";
setTimeout(function() {
// Link to the App Store should go here -- only fires if deep link fails
window.location = "https://itunes.apple.com/us/app/myapp/id123456789?ls=1&mt=8";
}, 500);
};
</script>
<iframe id="l" width="1" height="1" style="visibility:hidden"></iframe>
</body>
</html>
Again, this should work on any browser, thanks to the iframe.
If Chrome does not recognize the URL scheme, it defaults to a search.
This is what I see in Safari:
alt text http://img62.imageshack.us/img62/6792/clipboard02oh.jpg
and in Firefox:
alt text http://img138.imageshack.us/img138/9986/clipboard04xk.jpg
I believe the reason why Chrome defaults to search is that there are special google searches that use the colon.
E.g:
define: dictionary
filetype:pdf google chromium
This is one of the annoyances I have with Firefox, I have to jump to the "search box" rather than the address bar to execute these types of searches. Since Chrome does not have a separate search box like Firefox, IE and Safari have, this functionality is required.
Ajax requests won't get you around this.
Some weeks later ....
Looks like window.location.replace('myscheme://whatever') has full cross-browser support , works with chrome,firefox,safari,edge,opera see https://developer.mozilla.org/en-US/docs/Web/API/Location/replace