Category Archives: Techniques

Multi-device Syncing Strategy

While reconstructing my app (WordsBaking), a big challenge is data synchronizing. I’ve spent a lot of time thinking about possible ways, and still not sure if I got the best one.

There are two main problems I am facing.

Physical timestamps can’t be trusted

When the user is online, well we may actually calculate the timestamp based on the difference between client and server that can be somehow trusted at some degree. However the process could be really complex if we want to get every detail right. And if the user is offline, you can never tell the timestamp that can be trusted.

So I have to get rid of it, and choose only to trust the physical timestamps with limited correction (lower and upper bounds).

There are too many records to compare when syncing

For my app, there could be thousands of records. And I can’t just upload all of them every time to check whether their timestamps are smaller than the copies on the server. Another independent timestamp for syncing has to be set for quickly picking up records that might have newer version.

The solution seems to be really obvious, just add another timestamp for sync seeking. The question keeps around in my mind is, do both of the timestamp for seeking and for version comparing necessary?

If they are, the complete synchronizing logic would be:

Client

clientStamp: updated every time after syncing, and the value equals the server time when that syncing happens.
itemUpdateStamp: updated every time when an item gets created/updated/removed, and the value should be greater than the latest clientStamp.

When syncing, client would upload the clientStamp and changed items along with their own itemUpdateStamps. And then it would receive changed items from the server along with the new clientStamp, it won’t receive new itemUpdateStamps because it’s not the device that would compare the records version.

Server

For every record in the database, it will have both the clientStamp and the itemUpdateStamp. When receiving a syncing request, it will first find all the records that have the clientStamp greater than the value it receives or have the same ids, and then comparing itemUpdateStamp with the items it receives respectively if they match the items it receives. If a change from the client has a newer itemUpdateStamp, then update the record in database (with the upper bound of itemUpdateStamp being the current time of the server). Otherwise, send the change to the client.

Seems to be quick clear after writing the logic down. ;)

Later I added another feature called passive syncing, thus the client is now able to sync down some related data on demand.

Original link of this archive: http://vilic.info/blog/archives/1159
本文的原始链接: http://vilic.info/blog/archives/1159

Disable Scroll Bouncing Effect of WebBrowser Control on Windows Phone 8

Just another story happens when developing WordsBaking.

First, the basis. If you don’t have any element in your web page that requires overflow style being auto or scroll, “-ms-touch-action: none;” under “html” selector should work well . Actually it works all the time in Internet Explorer, but in a WebBrowser control, if there’s something like a list for which you may need that style, the solution becomes tricky.

I spent tons of hours and tried tons of ways hoping figure out a solution, and luckily, found one.

That is the good news, but the bad news is, this solution doesn’t seem to be elegant (though it works perfectly so far).

The first thing that I found might be useful is that this bouncing effect happens only when your finger touches the elements that already have their contents at the top/bottom or both. So, the first solution I thought might work was to add a pointerdown (MSPointerDown) event listener on the element, and determine whether its content has reached the top or bottom. Unfortunately, it doesn’t work well.

Later I read about an article shows a solution on suppressing scrolling and zooming in WP7 WebBrowser control, I can’t say that it works (on WP8), but it helps.

Combining these two parts (and this is why I think it’s not elegant enough), here’s the solution:

C# Part

private void mainBrowser_Loaded(object sender, RoutedEventArgs e) {
    // here we are using a library named Linq to Visual Tree.
    // http://www.scottlogic.com/blog/2010/03/04/linq-to-visual-tree.html
    var border = mainBrowser.Descendants().Last() as Border;
    border.ManipulationDelta += border_ManipulationDelta;
    border.ManipulationCompleted += border_ManipulationCompleted;
}

void border_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {
    mainBrowser.InvokeScript("onmanipulationcompleted");
}

void border_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) {
    var status = mainBrowser.InvokeScript("onmanipulationdelta") as string;
    if (status == "top" || status == "both") {
        if (e.DeltaManipulation.Translation.Y > 0) {
            e.Handled = true;
        }
    }
    if (status == "bottom" || status == "both") {
        if (e.DeltaManipulation.Translation.Y < 0) {
            e.Handled = true;
        }
    }
}

JavaScript Part

window.manipulationTarget = null;

window.onmanipulationdelta = function () {
    if (!window.manipulationTarget) {
        return '';
    }

    var target = window.manipulationTarget;

    var top = target.scrollTop == 0;
    var bottom = target.scrollTop + target.clientHeight == target.scrollHeight;

    return top ? bottom ? 'both' : 'top': bottom ? 'bottom' : '';
};

window.onmanipulationcompleted = function () {
    window.manipulationTarget = null;
};

// and you'll need to make calls to every elements
// with overflow auto or scroll with this:
function preventBouncing(ele) {
    // using jQuery.
    ele.on('MSPointerDown pointerdown', function (e) {
        window.manipulationTarget = this;
    });
}

And good luck fellows~

Original link of this archive: http://vilic.info/blog/archives/1085
本文的原始链接: http://vilic.info/blog/archives/1085

Some Thoughts on Touch-friendly Mobile Web Apps

These days I am working on a project related to English study as my startup (though part-time), due to the limited resources, I chose a native browser based solution, So that we’ll save some time for building only the single main part of the app which will run on multiple devices.

