Skip to content

Instantly share code, notes, and snippets.

@reid
Created November 10, 2008 20:35
Show Gist options
  • Save reid/23620 to your computer and use it in GitHub Desktop.
Save reid/23620 to your computer and use it in GitHub Desktop.
A YAP 1.0 Ready OpenSocial Application
<!--
A sample YAP 1.0 ready OpenSocial application.
Adapted from http://code.google.com/apis/opensocial/articles/tutorial/tutorial-0.7.html
Updated for OpenSocial 0.8 and the Yahoo! Application Platform by Reid Burke 5 Sep 2008
YAP or 0.8 specific comments are annotated with YAPNOTE
Updated 10 Nov 2008
-->
<script type="text/javascript">
// Original JS code: http://opensocial-resources.googlecode.com/svn/samples/tutorial/tags/api-0.7/gifts_5_streams.js
var globalGivenGifts = {};
var globalViewer = {};
var globalFriends = {};
// YAPNOTE: You may store up to 1K of data per AppData key, up to 1MB total.
// Currently, using gadgets.json.stringify will include properties attached to objects used by Caja
// which take up several hundred bytes. This is a known issue we are working on.
// In this example, we will use a simple comma-seperated format for storing data in a
// single AppData key to save storage space.
function serializeGifts(obj) {
var out = new Array();
for (var id in obj) {
if (id.substr(-3) !== '___') {
continue; // YAPNOTE: Skip Caja properties, which always end with a triple underscore
}
out.push(id);
out.push(obj[id]);
}
return out.join(',');
}
function unserializeGifts(str) {
var out = new Object();
var arr = str.split(',');
var name = false;
for (var i in arr) {
if (!name) {
name = arr[i];
continue;
}
out[name] = arr[i];
name = false;
}
return out;
}
function postActivity(nut, friend) {
var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut'];
var title = globalViewer.getDisplayName() + ' gave ' + globalFriends[friend] + ' ' + options[nut];
var params = {};
params[opensocial.Activity.Field.TITLE] = title;
var activity = opensocial.newActivity(params);
// YAPNOTE: HIGH priority events are treated the same as LOW priority activities in YAP v1.0
// The callback here is specified as an empty function
opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, function() {});
}
function updateReceivedList(viewer, data, friends) {
var viewerId = viewer.getId();
var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut'];
var html = new Array();
html.push('You have received:<ul>');
friends.each(function(person) {
var personData = data[person.getId()];
if (personData) {
var json = data[person.getId()]['gifts'];
// YAPNOTE: You must be very careful to create well-formed JavaScript when working with Caja.
// Missing semicolons are a source of common problems, such as this line:
// var gifts = {}
// should be
var gifts = {};
if (!json) {
gifts = {};
}
try {
gifts = unserializeGifts(gadgets.util.unescapeString(json));
} catch (e) {
gifts = {};
}
// YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja
// Therefore, this code:
// for (i in gifts) {
// should be:
for (var i in gifts) {
// YAPNOTE: We use alphanumeric GUIDs, so the +i > 0 check should be removed
// This line:
// if (+(i) > 0 && i == viewerId) {
// should be simply:
if (i == viewerId) {
html.push('<li>' + options[gifts[i]] + ' from ' + person.getDisplayName() + '</li>');
}
}
}
});
html.push('</ul>');
document.getElementById('received').innerHTML = html.join('');
}
function updateGiftList(viewer, data, friends) {
var json = data[viewer.getId()]['gifts'];
if (!json) {
globalGivenGifts = {};
}
try {
globalGivenGifts = unserializeGifts(gadgets.util.unescapeString(json));
} catch (e) {
globalGivenGifts = {};
}
console.log(globalGivenGifts);
var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut'];
var html = new Array();
html.push('You have given:');
html.push('<ul>');
// YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja
// Therefore, this code:
// for (i in globalGivenGifts) {
// should be:
for (var i in globalGivenGifts) {
// YAPNOTE: We use alphanumeric GUIDs, so this check should be removed:
//if (+(i) > 0) {
html.push('<li>' + friends[i] + ' received ' + options[globalGivenGifts[i]] + '</li>');
//}
}
html.push('</ul>');
document.getElementById('given').innerHTML = html.join('');
}
function giveGift() {
var nut = document.getElementById('nut').value;
var friend = document.getElementById('person').value;
globalGivenGifts[friend] = nut;
var json = serializeGifts(globalGivenGifts);
var req = opensocial.newDataRequest();
// YAPNOTE: DataRequest.PersonId is now IdSpec.PersonId in 0.8
// Therefore, this code:
// req.add(req.newUpdatePersonAppDataRequest(opensocial.DataRequest.PersonId.VIEWER, 'gifts', json));
// is now:
req.add(req.newUpdatePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, 'gifts', json));
// YAPNOTE: For Person requests, specify a string ID as the first argument:
// req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
// Although that code would work, the semantically correct way is to use IdSpec.PersonId when possible:
req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
// YAPNOTE: For fetch People and AppData requests, specify an IdSpec object (not a string ID) as the first argument.
// In 0.7, VIEWER_FRIENDS is no longer available. Instead, use NETWORK_DISTANCE
// Therefore, this code:
// req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS'), 'viewerFriends');
// req.add(req.newFetchPersonAppDataRequest('VIEWER', 'gifts'), 'data');
// req.add(req.newFetchPersonAppDataRequest('VIEWER_FRIENDS', 'gifts'), 'viewerFriendData');
// is now:
var idSpec = opensocial.newIdSpec();
idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER);
var idSpecFriends = opensocial.newIdSpec();
idSpecFriends.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER);
idSpecFriends.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); // YAPNOTE: Groups aren't supported in YAP v1. If you don't specify one, we assume you want friends
req.add(req.newFetchPeopleRequest(idSpecFriends), 'viewerFriends');
req.add(req.newFetchPersonAppDataRequest(idSpec, 'gifts'), 'data');
req.add(req.newFetchPersonAppDataRequest(idSpecFriends, 'gifts'), 'viewerFriendData');
req.send(onLoadFriends);
postActivity(nut, friend);
}
function makeOptionsMenu() {
var options = ['a cashew nut', 'a peanut', 'a hazelnut', 'a red pistachio nut'];
var html = new Array();
html.push('<select id="nut">');
for (var i = 0; i < options.length; i++) {
html.push('<option value="' + i + '">' + options[i] + '</option>');
}
html.push('</select>');
document.getElementById('gifts').innerHTML = html.join('');
}
function loadFriends() {
var req = opensocial.newDataRequest();
// YAPNOTE: For Person requests, specify a string ID as the first argument:
// req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
// Although that code would work, the semantic way is to use IdSpec.PersonId when possible:
req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
// YAPNOTE: For fetch People and AppData requests, specify an IdSpec object (not a string ID) as the first argument.
// In 0.7, VIEWER_FRIENDS is no longer available. Instead, use NETWORK_DISTANCE
// Therefore, this code:
// req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS'), 'viewerFriends');
// req.add(req.newFetchPersonAppDataRequest('VIEWER', 'gifts'), 'data');
// req.add(req.newFetchPersonAppDataRequest('VIEWER_FRIENDS', 'gifts'), 'viewerFriendData');
// is now:
var idSpec = opensocial.newIdSpec();
idSpec.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER);
var idSpecFriends = opensocial.newIdSpec();
idSpecFriends.setField(opensocial.IdSpec.Field.USER_ID, opensocial.IdSpec.PersonId.VIEWER);
idSpecFriends.setField(opensocial.IdSpec.Field.NETWORK_DISTANCE, 1); // YAPNOTE: No need to specify groups. If you don't specify one, we assume you want friends
req.add(req.newFetchPeopleRequest(idSpecFriends), 'viewerFriends');
req.add(req.newFetchPersonAppDataRequest(idSpec, 'gifts'), 'data');
req.add(req.newFetchPersonAppDataRequest(idSpecFriends, 'gifts'), 'viewerFriendData');
req.send(onLoadFriends);
}
function onLoadFriends(data) {
var viewer = globalViewer = data.get('viewer').getData();
var viewerFriends = data.get('viewerFriends').getData();
var giftData = data.get('data').getData();
var viewerFriendData = data.get('viewerFriendData').getData();
var friends = new Array();
// YAPNOTE: Be sure to use 'var' whenever appropiate when working in Caja
// Therefore, this code:
// html = new Array();
// should be:
var html = new Array();
html.push('<select id="person">');
viewerFriends.each(function(person) {
html.push('<option value="' + person.getId() + '">' + person.getDisplayName() + "</option>");
friends[person.getId()] = person.getDisplayName();
});
html.push('</select>');
document.getElementById('friends').innerHTML = html.join('');
globalFriends = friends;
updateGiftList(viewer, giftData, friends);
updateReceivedList(viewer, viewerFriendData, viewerFriends);
}
function init() {
loadFriends();
makeOptionsMenu();
}
gadgets.util.registerOnLoadHandler(init);
</script>
<style type="text/css">
#yap-app {
font-family: Arial, sans-serif;
padding: 5px;
}
#yap-status div, .yap-notice, .yap-error {
background: #ffc;
padding: 5px 15px 5px;
margin-bottom: 3px;
}
.yap-error {
font-style: italic;
background: #fcc;
}
ul {
list-style: none;
}
li {
padding: 3px;
border: 1px solid #ccc;
margin-bottom: 3px;
}
</style>
<!-- HTML that would be within the <Content> gadget XML: -->
<div id='yap-app'>
<h1>Gift Giving!</h1>
<div id='give'>
<form id='gift_form'>
<!-- YAPNOTE: You can't link to javascript:void in Caja. Use '#' instead -->
<!-- This is invalid:
Give <span id='gifts'></span> to <span id='friends'></span>. <a href="javascript:void(0);" onclick='giveGift();'>Give!</a>
-->
Give <span id='gifts'></span> to <span id='friends'></span>. <a href="#" onclick='giveGift(); return false;'>Give!</a>
</form>
</div>
<div id='given'></div>
<!-- YAPNOTE: You must also be careful to create well-formed HTML markup when working with Caja -->
<!-- This is invalid:
<div id='received'</div>
-->
<div id='received'></div>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment