November 9, 2011

Adobe focuses on technologies which actually work

According to rumors, which are likely to be confirmed soon, Adobe has stopped development on Flash Player for browsers on mobile.

Easy to guess that it will trigger an avalanche of sarcastic comments from fanboys who have no clue about the technology.

This already happens.

But is it really game changing announcement?

Definitely not!

In fact, nothing has changed, because until now there was no single significant Flash project targeting mobile browsers.

From the very beginning with Flash Lite the whole idea of delivering ANY SWF to mobile browser was weak.

Complex web applications are not suitable for that at all from UI and performance perspective.

Games could be and should be packaged as apps and some companies already do so.

Ads with the flying tagline and pulsating product picture? Well, I do not really care about ads, but this is probably the area where so called HTML5 is already good enough.

That is why I totally support Adobe's move to sharpen focus on:

  1. Desktop Flash Player. It is crucial to choose the right tool for the right task. Using Flash for simple wizard nowdays is nonsense. At the same time it remains the obvious choice for complex web applications. With Flash Builder and Flex SDK you can build high-quality applications with unbeatable performance which work the same in all browsers on all operation systems. Other than that there are still a lot of important features which are either not supported as such or virtually impossible to implement and maintain with HTML/CSS/JS stack of technologies. When you attach multiple files in GMail - it's Flash. Charts in Google Analytics Flash again. All more or less complex operations with media content from Grooveshark to YouTube are also implemented in Flash.

  2. Air as a tool to build cross platform apps. Now also for mobile. Although there is huge iOS domination in smartphone and tablet markets, there are some other platforms already present on the market and it is quite possible that new will appear. Companies have to invest a lot to address all of them with native apps. For giants it is not a big issue. For certain performance sensitive applications it will remain inevitable as well. But with latest releases from Adobe and native extensions support Air becomes the best choice for many others. With single code base you address iOS, Android and other platforms and use any platform specific feature when needed.

  3. HTML5 authoring software. There is too much hype about HTML5 (mostly from people who know this buzzword only from Steve Jobs famous Thoughts on Flash), but until now there are no tools for creative professionals to produce content comparable even to Flash 3 (more than 10 years ago!). Every single HTML5 ad, demo, promo is PROGRAMMED by frontend developers. For sure this must be changed. And there is a big opportunity for Adobe here. Hopefully in future JavaScript, that is probably the worst programming language in the world, will evolve to something like ActionScript 3.0 and we will see HTML5 authoring software not only for designers and animators, but also for developers.
UPDATE

http://www.beautifycode.com/flash-mobile-died-so-what
http://gskinner.com/blog/archives/2011/11/flash-player-mobile-a-post-mortem.html
http://www.leebrimelow.com/?p=3151

September 22, 2010

How to format the time span between now and the date specified in a "Facebook way"

