Thought Stream

EditPlus 3.40 Excitement!

leave a comment »

I just upgraded to EditPlus 3.40, and I got all the search-and-replace features I’ve been wanting for years!

First of all, the Replace dialog now allows for storing search-and-replace presets, including the most important flags — case sensitivity, whole word, and regular expression toggle. This feature is accessed through another dialog via the List button, and then you have to press Add before you start typing. This is the EditPlus Way.

The best part is that I can finally record a relatively reliable macro (aka recording) for a preset search-and-replace. The setup is a little awkward — you have to record the whole process of opening the Replace dialog, then opening the List dialog, somehow selecting the correct item from the list, and then pressing OK and Find, but it seems to work pretty reliably.

Then there’s the Set Marker button in the Find dialog, which will set a marker on every line with the search string. (Personally, I would have gone the extra mile and added an s to that button’s caption.) I have definitely done this by hand several times. The markers are there until you clear them.

As an aside, this behavior is quite comforting to someone who has suffered many times from the frustrating compromise offered by many other applications, where the markers are displayed, but only while the search dialog is open or the text field has focus and disappear as soon as one starts browsing around.

The Find in Files dialog got an option to open the results in a new file, but this was already a matter of a couple of clicks. The automatic backup feature now lets you preserve the original directory structure.

Bonus: TortoiseGit integration, which I haven’t tried yet, but probably will soon. It’s hidden away as a menu-checkbox under the File, TortoiseSVN menu, but that’s acceptable. It may even be logical — if you understand the EditPlus logic.

Written by Ilya Gulko

March 14, 2012 at 23:50

Posted in Software

Analysis of an Order Form

leave a comment »

Zagat Wine offers an example of a near-perfect combination order and registration form. What follows is my opinion and has not been user-tested.


The email and billing addresses come first, because it is information the user is least likely to have to think about. If the credit card is not around, they’ve already invested a minute into filling out the form. The zip code comes first; The city and state fields are automatically populated.

I’m on the fence about the city and state fields being read-only. I tried a zip code that is assigned to multiple cities and didn’t see any kind of choice, but maybe it’s looked up based on the address?

The shipping address section is identical to the billing address one, but it’s hidden away until you uncheck the “Same as Billing” checkbox. This is a great way to reduce clutter and make the form less daunting to the user.

Sadly, the “Same as Billing?” text was not enclosed in a <label> tag, so clicking it does nothing; You have to aim at the tiny checkbox. Not only should there be a label, but the clickable area for that element should be twice as tall in my.

Thanks to the absence of a credit card type field, which can always be deduced from the number itself, the entire payment information section fits on one row. The expiration date field is not exactly the same format as on most credit cards, but it’s numeric, which is good enough.

Finally, you are given the option to create an account by entering a password. When you focus the first password field, an odd-looking tooltip appears with the password requirements. This works to draw the user’s attention just as they need the information. I would give it a brighter color or a border to make it look less odd floating on top of the Confirm Order button, which is roughly the same width and looks like a border that fell apart.

The option to receive special offers by email is opt-out — checked by default — but I suppose that’s just the age we live in.

Written by Ilya Gulko

December 15, 2011 at 23:16

Posted in Forms, Usability

Adium vs. Pidgin: Little Things Matter

with one comment

I’ve been using a Mac mini as my primary desktop, as a result of having to do some sound recording. This means I’ve had to switch to Adium from Pidgin. Here are a few simple things that make Pidgin very convenient to use, which I really miss in Adium.

  1. Sorting the contact list by log size, descending. Once you’ve tried this, you’ll probably agree that it’s far more convenient than any other sorting methods. People you talk to a lot float to the top, everyone else is more or less alphabetically sorted below. It’s the only sorting method I’ve found that makes a huge contact list manageable.
  2. The “new chat” dialog in Adium will only autocomplete usernames from the currently selected (in the dialog) account. This makes little sense and is a common data entry process flaw. The user is already typing the name in, and the program should adjust itself and look through all of the account names. If an account is in multiple contact lists, it can present this extra information as needed. Fixed!
  3. Pidgin’s log format is very simple HTML, which means the logs are readable anywhere, versionable, portable, and accessible. This also allows you to merge IM logs from multiple computers, something I’ve found very useful. I haven’t gotten deep into the reasons, but Adium’s developers refuse to support plaintext or HTML logging, opting for a proprietary format that, to my understanding, is not readable by other programs, let alone computers. This is a strange decision for an open source project, but it looks to be a permanent one.
  4. It would be really nice if Adium had a “switch to next unread message” command. Pidgin does this by default when you press Ctrl+Tab and you have unread messages, which can be a little disorienting. This is a feature I’ve grown to love in irssi and would like to see in other programs.
This list will continue to grow as I encounter more things that I’m forgetting so far.

