Google Docs Notifier 2

Motivation
“Does Google Docs notify you when collaborators make changes/edit documents… when you are the creator of the document & you’ve shared it with other collaborators?”

This question was asked in 2009 on the Docs Community (http://www.google.com/support/forum/p/Google+Docs/thread?tid=231452b7671aa264&hl=en). Up to now, this question is still not answered by any Google staff officially. In the previous semester, I released Google Docs Notifer and announced it on the forum. Just within few months after that, I received feedback from three users. They gave me some suggestions and ideas regarding how to improve the Google Docs Notifier.

So, I decided to continue working on this project and finally released the second version of Google Docs Notifier.

Google Docs Notifier 2 Login Screen
Google Docs Notifier 2 Login Screen

GUI Improvement
Unlike the previous version, Google Docs Notifier 2 is done using WPF which allows me to do better GUI. Now its main window is smaller than the previous one. In the main page, user needs to key in their user name and password first.

After signing in, user can view all his unread documents and their updated date, time and person. In WPF, I can customize the listViewItem in XAML so that I can present the information in a nicer and more organized manner. User can easily find out what are the latest documents updated, who modified them and when they are modified.

To make users’ life easier, the app will display the total number of unread documents on system tray as well. So, they can easily find out whether there are new updates in their Google Docs or not.

System Tray Notification Popup
System Tray Notification Popup

Remember Me!
I was asked by a user if I can add in the feature of remembering user’s password so that he doesn’t need to login every time he runs Google Docs Notifier. I answered him yes but I warned him that there was a risk of losing his password easily especially if he run it on shared computer. Finally, I decided to have a checkbox there for the users to make their own choice on whether to store their password or not.

This feature is not that hard to implement. I used one evening to figure out the way to correctly encrypt and decrypt data using the Data Protection API, or DPAPI. There is an article online about how to do this correctly: http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx.

Unread vs. Unviewed
In Google Docs site, they use the words “viewed” and “unviewed” to differentiate documents which are read and not read by the users. In addition, the users are allowed to mark read documents as “unviewed documents” and unread documents as “viewed documents”.

However, in their API, these two words mean different thing. In the Documents List API, they call newly created documents as “unviewed documents” and the rest as “viewed documents”. This causes the developers can only depend on the updated and lastViewed timestamps to figure out the documents which are not yet read. Hence, in Google Docs Notifier, I use the word “unread” instead of “unviewed”. This means that as long as the document is not yet read, it will be labelledĀ as unread documentĀ in Google Docs Notifier, no matter whether it is already marked as “viewed” or “unviewed” in online Google Docs site.

Only Display Unread Documents
Only Display Unread Documents

Conclusion
Google is now developing the third version of the Documents List API. However, the API is only applicable for Java and Python. Their .NET library is still based on the second version, which is order. In addition, arbitrary files are not recognized by the Documents List API, so if they are arbitrary files uploaded to Google Docs site, the Google Docs Notifier won’t able to know that.

If you are using Google Docs and you are also looking for a way to get notified for every new update on your Google Docs, please take a look at my Google Docs Notifier: http://googledocsnotifier.googlecode.com. Thank you very much! =)

Drag-and-drop Reordering in WPF ListView

Problem
When I was working in OneSync project, our team was once asked if there was a way to implement drag-and-drop reordering in the ListView control. We answered no because we could not find any way to implement that functionality. In the end, we used two buttons: Up and Down for reordering the rows in listView.

Up-and-Down Reordering Buttons in OneSync
Up-and-Down Reordering Buttons in OneSync
Solution
Last week, I was again asked by my friend to implement similar stuff in WPF. I tried to google and I found the solution, finally: http://www.codeproject.com/KB/WPF/ListViewDragDropManager.aspx.

Drag-and-Drop Reordering Is Possible in WPF ListView
Drag-and-Drop Reordering Is Possible in WPF ListView
There are three major classes I use in the new project:

  1. ListViewDragDrop.cs: Manages the drag-and-drop reordering in ListView.
  2. DragAdorner.cs: Draws a translucent listViewItem on top of the ListView and makes it follow the cursor during the drag-and-drop operation.
  3. MouseUtilities.cs: There is a method which returns the position of the cursor.

I find the MouseUtilities class to be quite interesting. The author of the method is Dan Crevier from Microsoft. According to the documentation, the purpose of having the class is because “the WPF mechanisms for retrieving the cursor coordinates are unreliable”.

It uses unmanaged code to solve the problem. After coding in C# for several years, I am getting used to reading the managed code, but not unmanaged code in C#. However, for those who are good at C and C++, they can try reading the code in MouseUtilities.cs.

Drag-and-Drop or Up-and-Down Buttons?
In fact, I like the Up and Down buttons very much because they allow the last item in the list to become the first item with just one click on the Down button. If we use the drag-and-drop feature, then we have to drag the last item all the way up to the top of the list. It will be quite troublesome when the list is very long.

Re-Player Wave: Lesson Learnt from YouTube RealTime

Motivation
I have been doing the YouTube related projects since late 2008. As a YouTube user (and fan), I find that watching videos together with friends or family is a very unique experience also because normally we only watch YouTube on our own laptop or computer.

In the early 2010, when I was doing the first assignment for CS4341 Multimedia Technologies in NUS, I found an interesting feature provided by YouTube. It was called YouTube RealTime. In YouTube itself, it allowed user-to-user interaction, an element which is getting more and more important due to the rise of social networking sites.

In YouTube RealTime, people are able to see what their friends are doing on YouTube, for example the videos they are watching, their comments for the videos and so on. They can also receive real-time notifications when their friends add a new comment to the video. So, it is something like Facebook where the users can see their friends’ status as well as receive real-time notification when their friends like or comment on their posts.

YouTube RealTime Toolbar Showing Friend Activities
YouTube RealTime Toolbar Showing Friend Activities

However, just about one month after the school assignment was done, YouTube RealTime was discontinued by Google in March (Reference: http://www.google.com/support/forum/p/youtube/thread?tid=114593f2f666e137&hl=en). About the same time, I attended a Google Wave workshop for CS3216 students. So, I was thinking whether I could do something similar to YouTube RealTime which would allow me to share and watch videos together with friends staying in different places. On 6 February, a new project Re-Player Wave began.

Google Wave
Google Wave is a software application originally developed by Google and later continued by Apache as its Incubator program on 6 December. Google Wave is mainly for real-time communication and collaboration. It was a cool toy for the web developers as well because they could write a gadget for Google Wave. Building a Wave gadget is not that difficult because it requires simple JavaScript, HTML and XML knowledge only.

Luckily, Google Wave does not meet the same fate as YouTube RealTime which is discontinued by Google. Hence, I was still working on the project of building Re-Player Wave, which is also a Wave gadget, in the past few days.

Real-time Videos Sharing and Communication
Google Wave provides a very interesting feature which is online real-time collaborative editing. The main reason why I choose Google Wave as the platform is also because of this feature. Re-Player Wave allows user to share videos with a selected group of his friends on Wave. For each time he adds a new video to Re-Player Wave, the group of friends will be updated at the same time as well.

In order to prove that Re-Player Wave is able to do that, I borrow my sister’s Wave account to do the experiment. If I add a video on my computer, then my sister’s Wave thread will be updated with the new video which is added by me. Similarly, if I add a video on her computer, then I can see the update in my computer as well. The new video will only be added to the list but will not replace the current viewing video.

Re-Player Wave: Sharing Playlist with Friends
Re-Player Wave: Sharing Playlist with Friends

YouTube RealTime also provided the feature for real-time communication. Thanks to the same feature offered by Google Wave, real-time communication will thus be possible in Re-Player Wave as well. Besides, there is no need to find a place to host my YouTube Re-Player because all the key information can be stored easily in the state of each Wave thread. After trying to find a place to host my YouTube Re-Player, I finally find a solution to this problem by just transforming YouTube Re-Player to be a Wave gadget.

JSON-C
I learnt about the JSON in my previous GCL Project. In this project, I came to know about the JSON-C. According to the YouTube API Developer Guide, the developers are encouraged to use the JSON-C, instead of JSON, for their applications because the JSON feed will be eventually be replaced by the new functionality provided by JSON-C.

According to the guide (http://code.google.com/apis/youtube/2.0/developers_guide_jsonc.html#Comparing_JSON_and_JSONC), JSON-C feeds are something like the simplified version of JSON because all those XML namespaces and schema related information will not be kept in JSON-C. So, JSON-C is easier to be parsed and used. I am currently finding ways to improve Google Docs Notifier from my another GCL Project. Google Docs Notifier retrieves all the information stored in the JSON format, not in the JSON-C format. So, it is sometimes very hard for me to find out where I should get a certain information out from the JSON.

YouTube Social
YouTube Social

Another Alternative: YouTube Social
Actually besides YouTube RealTime, there is another application called YouTube Social which does almost the same thing as YouTube RealTime and Re-Player Wave. One interesting feature of YouTube Social is the remote control. Unlike Re-Player Wave which the user cannot control what his or her friends are watching, YouTube Social gives the owner a remote control so that he can control the YouTube player of his or her friends as well. If you find this feature useful, you can try it out at http://www.youtubesocial.com.

Re-Player Wave
Re-Player Wave

What’s In It For The Users?
To summarize, Re-Player Wave is a new way for YouTube users to interact with their friends in real time. With Re-Player Wave, you can:

  1. Share videos with friends;
  2. Invite your friends to watch the video you are watching;
  3. Chat with friends about the videos in real time.

Now the Wave has come back from the dead, so please join the Wave community again. If you want to try out the gadget, you can download it at: http://www.comp.nus.edu.sg/~gohchunl/Re-PlayerWave.xml (available until 31 December 2011).

A Dynamic Web Page: Linking Up Website and Google Docs

One day, my friend told me that many websites were outdated or not maintained because it was sometimes troublesome to update the HTML files stored in the servers frequently. So, he was finding a solution where the text of the website was not in the HTML files, instead the text would be stored at a place where people could easily access and edit. I agreed with him. For example, in a university course homepage, there was a web page listing the recent news happening in the course. It turned out that even the prof found it troublesome because the News section of the website was never updated after the second week of the semester.

Dynamic Pages with Google Docs API
Hence, my friend and I were trying to find ways to solve the problem. Finally, we had this idea of turning the web pages into dynamic web pages by using the help of the Google Spreadsheets API. By using this methods, in the future, whenever we need to update those dynamic web pages, we can just update the spreadsheet in Google Docs. After that, the JavaScript code in those dynamic web pages will automatically retrieve the latest changes made in the Spreadsheet and then updates the corresponding parts in those web pages. In order to let the JavaScript get the updates of the Spreadsheet, the Spreadsheet is published as RSS feeds.

JSON + XML = Connection Between GDocs Spreadsheet and Web Pages
JSON + XML = Connection Between GDocs Spreadsheet and Web Pages