Recently I was looking for some method to format the time span between now and the date specified in a "Facebook way". There are some, but none was completely what I was looking for. So I have decided to create mine. Moreover, it's not that complicated:
package {

import mx.formatters.DateFormatter;
import mx.utils.StringUtil;

public class DateUtil {

public static const SECOND_IN_MILLISECONDS : int = 1000;

public static const FEW_SECONDS : int = 5;

public static const MINUTE_IN_SECONDS : int = 60;

public static const HOUR_IN_SECONDS : int = MINUTE_IN_SECONDS * 60;

private static const X_SECONDS_AGO : String = "{0} seconds ago";

private static const X_MINUTES_AGO : String = "{0} minutes ago";

private static const X_HOURS_AGO : String = "{0} hours ago";

private static const IN_X_SECONDS : String = "In {0} seconds";

private static const IN_X_MINUTES : String = "In {0} minutes";

private static const IN_X_HOURS : String = "In {0} hours";

private static const YESTERDAY_TOMORROW_PATTERN : String = "at L:NNA";

private static const THIS_WEEK_PATTERN : String = "EEEE at L:NNA";

private static const THIS_YEAR_PATTERN : String = "MMMM D at L:NNA";

private static const ANOTHER_YEAR_PATTERN : String = "MMMM D, YYYY at L:NNA";

/**
         * Format the time span between now and the date specified in a "Facebook way".
         *
         * Examples:
         *
         * May 18, 2011 at 5:11AM
         * December 25 at 8:43PM
         * Friday at 3:53PM
         * Tomorrow at 10:44AM
         * In 10 hours
         * In about an hour
         * In 25 minutes
         * In about a minute
         * In 17 seconds
         * In a few seconds
         * A few seconds ago
         * 31 seconds ago
         * About a minute ago
         * 47 minutes ago
         * About an hour ago
         * 4 hours ago
         * Yesterday at 6:25PM
         * Monday at 12:30AM
         * September 11 at 7:11AM
         * September 10, 2009 at 12:23PM
         */
public static function getTimeSpan(date : Date) : String {
var result : String;
var now : Date = new Date();
var dateFormatter : DateFormatter = new DateFormatter();
var range : Number = (now.time - date.time) / SECOND_IN_MILLISECONDS;

var nextYearStart : Date = new Date(now.fullYear + 1, 0, 1);
var nextWeekStart : Date = new Date(now.fullYear, now.month, now.date + (7 - now.day));
var tomorrowStart : Date = new Date(now.fullYear, now.month, now.date + 1);
var theDayAfterTomorrowStart : Date = new Date(now.fullYear, now.month, now.date + 2);
var todayStart : Date = new Date(now.fullYear, now.month, now.date);
var yesterdayStart : Date = new Date(now.fullYear, now.month, now.date - 1);
var thisWeekStart : Date = new Date(now.fullYear, now.month, now.date - now.day);
var thisYearStart : Date = new Date(now.fullYear, 0, 1);

var nextYearRange : Number = (now.time - nextYearStart.time) / SECOND_IN_MILLISECONDS;
var nextWeekRange : Number = (now.time - nextWeekStart.time) / SECOND_IN_MILLISECONDS;
var theDayAfterTomorrowRange : Number = (now.time - theDayAfterTomorrowStart.time) / SECOND_IN_MILLISECONDS;
var tomorrowRange : Number = (now.time - tomorrowStart.time) / SECOND_IN_MILLISECONDS;
var todayRange : Number = (now.time - todayStart.time) / SECOND_IN_MILLISECONDS;
var yesterdayRange : Number = (now.time - yesterdayStart.time) / SECOND_IN_MILLISECONDS;
var thisWeekRange : Number = (now.time - thisWeekStart.time) / SECOND_IN_MILLISECONDS;
var thisYearRange : Number = (now.time - thisYearStart.time) / SECOND_IN_MILLISECONDS;

if (range >= 0) {
if (range < FEW_SECONDS) {
result = "A few seconds ago";
} else if (range < MINUTE_IN_SECONDS) {
result = StringUtil.substitute(X_SECONDS_AGO, Math.floor(range));
} else if (range < MINUTE_IN_SECONDS * 2) {
result = "About a minute ago";
} else if (range < HOUR_IN_SECONDS) {
result = StringUtil.substitute(X_MINUTES_AGO, Math.floor(range / MINUTE_IN_SECONDS));
} else if (range < HOUR_IN_SECONDS * 2) {
result = "About an hour ago";
} else if (range < todayRange) {
result = StringUtil.substitute(X_HOURS_AGO, Math.floor(range / HOUR_IN_SECONDS));
} else if (range < yesterdayRange) {
dateFormatter.formatString = YESTERDAY_TOMORROW_PATTERN;
result = "Yesterday " + dateFormatter.format(date);
} else if (range < thisWeekRange) {
dateFormatter.formatString = THIS_WEEK_PATTERN;
result = dateFormatter.format(date);
} else if (range < thisYearRange) {
dateFormatter.formatString = THIS_YEAR_PATTERN;
result = dateFormatter.format(date);
} else {
dateFormatter.formatString = ANOTHER_YEAR_PATTERN;
result = dateFormatter.format(date);
}
} else {
if (range > -FEW_SECONDS) {
result = "In a few seconds";
} else if (range > -MINUTE_IN_SECONDS) {
result = StringUtil.substitute(IN_X_SECONDS, Math.floor(-range));
} else if (range > -MINUTE_IN_SECONDS * 2) {
result = "In about a minute";
} else if (range > -HOUR_IN_SECONDS) {
result = StringUtil.substitute(IN_X_MINUTES, Math.floor(-range / MINUTE_IN_SECONDS));
} else if (range > -HOUR_IN_SECONDS * 2) {
result = "In about an hour";
} else if (range > tomorrowRange) {
result = StringUtil.substitute(IN_X_HOURS, Math.floor(-range / HOUR_IN_SECONDS));
} else if (range > theDayAfterTomorrowRange) {
dateFormatter.formatString = YESTERDAY_TOMORROW_PATTERN;
result = "Tomorrow " + dateFormatter.format(date);
} else if (range > nextWeekRange) {
dateFormatter.formatString = THIS_WEEK_PATTERN;
result = dateFormatter.format(date);
} else if (range > nextYearRange) {
dateFormatter.formatString = THIS_YEAR_PATTERN;
result = dateFormatter.format(date);
} else {
dateFormatter.formatString = ANOTHER_YEAR_PATTERN;
result = dateFormatter.format(date);
}
}

return result;
}
}
}

November 6, 2008

Do not comment code!

Commenting code is the worst practice promoted by "wannabe smart" books about software engineering. Joshua Block in his How to Design a Good API and Why it Matters keynote notes that code should read like prose and shows the good example:

if (car.speed() > 2 * SPEED_LIMIT)
generateAlert("Watch out for cops!");


And I completely agree with this statement. Thus good code is self-explanatory and does not require comments. On the other hand comments will never rescue bad code. Sure, we can use something like "TODO: I will fix this dummy trick in the next iteration", but no more than it.

May 12, 2008

Second Ukrainian Flash Platform User Group official meeting

This time Ukrainian Flash Platform User Group meeting has been held in Kiev. Two previous meetings have been held in Kharkov. We have gathered at cozy Golden Gate Pub of Mirovaya Karta chain near Golden Gates. Ilya Panin from Kharkov has compared different IDEs (Adobe Flex Builder, FDT, FlashDevelop, IDEA) and summarized that as a whole Adobe Flex Builder is the best choice to develop Flex applications now. Tatyana Belaya from Moscow has told about sound visualization using SoundMixer.computeSpectrum() method with snowflakes on background. Roman Shuper has shared his experience using Apache Ant to deploy Flex projects and also told about conditional compilation and running executables from AIR applications.

Flash Platform User Group

April 17, 2008

Flex SDK coding conventions and best practices

Adobe has published Flex SDK coding conventions and best practices. Now it is mostly about ActionScript 3.0. I work in a team for a long time, so we have created our own conventions long time ago, because it is a must for collaborative development. It is based on ActionScript 2.0 Best Practices, Code Conventions for the Java Programming Language and the common sense. Nevertheless, it's a great effort from Adobe, because vendor supported guidelines are always more respected and tend to become industry standard. Now I hope Adobe would also extend the document with MXML conventions.