Initial import.

This commit is contained in:
Erik C. Thauvin 2010-03-10 23:13:25 +00:00
parent 980cedcdc7
commit 028ace4143
22 changed files with 1006 additions and 0 deletions

31
Ping.fm/LICENSE.txt Normal file
View file

@ -0,0 +1,31 @@
Software License Agreement (BSD License)
Copyright (c) 2010, Erik C. Thauvin (http://erik.thauvin.net/)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the authors nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
$Id$

View file

@ -0,0 +1,732 @@
// ---------------------------------------------------------------------------
// KeyDialogAssistant
// ---------------------------------------------------------------------------
function KeyDialogAssistant(sceneAssistant, focusField)
{
this.sceneAssistant = sceneAssistant;
this.focusField = focusField;
}
KeyDialogAssistant.prototype.setup = function(widget)
{
this.widget = widget;
this.sceneAssistant.controller.setupWidget('mobileKey',
{
hintText: 'Enter your Ping.fm mobile key...',
autoFocus: true,
limitResize: true,
autoReplace: false,
textCase: Mojo.Widget.steModeLowerCase,
focusMode: Mojo.Widget.focusAppendMode,
maxLength: 4
}, this.mobileKeyModel =
{
value: '',
disabled: false
});
this.okButtonModel =
{
label: 'OK',
disabled: false
};
this.sceneAssistant.controller.setupWidget('okButton',
{
type: Mojo.Widget.activityButton
}, this.okButtonModel);
this.okButton = this.sceneAssistant.controller.get('okButton');
this.checkKeyHandler = this.checkKey.bindAsEventListener(this);
this.sceneAssistant.controller.listen('okButton', Mojo.Event.tap, this.checkKeyHandler);
this.handleKeyHandler = this.handleKeyEvent.bindAsEventListener(this);
this.sceneAssistant.controller.document.addEventListener('keyup', this.handleKeyHandler, true);
this.cancelButtonModel =
{
label: 'Cancel',
disabled: false
};
this.sceneAssistant.controller.setupWidget('cancelButton',
{
type: Mojo.Widget.defaultButton
}, this.cancelButtonModel);
this.sceneAssistant.controller.listen('cancelButton', Mojo.Event.tap, this.widget.mojo.close);
};
KeyDialogAssistant.prototype.checkKey = function()
{
this.okButton.mojo.activate();
this.okButtonModel.label = 'Validating Key';
this.okButtonModel.disabled = true;
this.sceneAssistant.controller.modelChanged(this.okButtonModel);
var params = new Hash(
{
'api_key': this.sceneAssistant.api_key,
'mobile_key': this.mobileKeyModel.value
});
Mojo.Log.info('checkKey: ' + params.toQueryString());
var request = new Ajax.Request('http://api.ping.fm/v1/user.key',
{
method: 'post',
parameters: params,
evalJSON: 'false',
onSuccess: this.checkKeySuccess.bind(this),
onFailure: this.checkKeyFailure.bind(this)
});
};
KeyDialogAssistant.prototype.checkKeySuccess = function(transport)
{
if (transport.responseXML === null)
{
Mojo.Controller.errorDialog("Invalid response from the Ping.fm API.", this.controller.window);
}
else
{
var rsp = transport.responseXML.getElementsByTagName('rsp');
var status = rsp[0].getAttribute('status');
if (status == 'FAIL')
{
this.sceneAssistant.controller.get('keyDialogTitle').update('Invalid or Expired Key. Please Retry.');
this.mobileKeyModel.value = '';
this.sceneAssistant.controller.modelChanged(this.mobileKeyModel);
this.sceneAssistant.controller.get('mobileKey').mojo.focus();
Mojo.Log.info(transport.responseText);
this.okButton.mojo.deactivate();
this.okButtonModel.label = 'OK';
this.okButtonModel.disabled = false;
this.sceneAssistant.controller.modelChanged(this.okButtonModel);
}
else
{
this.sceneAssistant.prefs.user_app_key = rsp[0].getElementsByTagName('key').item(0).textContent;
this.sceneAssistant.updateMethods();
this.okButton.mojo.deactivate();
this.widget.mojo.close();
}
}
};
KeyDialogAssistant.prototype.checkKeyFailure = function(transport)
{
this.sceneAssistant.transportFailure('checkKeyFailure', transport);
};
KeyDialogAssistant.prototype.handleKeyEvent = function(event)
{
if (Mojo.Char.isEnterKey(event.keyCode))
{
if (event.srcElement.parentElement.id == 'mobileKey')
{
this.checkKey();
}
}
};
KeyDialogAssistant.prototype.cleanup = function()
{
this.sceneAssistant.controller.stopListening('okButton', Mojo.Event.tap, this.checkKeyHandler);
this.sceneAssistant.controller.stopListening('cancelButton', Mojo.Event.tap, this.widget.mojo.close);
this.sceneAssistant.controller.document.removeEventListener('keyup', this.handleKeyHandler, false);
this.focusField.mojo.focus();
};
KeyDialogAssistant.prototype.activate = function(event)
{
this.sceneAssistant.controller.get('mobileKey').mojo.focus();
};
// ---------------------------------------------------------------------------
// MainAssistant
// ---------------------------------------------------------------------------
function MainAssistant()
{
}
MainAssistant.prototype.setup = function()
{
//$$('body')[0].addClassName('palm-dark');
this.hasConnectivity = false;
this.checkConnectivity();
this.debug = 0;
this.cookieData = new Mojo.Model.Cookie('netThauvinErikWebOsPingFm');
this.prefs = this.cookieData.get();
this.api_key = 'edb93979c2abd58781f72d96f042e3a4';
this.messageMaxLen = 140;
this.defaultMethods = [
{
label: 'Default',
value: 'default'
},
{
label: 'Micro-blogs',
value: 'microblog'
},
{
label: 'Statuses',
value: 'status'
},
{
label: 'Blogs',
value: 'blog'
}];
if (!this.prefs)
{
this.prefs =
{
version: 1,
user_app_key: null,
showTitle: false,
defaultMethod: this.defaultMethods[0].value,
methods: this.defaultMethods.clone()
};
this.cookieData.put(this.prefs);
}
var hasNoMethods = (this.defaultMethods.length == this.prefs.methods.length);
this.updatedMethods =
{
hasNoServices: hasNoMethods,
hasNoTargets: hasNoMethods
};
this.showTitleMenuItem =
{
label: '',
command: 'do-title'
};
this.toggleTitleMenu();
this.appMenuModel =
{
visible: true,
items: [
{
label: 'About #{title}...'.interpolate(
{
title: Mojo.Controller.appInfo.title
}),
command: 'do-about'
}, Mojo.Menu.editItem, this.showTitleMenuItem,
{
label: 'Refresh Methods',
command: 'do-methods-refresh'
},
{
label: 'Reset Key...',
command: 'do-key-reset'
}]
};
this.controller.setupWidget(Mojo.Menu.appMenu,
{
omitDefaultItems: true
}, this.appMenuModel);
this.controller.setupWidget('methodList',
{
label: 'Method'
}, this.methodModel =
{
choices: this.prefs.methods,
value: this.prefs.defaultMethod
});
this.controller.setupWidget('titleField',
{
hintText: 'Type a title...',
focusMode: Mojo.Widget.focusAppendMode,
hide: true
}, this.titleModel =
{
value: ''
});
this.controller.setupWidget('messageField',
{
hintText: 'Type your message...',
multiline: true,
changeOnKeyPress: true,
focusMode: Mojo.Widget.focusAppendMode
}, this.messageModel =
{
value: ''
});
this.pingButton = this.controller.get('pingBtn');
this.pingBtnModel =
{
label: 'Ping It!',
original: 'Ping It!',
disabled: true
};
this.controller.setupWidget('pingBtn',
{
type: Mojo.Widget.activityButton
}, this.pingBtnModel);
this.handleKeyHandler = this.handleKeyEvent.bindAsEventListener(this);
this.controller.listen('messageField', Mojo.Event.propertyChange, this.handleKeyHandler);
this.pingItHandler = this.pingIt.bindAsEventListener(this);
this.controller.listen('pingBtn', Mojo.Event.tap, this.pingItHandler);
this.activateWindowHandler = this.activateWindow.bindAsEventListener(this);
this.controller.listen(this.controller.stageController.document, Mojo.Event.activate, this.activateWindowHandler);
};
MainAssistant.prototype.activateWindow = function()
{
this.askForKey();
};
MainAssistant.prototype.toggleTitleMenu = function()
{
if (!this.prefs.showTitle)
{
this.controller.get('titleRow').hide();
this.focusField = this.controller.get('messageField');
this.showTitleMenuItem.label = 'Show Title';
}
else
{
this.controller.get('titleRow').show();
this.focusField = this.controller.get('titleField');
this.showTitleMenuItem.label = 'Hide Title';
}
};
MainAssistant.prototype.togglePingButton = function()
{
Mojo.Log.info("togglePingButton");
if (this.hasConnectivity)
{
this.pingBtnModel.disabled = (this.messageModel.value.length == 0);
}
else
{
this.pingBtnModel.disabled = true;
}
this.controller.modelChanged(this.pingBtnModel);
};
MainAssistant.prototype.activate = function(event)
{
//this.askForKey();
};
MainAssistant.prototype.deactivate = function(event)
{
this.cookieData.put(this.prefs);
//this.cookieData.remove();
};
MainAssistant.prototype.cleanup = function()
{
this.controller.stopListening('pingBtn', Mojo.Event.tap, this.pingItHandler);
this.controller.stopListening('messageField', Mojo.Event.propertyChange, this.handleKeyHandler);
this.controller.stopListening(this.controller.stageController.document, Mojo.Event.activate, this.activateWindowHandler);
};
MainAssistant.prototype.handleCommand = function(event)
{
if (event.type == Mojo.Event.command)
{
switch (event.command)
{
case 'do-about':
var currentScene = this.controller.stageController.activeScene();
currentScene.showAlertDialog(
{
allowHTMLMessage: true,
onChoose: function(value)
{
},
message: '<big><b>#{title} v#{version}</b></big><br/>&copy; 2010, <a href="http://mobile.thauvin.net/">Erik C. Thauvin</a><br/><br/><small>This application uses the Ping.fm API but is not endorsed or certified by <a href="http://ping.fm/">Ping.fm</a></small>'.interpolate(
{
title: Mojo.Controller.appInfo.title,
version: Mojo.Controller.appInfo.version
}),
choices: [
{
label: 'OK',
value: ''
}]
});
break;
case 'do-title':
this.prefs.showTitle = !this.prefs.showTitle;
this.toggleTitleMenu();
this.focusField.mojo.focus();
break;
case 'do-methods-refresh':
this.resetMethods();
this.updateMethods();
this.focusField.mojo.focus();
break;
case 'do-key-reset':
this.resetMethods();
this.prefs.user_app_key = null;
this.askForKey();
break;
default:
break;
}
}
};
MainAssistant.prototype.handleKeyEvent = function(event)
{
var len = this.messageMaxLen - this.messageModel.value.length;
if (len < 0)
{
this.controller.get('cntLabel').update('<font color="red">' + len + '</font>');
}
else
{
this.controller.get('cntLabel').update(len);
}
this.togglePingButton();
};
MainAssistant.prototype.askForKey = function(event)
{
if (this.prefs.user_app_key === null)
{
this.controller.showDialog(
{
template: 'main/key-dialog',
assistant: new KeyDialogAssistant(this, this.focusField)
});
}
};
MainAssistant.prototype.pingIt = function()
{
var message = this.messageModel.value;
if (this.prefs.user_app_key === null)
{
this.pingButton.mojo.deactivate();
this.askForKey();
}
else if (message.length > 0)
{
this.pingBtnModel.label = 'Posting...';
this.pingBtnModel.disabled = true;
this.controller.modelChanged(this.pingBtnModel);
var method = this.methodModel.value;
var url = 'http://api.ping.fm/v1/user.post';
this.prefs.defaultMethod = method;
var params = new Hash(
{
'api_key': this.api_key,
'user_app_key': this.prefs.user_app_key,
'body': Base64.encode(message),
'encoding': 'base64',
'debug': this.debug
});
if (method.charAt(0) == '#')
{
url = 'http://api.ping.fm/v1/user.tpost';
params.set('trigger', method.substring(1));
}
else if (method.charAt(0) == '@')
{
params.set('service', method.substring(1));
params.set('post_method', 'default');
}
else
{
params.set('post_method', method);
}
var title = this.titleModel.value;
if (title != '')
{
params.set('title', Base64.encode(title));
}
Mojo.Log.info('pingIt: ' + params.toQueryString());
var request = new Ajax.Request(url,
{
method: 'post',
parameters: params,
evalJSON: 'false',
onSuccess: this.pingItSuccess.bind(this),
onFailure: this.pingItFailure.bind(this)
});
}
else
{
this.focusField.mojo.focus();
this.pingButton.mojo.deactivate();
}
};
MainAssistant.prototype.pingItSuccess = function(transport)
{
this.pingButton.mojo.deactivate();
this.pingBtnModel.label = this.pingBtnModel.original;
if (transport.responseXML === null)
{
Mojo.Log.warn("pingItSuccess failure.");
Mojo.Controller.errorDialog("Invalid response from the Ping.fm API.", this.controller.window);
this.pingBtnModel.disabled = false;
}
else
{
var rsp = transport.responseXML.getElementsByTagName('rsp');
var status = rsp[0].getAttribute('status');
if (status == 'FAIL')
{
Mojo.Log.warn(transport.responseText);
Mojo.Controller.errorDialog(rsp[0].getElementsByTagName('message').item(0).textContent, this.controller.window);
this.pingBtnModel.disabled = false;
}
else
{
this.messageModel.value = '';
this.titleModel.value = '';
this.controller.modelChanged(this.messageModel);
this.controller.modelChanged(this.titleModel);
this.controller.get('cntLabel').update(this.messageMaxLen);
this.pingBtnModel.disabled = true;
Mojo.Controller.getAppController().showBanner('Your message has been posted.', {});
}
}
this.controller.modelChanged(this.pingBtnModel);
this.focusField.mojo.focus();
};
MainAssistant.prototype.pingItFailure = function(transport)
{
this.pingButton.mojo.deactivate();
this.pingBtnModel.label = this.pingBtnModel.original;
this.pingBtnModel.disabled = false;
this.controller.modelChanged(this.pingBtnModel);
this.transportFailure('pingItFailure', transport);
};
MainAssistant.prototype.resetMethods = function()
{
this.updatedMethods.hasNoServices = true;
this.updatedMethods.hasNoTargets = true;
this.prefs.methods.clear();
for (var i = 0; i < this.defaultMethods.length; i++)
{
this.prefs.methods.push(this.defaultMethods[i]);
}
this.prefs.defaultMethod = this.defaultMethods[0].value;
this.methodModel.value = this.prefs.defaultMethod;
this.controller.modelChanged(this.methodModel);
};
MainAssistant.prototype.updateMethods = function()
{
if (this.prefs.user_app_key && this.hasConnectivity)
{
var request;
if (this.updatedMethods.hasNoServices)
{
request = new Ajax.Request('http://api.ping.fm/v1/user.services',
{
method: 'post',
parameters:
{
'api_key': this.api_key,
'user_app_key': this.prefs.user_app_key
},
evalJSON: 'false',
onSuccess: this.updateMethodsSuccess.bind(this),
onFailure: this.updateMethodsFailure.bind(this)
});
}
if (this.updatedMethods.hasNoTargets)
{
request = new Ajax.Request('http://api.ping.fm/v1/user.triggers',
{
method: 'post',
parameters:
{
'api_key': this.api_key,
'user_app_key': this.prefs.user_app_key
},
evalJSON: 'false',
onSuccess: this.updateTriggersSuccess.bind(this),
onFailure: this.updateTriggersFailure.bind(this)
});
}
}
};
MainAssistant.prototype.updateMethodsSuccess = function(transport)
{
if (transport.responseXML === null)
{
Mojo.Log.warn("updateMethodsSuccess failure.");
this.updateMethods();
}
else
{
this.updateMethods.hasNoServices = false;
var services = transport.responseXML.getElementsByTagName('service');
for (var i = 0; i < services.length; i++)
{
var id = '@' + services[i].getAttribute('id');
var name = services[i].getAttribute('name');
var trigger = services[i].getElementsByTagName('trigger').item(0).textContent;
this.prefs.methods.push(
{
label: name + ' (' + trigger + ')',
value: id
});
if (this.prefs.defaultMethod == id)
{
this.methodModel.value = id;
this.controller.modelChanged(this.methodModel);
}
}
Mojo.Controller.getAppController().showBanner('Methods successfully updated.', {});
}
};
MainAssistant.prototype.updateMethodsFailure = function(transport)
{
this.transportFailure('updateMethodFailure', transport);
};
MainAssistant.prototype.updateTriggersSuccess = function(transport)
{
if (transport.responseXML === null)
{
Mojo.Log.warn("updateTriggersSuccess failure.");
this.updateMethods();
}
else
{
this.updateMethods.hasNoTargets = false;
var triggers = transport.responseXML.getElementsByTagName('trigger');
for (var i = 0; i < triggers.length; i++)
{
var id = '#' + triggers[i].getAttribute('id');
//var method = triggers[i].getAttribute('method');
this.prefs.methods.unshift(
{
label: id,
value: id
});
if (this.prefs.defaultMethod == id)
{
this.methodModel.value = id;
this.controller.modelChanged(this.methodModel);
}
}
}
};
MainAssistant.prototype.updateTriggersFailure = function(transport)
{
this.transportFailure('updateTriggersFailure', transport);
};
MainAssistant.prototype.handleConnectivity = function(status)
{
if (status.isInternetConnectionAvailable === true)
{
this.hasConnectivity = true;
}
else
{
this.hasConnectivity = false;
Mojo.Controller.getAppController().showBanner('No connectivity to the Internet.', {});
}
this.togglePingButton();
};
MainAssistant.prototype.checkConnectivity = function()
{
this.controller.serviceRequest('palm://com.palm.connectionmanager',
{
method: 'getstatus',
parameters:
{
subscribe: true
},
onSuccess: this.handleConnectivity.bind(this)
});
};
MainAssistant.prototype.transportFailure = function(caller, transport)
{
Mojo.Log.error(caller + ': ' + transport.responseText);
Mojo.Controller.errorDialog('Error status #{status} returned from Ping.fm API request.'.interpolate(
{
status: transport.status
}), this.controller.window);
};

View file

@ -0,0 +1,8 @@
function StageAssistant()
{
}
StageAssistant.prototype.setup = function()
{
this.controller.pushScene('main');
};

View file

@ -0,0 +1,86 @@
// ---------------------------------------------------------------------------
// Base64
//
// Encodes binary files into base64 strings.
// Taken from the Palm's Data sample application.
// ---------------------------------------------------------------------------
var Base64 =
{
// private property
_keyStr: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
// public method for encoding
encode: function(input)
{
var output = '';
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
while (i < input.length)
{
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2))
{
enc3 = enc4 = 64;
}
else if (isNaN(chr3))
{
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) +
this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) +
this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode: function(input)
{
var output = '';
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
while (i < input.length)
{
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64)
{
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64)
{
output = output + String.fromCharCode(chr3);
}
}
return output;
}
};

View file

@ -0,0 +1,18 @@
<div id="palm-dialog-content" class="palm-dialog-content">
<div id="keyDialogTitle" class="palm-dialog-title un-capitalize">
Enter Ping.fm Mobile Key
</div>
<div id="keyDialogSubTitle">
Get your <a href="http://ping.fm/m/key">Mobile Key</a>
</div>
<div class="palm-dialog-separator"></div>
<div class="textfield-group" x-mojo-focus-highlight="true">
<div class="title">
<div x-mojo-element="PasswordField" id="mobileKey"></div>
</div>
</div>
<div class="palm-dialog-buttons">
<div x-mojo-element="Button" id="okButton"></div>
<div x-mojo-element="Button" id="cancelButton"></div>
</div>
</div>

View file

@ -0,0 +1,52 @@
<div class="palm-page-header">
<div class="header-icon mini-icon">
</div>
<div class="header-text un-capitalize">
Ping.fm
</div>
</div>
<div class="palm-group">
<div class="palm-group-title">
<span>Ping My</span>
</div>
<div class="palm-list">
<div class="palm-row single">
<div class="palm-row-wrapper">
<div x-mojo-element="ListSelector" id="methodList">
</div>
</div>
</div>
</div>
</div>
<div class="palm-group">
<div class="palm-group-title">
<span>Your Message</span>
</div>
<div class="palm-list">
<div id="titleRow" class="palm-row single">
<div class="palm-row-wrapper">
<div class="textfield-group" x-mojo-focus-highlight="true">
<div class="title">
<div id="titleField" x-mojo-element="TextField">
</div>
</div>
</div>
</div>
</div>
<div class="palm-row single">
<div class="palm-row-wrapper">
<div class="textfield-group" x-mojo-focus-highlight="true">
<div class="title">
<div id="messageField" x-mojo-element="TextField">
</div>
<div id="cntLabel" class="label">
140
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div x-mojo-element="Button" id="pingBtn">
</div>