However, the app I want to build has to be user-friendly, and for an HTML based app on a mobile device, which means, relatively poorer performance, to make the user experience acceptable forms a challenge. Also, as the UX we designed, there would be some touch gestures, how to manage these gestures is also a core issue to figure out.

Luckily, both of these two issues are not tricky.

There are some transition animations during page switching, elements removing, etc. I tried to use something like margin (CSS), but it doesn’t work that well, the animation doesn’t look smooth. So I made some searches, an article says CSS 3 transform has even slower performance comparing to CSS properties like margin and the position stuffs. I believed it… But it turned to be wrong. After I randomly changed the page switching from margin to CSS 3 transform + transition, the animation runs like a charm! I can’t say it’s as good as native apps, but it’s far from acceptable.

I am using Lumia 1020 with IE 10 Mobile myself, and get a Xiaomi 2S with its built-in browser and Chrome Mobile. These browsers all perform well, especially IE 10 and Chrome Mobile. Also, I tested it on an iPhone 5 of my friend, Safari Mobile does a great job, too. That’s actually not a surprise, I wrote some web games in 2010 runs on my iPod touch 3 32G using CSS 3 animations, even with some 3D stuffs, and the game performed well.

As for gestures management, I wrote two classes respectively called GestureIdentifier and GestureDelegate and so far they works well. The idea is really simple but it really makes things much easier, hoping telling this will help some starters learn about the power of ideas which is far above code itself.

And also some quick notes:

About “meta viewport”, seems that some phones have a minimum valid width of 360 instead of 320, so any value below 360 will not work… T-T gotta make some changes to fit this new value…

About click and “tap”. Seems that if these is a click event (especially on an “a” tag), these will be a semi-transparent rectangle when you “tap”. But sometimes, it doesn’t look well… Luckily “tap” based on touch event would be a solution… As I got the two gesture classes, I can simply define a new GestureIdentifier called “tap” and write a simple rule like the path of touch has only one point. Solved.

Wishing this tool will soon be available to everyone!

[Update]

The touch event trick for preventing tap highlight works most of the time, but on IE Mobile there are still some conditions on which the semi-transparent rectangle (tap highlight) will show up, so I continued searching for solutions. Luckily, there are way better and more official ones:

For IE, there’s a meta item named “msapplication-tap-highlight”, and simply setting the content to “no” solves the problem.

<meta name="msapplication-tap-highlight" content="no" />

For Webkit (Chrome and Safari), there’s a style named “-webkit-tap-highlight-color”, and “transparent” is the answer.

html { -webkit-tap-highlight-color: transparent; }

Original link of this archive: http://vilic.info/blog/archives/1062
本文的原始链接: http://vilic.info/blog/archives/1062

C# Refresh System Tray Icons (Remove the dead ones)

I was writing a small tool to restart a related application when it seems to stop working. As I don’t want to spend much time on this thing, I use Process.Kill to do that part of job. But after that, I will need to clean the notification area and remove the dead system tray icons.

I made searches and found one working great on my computer running English Windows 7.

http://maruf-dotnetdeveloper.blogspot.com/2012/08/c-refreshing-system-tray-icon.html

However, when I copied it to the server, the code was just doing nothing. As I am not familiar with Windows API and its programming, it took me a long time to realize the problem. Though the window titles such as “User Promoted Notification Area” are not visible, it’s been translated on the non-English Windows OS.

So I tried Spy++ (which I am not familiar with, either), and found out the Chinese ones for those strings.

“User Promoted Notification Area” => “用户升级的通知区域”
“Overflow Notification Area” => “溢出通知区域”

I didn’t find “Notification Area” one, and guess it’s on Windows XP. But I think it should be translated into “通知区域”.

And, it now works like a charm. ;)

Original link of this archive: http://vilic.info/blog/archives/1050
本文的原始链接: http://vilic.info/blog/archives/1050

HowTo: Add Facebook Account on a China Country Variant Lumia

Before we start, there’s something you may need to know:
1. It has to be Windows Phone 8.
2. Twitter account can’t be added this way.
3. When come to flashing ROM, I refer the WCDMA model (for China Unicom).

And the technique here is simple, though not very easy to be done. We’ll need to add the Facebook account somewhere else first, backup the settings and then restore it on the China Country Variant Windows Phone.

I was lucky because I got a Hong Kong CV Lumia 920, so I simply restored the backup data on my new Lumia 1020 and the Facebook account showed up. However for other people who don’t have an older Windows Phone runing WP8, they won’t be able to add that account at the first place. Luckily, we get Vietnam CV Lumias sharing the same models (you can check the RM-xxx code to see if that really matches) as Lumias for Mainland of China. So we can flash the Vietnam ROM and then get Facebook account added.

Actually if you are cool with that Vietnam ROM, you can just get off the bus here and enjoy the social network, or you may want to flash back ROM for China as what I would do.

Some photos here by Lumia 1020.

NOKIA Pro Camera – Auto mode:

WP_20130820_18_37_05_Pro WP_20130820_19_26_27_Pro WP_20130817_18_30_22_Pro

NOKIA Pro Camera – ISO 100 / 0.8 seconds:

WP_20130819_21_02_20_Pro

And a bonus by Lumia 920 (Edited by Fireworks CS6).

1020-small

Original link of this archive: http://vilic.info/blog/archives/1037
本文的原始链接: http://vilic.info/blog/archives/1037