Written by Ilya Gulko

July 15, 2011 at 16:06

Posted in Usability

Quality Checklist for iPhone Apps

leave a comment »

Introduction

A lot of iPhone apps are being introduced to market, and a pattern of UI shortcomings and aggravating bugs is emerging. Below, I will attempt to provide a checklist for any developer who wants to give their app one last look-over, perhaps during the quiet period that so often presents itself shortly before a deadline or close to project completion.does

This post is a work in progress. More material, examples, and screenshots will be added as time goes on. Suggestions and ideas are encouraged.

Last updated May 26, 2011. Renamed the section about the Silent switch and added a section about status bar behavior. To do: Letting auto-correction do its thing on the last word of a message before sending it.

Categorize Text Fields Correctly

Incorrectly classified text fields will result in a lot of inconvenience and problems. For example, if you forget to correctly classify an e-mail entry field, you may end up with a high occurrence of invalid e-mail addresses that have been auto-corrected by iOS.

  • E-mail and URL fields should have auto-capitalization and auto-correct disabled. Ensure that the correct keyboard appears.
  • Name and address fields should be auto-capitalized, but not auto-corrected.
  • Phone numbers and postal codes should not be auto-capitalized or auto-corrected, and the keyboard should switch to the appropriate mode.

Remember to Hook All Termination APIs

Disclaimer: This section may contain some inaccuracies when it comes to API names and the details of how they work. Corrections are welcome and encouraged. Regardless of the exact mechanics, the fact remains that many apps only save state in some scenarios and not others, which is a major flaw.

With new iOS releases, additional scenarios and reasons have come into existence for your program to be terminated. Because Apple doesn’t spend a lot of time on backwards compatibility, it’s up to you to keep up with these changes. Failing to do so may result in your program failing to save state in certain situations, giving the user the perception that a certain state has become “stuck”.

An example of this behavior is evident in the Meebo app, as of version 1.9.49067. I suspect that Meebo only watches for the applicationWillTerminate event, and not applicationDidEnterBackground. The resulting behavior is far from desirable — the app only saves the current state in certain scenarios, and revert to the last saved one in most cases.

Make the App Usable Without Registration

Aside from it being against the App Store terms of service, an app that presents little more than a sign-in dialog on launch is bound to make the user feel like the butt of a practical joke. Paperlinks is a good example of an app that misses this one, despite being little more than a barcode scanner.

Offline Performance and Behavior

What happens if there is no network connection when the app first launches? What about resuming?

Don’t Lose That Data!

Your app should do everything possible to ensure that anything input or stored by the user is retained, regardless of the circumstances. Here are some scenarios to consider:

  • Polite app termination; impolite app termination; phone powerdown; phone restart
  • Slow network; flaky network; inaccessible network — in whatever order they decide to present themselves
  • Disconnection and reconnection during any phase of data transfer

Don’t Lose Those Breadcrumbs!

When navigating from screen to screen, the user should always have a clear path back to the previous screen. For example, when using the history list in the Bing app, there doesn’t seem to be a way to return to the list after choosing an item in the list. The user must repeat all of the steps again, navigating to the main screen, tapping the ambiguous arrow, and choosing “history” from the list.

Pay Attention to the Silent Switch

Except for apps that play music, your app should not play any sounds if the Silent switch is set to silent. The most recent offender in this category is the “Words with Friends” app, which plays sounds regardless of the switch setting. (This behavior is only exhibited if another app is already playing music.)

For video playback, I am a fan of some apps that mute the sound for a video when Silent Mode is enabled and the app is active.

I think that Apple carries some of the blame for poor user experience here. If you provide an option called “Silent Mode”, an app that unexpectedly plays sounds can turn into a serious liability.

Standard Status Bar Behaviors

If a scrollable list is displayed, touching the status bar should immediately scroll to the top; This should happen on the touchstart event — as soon as the user touches the status bar.

Putting the finger down above the screen area and then moving it down until it reaches the screen should also result in scrolling to the top. For some reason, this triggers the area directly below the status bar in several apps. This results in accidental activation of breadcrumbs, Edit buttons, etc.

Account for Auto-Correction

If the user is pressing a “Send” button, on the keyboard or otherwise, be sure to allow auto-correct to do its thing one last time before sending the message. An app that currently forgets to do this is imo.im.

Another interesting issue I recently noticed in the Gmail web app is that, somehow, the autocorrect pop-up “labels” don’t respond to being tapped, probably overlaid by something else. Make sure you can still tap them to cancel the correction. On Gmail, this bug affects the search query field on the search results page.

Written by Ilya Gulko

April 13, 2011 at 08:51

Posted in iPhone, Software

Web Browsing for the Paranoid and Privacy-Conscious

leave a comment »

You may already be familiar with NoScript, the Firefox extension that allows you to allow JavaScript on a site-by-site basis (by domain or sub-domain. However, there are two things that NoScript doesn’t cover:

First, there is information leaked through the HTTP referrer header. In particular, search engine queries can be seen by any sites you visit from a search results page. One easy solution to this is to just disable the referrer header altogether. The problem is that some sites require it, and I end up constantly going back into about:config to toggle this setting, not to mention forgetting to change it back.

RefControl

An extension called RefControl by James Abbatiello takes care of this issue. RefControl makes the referrer header a domain-level setting. Besides just blocking or allowing the header through, RefControl allows me a custom setting for each site; There is also a “forge” option, which makes Firefox always send the root URL for the domain as the referrer header. (For example, visiting http://www.example.com/abc/def/ will send a referrer header of http://www.example.com/.)

The other hole not covered by NoScript is cross-domain requests. For example, a web site may embed a script from facebook.net, which will then fetch the currently logged in account and display that account’s information on the page, as well as notifying Facebook about what site I’m visiting. With NoScript, JavaScript permissions for a domain are all-or-nothing. If you want Facebook to work properly, you have to allow scripts from facebook.net to run; And by doing this, you are also allowing them on every other site. Similar privacy questions also crop up when it comes to image elements, Flash, etc.

RequestPolicy

This is where an extension called RequestPolicy by Justin Samuel comes in, allowing you fine-grained control of cross-domain requests, for both source and target domains. RequestPolicy blocks all cross-domain requests by default, and allows three types of whitelists: origin, destination, and origin-to-destination. In other words, you can allow all requests from a domain, to a domain, or for a source-target pair. It also provides a convenient way to see exactly what’s going on with a Request Log pane, which lets you see what’s being blocked and allowed through.

Personal Wishlist

All three extensions could use a little more flexibility. NoScript is desperately the ability to create rules involving the parent page. For example, because Twitter hosts its scripts at amazonaws.com, in order for Twitter to work with NoScript, one has to allow scripts from that domain. However, anyone with an Amazon Web Services account can host something at that domain. An attacker could work around NoScript’s restrictions by hosting a script on one of these “trusted” domains.

It would be nice if RefControl allowed origin-based rules in addition to destination-based. For example if a website hosts its resources on a whole pool of servers without hostnames which also check the referral header. you either have to disable RefControl altogether, or create an individual rule for each IP address.

On a couple of occasions, I’ve wished that RequestPolicy also supported a blacklist with exceptions. It would probably not be trivial to implement in a way that doesn’t lead to unpredictable filtering behavior, so I’m pretty happy where it is today.

The Price You Pay

This brings us to the last part — the cost of all this control. With today’s widespread use of CDNs, as well as the whole Web going dynamic and often forgetting about graceful degradation, many popular sites will initially not work without a couple of new whitelist rules being added. This often means up to a minute of clicking before a site will work, which can be frustrating. Whether this is just the price you pay for control or too much hassle to bother is up to you.

Written by Ilya Gulko

March 25, 2011 at 17:13

Posted in Privacy, Security, Software

E-mail Opt Out: The Wrong Way

leave a comment »

If your e-mail servers’ reputation seems too good lately, here are two easy steps to get your e-mail flagged as spam, with a live demonstration by the VeriSign marketing department.

Step 1: Instead of a simple “click here to opt out” link, link me to a place to edit my “user profile”.

To remove yourself from receiving future VeriSign Authentication promotional mailings, please visit us at:
http://www.verisign.com/compref and update your communication preferences and user profile.

Step 2: Require me to re-enter my e-mail address and fill out a form. If you really want to go all out, make the form have at least 15 fields, even though only two of them are required.

Written by Ilya Gulko

March 23, 2011 at 15:43

Posted in Spam

Flagging Provides Useful Data, So Make It Easy

leave a comment »

If you’re displaying user-submitted content without the option to flag or promote it, you’re opening yourself up to spam and missing out on valuable feedback.

Flagging should be as easy as possible. Leave the hard work for the backend and statistics.

Above are two examples from the same iPhone app — Foursquare. It’s very easy to flag a venue for inaccuracies and immediately provide a correction. On the other hand, little can be done about spam in the user-submitted tips.

Written by Ilya Gulko

March 12, 2011 at 19:16

Posted in Software, Spam

Inception iPhone App

leave a comment »

With all the vague marketspeak on the Inception app description page on iTunes, you may be wondering what this app actually does:

This app is a dream machine that transforms the world around you into a dreamworld. It uses augmented sound to induce dreams through the headset of your iPhone or iPod Touch. It will change your perception of reality.

The app uses the microphone to sample surrounding sounds and weave them into ambient music — in realtime! I think that’s pretty awesome. It works great for sleeping on the train.

Written by Ilya Gulko

March 2, 2011 at 00:04

Posted in iPhone, Music