PhoneGap Build Watcher

I love PhoneGap Build.  I love not having to have anywhere from 3 to 7 different IDE/SDK rigs to get apps that run on multiple platforms. That being said, IDEs do give something that PhoneGap Build (henceforth referred to as PGB) lacks – workflow.

My current workflow with PGB goes something like this:

  • Push changes to PGB
  • Leave PGB open in browser tab
  • Get bored
  • Wander away to other browser tabs
  • Remember that I am working on a mobile app
  • Go back and check PGB
  • See that it has updated
  • Pick up device
  • Click download link
  • Reinstall

It’s not the best workflow.  Yeah, I could fix it by being more disciplined. But evidence suggests that’s not going to happen. I could solve my problem with technology. PGB has an API for answering questions like “Is the Android version of my app currently built?” So I put together a little mobile app to take advantage of that API. I call it PhoneGap Build Watcher. It does what you would expect:

  • You enter your PGB credentials
  • You get a list of all of your projects
  • You choose one
  • Any time that project gets updated you get sound, vibration and notification alerts.
  • From that alert you can click on the download link and install the new version of your application.

This has really helped my workflow with PGB, and I hope some of you out there can use it to do the same.

See it in action:

It’s of course Open Source and hosted on GitHub.

I’ve put it up on Google Play, but was unable to get it into the App Store.  I should have realized it before trying but Apple doesn’t like applications that prompt you to download applications. No worries. Great thing about PhoneGap apps, they’re just web apps, so I have a web app version running at http://pgbwatcher.com if any iOS users want to give it a try.

Let me know what you think.

Using Ant and Say Command for Notification

I use ANT to automate a lot of the work I do around the web.  Some things are so tedious I don’t want to have to do them.  Others just take a long time, and I would rather the computer spend that time instead of me.

The difficulty with that is ANT doesn’t notify you when it is done.  Sure it prints a message that it’s done in the terminal window, but unless you’re looking there, you’ll never know. I stumbled on an easy way of getting notifications that are flexible and easy to work with on OS X:

The say command

In OS X, go to your command line and type 

say hello

Your Mac should respond in creepy robotic tones “Hello.”

You can get it to say anything… Okay, get all the immature juvenile tricks out now. My personal favorite:

say "I've got the collywobbles."

Okay. You can make it say anything, so you can make it say:

say “I’m done uploading all of your files to the website.”

So make an ANT task like: 

https://gist.github.com/2776139.js?file=build1.xml

And join it with another ANT task like:

https://gist.github.com/2776139.js?file=build2.xml

Call them both from an ANT task like:

https://gist.github.com/2776139.js?file=build3.xml

And there you have it. ANT with notification. Creepy creepy robotic notifications.

What I like about this over say, sound effects, is that this method allows me to label specifically what each notification means, which helps if I run a few concurrent processes.

PhoneGap Starter Project – Productivity

A few weeks back Ryan Stewart posted on his idea for PhoneGap Starter projects. They were designed to take some of the grief out of getting started with various aspects of PhoneGap and PhoneGap Build projects.  I’ve contributed a project based on one of pet peeves with PhoneGap Build: the lack of productivity.

Don’t get me wrong. I love PhoneGap Build.  I love not having to open multiple IDEs to work on mobile apps. I love working on HTML apps in HTML tools – but you lose a few things in the trade. You lose being able to click one button and have your work available on your device.  You miss being able to click and get a pop up that says your work is ready to view on the device.

These things seem small, but having tried to build actual projects in PhoneGap Build, I found them critical.  I would go kick off a build, and then have to wait for the build to be complete.  I’d open a browser windows while I waited. 20 minutes later, I would cycle through my Chrome windows and remember that I was waiting for a build to complete.  

A few months back I tried my hand and solving this and came up with a shell script that handled this for Android.  Over the past few weeks, I’ve added to, improved, and modified it. I now have a solution in ANT that does the following:

  • Uploads files to PhoneGap Build triggering a rebuild
  • Polls for IOS and Android to be finished
  • Downloads ipa and apk files when ready
  • Installs them onto connected iOS and Android devices
  • Uses the “say” command to let you know when things are done.

It takes the form of an ANT build file, some properties, and 2 shell scripts. I’ve posted the whole thing as PhoneGap Starter Productivity on github. As far as I know this will only work on OS X, which I hope isn’t a huge problem for anyone, and I’m willing to collaborate with someone to make them more cross platform friendly.

Also I feel it’s important to note, that while these scripts mean you don’t have to use the IDE to accomplish these tasks, you still have to have Xcode and the Android SDK on your machine to use them. 

D2WC Next Week

Next week, I’ll be speaking at D2WC, a designer/developer workflow conference in Kansas City, Missouri. 

I’ll be talking about Using PhoneGap Build to simplify your mobile development life. One of the great things about PhoneGap is that it allows you to use HTML JS and CSS to build your applications, but you still have to use native tools to build your apps. PhoneGap Build helps immensely with this, but you make some productivity sacrifices. This session will show you how to maximize your work, and touch as little of the IDE as possible. 

First time for me at this conference, but from what I understand it’s a great conference that tackles a specific topic: getting development and design to work together better. Great goal, really looking forward to it.

D2WC
May 16-18
Kansas City Marriott Country Club Plaza
4445 Main Street
Kansas City, Missouri 64111
USA

Using CSS Regions as an Enhancement

If you were not aware of them CSS Regions are proposal to CSS3 that would allow for some magazine like layouts in HTML pages. Adobe has been leading the charge on getting them into WebKit.  They are currently available in Chrome. (Also I think IE10)

Now the way they work:

  • You create a bit of content in an element like an article
  • You designate that article as the source of a “flow”
  • You designate other elements as the recipients of the “flow” (We’ll call them “regions”)

Then when the browser renders the content

  • The element designated as the “flow” is not shown
  • The content of the “flow” pours into the “regions”

Assuming this HTML:

https://gist.github.com/2371301.js?file=htmlSnippet.html

And this CSS:

https://gist.github.com/2371301.js?file=css.css

You get something like this:

I have a demo. It only works in Chrome.  Resize the screen to see the flowing of the content.

I was presenting on them the other night and I got asked a pretty good question.

Have you thought about how these degrade?

I made a bad joke, then mumbled something about if the browser doesn’t support CSS Regions then the original “flow” element gets displayed and all is well.

I tested it today. And all is not well. Because I still created those region elements. And they show up down at the bottom and add whitespace.

Check out the demo on any browser bu Chrome and you’ll see what I’m talking about all the way at the bottom.

So after some experimentation I decided that the best way to handle this was to create my four regions with CSS exactly how I had but only inject the region holders if the browser supports regions, like so:

https://gist.github.com/2371301.js?file=enhance.js

Here’s a demo of the improved version.

In this case, I get a much better experience for non Chrome users–no weird mile of whitespace at the bottom of the content.

April NYC JavaScript and HTML5 Hackfest Meeting

I’m headed up to New York on Wednesday April 11 at 7pm  for the April meeting of the NYC JavaScript and HTML5 Monthly Hackfest. I was originally intending to just attend but I got tapped to do a 15 min talk.

I’ll be speaking about Adobe’s CSS contributions to Webkit, specifically Regions and Exclusions.

If you’re in NYC, it’s a great group so come on and check it out. Sign up on their site to find out the location details.

webDU 2012

Hello antipodeans and antipodiphiles, I will be speaking at webDU 2012 in Sydney, Australia in a few weeks.  If you have never heard of webDU, it is an absolutely fantastic web conference. It provides a great environment for honest open conversations and learning about the field.

I’ll be giving two talks:

Semantic HTML5

A foray into the geekier elements of internet HTML plumbing.

The Future of HTML5 Motion Design

Talking about Adobe Edge, and showing off some of the cool things we are doing with browser technology.

If you’re in the area, check it out.

webDU
May 3rd-4th
Sydney, Australia

MoDevUX 2012

It looks like I’m going to be speaking at MoDevUX outside Washington, DC later this month.

I’ll be talking about how to make great user experiences in mobile applications with PhoneGap.

It’s a new event and group for me, and it looks great. It’s a UX and UI focused conference with a focus on mobile.  Better yet, here it is in their words:

MoDevUX will bring together leading mobile developers, UX/UI designers, architects and managers to break the mold on user experience and design.  Attendees will discover the latest in mobile UX/design methods and meet likeminded people at the edge of the mobile frontier. Be sure to check out the workshops available on the 19th and the hackathon on the 21st!

 

If you’re in the DC area, check it out.

MoDevUX
April 20
McLean, VA

HTML Page Slide Without a Framework

I’m working on a little demo mobile application for an upcoming project, and I wanted to add sliding transitions between pages. Pretty simple, right? You just use jQuery, jQuery Mobile, zepto, or one of a bunch of other frameworks, and they handle this for you. I didn’t want to.  Part of my goal with this particular project is to challenge myself to work without a framework so that I can see how this stuff works by hand.  Also I wanted to keep the HTML as slim and uncrufted as possible

Googling found very little to go on – except a micro solution for page transitions by FASW. I like it, but it’s still using someone else’s work, and I didn’t like adding even the little bit of HTML cruft that it needed.

So I rolled my own.

The solution I came up with actually is pretty lightweight and is powered by a little AJAX, some CSS transitions, and CSS transition events. It’s also important to note that this only works with WebKit. (My personal use case is for a mobile application with PhoneGap targeting Android and iOS, so I only need WebKit compatibility.)

First thing is to set the CSS of the body to have a transition on it, so when I move it around it’s animated.

https://gist.github.com/2303369.js?file=css.css

Next thing I do is fire off a function when the page loads to replace all links with a function that will create the effect.  I use some techniques I learned from a great article named From jQuery to JavaScript: A Reference to handle these operations without jQuery.

https://gist.github.com/2303369.js?file=step1.js

Next step is to use AJAX to get the linked page.

https://gist.github.com/2303369.js?file=step2.js

Now comes the transitions.  What I need to do to accomplish this page slide is:

  1. Slide the page off the screen to the left.
  2. Instantaneously move the page to the right side off screen
  3. Replace the contents of the body with the new content
  4. Slide the page on to the screen from the right.

I have to do it in that order.  If you replace the contents independent of the animation, you get weird effects like the page changing then the animation happening, which looks jarring. Or you get the opposite, the transition happening, then the contents changing.  Looks ugly.  Trying to time these proved problematic. The best thing to do would be to wait for the transition offscreen to happen, then change the content, then move it back on screen. I was able to do this by using a transition event.

Basically as far as I can tell there is only one transition event “transitionEnd” regardless of browser manufacturer.  I haven’t been able to figure that out. Animation events appear similarly limited.  So here’s how I did it:

I moved the body to the left side of the screen.

https://gist.github.com/2303369.js?file=step3.js

There is an event listener that handles making it transparent while I move it to the other side of the screen.

https://gist.github.com/2303369.js?file=step4.js

I then replace the content, make it visible again, adjust the browser history, and move it back to the center.

https://gist.github.com/2303369.js?file=step5.js

Then to be thorough, I make sure that I reverse the process if the user hits the back button.

https://gist.github.com/2303369.js?file=step6.js

Is this the best way to do this?  I have no idea.  But it works for me and I couldn’t find a comparable solution via Google.

There is a demo here.(WebKit browsers only)

Full source code is available via github.

We Suck at Apologies

apology_kid_opt

Several incidents in the past few weeks, both public and private, have led me to the conclusion that we all suck at apologies when we have offended people. I’d like to try and start a conversation to see if we can fix that.  I feel like I am qualified to give advice here, as I spent my 20’s as an angry and often offensive guy, who had to apologize quite a bit.  Because of this, I’ve learned a little of what works and what doesn’t.

Let’s start with a premise.  You said something that offended someone somewhere. They are angry, and they have called you out on it in some fashion.  (It’s vague, but every example I could come up with might have been offensive.)

“Why should I apologize, what I said (or did) was right?”

This here is the major problem we have with apologizing. We think that apologizing means that we are saying “I was wrong, and you were right.” It doesn’t.  When you offend someone, you have damaged your relationship with them. Whether you are an individual offending another individual or a company who offended a potential market, your actions have damaged the relationship.  The true purpose of an apology is to try and fix the damage in the relationship between you and the offended party. That should be your goal.

“I didn’t mean to offend you.”

Actions have consequences, intentions do not matter.  Actually, it would be better to say, intentions can mitigate consequences, but they cannot erase them.  Suppose I hit a young man with my car. That my intention was to drive home has no impact on the consequence that the young man’s leg is broken. Now the fact that I was soberly driving home, and did my best to swerve out of the way can maybe mitigate what the law says about my culpability, but it cannot fix the man’s leg.

So, good on ya, that you didn’t want to offend anyone. Unless you’re a deliberate provocateur I don’t assume anyone believes you did.  If you were deliberately offending people, I assume you don’t have any interest in apologizing.  So if you are apologizing, shut up about your intentions. You just sound like you are trying to excuse yourself.

“I don’t see what you are getting so upset about.”

This is a shitty, defensive way of saying “I don’t understand how I offended you.” That’s fine.  It is perfectly acceptable to not understand how you have been offensive. If you were able to wrap your mind perfectly around the thoughts and considerations of the offended party, you probably wouldn’t have taken the action that offended them. It’s perfectly fine to ask for clarification and an explanation. Just try not to phrase that request like an asshole.

  • “I’m having trouble wrapping my mind around this, can you explain where you’re coming from?” Good.
  • “Can you tell me why a person like you is offended by this?” – Bad.

“I can’t have said something homophobic, I have quite a few gay friends.”

Repeat after me: There is no such thing as a “ghetto pass.” That you have gay/female/minority friends does not mean you can’t say homophobic/sexist/racist things.  It means that you probably shouldn’t say them, and perhaps you should check to see if you still have those friends.

“You’re overly sensitive.”

This encapsulates a lot of things but at the core of it you are denying the reasonableness of the person taking offense.  The thought here being there are thoughts that while controversial, reasonable people can talk about without taking offense.  There are two problems with this.

The first problem with the reasonableness trope is that it assumes offense is an intellectual response.  It’s not, it’s an emotional response. Therefore reasonableness of the offense is irrelevant as offense in this case is not a product of the reason.  You can tell someone to stop being sad because their life is overall great, but if a personal tragedy has occurred, you can’t stop them from being sad. Likewise whether or not it is reasonable to be offended is irrelevant in the face of actual offense.

The second problem with reasonableness is that it doesn’t matter. Because reasonableness is part of the right/wrong discussion. “It is not reasonable to be offended over this, therefore you are wrong and I am right.”  –which is irrelevant, because apologies aren’t about right and wrong, they’re are about repairing the damage to the relationship.

“140 characters/email/IM is not enough to have a proper conversation about this.”

You’re right. Happy?  Now stop wasting time and move to a higher bandwidth form of communication.

“That’s not what I meant.”

Okay, this is a tough one, and it’s different from “I didn’t mean to be offensive.”  It happens when what they think you said and what you think you said are two different things.  It could be because of someone mishearing you. It’s also perfectly possible that someone is reading into what you have said or done, and giving it a context that makes it offensive to them. It’s also possible that you were not communicating well.

Again it’s time to remember what’s important, fixing the damage.  So apologize first, get acceptance that you want to fix the damage, then start to talk about the misunderstanding.  Ask what language you could have use to make your intended meaning come through.

So how should you apologize?

  1. Start with “I am sorry I offended you.” No qualifiers.  No “If I offended anyone.” You’re sorry that the relationship is damaged and that you caused the damage.  Start from there.
  2. Seek an understanding of what you did that caused offense, and acknowledge it.
  3. No excuses. Unless you were kidnapped, drugged and slammed down in front of a keyboard or phone, you are responsible for whatever you did to offend someone.  Even if it is a “not what I meant” incident. You’re responsible at least in part for the misunderstanding.
  4. Don’t apologize angry. When we are criticized, it’s easy to get angry and emotional ourselves, and therefore get in the way of a real apology.  If the criticism you receive makes you angry or defensive, then wait and calm down.  Very little relationship damage can be fixed with anger.

There you have it, apology advice from someone who’s had to do a lot of it. It’s not about winning an argument, it’s about saving a relationship.