10
Ping.fm/appinfo.json Normal file
View file

@ -0,0 +1,10 @@
{
"id": "net.thauvin.erik.webos.pingfm",
"version": "1.0.0",
"vendor": "Erik C. Thauvin",
"type": "web",
"theme": "light",
"main": "index.html",
"title": "Ping.fm",
"icon": "icon.png"
}

BIN
Ping.fm/ect-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,3 @@
{
"logLevel":0
}

BIN
Ping.fm/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

14
Ping.fm/index.html Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Ping.fm</title>
<script src="/usr/palm/frameworks/mojo/mojo.js" type="text/javascript" x-mojo-version="1" />
<!-- application stylesheet should come in after the one loaded by the framework -->
<link href="stylesheets/pingfm.css" media="screen" rel="stylesheet" type="text/css" />
<!-- load the helpers --><script src="app/helpers/base64.js" type="text/javascript" charset="utf-8" />
</head>
<body>
Ping.fm
</body>
</html>

7
Ping.fm/sources.json Normal file
View file

@ -0,0 +1,7 @@
[
{"source": "app/assistants/stage-assistant.js"},
{
"scenes": "main",
"source": "app/assistants/main-assistant.js"
},
]

View file

@ -0,0 +1,38 @@
/* Header Styles */
.header-icon.mini-icon {
background: url(../images/mini-icon.png) center center no-repeat;
width: 33px;
height: 32px;
}
/* Main Scene Styles */
#messageField {
font-size: 12pt;
min-height: 110px !important;
}
#messageField textarea, #titleField, #titleField input {
font-size: 12pt;
}
#cntLabel {
margin-top: -35px;
margin-bottom: -10px;
}
/* KeyDialog Styles */
#keyDialogTitle {
padding-bottom: 5px;
}
#keyDialogSubTitle {
font-size: 12pt;
margin-bottom: 10px;
text-align: right;
}
/* AppMenu */
#palm-app-menu {
/* No capitalization */
text-transform: none;
}

BIN
images/icon48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

4
install.bat Normal file
View file

@ -0,0 +1,4 @@
@echo on
call palm-package Ping.fm
call palm-install net.thauvin.erik.webos.pingfm*.ipk
pause

3
make.bat Normal file
View file

@ -0,0 +1,3 @@
@echo on
call palm-package Ping.fm
pause

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
screenshots/pingfm.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB