Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71e143ecb1 | ||
|
|
4d56a992a0 | ||
|
|
78568bce56 | ||
|
|
4a1b85936e | ||
|
|
3dac57e20d | ||
|
|
cdfa4013ee | ||
|
|
9979b509df | ||
|
|
54f905a458 | ||
|
|
295d774488 | ||
|
|
ab11c4ea57 | ||
|
|
ef7cb5a2fb | ||
|
|
5ca6c24ea0 | ||
|
|
eca2e7537a | ||
|
|
be4f547873 | ||
|
|
ebe00543aa | ||
|
|
4816b817dc | ||
|
|
7b772c1d99 | ||
|
|
cf913f7900 | ||
|
|
323b8a81a0 | ||
|
|
5bd35db2e0 | ||
|
|
dc49a6dbd9 | ||
|
|
af90efd60d | ||
|
|
e32fcbbea2 | ||
|
|
561b54bf97 | ||
|
|
cbb507b4cb | ||
|
|
ea2c54fcf4 | ||
|
|
00657e6fb0 | ||
|
|
946d21b431 | ||
|
|
1f99489737 | ||
|
|
4dc4e96b85 | ||
|
|
b22e1ec4a2 | ||
|
|
3f951e75d9 | ||
|
|
c5a0997c11 | ||
|
|
76149a40ac | ||
|
|
d61bee6ab3 | ||
|
|
a990fca7bc | ||
|
|
4c9b302df1 |
No files matched your search
@@ -1,2 +1,2 @@
|
||||
secrets.js
|
||||
.DS_Store
|
||||
secrets.js
|
||||
@@ -1,3 +1,6 @@
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
cp $DIR/../../webos-common/Mojo/updater-model.js $DIR/../app/models/updater-model.js
|
||||
cp $DIR/../../webos-common/Mojo/system-model.js $DIR/../app/models/system-model.js
|
||||
cp $DIR/../../webos-common/Mojo/com.wosa.mojo.additions.js $DIR/../app/com.wosa.mojo.additions.js
|
||||
mkdir -p $DIR/../_bin
|
||||
palm-package $DIR/../ -o $DIR/../_bin
|
||||
@@ -1,5 +1,5 @@
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
palm-package simplechat-app simplechat-service simplechat-package
|
||||
palm-install com.jonandnic.simplechat_2.0.0_all.ipk
|
||||
palm-launch com.jonandnic.simplechat
|
||||
palm-log -f com.jonandnic.simplechat.app
|
||||
cp $DIR/../../webos-common/Mojo/updater-model.js $DIR/../app/models/updater-model.js
|
||||
cp $DIR/../../webos-common/Mojo/system-model.js $DIR/../app/models/system-model.js
|
||||
cp $DIR/../../webos-common/Mojo/com.wosa.mojo.additions.js $DIR/../app/com.wosa.mojo.additions.js
|
||||
palm-run $DIR/../
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Jon W
|
||||
Copyright (c) 2022 webOS Archive
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -0,0 +1,12 @@
|
||||
# Share Space app for webOS
|
||||
|
||||

|
||||
|
||||
Share Space is a sharing service app for legacy Palm/HP webOS devices, which depends on the back-end service listed below.
|
||||
You can download it for your webOS Device from the [webOS Archive App Museum II](appcatalog.webosarchive.org).
|
||||
|
||||
Tested on Pre, Pre2, Pre3, Veer and Touchpad.
|
||||
|
||||
Uses [Sharing Service](https://github.com/webosarchive/sharing-service) which is hosted by [webOSArchive](http://www.webosarchive.org) for the webOS community without guarantee of privacy or performance. Illegal or illicit use strictly prohibited.
|
||||
|
||||
You can also self-host the service, see the [instructions here](https://github.com/webosarchive/sharing-service/blob/main/README.md).
|
||||
|
After Width: | Height: | Size: 81 KiB |
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
In the app assistant, we setup some app-wide global objects and handle different kinds of launches, creating and delegating to the main stage
|
||||
*/
|
||||
var appModel = null;
|
||||
var updaterModel = null;
|
||||
var serviceModel = null;
|
||||
var MainStageName = "main";
|
||||
var InDockMode = false;
|
||||
|
||||
function AppAssistant() {
|
||||
appModel = new AppModel();
|
||||
updaterModel = new UpdaterModel();
|
||||
serviceModel = new ShareServiceModel();
|
||||
systemModel = new SystemModel();
|
||||
Mojo.Additions = Additions;
|
||||
}
|
||||
|
||||
//This function will handle relaunching the app when an alarm goes off(see the device/alarm scene)
|
||||
AppAssistant.prototype.handleLaunch = function(params) {
|
||||
Mojo.Log.info("Share Space is Launching! Launch params: " + JSON.stringify(params));
|
||||
|
||||
//Load preferences
|
||||
appModel.LoadSettings();
|
||||
Mojo.Log.info("settings now: " + JSON.stringify(appModel.AppSettingsCurrent));
|
||||
|
||||
if (!appModel.AppSettingsCurrent["AutoDownloadTime"]) {
|
||||
appModel.AppSettingsCurrent["AutoDownloadTime"] = appModel.AppSettingsDefaults["AutoDownloadTime"];
|
||||
appModel.SaveSettings();
|
||||
}
|
||||
|
||||
appModel.EstablishAlarms();
|
||||
|
||||
if (!params || !params["action"]) {
|
||||
var mainStage = this.controller.getStageProxy("main"); //get the proxy for the stage if it already exists (eg: app is currently open)
|
||||
if (mainStage) //If the stage exists, use it
|
||||
{
|
||||
Mojo.Log.info("Found existing main stage, app was already running");
|
||||
Mojo.Log.info("This is a non-alarm re-launch");
|
||||
|
||||
var stageController = this.controller.getStageController("main");
|
||||
stageController.activate(); //bring existing stage into focus
|
||||
if (params)
|
||||
this.handleParameterLaunch(params, stageController);
|
||||
|
||||
} else //If not, determine if we should make one
|
||||
{
|
||||
Mojo.Log.info("Did not find existing main stage, app is not running");
|
||||
Mojo.Log.info("This is a non-alarm launch of version " + Mojo.Controller.appInfo.version);
|
||||
|
||||
var stageArguments = { name: MainStageName, lightweight: true };
|
||||
this.controller.createStageWithCallback(stageArguments, function(stageController) {
|
||||
stageController.pushScene(MainStageName);
|
||||
if (params)
|
||||
this.handleParameterLaunch(params, stageController);
|
||||
}.bind(this));
|
||||
}
|
||||
} else {
|
||||
this.handleParameterLaunch(params);
|
||||
}
|
||||
};
|
||||
|
||||
AppAssistant.prototype.handleParameterLaunch = function(params) {
|
||||
Mojo.Log.info("Launch params: " + JSON.stringify(params));
|
||||
//Touch2Share Launch (goes to main)
|
||||
if (params["sendDataToShare"]) {
|
||||
Mojo.Log.info("Launch with Touch2Share request!");
|
||||
systemModel.SendDataForTouch2Share(appModel.CurrentShareURL);
|
||||
}
|
||||
|
||||
//Alarm Launch (goes to dashboard)
|
||||
else if (params.action && params.action == "BackgroundDownload"){
|
||||
Mojo.Log.info("Alarm launch for background sync...");
|
||||
//TODO: Check if in Dock Mode (and remember)
|
||||
systemModel.GetDisplayState(function(response) {
|
||||
Mojo.Log.info("Called back from GetDisplayState with response: " + JSON.stringify(response));
|
||||
InDockMode = false;
|
||||
if (response && response.state == "on" && response.active == false) {
|
||||
InDockMode = true;
|
||||
systemModel.SetDisplayState("unlock");
|
||||
systemModel.SetDisplayState("on");
|
||||
}
|
||||
appModel.ShowDownloaderStage();
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
//JustType or other (goes to main)
|
||||
else {
|
||||
Mojo.Log.info("Launch with item request to be handled by Main scene...");
|
||||
appModel.LaunchQuery = params;
|
||||
|
||||
var mainStage = this.controller.getStageProxy(MainStageName);
|
||||
if (mainStage) {
|
||||
var stageController = this.controller.getStageController(MainStageName);
|
||||
stageController.swapScene({ transition: Mojo.Transition.crossFade, name: MainStageName });
|
||||
}
|
||||
else {
|
||||
var stageArguments = { name: MainStageName, lightweight: true };
|
||||
this.controller.createStageWithCallback(stageArguments, function(stageController) {
|
||||
stageController.pushScene(MainStageName);
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
function DetailAssistant() {
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
}
|
||||
|
||||
DetailAssistant.prototype.setup = function() {
|
||||
/* setup widgets here */
|
||||
|
||||
//Menu
|
||||
this.appMenuAttributes = { omitDefaultItems: true };
|
||||
this.appMenuModel = {
|
||||
label: "Settings",
|
||||
items: [{
|
||||
label: $L('Select All'),
|
||||
command: Mojo.Menu.selectAllCmd,
|
||||
shortcut: 'a',
|
||||
disabled: false
|
||||
}, {
|
||||
label: $L('Copy'),
|
||||
command: Mojo.Menu.copyCmd,
|
||||
shortcut: 'c',
|
||||
disabled: false
|
||||
}]
|
||||
};
|
||||
this.controller.setupWidget(Mojo.Menu.appMenu, this.appMenuAttributes, this.appMenuModel);
|
||||
//Text content field
|
||||
this.controller.setupWidget("divTextContent",
|
||||
this.attributes = {
|
||||
multiline: true,
|
||||
enterSubmits: false,
|
||||
focus: false
|
||||
},
|
||||
this.model = {
|
||||
value: "",
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//OK Button
|
||||
this.controller.setupWidget("btnOK",
|
||||
this.attributes = {
|
||||
},
|
||||
this.model = {
|
||||
label : "OK",
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//Command Menu
|
||||
this.cmdMenuAttributes = {
|
||||
spacerHeight: 0,
|
||||
menuClass: 'no-fade'
|
||||
},
|
||||
this.cmdMenuModel = {
|
||||
visible: true,
|
||||
items: [{
|
||||
items: [
|
||||
{ label: 'Back', icon: 'back', command: 'do-goBack' }
|
||||
]
|
||||
},
|
||||
{
|
||||
items: [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{ label: 'Share', command: 'do-share' },
|
||||
{ label: 'Save', icon: 'save', command: 'do-save' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
this.controller.setupWidget(Mojo.Menu.commandMenu, this.cmdMenuAttributes, this.cmdMenuModel);
|
||||
|
||||
/* add event handlers to listen to events from widgets */
|
||||
};
|
||||
|
||||
DetailAssistant.prototype.activate = function(event) {
|
||||
|
||||
//Bind selected podcast to scene elements
|
||||
Mojo.Log.info(JSON.stringify(appModel.LastShareSelected));
|
||||
|
||||
this.controller.get("divShareTitle").innerHTML = "Shared: " + appModel.ConvertTimeStamp(appModel.LastShareSelected.timestamp, true);
|
||||
|
||||
//Calculate links
|
||||
if (appModel.LastShareSelected && appModel.LastShareSelected.contenttype && appModel.LastShareSelected.contenttype.indexOf("image") != -1) { //image links
|
||||
var link = serviceModel.MakeShareURL(appModel.AppSettingsCurrent["Username"], appModel.LastShareSelected.guid, "image");
|
||||
appModel.CurrentShareURL = link;
|
||||
this.controller.get("divShareLinks").innerHTML += "• <a href='" + link + "'>View in Browser</a>";
|
||||
this.controller.get("divShareLinks").innerHTML += " (<a href='javascript:this.doCopy(\"" + link + "\")'>Copy Link</a>)<br>";
|
||||
link = this.makeDownloadURL(appModel.LastShareSelected.thumbnail, "i");
|
||||
this.downloadLink = link;
|
||||
} else { //text links
|
||||
var link = serviceModel.MakeShareURL(appModel.AppSettingsCurrent["Username"], appModel.LastShareSelected.guid, "t");
|
||||
appModel.CurrentShareURL = link;
|
||||
this.downloadLink = link;
|
||||
this.controller.get("divShareLinks").innerHTML = "• <a href='" + link + "'>View in Browser</a>";
|
||||
this.controller.get("divShareLinks").innerHTML += " (<a href='javascript:this.doCopy(\"" + link + "\")'>Copy Link</a>)<br>";
|
||||
}
|
||||
if (appModel.AppSettingsCurrent["DebugMode"]) { //If debugging, show links
|
||||
this.controller.get("divShareInfo").style.display = "block";
|
||||
}
|
||||
//Show actual content
|
||||
if (appModel.LastShareSelected.contenttype == "application/json") {
|
||||
this.controller.get("divTextContent").innerHTML = "<pre>" + JSON.stringify(appModel.LastShareSelected.content, null, 1) + "</pre>"
|
||||
} else if (appModel.LastShareSelected.contenttype == "text/plain") {
|
||||
this.controller.get("divTextContent").innerHTML = "<pre>" + appModel.LastShareSelected.content + "</pre>"
|
||||
} else {
|
||||
var useImg = appModel.LastShareSelected.content;
|
||||
useImg = useImg.split("?");
|
||||
useImg = useImg[0] + "?img=" + useImg[1] + "&size=" + this.setPhotoSize();
|
||||
Mojo.Log.info("Rendering img: " + useImg);
|
||||
this.controller.get("divImageContent").innerHTML = "<img src='" + useImg + "' style='max-width:90%;'>";
|
||||
}
|
||||
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'Touch2Share Ready!', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
};
|
||||
|
||||
doCopy = function(link) {
|
||||
Mojo.Log.info("Copy tapped for link " + link);
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController()
|
||||
stageController.setClipboard(link);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'Link copied!', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
}
|
||||
|
||||
DetailAssistant.prototype.makeDownloadURL = function(thumbUrl, type) {
|
||||
var newURL = thumbUrl;
|
||||
newURL = newURL.replace("tthumb", type);
|
||||
newURL = newURL.replace("ithumb", type);
|
||||
return newURL;
|
||||
}
|
||||
|
||||
DetailAssistant.prototype.setPhotoSize = function() {
|
||||
switch(systemModel.DetectDevice()) {
|
||||
case "TouchPad":
|
||||
return 800;
|
||||
break;
|
||||
case "Pre3":
|
||||
return 400;
|
||||
break;
|
||||
case "Pre":
|
||||
return 300;
|
||||
break;
|
||||
case "Tiny":
|
||||
return 280;
|
||||
break;
|
||||
default:
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
|
||||
//Handle menu and button bar commands
|
||||
DetailAssistant.prototype.handleCommand = function(event) {
|
||||
|
||||
Mojo.Log.info("handling command button press for command: " + event.command);
|
||||
if (event.type == Mojo.Event.command) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
switch (event.command) {
|
||||
case 'do-goBack':
|
||||
stageController.popScene();
|
||||
break;
|
||||
case 'do-share':
|
||||
var itemsToShow = [
|
||||
{ label: 'Open in Browser', command: 'do-browserOpen' },
|
||||
{ label: 'Email Link', command: 'do-emailLink' },
|
||||
{ label: 'Message Link', command: 'do-messageLink' },
|
||||
{ label: 'Copy Link', command: 'do-copyLink' }
|
||||
]
|
||||
if (appModel.LastShareSelected.contenttype.indexOf("image") == -1) {
|
||||
itemsToShow.push({ label: 'Copy Content', command: 'do-copyContent' });
|
||||
}
|
||||
this.controller.popupSubmenu({
|
||||
onChoose: this.handlePopupChoose.bind(this, event.item),
|
||||
//placeNear: Mojo.Menu.commandMenu,
|
||||
items: itemsToShow
|
||||
});
|
||||
break;
|
||||
case 'do-save':
|
||||
var usePath = "sharespace/" + appModel.AppSettingsCurrent["Username"];
|
||||
if (appModel.AppSettingsCurrent["UseCustomDownloadPath"] && appModel.AppSettingsCurrent["CustomDownloadPath"] != "")
|
||||
usePath = appModel.AppSettingsCurrent["CustomDownloadPath"];
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'Downloading content...', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
systemModel.DownloadFile(this.downloadLink, appModel.LastShareSelected.contenttype, usePath, appModel.LastShareSelected.guid, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DetailAssistant.prototype.handlePopupChoose = function(task, command) {
|
||||
Mojo.Log.info("Perform: ", command);
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
switch (command) {
|
||||
case "do-browserOpen":
|
||||
this.controller.serviceRequest("palm://com.palm.applicationManager", {
|
||||
method: "launch",
|
||||
parameters: {
|
||||
id: 'com.palm.app.browser',
|
||||
params: {
|
||||
"target": appModel.CurrentShareURL
|
||||
}
|
||||
}
|
||||
});
|
||||
Mojo.Log.warn("target: " + appModel.CurrentShareURL);
|
||||
break;
|
||||
case "do-emailLink":
|
||||
this.controller.serviceRequest("palm://com.palm.applicationManager", {
|
||||
method: 'open',
|
||||
parameters: {
|
||||
id: "com.palm.app.email",
|
||||
params: {
|
||||
summary: "Check out this link",
|
||||
text: appModel.CurrentShareURL
|
||||
}
|
||||
}
|
||||
});
|
||||
Mojo.Log.warn("target: " + appModel.CurrentShareURL);
|
||||
break;
|
||||
case "do-messageLink":
|
||||
this.controller.serviceRequest('palm://com.palm.applicationManager', {
|
||||
method: 'open',
|
||||
parameters: {
|
||||
id: 'com.palm.app.messaging',
|
||||
params: {
|
||||
messageText: "Check out this link: " + appModel.CurrentShareURL
|
||||
}
|
||||
}
|
||||
});
|
||||
Mojo.Log.warn("target: " + appModel.CurrentShareURL);
|
||||
break;
|
||||
case "do-copyLink":
|
||||
stageController.setClipboard(appModel.CurrentShareURL);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'Link copied!', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
Mojo.Log.warn("target: " + appModel.CurrentShareURL);
|
||||
break;
|
||||
case "do-copyContent":
|
||||
stageController.setClipboard(appModel.LastShareSelected.content);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'Content copied!', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DetailAssistant.prototype.deactivate = function(event) {
|
||||
/* remove any event handlers you added in activate and do any other cleanup that should happen before
|
||||
this scene is popped or another scene is pushed on top */
|
||||
|
||||
};
|
||||
|
||||
DetailAssistant.prototype.cleanup = function(event) {
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
|
||||
};
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
This alarm scene is used for Touchpads, which will only pretend to change settings if running in the background
|
||||
Launching this scene forces the Touchpad to wake up to deal with presenting it, and when it does we have a good
|
||||
chance of successfully changing the settings. We can then close this window. All the smarts for this are in stage assistant.
|
||||
*/
|
||||
var downloadMgrInt = null;
|
||||
function DownloadAssistant(argFromPusher) {
|
||||
this.passedArguments = argFromPusher;
|
||||
this.downloadList = [];
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.setup = function() {
|
||||
Mojo.Log.info("Dashboard notification stage setup at " + new Date());
|
||||
this.displayDashboard(Mojo.Controller.appInfo.title, "Checking for new shares...");
|
||||
|
||||
//Event handlers
|
||||
Mojo.Event.listen(this.controller.get("dashboardinfo"), Mojo.Event.tap, this.handleTap.bind(this));
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.activate = function(event) {
|
||||
Mojo.Log.info("Dashboard activating!");
|
||||
//Set options for service model
|
||||
serviceModel.ForceHTTP = appModel.AppSettingsCurrent["ForceHTTP"];
|
||||
serviceModel.UseCustomEndpoint = appModel.AppSettingsCurrent["UseCustomEndpoint"];
|
||||
serviceModel.CustomEndpointURL = appModel.AppSettingsCurrent["EndpointURL"];
|
||||
serviceModel.CustomShortURL = appModel.AppSettingsCurrent["ShortURL"];
|
||||
serviceModel.CustomCreateKey = appModel.AppSettingsCurrent["CustomCreateKey"];
|
||||
serviceModel.UseCustomClientId = appModel.AppSettingsCurrent["UseCustomClientId"];
|
||||
serviceModel.CustomClientId = appModel.AppSettingsCurrent["CustomClientId"];
|
||||
|
||||
this.fetchShares();
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.displayDashboard = function(title, message, count) {
|
||||
var infoElement = this.controller.get("dashboardinfo");
|
||||
var info = { title: title, message: message };
|
||||
if (count) {
|
||||
info.count = count;
|
||||
info.showCount = "inline";
|
||||
} else {
|
||||
info.showCount = "none";
|
||||
}
|
||||
var renderedInfo = Mojo.View.render({ object: info, template: "download/item-info" });
|
||||
infoElement.innerHTML = renderedInfo;
|
||||
this.controller.getSceneScroller().mojo.revealTop(true);
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.fetchShares = function() {
|
||||
serviceModel.DoShareListRequest(appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], function(responseObj){
|
||||
if (responseObj != null) {
|
||||
if (responseObj.shares) {
|
||||
//If we got a good looking response, find out what to download
|
||||
Mojo.Log.info("Download dashboard ready to process share list: " + JSON.stringify(responseObj));
|
||||
this.checkIfDownloadNeeded(appModel.AppSettingsCurrent["Username"], responseObj.shares, responseObj.accesslevel);
|
||||
} else {
|
||||
Mojo.Log.warn("Share list was empty in Download dashboard. Either there was no matching result, or there were server or connectivity problems.");
|
||||
appModel.CloseNotificationStage();
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.error("No usable response from server while Download dashboard loading shares: " + response);
|
||||
appModel.CloseNotificationStage();
|
||||
}
|
||||
}.bind(this), this.errorHandler.bind(this));
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.checkIfDownloadNeeded = function(username, results, accessLevel) {
|
||||
|
||||
Mojo.Log.info("Determining which shares need to be downloaded...");
|
||||
this.downloadList = [];
|
||||
this.getFileListForUser(username, function(fileList) {
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
if (results[i].guid) {
|
||||
//Figure out what mimetype to use
|
||||
if (results[i].contenttype == "image/jpeg")
|
||||
ext = ".jpg";
|
||||
else if (results[i].contenttype == "text/plain")
|
||||
ext = ".txt";
|
||||
else if (results[i].contenttype == "text/json")
|
||||
ext = ".json";
|
||||
else {
|
||||
var ext = results[i].contenttype.split("/");
|
||||
ext = ext[ext.length - 1];
|
||||
ext = "." + ext;
|
||||
}
|
||||
var fileToCheck = results[i].guid + ext;
|
||||
var found = false;
|
||||
if (fileList.items) {
|
||||
for (var f = 0;f < fileList.items.length;f ++){
|
||||
if (fileList.items[f].name == fileToCheck) {
|
||||
Mojo.Log.info("Already downloaded: " + fileToCheck);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
var newURL = results[i].thumbnail;
|
||||
newURL = newURL.replace("tthumb", "t");
|
||||
newURL = newURL.replace("ithumb", "i");
|
||||
Mojo.Log.info("Need to download: " + newURL);
|
||||
this.downloadList.push(newURL);
|
||||
var usePath = "sharespace/" + username;
|
||||
if (appModel.AppSettingsCurrent["UseCustomDownloadPath"] && appModel.AppSettingsCurrent["CustomDownloadPath"] != "")
|
||||
usePath = appModel.AppSettingsCurrent["CustomDownloadPath"];
|
||||
systemModel.DownloadFile(newURL, results[i].contenttype, usePath, results[i].guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
Mojo.Log.info("Files in download list: " + this.downloadList.length);
|
||||
if (this.downloadList.length > 0) {
|
||||
this.displayDashboard(Mojo.Controller.appInfo.title, "Downloading shares...", this.downloadList.length);
|
||||
} else {
|
||||
this.displayDashboard(Mojo.Controller.appInfo.title, "No new shares to download.");
|
||||
}
|
||||
downloadMgrInt = this.controller.window.setInterval(function() {
|
||||
this.checkDownloadManagerStatus();
|
||||
}.bind(this), 1500);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.getFileListForUser = function(username, callback) {
|
||||
if (callback)
|
||||
callback.bind(this);
|
||||
Mojo.Log.info("Asking FileMgr service for list of files");
|
||||
this.controller.serviceRequest('palm://ca.canucksoftware.filemgr', {
|
||||
method: 'listFiles',
|
||||
parameters: {
|
||||
path: "/media/internal/sharespace/" + username + "/",
|
||||
},
|
||||
onSuccess: callback,
|
||||
onFailure: callback
|
||||
});
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.checkDownloadManagerStatus = function() {
|
||||
if (this.downloadList.length > 0) {
|
||||
Mojo.Log.info("checking if download manager is done...");
|
||||
this.controller.serviceRequest('palm://com.palm.downloadmanager/', {
|
||||
method: 'listPending',
|
||||
parameters: {},
|
||||
onSuccess : function (response){
|
||||
//Mojo.Log.info("List Pending success, results="+JSON.stringify(response));
|
||||
if (response) {
|
||||
if (response.count && response.count > 0) {
|
||||
Mojo.Log.info("Remaining downloads: " + response.count);
|
||||
this.displayDashboard(Mojo.Controller.appInfo.title, "Downloading shares...", response.count);
|
||||
} else {
|
||||
Mojo.Log.info("Download Manager completed all downloads!");
|
||||
this.controller.window.clearInterval(downloadMgrInt);
|
||||
if (InDockMode)
|
||||
systemModel.SetDisplayState("dock");
|
||||
appModel.CloseDashboardStageByName("download");
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.error("List response failure");
|
||||
this.controller.window.clearInterval(downloadMgrInt);
|
||||
appModel.CloseDashboardStageByName("download");
|
||||
}
|
||||
}.bind(this),
|
||||
onFailure : function (e){
|
||||
Mojo.Log.error("List Pending failure, results="+JSON.stringify(e));
|
||||
this.controller.window.clearInterval(downloadMgrInt);
|
||||
appModel.CloseDashboardStageByName("download");
|
||||
}.bind(this)
|
||||
});
|
||||
} else {
|
||||
if (InDockMode)
|
||||
systemModel.SetDisplayState("dock");
|
||||
appModel.CloseDashboardStageByName("download");
|
||||
}
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.handleTap = function(event) {
|
||||
Mojo.Log.info("Dashboard tapped!");
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
var mainStage = appController.getStageProxy("main");
|
||||
if (!mainStage) {
|
||||
systemModel.LaunchApp(Mojo.Controller.appInfo.id);
|
||||
appController.closeAllStages();
|
||||
} else {
|
||||
mainStage.activate();
|
||||
appController.closeStage("dashboard")
|
||||
}
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.handleDrag = function(event) {
|
||||
var infoElement = this.controller.get("dashboardinfo");
|
||||
infoElement.style.opacity = "0.5"; //TODO: this only seems to effect the icon
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.handleDragEnd = function(event) {
|
||||
Mojo.Log.info("Dashboard drag end!");
|
||||
this.controller.window.clearInterval(downloadMgrInt);
|
||||
appModel.CloseDashboardStageByName("download");
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.errorHandler = function (errorText, callback) {
|
||||
Mojo.Log.error("Error in Dashboard scene: " + errorText);
|
||||
}
|
||||
|
||||
DownloadAssistant.prototype.deactivate = function(event) {
|
||||
Mojo.Event.stopListening(this.controller.get("dashboardinfo"), Mojo.Event.tap, this.handleTap);
|
||||
}
|
||||
|
||||
// Cleanup anything we did in setup function
|
||||
DownloadAssistant.prototype.cleanup = function() {
|
||||
Mojo.Log.info("Dashboard notification stage closing at " + new Date());
|
||||
//Event handlers
|
||||
Mojo.Event.stopListening(this.controller.get("dashboardinfo"), Mojo.Event.tap, this.handleTap);
|
||||
appModel.SaveSettings();
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
function LoginAssistant(sceneAssistant, doneCallBack) {
|
||||
this.doneCallBack = doneCallBack;
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
Mojo.Log.info("new Login assistant exists");
|
||||
this.sceneAssistant = sceneAssistant; //dialog's do not have their own controller, so need access to the launching scene's controller
|
||||
}
|
||||
|
||||
LoginAssistant.prototype.setup = function(widget) {
|
||||
/* this function is for setup tasks that have to happen when the scene is first created */
|
||||
this.widget = widget;
|
||||
Mojo.Log.info("login assistant setup");
|
||||
Mojo.Log.info("Current Move is: " + appModel.AppSettingsCurrent["Username"]);
|
||||
|
||||
/* setup widgets here */
|
||||
this.sceneAssistant.controller.setupWidget("txtUsername",
|
||||
this.attributes = {
|
||||
textFieldName: "Username",
|
||||
hintText: "User Name",
|
||||
property: 'value',
|
||||
multiline: false,
|
||||
changeOnKeyPress: true,
|
||||
autoReplace: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase,
|
||||
requiresEnterKey: false,
|
||||
focus: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["Username"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
this.sceneAssistant.controller.setupWidget("txtCredential",
|
||||
this.attributes = {
|
||||
textFieldName: "Credential",
|
||||
hintText: "Admin Password",
|
||||
property: 'value',
|
||||
multiline: false,
|
||||
changeOnKeyPress: true,
|
||||
autoReplace: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase,
|
||||
requiresEnterKey: false,
|
||||
focus: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["Credential"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
this.sceneAssistant.controller.setupWidget("linkSpinner",
|
||||
this.attributes = {
|
||||
spinnerSize: "small"
|
||||
},
|
||||
this.model = {
|
||||
spinning: true
|
||||
}
|
||||
);
|
||||
this.sceneAssistant.controller.setupWidget("goButton", { type: Mojo.Widget.activityButton }, { label: "OK", disabled: false });
|
||||
this.sceneAssistant.controller.setupWidget("cancelButton", { type: Mojo.Widget.button }, { label: "Cancel", disabled: false });
|
||||
|
||||
/* add event handlers to listen to events from widgets */
|
||||
Mojo.Event.listen(this.sceneAssistant.controller.get("txtUsername"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.sceneAssistant.controller.get("txtCredential"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.sceneAssistant.controller.get("goButton"), Mojo.Event.tap, this.handleGoPress.bind(this));
|
||||
Mojo.Event.listen(this.sceneAssistant.controller.get("cancelButton"), Mojo.Event.tap, this.handleCancelPress.bind(this));
|
||||
};
|
||||
|
||||
LoginAssistant.prototype.activate = function(event) {
|
||||
Mojo.Log.info("Login assistant activated");
|
||||
/* put in event handlers here that should only be in effect when this scene is active. For
|
||||
example, key handlers that are observing the document */
|
||||
|
||||
};
|
||||
|
||||
LoginAssistant.prototype.handleValueChange = function(event) {
|
||||
appModel.AppSettingsCurrent[event.srcElement.title] = event.value;
|
||||
}
|
||||
|
||||
LoginAssistant.prototype.handleCancelPress = function(event) {
|
||||
this.doneCallBack(false);
|
||||
this.widget.mojo.close();
|
||||
}
|
||||
|
||||
LoginAssistant.prototype.handleGoPress = function(event) {
|
||||
|
||||
if (this.sceneAssistant.controller.get("txtUsername").mojo.getValue() == "") {
|
||||
this.sceneAssistant.controller.get("txtUsername").mojo.focus();
|
||||
this.sceneAssistant.controller.get("goButton").mojo.deactivate();
|
||||
return;
|
||||
}
|
||||
if (this.sceneAssistant.controller.get("txtCredential").mojo.getValue() == "") {
|
||||
this.sceneAssistant.controller.get("txtCredential").mojo.focus();
|
||||
this.sceneAssistant.controller.get("goButton").mojo.deactivate();
|
||||
return;
|
||||
}
|
||||
//Update UI for this state
|
||||
this.tryServiceLogin();
|
||||
}
|
||||
|
||||
LoginAssistant.prototype.tryServiceLogin = function() {
|
||||
serviceModel.DoShareListRequest(appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], function(response) {
|
||||
if (response.error) {
|
||||
this.doneCallBack(response);
|
||||
} else {
|
||||
if (response && response.shares && response.shares != "") {
|
||||
Mojo.Log.info("Login success!");
|
||||
appModel.SaveSettings();
|
||||
this.doneCallBack(true);
|
||||
} else {
|
||||
this.doneCallBack({"error": "Login failure. Check connectivity and your credentials. If you haven't logged in for a long time, create a new account."});
|
||||
}
|
||||
}
|
||||
this.widget.mojo.close(); //Dismiss this dialog
|
||||
}.bind(this), this.errorHandler.bind(this));
|
||||
}
|
||||
|
||||
LoginAssistant.prototype.deactivate = function(event) {
|
||||
Mojo.Log.info("Login assistant deactivated");
|
||||
/* remove any event handlers you added in activate and do any other cleanup that should happen before
|
||||
this scene is popped or another scene is pushed on top */
|
||||
Mojo.Event.stopListening(this.sceneAssistant.controller.get("txtUsername"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.sceneAssistant.controller.get("txtCredential"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.sceneAssistant.controller.get("goButton"), Mojo.Event.tap, this.handleGoPress);
|
||||
Mojo.Event.stopListening(this.sceneAssistant.controller.get("cancelButton"), Mojo.Event.tap, this.handleCancelPress);
|
||||
};
|
||||
|
||||
LoginAssistant.prototype.cleanup = function(event) {
|
||||
Mojo.Log.info("Login assistant cleaned up");
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
};
|
||||
|
||||
LoginAssistant.prototype.errorHandler = function (errorText, callback) {
|
||||
Mojo.Log.error(errorText);
|
||||
if (callback) {
|
||||
callback.bind(this);
|
||||
callback({"error": errorText});
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: errorText, icon: "assets/notify.png" }, "", "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,607 @@
|
||||
/*
|
||||
Share Space clipboard app for webOS.
|
||||
This app depends on a sharing service, which is hosted by webOS Archive at no cost for what remains of the webOS mobile community.
|
||||
You can also host the service yourself: http://www.github.com/webosarchive/sharing-service
|
||||
*/
|
||||
|
||||
var refreshInt;
|
||||
function MainAssistant() {
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
}
|
||||
|
||||
MainAssistant.prototype.setup = function() {
|
||||
|
||||
//Load preferences
|
||||
appModel.LoadSettings();
|
||||
Mojo.Log.info("settings now: " + JSON.stringify(appModel.AppSettingsCurrent));
|
||||
this.deviceType = systemModel.DetectDevice();
|
||||
this.errorCount = 5;
|
||||
|
||||
//Loading spinner - with global members for easy toggling later
|
||||
this.spinnerAttrs = {
|
||||
spinnerSize: Mojo.Widget.spinnerLarge
|
||||
};
|
||||
this.spinnerModel = {
|
||||
spinning: false
|
||||
}
|
||||
this.controller.setupWidget('workingSpinner', this.spinnerAttrs, this.spinnerModel);
|
||||
//Share List (starts empty)
|
||||
this.emptyShares = [
|
||||
{ id: "-1", videoName: "Empty", thumbnail: "", selectedState: true }
|
||||
]
|
||||
this.shareListElement = this.controller.get('shareList');
|
||||
this.shareInfoModel = {
|
||||
items: this.emptyShares
|
||||
};
|
||||
//Share List templates (loads other HTML)
|
||||
this.template = {
|
||||
itemTemplate: 'main/item-template',
|
||||
listTemplate: 'main/list-template',
|
||||
swipeToDelete: true,
|
||||
preventDeleteProperty: "readonly",
|
||||
addItemLabel: "New Share"
|
||||
};
|
||||
this.controller.setupWidget("shareList", this.template, this.shareInfoModel);
|
||||
//Menu
|
||||
this.appMenuAttributes = { omitDefaultItems: true };
|
||||
this.appMenuModel = {
|
||||
label: "Settings",
|
||||
items: [
|
||||
Mojo.Menu.editItem,
|
||||
{ label: "Preferences", command: 'do-Preferences' },
|
||||
{ label: "Handle URLs", chosen: false, command: 'do-HandleURLs' },
|
||||
{ label: "Log In", command: 'do-LogInOut' },
|
||||
{ label: "About", command: 'do-myAbout' },
|
||||
{ label: "Version Info", command: 'do-versionInfo' },
|
||||
//{ label: "Debug Mode", chosen: appModel.AppSettingsCurrent["DebugMode"], command: 'do-debugMode' } //TODO: Remove Debug Menu
|
||||
]
|
||||
};
|
||||
|
||||
if(appModel.AppSettingsCurrent["SharePhrase"] && appModel.AppSettingsCurrent["SharePhrase"] != "") {
|
||||
this.appMenuModel.items.push({ label: "Show Share Phrase", command: 'do-mySharePhrase' });
|
||||
}
|
||||
this.controller.setupWidget(Mojo.Menu.appMenu, this.appMenuAttributes, this.appMenuModel);
|
||||
//Command Buttons
|
||||
this.cmdMenuAttributes = {
|
||||
spacerHeight: 40,
|
||||
//menuClass: 'no-fade'
|
||||
},
|
||||
this.cmdMenuModel = {
|
||||
visible: false,
|
||||
items: [{
|
||||
items: [
|
||||
{ label: 'Refresh', icon: 'refresh', command: 'do-refresh' }
|
||||
]
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{ label: 'New', icon: 'new', command: 'do-new' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
if (appModel.AppSettingsCurrent["DebugMode"]) {
|
||||
this.cmdMenuModel.items[0].items.push({ label: "Download", command: 'do-download' });
|
||||
}
|
||||
this.controller.setupWidget(Mojo.Menu.commandMenu, this.cmdMenuAttributes, this.cmdMenuModel);
|
||||
/* Always on Event handlers */
|
||||
Mojo.Event.listen(this.controller.get("shareList"), Mojo.Event.listDelete, this.handleListDelete.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("shareList"), Mojo.Event.listTap, this.handleListClick.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("shareList"), Mojo.Event.listAdd, this.handleListAdd.bind(this));
|
||||
//Just type
|
||||
//this.keypressHandler = this.handleKeyPress.bindAsEventListener(this);
|
||||
//this.controller.document.addEventListener("keypress", this.keypressHandler, true);
|
||||
|
||||
//Check for updates
|
||||
if (!appModel.UpdateCheckDone) {
|
||||
appModel.UpdateCheckDone = true;
|
||||
updaterModel.CheckForUpdate("Share Space", this.handleUpdateResponse.bind(this));
|
||||
//Check for dependencies
|
||||
this.checkForFileMgr();
|
||||
}
|
||||
};
|
||||
|
||||
MainAssistant.prototype.activate = function(data) {
|
||||
|
||||
//Set options for service model
|
||||
serviceModel.ForceHTTP = appModel.AppSettingsCurrent["ForceHTTP"];
|
||||
serviceModel.UseCustomEndpoint = appModel.AppSettingsCurrent["UseCustomEndpoint"];
|
||||
serviceModel.CustomEndpointURL = appModel.AppSettingsCurrent["EndpointURL"];
|
||||
serviceModel.CustomShortURL = appModel.AppSettingsCurrent["ShortURL"];
|
||||
serviceModel.CustomCreateKey = appModel.AppSettingsCurrent["CustomCreateKey"];
|
||||
serviceModel.UseCustomClientId = appModel.AppSettingsCurrent["UseCustomClientId"];
|
||||
serviceModel.CustomClientId = appModel.AppSettingsCurrent["CustomClientId"];
|
||||
|
||||
//Set correct menu label
|
||||
var loggedInLabel = "Log In";
|
||||
if (appModel.AppSettingsCurrent["Username"] != "" && appModel.AppSettingsCurrent["Credential"] != "") {
|
||||
loggedInLabel = "Log Out";
|
||||
var thisCommandModel = this.controller.getWidgetSetup(Mojo.Menu.commandMenu).model;
|
||||
thisCommandModel.visible = true;
|
||||
this.controller.modelChanged(thisCommandModel);
|
||||
}
|
||||
var thisMenuModel = this.controller.getWidgetSetup(Mojo.Menu.appMenu).model;
|
||||
thisMenuModel.items[3].label = loggedInLabel;
|
||||
this.controller.modelChanged(thisMenuModel);
|
||||
|
||||
if (appModel.AppSettingsCurrent["Username"] != "" && appModel.AppSettingsCurrent["Credential"] != "") {
|
||||
Mojo.Log.info("About to fetch shares...");
|
||||
this.controller.get('workingSpinner').mojo.start();
|
||||
this.fetchShares();
|
||||
|
||||
//handle launch with query
|
||||
Mojo.Log.info("Main scene loaded with launch query: " + JSON.stringify(appModel.LaunchQuery) + ", data: " + JSON.stringify(data));
|
||||
var busy = false;
|
||||
if (appModel.LaunchQuery && appModel.LaunchQuery != "") {
|
||||
busy = true;
|
||||
//JustType Launch
|
||||
if (appModel.LaunchQuery.newshare) {
|
||||
Mojo.Log.info("Creating new text Share from Just Type");
|
||||
appModel.LastShareSelected = { guid: "new", contenttype: "text/plain", content: appModel.LaunchQuery.newshare };
|
||||
this.showNewShareScene();
|
||||
}
|
||||
//URL Launch
|
||||
else if (appModel.LaunchQuery.target && appModel.LaunchQuery.target != "") {
|
||||
this.handleURLInvocation(appModel.LaunchQuery.target);
|
||||
}
|
||||
//Some other kind of query launch
|
||||
else {
|
||||
Mojo.Log.warn("Ignoring unhandled launch query");
|
||||
}
|
||||
appModel.LaunchQuery = "";
|
||||
}
|
||||
//Handle camera sub-launch
|
||||
if (data && data.filename) {
|
||||
busy = true;
|
||||
Mojo.Log.info("Creating a new share from Camera sub-launch " + data.filename);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Sharing camera image...", icon: "assets/notify.png" }, "", "");
|
||||
this.uploadCameraImage(data.filename);
|
||||
}
|
||||
if (!busy && appModel.AppSettingsCurrent["LastVersionRun"] != Mojo.Controller.appInfo.version) {
|
||||
appModel.AppSettingsCurrent["LastVersionRun"] = Mojo.Controller.appInfo.version;
|
||||
appModel.SaveSettings();
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ name: "version", disableSceneScroller: false });
|
||||
}
|
||||
} else {
|
||||
appModel.LaunchQuery = "";
|
||||
this.showWelcomePrompt();
|
||||
}
|
||||
|
||||
|
||||
//Check if we're registered to handle URLs
|
||||
useShortLink = Mojo.Controller.appInfo.shortURL;
|
||||
if (appModel.AppSettingsCurrent["UseCustomEndpoint"] && appModel.AppSettingsCurrent["ShortURL"] && appModel.AppSettingsCurrent["ShortURL"] != "")
|
||||
useShortLink = appModel.AppSettingsCurrent["ShortURL"];
|
||||
systemModel.ListHandlersForURL("https://wosa.link",
|
||||
function(response) {
|
||||
var thisMenuModel = this.controller.getWidgetSetup(Mojo.Menu.appMenu).model;
|
||||
if (JSON.stringify(response).indexOf(Mojo.Controller.appInfo.id) != -1) {
|
||||
Mojo.Log.warn("This app handles the Short URL " + useShortLink);
|
||||
thisMenuModel.items[2].chosen = true;
|
||||
} else {
|
||||
Mojo.Log.warn("This app does not handle the Short URL " + useShortLink);
|
||||
thisMenuModel.items[2].chosen = false;
|
||||
}
|
||||
this.controller.modelChanged(thisMenuModel);
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
};
|
||||
|
||||
MainAssistant.prototype.checkForFileMgr = function() {
|
||||
systemModel.GetInstalledApps(function(response) {
|
||||
var found = false;
|
||||
if (response && response.apps) {
|
||||
for (var i=0; i<response.apps.length; i++)
|
||||
{
|
||||
if (response.apps[i].id == "ca.canucksoftware.filemgr")
|
||||
found = true;
|
||||
}
|
||||
} else
|
||||
Mojo.Log.info("Could not get listed of installed apps.")
|
||||
if (found)
|
||||
Mojo.Log.info("Found FileMgr by Jason Robitaille! Download features enabled.")
|
||||
else {
|
||||
appModel.AppSettingsCurrent["UseAutoDownload"] = false;
|
||||
Mojo.Log.info("Could not find FileMgr installed! Download features disabled.")
|
||||
}
|
||||
appModel.FileMgrPresent = found;
|
||||
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
MainAssistant.prototype.handleUpdateResponse = function(responseObj) {
|
||||
if (responseObj && responseObj.updateFound) {
|
||||
updaterModel.PromptUserForUpdate(function(response) {
|
||||
if (response)
|
||||
updaterModel.InstallUpdate();
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.handleURLInvocation = function(query) {
|
||||
Mojo.Log.info("Handling URL launch of: " + appModel.LaunchQuery.target);
|
||||
serviceModel.QueryShareData(query, function(itemData) {
|
||||
Mojo.Log.info("Item query response payload was: " + JSON.stringify(itemData));
|
||||
if (itemData && itemData.guid) {
|
||||
appModel.LastShareSelected = itemData;
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ transition: Mojo.Transition.crossFade, name: "detail" });
|
||||
} else {
|
||||
Mojo.Log.error("Item query data invalid.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* UI Event Handlers */
|
||||
|
||||
//Handles the enter key
|
||||
MainAssistant.prototype.handleKeyPress = function(event) {
|
||||
if (event.srcElement.toString().indexOf("HTMLInputElement") == -1) {
|
||||
if (!event.shiftKey && !this.DoingEdit) {
|
||||
Mojo.Log.info("Key pressed!" + String.fromCharCode(event.keyCode));
|
||||
appModel.LastShareSelected = { guid: "new" };
|
||||
this.showNewShareOptions();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MainAssistant.prototype.handleCommand = function(event) {
|
||||
if (event.type == Mojo.Event.command) {
|
||||
switch (event.command) {
|
||||
case 'do-HandleURLs':
|
||||
var thisMenuModel = this.controller.getWidgetSetup(Mojo.Menu.appMenu).model;
|
||||
if (thisMenuModel.items[2].chosen) {
|
||||
//remote URL handler
|
||||
systemModel.removeHandlerForURL(Mojo.Controller.appInfo.id);
|
||||
thisMenuModel.items[2].chosen = false;
|
||||
} else {
|
||||
//add URL handler
|
||||
systemModel.AddHandlerForURL("^[^:]+://wosa.link", Mojo.Controller.appInfo.id);
|
||||
thisMenuModel.items[2].chosen = true;
|
||||
}
|
||||
this.controller.modelChanged(thisMenuModel);
|
||||
break;
|
||||
case 'do-LogInOut':
|
||||
this.doLogInOut();
|
||||
break;
|
||||
case 'do-Preferences':
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ name: "preferences", disableSceneScroller: false });
|
||||
break;
|
||||
case 'do-myAbout':
|
||||
Mojo.Additions.ShowDialogBox("Share Space - " + Mojo.Controller.appInfo.version, "Share Space sharing service client for webOS. Copyright 2022, webOS Archive. Distributed under an MIT License.<br>Source code available at: https://github.com/webosarchive/webos-sharespace");
|
||||
break;
|
||||
case 'do-versionInfo':
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ name: "version", disableSceneScroller: false });
|
||||
break;
|
||||
case 'do-mySharePhrase':
|
||||
Mojo.Additions.ShowDialogBox("Your Share Phrase", "<b>" + appModel.AppSettingsCurrent["SharePhrase"] + "</b><br><br>Remember that anyone who has your Share Space name and Share Phrase can share with you.");
|
||||
break;
|
||||
case 'do-debugMode':
|
||||
if (appModel.AppSettingsCurrent["DebugMode"]) {
|
||||
appModel.AppSettingsCurrent["DebugMode"] = false;
|
||||
} else {
|
||||
appModel.AppSettingsCurrent["DebugMode"] = true;
|
||||
}
|
||||
appModel.SaveSettings();
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.swapScene({ transition: Mojo.Transition.crossFade, name: "main" });
|
||||
break;
|
||||
case 'do-download':
|
||||
Mojo.Log.info("Trying to download in background");
|
||||
appModel.ShowDownloaderStage();
|
||||
break;
|
||||
case 'do-new':
|
||||
appModel.LastShareSelected = { guid: "new" };
|
||||
this.showNewShareOptions();
|
||||
break;
|
||||
case 'do-refresh':
|
||||
this.fetchShares();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.handleListDelete = function(event) {
|
||||
Mojo.Log.warn("Deleting item: " + event.item.guid);
|
||||
serviceModel.DoShareDeleteRequest(event.item.guid, appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"]);
|
||||
}
|
||||
|
||||
MainAssistant.prototype.handleListClick = function(event) {
|
||||
|
||||
Mojo.Log.info("Item tapped with element class " + event.originalEvent.target.className);
|
||||
Mojo.Log.info("Item details: " + JSON.stringify(event.item));
|
||||
appModel.LastShareSelected = event.item;
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ transition: Mojo.Transition.crossFade, name: "detail" });
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MainAssistant.prototype.handleListAdd = function(event) {
|
||||
//TODO: Verify this works
|
||||
appModel.LastShareSelected = { guid: "new" };
|
||||
this.showNewShareOptions();
|
||||
}
|
||||
|
||||
MainAssistant.prototype.handlePopupChoose = function(share, command) {
|
||||
Mojo.Log.info("Perform: ", command, " on ", share.guid);
|
||||
switch (command) {
|
||||
case "do-complete":
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get Share Stuff */
|
||||
MainAssistant.prototype.fetchShares = function() {
|
||||
|
||||
this.controller.window.clearInterval(refreshInt);
|
||||
if (appModel.AppSettingsCurrent["RefreshTimeout"] && appModel.AppSettingsCurrent["RefreshTimeout"] > 1000) {
|
||||
Mojo.Log.info("Auto refresh interval: " + appModel.AppSettingsCurrent["RefreshTimeout"]);
|
||||
refreshInt = this.controller.window.setInterval(this.fetchShares.bind(this), appModel.AppSettingsCurrent["RefreshTimeout"]);
|
||||
} else {
|
||||
Mojo.Log.warn("Using Manual Refresh");
|
||||
}
|
||||
|
||||
serviceModel.DoShareListRequest(appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], function(responseObj){
|
||||
//Mojo.Log.info("ready to process share list: " + JSON.stringify(responseObj));
|
||||
|
||||
if (responseObj != null) {
|
||||
if (responseObj.shares) {
|
||||
//If we got a good looking response, update the UI
|
||||
this.updateShareListWidget(appModel.AppSettingsCurrent["Username"], responseObj.shares, responseObj.accesslevel);
|
||||
if ((!appModel.AppSettingsCurrent["SharePhrase"] || appModel.AppSettingsCurrent["SharePhrase"] == "") && responseObj.sharephrase){
|
||||
appModel.AppSettingsCurrent["SharePhrase"] = responseObj.sharephrase;
|
||||
appModel.SaveSettings();
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.warn("Share list was empty. Either there was no matching result, or there were server or connectivity problems.");
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.error("No usable response from server while loading shares: " + response);
|
||||
this.errorHandler("The server did not answer with a usable response to the share list request. Check network connectivity, SSL and/or self-host settings.");
|
||||
}
|
||||
}.bind(this), this.errorHandler.bind(this));
|
||||
}
|
||||
|
||||
MainAssistant.prototype.updateShareListWidget = function(username, results, accessLevel) {
|
||||
|
||||
Mojo.Log.info("Displaying shares for: " + username + " with access level: " + accessLevel);
|
||||
this.controller.get("spnUsername").innerHTML = username;
|
||||
this.controller.get("workingSpinner").mojo.stop();
|
||||
this.controller.get("divSpinnerContainer").style.display = "none";
|
||||
|
||||
var thisShareList = this.controller.getWidgetSetup("shareList");
|
||||
thisShareList.model.items = []; //remove the previous list
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
if (accessLevel && accessLevel == "admin") {
|
||||
results[i].readonly = false;
|
||||
} else {
|
||||
results[i].readonly = true;
|
||||
}
|
||||
results[i].timestamp = appModel.ConvertTimeStamp(results[i].timestamp, true);
|
||||
thisShareList.model.items.push(results[i]);
|
||||
}
|
||||
|
||||
Mojo.Log.info("Updating share list widget with " + results.length + " results!");
|
||||
this.controller.get("showShareList").style.display = "block";
|
||||
this.controller.modelChanged(thisShareList.model);
|
||||
this.errorCount = 0;
|
||||
}
|
||||
|
||||
/* New Share Stuff */
|
||||
|
||||
MainAssistant.prototype.showNewShareOptions = function() {
|
||||
var choices = [
|
||||
{ label: "Text", value: "text/plain", type: "neutral" },
|
||||
{ label: "JSON", value: "application/json", type: "neutral" },
|
||||
{ label: "Image", value: "image", type: "neutral" },
|
||||
];
|
||||
if (this.deviceType != "TouchPad")
|
||||
choices.push({ label: "Camera", value: "camera", type: "neutral" });
|
||||
choices.push({ label: "Cancel", value: "cancel", type: "negative" });
|
||||
|
||||
this.controller.showAlertDialog({
|
||||
onChoose: function(value) {
|
||||
Mojo.Log.info("Choice was: " + value);
|
||||
if (value == "image") {
|
||||
this.pickAndUploadImage();
|
||||
} else if (value == "camera") {
|
||||
this.getCameraImage();
|
||||
} else if (value == "text/plain" || value == "application/json") {
|
||||
appModel.LastShareSelected.contenttype = value;
|
||||
Mojo.Log.info("LastShareSelected: " + JSON.stringify(appModel.LastShareSelected));
|
||||
this.showNewShareScene();
|
||||
} else {
|
||||
Mojo.Log.info("Cancelled new share");
|
||||
}
|
||||
},
|
||||
title: "New Share",
|
||||
message: "What do you want to share?",
|
||||
choices: choices
|
||||
});
|
||||
}
|
||||
|
||||
MainAssistant.prototype.pickAndUploadImage = function() {
|
||||
var self = this; //Retain the reference for the callback
|
||||
var params = { kind: 'image', actionName: 'Share Photo',
|
||||
onSelect: function(file){
|
||||
Mojo.Log.info("selected file was: " + JSON.stringify(file));
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'Sharing image...', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
|
||||
//Figure out what mimetype to use
|
||||
var ext = file.fullPath.split(".");
|
||||
ext = ext[ext.length - 1].toLowerCase();
|
||||
if (ext == "jpg")
|
||||
mimetype = "image/jpeg";
|
||||
else
|
||||
mimetype = "image/" + ext;
|
||||
|
||||
serviceModel.DoShareAddRequestImage(file.fullPath, appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], mimetype, function(responseObj) {
|
||||
if (responseObj != null) {
|
||||
Mojo.Log.info("image share response: " + JSON.stringify(responseObj));
|
||||
if (appModel.AppSettingsCurrent["CopyLinkOnShare"]) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController()
|
||||
stageController.setClipboard(serviceModel.MakeShareURL(appModel.AppSettingsCurrent["Username"], responseObj.guid, "image"));
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Image shared, link copied!", icon: "assets/notify.png" }, "", "");
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Image shared!", icon: "assets/notify.png" }, "", "");
|
||||
}
|
||||
self.fetchShares();
|
||||
} else {
|
||||
Mojo.Log.error("No usable response from server while uploading share");
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Bad response uploading image", icon: "assets/notify.png" }, "", "");
|
||||
}
|
||||
}.bind(self), function(errorText) {
|
||||
Mojo.Log.error(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Upload failure: " + errorText, icon: "assets/notify.png" }, "", "");
|
||||
});
|
||||
}
|
||||
}
|
||||
Mojo.FilePicker.pickFile(params, this.controller.stageController);
|
||||
}
|
||||
|
||||
MainAssistant.prototype.getCameraImage = function() {
|
||||
this.controller.stageController.pushScene(
|
||||
{ appId: "com.palm.app.camera", name: "capture" },
|
||||
{ sublaunch: true, mode: "stil" }
|
||||
);
|
||||
}
|
||||
|
||||
MainAssistant.prototype.uploadCameraImage = function(file) {
|
||||
var self = this;
|
||||
serviceModel.DoShareAddRequestImage(file, appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], "image/jpeg", function(responseObj) {
|
||||
if (responseObj != null) {
|
||||
if (appModel.AppSettingsCurrent["CopyLinkOnShare"]) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController()
|
||||
stageController.setClipboard(serviceModel.MakeShareURL(appModel.AppSettingsCurrent["Username"], responseObj.guid, "image"));
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Image shared, link copied!", icon: "assets/notify.png" }, "", "");
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Image shared!", icon: "assets/notify.png" }, "", "");
|
||||
}
|
||||
self.fetchShares();
|
||||
} else {
|
||||
Mojo.Log.error("No usable response from server while uploading share");
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Bad response uploading image", icon: "assets/notify.png" }, "", "");
|
||||
}
|
||||
}.bind(self), function(errorText) {
|
||||
Mojo.Log.error(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Upload failure: " + errorText, icon: "assets/notify.png" }, "", "");
|
||||
});
|
||||
}
|
||||
|
||||
MainAssistant.prototype.showNewShareScene = function() {
|
||||
this.DoingEdit = true;
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
if (!stageController)
|
||||
stageController = Mojo.Controller.getAppController().getStageController(MainStageName);
|
||||
stageController.pushScene({ transition: Mojo.Transition.crossFade, name: "newshare" });
|
||||
}
|
||||
|
||||
/* Login Stuff */
|
||||
MainAssistant.prototype.showWelcomePrompt = function() {
|
||||
this.controller.showAlertDialog({
|
||||
onChoose: function(value) {
|
||||
if (value == "login") {
|
||||
this.showLogin();
|
||||
} else if (value == "new") {
|
||||
Mojo.Log.info("new selected!");
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.swapScene({ transition: Mojo.Transition.crossFade, name: "newuser" });
|
||||
}
|
||||
},
|
||||
title: "Welcome to Share Space!",
|
||||
message: "Your shared clipboard for webOS! This client app can be used with a web service and web app that lets you share content between devices, or with other users! Do you want to Log In to an existing share space, or create a new one?",
|
||||
choices: [
|
||||
{ label: 'Log In', value: "login", type: 'affirmative' },
|
||||
{ label: 'Create New', value: "new", type: 'neutral' },
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
MainAssistant.prototype.doLogInOut = function() {
|
||||
if (appModel.AppSettingsCurrent["Username"] == "" && appModel.AppSettingsCurrent["Credential"] == "") {
|
||||
this.showWelcomePrompt();
|
||||
} else { //Log out
|
||||
|
||||
//Clear credentials
|
||||
appModel.AppSettingsCurrent["Username"] = "";
|
||||
appModel.AppSettingsCurrent["Credential"] = "";
|
||||
appModel.AppSettingsCurrent["SharePhrase"] = "";
|
||||
appModel.SaveSettings();
|
||||
|
||||
//Re-paint scene
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.swapScene({ transition: Mojo.Transition.crossFade, name: "main", disableSceneScroller: false });
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.showLogin = function() {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
if (stageController) {
|
||||
this.controller = stageController.activeScene();
|
||||
this.controller.showDialog({
|
||||
template: 'login/login-scene',
|
||||
assistant: new LoginAssistant(this, function(dialogResponse) {
|
||||
if (dialogResponse == true) {
|
||||
Mojo.Log.info("Re-painting scene after successful login!");
|
||||
//Re-paint scene
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.swapScene({ transition: Mojo.Transition.crossFade, name: "main", disableSceneScroller: false });
|
||||
} else {
|
||||
if (dialogResponse.error) {
|
||||
var readableError = dialogResponse.error.replace("Share service error: ", "");
|
||||
readableError = readableError.charAt(0).toUpperCase() + readableError.slice(1);
|
||||
Mojo.Additions.ShowDialogBox("Share Service Error", readableError);
|
||||
}
|
||||
}
|
||||
}.bind(this))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* End of Life Stuff */
|
||||
|
||||
MainAssistant.prototype.deactivate = function(event) {
|
||||
/* remove any event handlers you added in activate and do any other cleanup that should happen before
|
||||
this scene is popped or another scene is pushed on top */
|
||||
this.controller.window.clearInterval(refreshInt);
|
||||
Mojo.Event.stopListening(this.controller.get("shareList"), Mojo.Event.listDelete, this.handleListDelete);
|
||||
Mojo.Event.stopListening(this.controller.get("shareList"), Mojo.Event.listTap, this.handleListClick);
|
||||
Mojo.Event.stopListening(this.controller.get("shareList"), Mojo.Event.listAdd, this.handleListAdd);
|
||||
//Just type
|
||||
//this.controller.document.removeEventListener("keypress", this.keypressHandler);
|
||||
|
||||
};
|
||||
|
||||
MainAssistant.prototype.cleanup = function(event) {
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
};
|
||||
|
||||
/* Helper Functions */
|
||||
|
||||
MainAssistant.prototype.errorHandler = function (errorText, callback) {
|
||||
this.errorCount++;
|
||||
Mojo.Log.error("error count: " + this.errorCount + ", " + errorText);
|
||||
if (this.errorCount > 5) {
|
||||
Mojo.Additions.ShowDialogBox("Sync Error", errorText);
|
||||
this.controller.window.clearInterval(refreshInt);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Offline", icon: "assets/notify.png" }, "", "");
|
||||
}
|
||||
if (callback) {
|
||||
callback.bind(this);
|
||||
callback({"error": errorText});
|
||||
}
|
||||
}
|
||||
|
||||
Array.prototype.move = function(from, to) {
|
||||
this.splice(to, 0, this.splice(from, 1)[0]);
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
function NewshareAssistant(sceneAssistant, doneCallBack) {
|
||||
this.doneCallBack = doneCallBack;
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
Mojo.Log.info("new NewShare assistant exists");
|
||||
this.sceneAssistant = sceneAssistant; //dialog's do not have their own controller, so need access to the launching scene's controller
|
||||
}
|
||||
|
||||
NewshareAssistant.prototype.setup = function(widget) {
|
||||
/* this function is for setup tasks that have to happen when the scene is first created */
|
||||
this.widget = widget;
|
||||
Mojo.Log.info("Current Share Target is: " + appModel.AppSettingsCurrent["Username"]);
|
||||
|
||||
/* setup widgets here */
|
||||
//Text box
|
||||
var textAttrib = {
|
||||
textFieldName: "ShareContent",
|
||||
hintText: "Text to share",
|
||||
property: 'value',
|
||||
multiline: true,
|
||||
changeOnKeyPress: true,
|
||||
autoReplace: true,
|
||||
textCase: Mojo.Widget.steModeSentenceCase,
|
||||
requiresEnterKey: false,
|
||||
focus: true
|
||||
};
|
||||
if (appModel.LastShareSelected.contenttype == "application/json") {
|
||||
textAttrib.hintText = "JSON to share"
|
||||
textAttrib.autoReplace = false;
|
||||
textAttrib.textCase = Mojo.Widget.steModeLowerCase;
|
||||
}
|
||||
Mojo.Log.info("Using Last Share: " + JSON.stringify(appModel.LastShareSelected));
|
||||
this.controller.setupWidget("txtShareContent",
|
||||
this.attributes = textAttrib,
|
||||
this.model = {
|
||||
value: appModel.LastShareSelected.content,
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("goButton", { type: Mojo.Widget.activityButton }, { label: "OK", disabled: false });
|
||||
this.controller.setupWidget("cancelButton", { type: Mojo.Widget.button }, { label: "Cancel", disabled: false });
|
||||
};
|
||||
|
||||
NewshareAssistant.prototype.activate = function(event) {
|
||||
Mojo.Log.info("NewShare assistant activated for share: " + appModel.LastShareSelected.guid);
|
||||
if (appModel.LastShareSelected.guid == "new") {
|
||||
this.controller.get("divEditTitle").innerHTML = "New Share Content";
|
||||
|
||||
} else {
|
||||
this.controller.get("divEditTitle").innerHTML = "Edit Share Content";
|
||||
}
|
||||
|
||||
/* add event handlers to listen to events from widgets */
|
||||
Mojo.Event.listen(this.controller.get("goButton"), Mojo.Event.tap, this.handleOKPress.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("cancelButton"), Mojo.Event.tap, this.handleCancelPress.bind(this));
|
||||
//Resize event
|
||||
this.controller.window.onresize = this.calculateControlsPosition.bind(this);
|
||||
this.calculateControlsPosition();
|
||||
};
|
||||
|
||||
NewshareAssistant.prototype.calculateControlsPosition = function() {
|
||||
var maxHeight = 380;
|
||||
if ((this.controller.window.innerHeight - 210) < maxHeight)
|
||||
maxHeight = this.controller.window.innerHeight - 210;
|
||||
this.controller.get("txtShareContent").style.height = maxHeight + "px";
|
||||
}
|
||||
|
||||
NewshareAssistant.prototype.handleCancelPress = function(event) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ transition: Mojo.Transition.crossFade, name: "main" });
|
||||
}
|
||||
|
||||
NewshareAssistant.prototype.handleOKPress = function(event) {
|
||||
var shareContent = this.controller.get("txtShareContent").mojo.getValue();
|
||||
if (shareContent && shareContent != "") {
|
||||
if (appModel.LastShareSelected.contenttype == "application/json") {
|
||||
try {
|
||||
var testObj = JSON.parse(shareContent);
|
||||
} catch (ex) {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'JSON content not be parsed', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
this.controller.get('goButton').mojo.deactivate();
|
||||
this.controller.window.setTimeout(this.controller.get('txtShareContent').mojo.focus(), 500);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
appModel.LastShareSelected.content = shareContent;
|
||||
this.tryAddShare();
|
||||
} else {
|
||||
this.controller.get('goButton').mojo.deactivate();
|
||||
this.controller.get("txtShareContent").mojo.focus();
|
||||
}
|
||||
}
|
||||
|
||||
NewshareAssistant.prototype.tryAddShare = function() {
|
||||
serviceModel.DoShareAddRequestText(appModel.LastShareSelected.content, appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], appModel.LastShareSelected.contenttype, function(responseObj) {
|
||||
if (responseObj && responseObj.guid && responseObj.guid != "") {
|
||||
Mojo.Log.info("Add share success!");
|
||||
if (appModel.AppSettingsCurrent["CopyLinkOnShare"]) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController()
|
||||
stageController.setClipboard(serviceModel.MakeShareURL(appModel.AppSettingsCurrent["Username"], responseObj.guid, "text"));
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'Content shared, link copied!', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: 'Content shared!', icon: 'assets/notify.png' }, { source: 'notification' });
|
||||
}
|
||||
} else {
|
||||
this.errorHandler("Share failure: " + JSON.stringify(responseObj))
|
||||
}
|
||||
this.handleCancelPress();
|
||||
}.bind(this), this.errorHandler.bind(this));
|
||||
}
|
||||
|
||||
NewshareAssistant.prototype.errorHandler = function (errorText, callback) {
|
||||
Mojo.Log.error(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: errorText, icon: "assets/notify.png" }, "", "");
|
||||
errorText = errorText.charAt(0).toUpperCase() + errorText.slice(1);
|
||||
this.controller.get('goButton').mojo.deactivate();
|
||||
Mojo.Additions.ShowDialogBox("Share Sevice Error", errorText);
|
||||
}
|
||||
|
||||
NewshareAssistant.prototype.deactivate = function(event) {
|
||||
Mojo.Log.info("NewShare assistant deactivated");
|
||||
Mojo.Event.stopListening(this.controller.get("goButton"), Mojo.Event.tap, this.handleOKPress);
|
||||
Mojo.Event.stopListening(this.controller.get("cancelButton"), Mojo.Event.tap, this.handleCancelPress);
|
||||
};
|
||||
|
||||
NewshareAssistant.prototype.cleanup = function(event) {
|
||||
Mojo.Log.info("NewShare assistant cleaned up");
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
};
|
||||
@@ -0,0 +1,173 @@
|
||||
function NewuserAssistant() {
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
}
|
||||
|
||||
NewuserAssistant.prototype.setup = function() {
|
||||
/* setup widgets here */
|
||||
this.controller.setupWidget("scrollTnC",
|
||||
this.attributes = {
|
||||
mode: 'vertical'
|
||||
},
|
||||
this.model = {}
|
||||
);
|
||||
|
||||
//Agree Button
|
||||
this.controller.setupWidget("btnAgree", { type: Mojo.Widget.defaultButton }, { label: "Agree", buttonClass: "affirmative", disabled: true });
|
||||
//Cancel Button
|
||||
this.controller.setupWidget("btnCancel", { type: Mojo.Widget.defaultButton }, { label: "Cancel", buttonClass: "negative", disabled: false });
|
||||
//OK Button
|
||||
this.controller.setupWidget("btnOK", { type: Mojo.Widget.activityButton }, { label: "Create Space", buttonClass: "affirmative", disabled: false });
|
||||
|
||||
//Username Field
|
||||
this.controller.setupWidget("txtUsername",
|
||||
this.attributes = {
|
||||
hintText: $L("Choose a username"),
|
||||
multiline: false,
|
||||
enterSubmits: false,
|
||||
focus: true,
|
||||
textCase: Mojo.Widget.steModeLowerCase,
|
||||
autoReplace: false
|
||||
},
|
||||
this.model = {
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//Username Field
|
||||
this.controller.setupWidget("txtPassword",
|
||||
this.attributes = {
|
||||
hintText: $L("Enter a Password"),
|
||||
multiline: false,
|
||||
enterSubmits: false,
|
||||
focus: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase,
|
||||
autoReplace: false
|
||||
},
|
||||
this.model = {
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
|
||||
//Menu
|
||||
this.appMenuAttributes = { omitDefaultItems: true };
|
||||
this.appMenuModel = {};
|
||||
this.controller.setupWidget(Mojo.Menu.appMenu, this.appMenuAttributes, this.appMenuModel);
|
||||
};
|
||||
|
||||
NewuserAssistant.prototype.activate = function(event) {
|
||||
/* add event handlers to listen to events from widgets */
|
||||
Mojo.Event.listen(this.controller.get("btnAgree"), Mojo.Event.tap, this.agreeClick.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("btnCancel"), Mojo.Event.tap, this.cancelClick.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("btnOK"), Mojo.Event.tap, this.okClick.bind(this));
|
||||
//bind tryagain listener
|
||||
this.controller.get("imgTryagain").addEventListener("click", this.generateSharePhrase.bind(this));
|
||||
|
||||
//Get terms and conditions from service and put into UI
|
||||
serviceModel.GetTnC(function(response) {
|
||||
this.controller.get("divTnC").innerHTML = response;
|
||||
Mojo.Additions.DisableWidget("btnAgree", false);
|
||||
}.bind(this));
|
||||
this.sharephrase = "";
|
||||
|
||||
//Resize event
|
||||
this.controller.window.onresize = this.calculateControlsPosition.bind(this);
|
||||
this.calculateControlsPosition();
|
||||
};
|
||||
|
||||
NewuserAssistant.prototype.calculateControlsPosition = function() {
|
||||
var maxHeight = 380;
|
||||
if ((this.controller.window.innerHeight - 180) < maxHeight)
|
||||
maxHeight = this.controller.window.innerHeight - 180;
|
||||
this.controller.get("scrollTnC").style.height = maxHeight + "px";
|
||||
}
|
||||
|
||||
NewuserAssistant.prototype.agreeClick = function(event) {
|
||||
|
||||
Mojo.Additions.DisableWidget("btnAgree", true);
|
||||
this.controller.get("divCredentials").style.display = "block";
|
||||
this.controller.get("btnOK").style.display = "block";
|
||||
this.generateSharePhrase();
|
||||
this.controller.getSceneScroller().mojo.revealElement(this.controller.get("txtPassword"));
|
||||
}
|
||||
|
||||
NewuserAssistant.prototype.generateSharePhrase = function() {
|
||||
//Get new credentials from service and put into UI
|
||||
serviceModel.GetRandomWords(function(response) {
|
||||
if (response) {
|
||||
this.controller.get("divSharephrase").innerHTML = response;
|
||||
this.sharephrase = response;
|
||||
} else {
|
||||
Mojo.Additions.ShowDialogBox("Service Error", "Did not receive random words from service.");
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
NewuserAssistant.prototype.okClick = function(event) {
|
||||
//validate input
|
||||
var disallowed = ["con", "prn", "aux", "nul", "com", "do", "done", "elif", "else", "esac", "fi", "for", "function", "if", "in", "select", "then", "until", "while", "time"];
|
||||
this.username = this.controller.get('txtUsername').mojo.getValue().toLowerCase();
|
||||
if (this.username == "" || disallowed.indexOf(this.username) != -1 || this.username.match(/[^a-z]/g) || this.username.indexOf(" ") != -1) {
|
||||
Mojo.Additions.ShowDialogBox("Invalid username", "Your username must be one word, alphabetic characters only, and cannot contain any reserved words for Unix or Windows operating systems.");
|
||||
this.controller.get('btnOK').mojo.deactivate();
|
||||
} else {
|
||||
if (this.sharephrase && this.sharephrase != "") {
|
||||
this.password = this.controller.get('txtPassword').mojo.getValue().toLowerCase();
|
||||
if (this.password == "" || disallowed.indexOf(this.password) != -1 || this.password.match(/[^A-Za-z0-9 ]/g) || this.password.indexOf(" ") != -1) {
|
||||
Mojo.Additions.ShowDialogBox("Invalid password", "Your password must be one word, alpha-numeric characters only, and cannot contain any reserved words for Unix or Windows operating systems.");
|
||||
this.controller.get('btnOK').mojo.deactivate();
|
||||
} else {
|
||||
serviceModel.DoNewUserRequest(this.username, this.sharephrase, this.password, function(responseObj) {
|
||||
if (responseObj != null) {
|
||||
appModel.AppSettingsCurrent["Username"] = this.username;
|
||||
appModel.AppSettingsCurrent["Credential"] = this.password;
|
||||
appModel.AppSettingsCurrent["SharePhrase"] = this.sharephrase;
|
||||
appModel.SaveSettings();
|
||||
Mojo.Log.info("Successfully created account ", appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], appModel.AppSettingsCurrent["SharePhrase"]);
|
||||
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.swapScene({ transition: Mojo.Transition.zoomFade, name: "welcome" });
|
||||
} else {
|
||||
Mojo.Log.error("No usable response from server while uploading share");
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Bad response uploading image", icon: "assets/notify.png" }, "", "");
|
||||
}
|
||||
this.controller.get('btnOK').mojo.deactivate();
|
||||
}.bind(this), this.errorHandler.bind(this));
|
||||
}
|
||||
} else {
|
||||
Mojo.Additions.ShowDialogBox("Missing Share Phrase", "The share phrase is provided by the server, but appears to be missing. This likely means the server is unreachable, down, or improperly configured.");
|
||||
this.controller.get('btnOK').mojo.deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NewuserAssistant.prototype.cancelClick = function(event) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.swapScene({ transition: Mojo.Transition.zoomFade, name: "main" });
|
||||
}
|
||||
|
||||
NewuserAssistant.prototype.errorHandler = function (errorText, callback) {
|
||||
Mojo.Log.error(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: errorText, icon: "assets/notify.png" }, "", "");
|
||||
errorText = errorText.charAt(0).toUpperCase() + errorText.slice(1);
|
||||
Mojo.Additions.ShowDialogBox("Share Sevice Error", errorText);
|
||||
this.controller.get('btnOK').mojo.deactivate();
|
||||
}
|
||||
|
||||
NewuserAssistant.prototype.deactivate = function(event) {
|
||||
/* remove any event handlers you added in activate and do any other cleanup that should happen before
|
||||
this scene is popped or another scene is pushed on top */
|
||||
|
||||
Mojo.Event.stopListening(this.controller.get("btnAgree"), Mojo.Event.tap, this.agreeClick);
|
||||
Mojo.Event.stopListening(this.controller.get("btnCancel"), Mojo.Event.tap, this.cancelClick);
|
||||
Mojo.Event.stopListening(this.controller.get("btnOK"), Mojo.Event.tap, this.cancelClick);
|
||||
this.controller.window.removeEventListener("resize", this.calculateControlsPosition);
|
||||
this.controller.window.onresize = null;
|
||||
};
|
||||
|
||||
NewuserAssistant.prototype.cleanup = function(event) {
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
|
||||
};
|
||||
@@ -0,0 +1,310 @@
|
||||
function PreferencesAssistant() {
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
}
|
||||
|
||||
PreferencesAssistant.prototype.setup = function() {
|
||||
/* setup widgets here */
|
||||
|
||||
//Refresh timeout picker
|
||||
this.controller.setupWidget("listRefresh",
|
||||
this.attributes = {
|
||||
label: $L("Refresh"),
|
||||
choices: [
|
||||
{ label: "Manual", value: "" },
|
||||
{ label: "1 minute", value: 60000 },
|
||||
{ label: "2 minutes", value: 120000 },
|
||||
{ label: "3 minutes", value: 180000 },
|
||||
{ label: "5 minutes", value: 300000 }
|
||||
]
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["RefreshTimeout"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//Toggles
|
||||
var disableDL = true;
|
||||
if (appModel.FileMgrPresent)
|
||||
disableDL = false;
|
||||
this.controller.setupWidget("toggleAutoDownload",
|
||||
this.attributes = {
|
||||
trueValue: true,
|
||||
falseValue: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["UseAutoDownload"],
|
||||
disabled: disableDL
|
||||
}
|
||||
);
|
||||
//List boxes
|
||||
this.controller.setupWidget("listAutoDownloadTime",
|
||||
this.attributes = {
|
||||
label: $L("Download Interval"),
|
||||
choices: [
|
||||
{ label: "5 minutes", value: "00:05:00" },
|
||||
{ label: "30 minutes", value: "00:30:00" },
|
||||
{ label: "1 Hour", value: "01:00:00" },
|
||||
{ label: "2 Hours", value: "02:00:00" },
|
||||
{ label: "3 Hours", value: "03:00:00" },
|
||||
{ label: "6 Hours", value: "06:00:00" },
|
||||
{ label: "12 Hours", value: "12:00:00" },
|
||||
{ label: "24 Hours", value: "23:59:59" }
|
||||
]
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["AutoDownloadTime"],
|
||||
disabled: disableDL
|
||||
}
|
||||
);
|
||||
if (appModel.FileMgrPresent)
|
||||
this.controller.get("divDownloadExplain").innerHTML = "Frequent automatic downloads can have significant impact on battery life.";
|
||||
//More toggles
|
||||
this.controller.setupWidget("toggleCopyLinkOnShare",
|
||||
this.attributes = {
|
||||
trueValue: true,
|
||||
falseValue: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["CopyLinkOnShare"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("toggleForceHTTP",
|
||||
this.attributes = {
|
||||
trueValue: true,
|
||||
falseValue: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["ForceHTTP"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("toggleCustomClientId",
|
||||
this.attributes = {
|
||||
trueValue: true,
|
||||
falseValue: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["UseCustomClientId"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("toggleCustomEndPoint",
|
||||
this.attributes = {
|
||||
trueValue: true,
|
||||
falseValue: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["UseCustomEndpoint"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//Text fields
|
||||
this.controller.setupWidget("txtCustomClientId",
|
||||
this.attributes = {
|
||||
hintText: $L("Your Service Client Id"),
|
||||
multiline: false,
|
||||
enterSubmits: false,
|
||||
autoReplace: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["CustomClientId"],
|
||||
disabled: !appModel.AppSettingsCurrent["UseCustomEndpoint"]
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("txtEndpointURL",
|
||||
this.attributes = {
|
||||
hintText: $L("http://your-server.com/"),
|
||||
multiline: false,
|
||||
enterSubmits: false,
|
||||
autoReplace: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["EndpointURL"],
|
||||
disabled: !appModel.AppSettingsCurrent["UseCustomEndpoint"]
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("txtShortURL",
|
||||
this.attributes = {
|
||||
hintText: $L("http://short.link/"),
|
||||
multiline: false,
|
||||
enterSubmits: false,
|
||||
autoReplace: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["ShortURL"],
|
||||
disabled: !appModel.AppSettingsCurrent["UseCustomEndpoint"]
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("txtCustomCreateKey",
|
||||
this.attributes = {
|
||||
hintText: $L("Your Service Create Key"),
|
||||
multiline: false,
|
||||
enterSubmits: false,
|
||||
autoReplace: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["CustomCreateKey"],
|
||||
disabled: !appModel.AppSettingsCurrent["UseCustomEndpoint"]
|
||||
}
|
||||
);
|
||||
//Drawer
|
||||
this.controller.setupWidget("drawerSelfHost",
|
||||
this.attributes = {
|
||||
modelProperty: 'open',
|
||||
unstyled: false
|
||||
},
|
||||
this.model = {
|
||||
open: appModel.AppSettingsCurrent["UseCustomEndpoint"]
|
||||
}
|
||||
);
|
||||
|
||||
//OK Button
|
||||
this.controller.setupWidget("btnOK", { type: Mojo.Widget.activityButton }, { label: "Done", disabled: false });
|
||||
//Menu
|
||||
this.appMenuAttributes = { omitDefaultItems: true };
|
||||
this.appMenuModel = {
|
||||
label: "Settings",
|
||||
items: [
|
||||
Mojo.Menu.editItem,
|
||||
{ label: "Reset Settings", command: 'do-resetSettings' }
|
||||
]
|
||||
};
|
||||
this.controller.setupWidget(Mojo.Menu.appMenu, this.appMenuAttributes, this.appMenuModel);
|
||||
|
||||
};
|
||||
|
||||
PreferencesAssistant.prototype.activate = function(event) {
|
||||
/* put in event handlers here that should only be in effect when this scene is active. For
|
||||
example, key handlers that are observing the document */
|
||||
|
||||
/* add event handlers to listen to events from widgets */
|
||||
Mojo.Event.listen(this.controller.get("listRefresh"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("toggleAutoDownload"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("listAutoDownloadTime"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("toggleCopyLinkOnShare"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("toggleForceHTTP"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("toggleCustomClientId"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("txtCustomClientId"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("toggleCustomEndPoint"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("txtEndpointURL"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("txtShortURL"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("txtCustomCreateKey"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("btnOK"), Mojo.Event.tap, this.okClick.bind(this));
|
||||
};
|
||||
|
||||
PreferencesAssistant.prototype.showBetaFeatures = function() {
|
||||
//No beta features right now
|
||||
}
|
||||
|
||||
PreferencesAssistant.prototype.handleValueChange = function(event) {
|
||||
|
||||
Mojo.Log.info(event.srcElement.id + " value changed to " + event.value);
|
||||
switch (event.srcElement.id) {
|
||||
case "toggleCustomClientId":
|
||||
{
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("txtCustomClientId");
|
||||
thisWidgetSetup.model.disabled = !event.value;
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
if (event.value)
|
||||
this.controller.get('txtCustomClientId').mojo.focus();
|
||||
break;
|
||||
}
|
||||
case "toggleAutoDownload":
|
||||
{
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("listAutoDownloadTime");
|
||||
thisWidgetSetup.model.disabled = !event.value;
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
break;
|
||||
}
|
||||
case "toggleCustomEndPoint":
|
||||
{
|
||||
//Toggle enabled on related text boxes
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("drawerSelfHost");
|
||||
thisWidgetSetup.model.open = event.value;
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("txtEndpointURL");
|
||||
thisWidgetSetup.model.disabled = !event.value;
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("txtShortURL");
|
||||
thisWidgetSetup.model.disabled = !event.value;
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("txtCustomCreateKey");
|
||||
thisWidgetSetup.model.disabled = !event.value;
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
if (event.value)
|
||||
this.controller.get('txtEndpointURL').mojo.focus();
|
||||
break;
|
||||
}
|
||||
case "txtEndpointURL":
|
||||
var lastChar = event.value[event.value.length - 1]
|
||||
if (lastChar != "/") {
|
||||
event.value = event.value + "/";
|
||||
Mojo.Log.warn("Custom end point URL was missing trailing slash, it has been added. Value is now: " + event.value);
|
||||
}
|
||||
if(!appModel.AppSettingsCurrent["ShortURL"] || appModel.AppSettingsCurrent["ShortURL"] == "") {
|
||||
this.controller.get('txtShortURL').mojo.setValue(event.value);
|
||||
appModel.AppSettingsCurrent["ShortURL"] = event.value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//We stashed the preference name in the title of the HTML element, so we don't have to use a case statement
|
||||
Mojo.Log.info(event.srcElement.title + " now: " + event.value);
|
||||
appModel.AppSettingsCurrent[event.srcElement.title] = event.value;
|
||||
appModel.SaveSettings();
|
||||
};
|
||||
|
||||
//Handle menu and button bar commands
|
||||
PreferencesAssistant.prototype.handleCommand = function(event) {
|
||||
if (event.type == Mojo.Event.command) {
|
||||
switch (event.command) {
|
||||
case 'do-goBack':
|
||||
Mojo.Controller.stageController.popScene();
|
||||
break;
|
||||
case 'do-resetSettings':
|
||||
appModel.ResetSettings(appModel.AppSettingsDefaults);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PreferencesAssistant.prototype.okClick = function(event) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.popScene();
|
||||
}
|
||||
|
||||
PreferencesAssistant.prototype.deactivate = function(event) {
|
||||
if (this.controller.get('txtEndpointURL').mojo.getValue() == "") {
|
||||
appModel.AppSettingsCurrent["UseCustomEndpoint"] = false;
|
||||
}
|
||||
appModel.SaveSettings();
|
||||
appModel.EstablishAlarms();
|
||||
|
||||
/* remove any event handlers you added in activate and do any other cleanup that should happen before
|
||||
this scene is popped or another scene is pushed on top */
|
||||
Mojo.Event.stopListening(this.controller.get("listRefresh"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("toggleAutoDownload"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("listAutoDownloadTime"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("toggleForceHTTP"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("toggleCustomClientId"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("txtCustomClientId"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("toggleCustomEndPoint"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("txtEndpointURL"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("txtShortURL"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("txtCustomCreateKey"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("btnOK"), Mojo.Event.tap, this.okClick);
|
||||
};
|
||||
|
||||
PreferencesAssistant.prototype.cleanup = function(event) {
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
Mojo.Additions = Additions;
|
||||
|
||||
function StageAssistant() {
|
||||
/* this is the creator function for your stage assistant object */
|
||||
}
|
||||
|
||||
StageAssistant.prototype.setup = function() {
|
||||
/* this function is for setup tasks that have to happen when the stage is first created */
|
||||
this.controller.pushScene({ name: "main" });
|
||||
this.controller.setWindowOrientation("free");
|
||||
};
|
||||
@@ -2,29 +2,41 @@ function VersionAssistant(startup) {
|
||||
this.isStartup = startup;
|
||||
|
||||
// on first start, this message is displayed, along with the current version message from below
|
||||
this.startupMessage = $L("<img src='icon.png' style='float:left; margin-right:8px'>Welcome to SimpleChat! We're so excited you're here chatting with us 10 years after this platform was supposed to have died!<br>You can also join this chat from Discord: <a href='discord.gg/7NrrT8exrn'>discord.gg/7NrrT8exrn</a> or view the log on the web: <a href='http://chat.webosarchive.com'>chat.webosarchive.com</a>");
|
||||
this.startupMessage = Mojo.Controller.appInfo.startupMessage;
|
||||
|
||||
//New Features
|
||||
this.changelog = [{
|
||||
version: "Version 1.1.3",
|
||||
detail: [
|
||||
"Bug fixes and general maintenance"
|
||||
]
|
||||
}, {
|
||||
version: "Version 1.1.2",
|
||||
detail: [
|
||||
"Show/Hide the Command menu buttons by tapping the Compose area title bar",
|
||||
"Enable/Disable Discord Emojis in Preferences",
|
||||
]
|
||||
}, {
|
||||
version: "Version 1.1.1",
|
||||
detail: [
|
||||
"Improved Discord integration, including showing Emojis!<span class='emoji-outer emoji-sizer'><span class='emoji-inner emoji1f388'></span></span>",
|
||||
"Now with a smaller emoji file!",
|
||||
"Improved timeout logic.",
|
||||
"Trying different background sync logic."
|
||||
]
|
||||
}];
|
||||
this.changelog = [
|
||||
{
|
||||
version: "Version 1.0.2 Changes",
|
||||
detail: [
|
||||
"Fixes a bug that prevents background downloads when Always Use HTTP is on",
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "Version 1.0.1 Changes",
|
||||
detail: [
|
||||
"Add download button to detail scene",
|
||||
"Fix a layout issue",
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "Version 1.0.0 Features",
|
||||
detail: [
|
||||
"Wirelessly add photos to Exhibition from anywhere with automatic downloads -- just turn it on in Preferences (requires FileMgr)",
|
||||
"Touch2Share content between your devices, either loading it in a web page, or right in the app (turn on 'Handle URLs' in the menu)",
|
||||
"Share photos you take on your device via email, text message, or other web apps by copying the link the app makes for you -- grab it from the content detail scene, or turn on 'Copy Link on Share' in Preferences",
|
||||
"Start a new share from JustType -- turn it on in your JustType settings",
|
||||
"Host your own server for more control and privacy!"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "Coming Soon",
|
||||
detail: [
|
||||
"Shared Clipboard mode will minimize to a Dashboard to make it quick and easy to share text and links between your devices",
|
||||
"Share with other users, without needing to log out and back in",
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// setup command menu
|
||||
this.cmdMenuModel = {
|
||||
@@ -0,0 +1,68 @@
|
||||
function WelcomeAssistant(startup) {
|
||||
this.isStartup = startup;
|
||||
|
||||
// on first start, this message is displayed, along with the current version message from below
|
||||
//this.startupMessage = Mojo.Controller.appInfo.startupMessage;
|
||||
this.startupMessage = "Your account has been created!";
|
||||
|
||||
// setup command menu
|
||||
this.cmdMenuModel = {
|
||||
visible: false,
|
||||
items: [
|
||||
{},
|
||||
{
|
||||
label: $L("Got it!"),
|
||||
command: 'do-continue'
|
||||
},
|
||||
{}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
WelcomeAssistant.prototype.setup = function() {
|
||||
//this.titleElement = this.controller.get('title');
|
||||
this.dataElement = this.controller.get('welcome-data');
|
||||
|
||||
//this.titleElement.innerHTML = $L('Version Info');
|
||||
|
||||
var useURL = serviceModel.buildURL(null, "");
|
||||
useURL = useURL.replace(".php", "");
|
||||
var html = '<p>';
|
||||
html += '<b>Name:</b> <em>' + appModel.AppSettingsCurrent["Username"] + "</em><br>";
|
||||
html += '<b>Share Phrase:</b> <em>' + appModel.AppSettingsCurrent["SharePhrase"] + "</em><br>";
|
||||
html += '<b>Admin Password:</b> <em>' + appModel.AppSettingsCurrent["Credential"] + "</em><br>";
|
||||
html += '<b>URL:</b> <em>' + useURL + "</em><br></p>";
|
||||
|
||||
// set data
|
||||
this.dataElement.innerHTML = html;
|
||||
|
||||
// setup menu
|
||||
this.controller.setupWidget(Mojo.Menu.appMenu, { omitDefaultItems: true }, { visible: false });
|
||||
|
||||
//if (this.isStartup) {
|
||||
// set command menu
|
||||
this.controller.setupWidget(Mojo.Menu.commandMenu, { menuClass: 'no-fade' }, this.cmdMenuModel);
|
||||
//}
|
||||
};
|
||||
|
||||
WelcomeAssistant.prototype.activate = function(event) {
|
||||
this.timer = this.controller.window.setTimeout(this.showContinue.bind(this), 4 * 1000);
|
||||
};
|
||||
WelcomeAssistant.prototype.deactivate = function(event) {};
|
||||
WelcomeAssistant.prototype.cleanup = function(event) {};
|
||||
|
||||
WelcomeAssistant.prototype.showContinue = function() {
|
||||
// show the command menu
|
||||
this.controller.setMenuVisible(Mojo.Menu.commandMenu, true);
|
||||
};
|
||||
|
||||
WelcomeAssistant.prototype.handleCommand = function(event) {
|
||||
if (event.type == Mojo.Event.command) {
|
||||
switch (event.command) {
|
||||
case 'do-continue':
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.swapScene({ transition: Mojo.Transition.zoomFade, name: "main" });
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -2,14 +2,18 @@
|
||||
Mojo Additions
|
||||
Version 0.3e
|
||||
Created: 2018
|
||||
Author: Jonathan Wise
|
||||
Author: Jon W
|
||||
License: MIT
|
||||
Description: Functions I use often, that probably should have been part of Mojo.
|
||||
They either fix bugs in Mojo or make it easier to use.
|
||||
*/
|
||||
|
||||
//** Note: If you synced this file from a common repository, local edits may be over-written! */
|
||||
|
||||
this.Additions = function() {}
|
||||
|
||||
Mojo.Log.info("#### Mojo Additions added");
|
||||
|
||||
Additions.ShowDialogBox = function(title, message) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
if (stageController) {
|
||||
@@ -20,7 +24,6 @@ Additions.ShowDialogBox = function(title, message) {
|
||||
title: title,
|
||||
message: message,
|
||||
choices: [{ label: 'OK', value: 'OK' }],
|
||||
preventCancel: true,
|
||||
allowHTMLMessage: true
|
||||
});
|
||||
}
|
||||
@@ -62,6 +65,16 @@ Additions.SetWidgetLabel = function(widgetName, newvalue) {
|
||||
}
|
||||
}
|
||||
|
||||
Additions.GetWidgetLabel = function(widgetName) {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
if (stageController) {
|
||||
this.controller = stageController.activeScene();
|
||||
|
||||
var thisWidgetModel = this.controller.getWidgetSetup(widgetName).model;
|
||||
return thisWidgetModel.label;
|
||||
}
|
||||
}
|
||||
|
||||
Additions.SetToggleState = function(widgetName, toggledValue) {
|
||||
var stageController = Mojo.Controller.getAppController().getStageController("");
|
||||
if (stageController) {
|
||||
@@ -2,7 +2,6 @@
|
||||
App Model
|
||||
Version 0.4
|
||||
Created: 2018
|
||||
Author: Jonathan Wise
|
||||
License: MIT
|
||||
Description: Common functions for webOS apps, particularly for managing persisted options in cookies
|
||||
*/
|
||||
@@ -12,31 +11,113 @@ var AppModel = function() {
|
||||
this.DefaultScene = "main";
|
||||
|
||||
//Define your app-wide, non-persisted settings here
|
||||
this.UpdateCheckDone = false;
|
||||
this.LaunchQuery = "";
|
||||
this.ServiceEndpointBase = "http://chat.webosarchive.com/";
|
||||
this.ClientId = secrets.clientid;
|
||||
this.LastMessageSelected = null;
|
||||
this.LastShareSelected = null;
|
||||
this.CurrentShareURL = null;
|
||||
this.FileMgrPresent = true;
|
||||
|
||||
//Define your app preferences (to be saved by OS)
|
||||
this.AppSettingsCurrent = null;
|
||||
this.AppSettingsDefaults = {
|
||||
ForegroundUpdate: 10000,
|
||||
BackgroundUpdate: "00:30:00",
|
||||
AlertSound: "Subtle (short)",
|
||||
ShowEmojis: true,
|
||||
UseClientAPIKey: false,
|
||||
Username: "",
|
||||
Credential: "",
|
||||
SharePhrase: "",
|
||||
RefreshTimeout: 60000,
|
||||
UseAutoDownload: false,
|
||||
AutoDownloadTime: "01:00:00",
|
||||
CopyLinkOnShare: true,
|
||||
ForceHTTP: false,
|
||||
UseCustomEndpoint: false,
|
||||
ClientAPIKey: "",
|
||||
EndpointURL: "",
|
||||
SenderName: "webOS User",
|
||||
FirstRun: true,
|
||||
MyMessages: null,
|
||||
LastKnownMessage: null,
|
||||
LastVersionRun: 0
|
||||
ShortURL: "",
|
||||
UseCustomClientId: false,
|
||||
CustomClientId: "",
|
||||
CustomCreateKey: "",
|
||||
UseCustomDownloadPath: false,
|
||||
CustomDownloadPath: null,
|
||||
LastVersionRun: "0.0.1",
|
||||
DebugMode: false,
|
||||
};
|
||||
}
|
||||
|
||||
AppModel.prototype.ShowDownloaderStage = function() {
|
||||
Mojo.Log.info("App Model checking if we should to show Dashboard stage...");
|
||||
this.serviceEndpointBase = appModel.ServiceEndpointBase;
|
||||
if (appModel.AppSettingsCurrent["UseCustomEndpoint"] && appModel.AppSettingsCurrent["EndpointURL"]) {
|
||||
this.serviceEndpointBase = appModel.AppSettingsCurrent["EndpointURL"];
|
||||
}
|
||||
//Check for connectivity, then check for messages
|
||||
systemModel.GetInternetConnectionState(this.checkForMessages.bind(this));
|
||||
}
|
||||
|
||||
AppModel.prototype.checkForMessages = function(connMgrResponse) {
|
||||
Mojo.Log.info("App Model got response from connection manager: " + JSON.stringify(connMgrResponse));
|
||||
if (connMgrResponse && connMgrResponse.isInternetConnectionAvailable) {
|
||||
this.actuallyShowDownloaderStage();
|
||||
}
|
||||
}
|
||||
|
||||
AppModel.prototype.actuallyShowDownloaderStage = function() {
|
||||
this.controller = Mojo.Controller.getAppController();
|
||||
var dashboardStage = this.controller.getStageProxy("download");
|
||||
var pushDashScene = function(stageController) {
|
||||
stageController.pushScene('download', "download/download-scene");
|
||||
}.bind(this);
|
||||
|
||||
if (!dashboardStage) {
|
||||
Mojo.Log.info("Download dashboard not open, creating it...");
|
||||
this.controller.createStageWithCallback({
|
||||
name: 'download',
|
||||
lightweight: true,
|
||||
height: 100,
|
||||
soundclass: "assets/silent.mp3"
|
||||
}, pushDashScene, 'dashboard');
|
||||
} else {
|
||||
Mojo.Log.info("Download dashboard already open, activating it...");
|
||||
var dashboardStageController = this.controller.getStageController("download");
|
||||
if (dashboardStageController) {
|
||||
dashboardStageController.activate();
|
||||
dashboardStageController.delegateToSceneAssistant("activate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AppModel.prototype.CloseDashboardStageByName = function(stageName) {
|
||||
this.controller = Mojo.Controller.getAppController();
|
||||
var dashboardStage = this.controller.getStageProxy(stageName);
|
||||
|
||||
if (!dashboardStage) {
|
||||
Mojo.Log.info(stageName + " dashboard not open, nothing to do");
|
||||
} else {
|
||||
Mojo.Log.info(stageName + " dashboard open, closing it...");
|
||||
this.controller.closeStage(stageName);
|
||||
}
|
||||
}
|
||||
|
||||
AppModel.prototype.EstablishAlarms = function() {
|
||||
//Reset alarms
|
||||
systemModel.ClearSystemAlarm("BackgroundDownload");
|
||||
if (appModel.AppSettingsCurrent["UseAutoDownload"] && appModel.AppSettingsCurrent["Username"] != "" && appModel.AppSettingsCurrent["Credential"]) {
|
||||
Mojo.Log.warn("Re-establishing background download alarm with time: " + appModel.AppSettingsCurrent["AutoDownloadTime"]);
|
||||
systemModel.SetSystemAlarmRelative("BackgroundDownload", appModel.AppSettingsCurrent["AutoDownloadTime"]);
|
||||
} else {
|
||||
Mojo.Log.warn("Not setting background download alarm since conditions weren't met.");
|
||||
}
|
||||
}
|
||||
|
||||
AppModel.prototype.ConvertTimeStamp = function(timeStamp, isUTC) {
|
||||
if (isUTC) {
|
||||
var offset = new Date().getTimezoneOffset();
|
||||
timeStamp = Date.parse(timeStamp);
|
||||
timeStamp = timeStamp - ((offset * 60) * 1000);
|
||||
timeStamp = new Date(timeStamp);
|
||||
}
|
||||
timeStamp = timeStamp.toLocaleString();
|
||||
timeStamp = timeStamp.split("GMT");
|
||||
timeStamp = timeStamp[0];
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
//You probably don't need to change the below functions since they all work against the Cookie defaults you defined above.
|
||||
// LoadSettings: call when your app starts, or you want to load previously persisted options.
|
||||
// SaveSettings: call any time you want to persist an option.
|
||||
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
ShareBoard Model - Mojo
|
||||
Version 1.0
|
||||
Created: 2021
|
||||
License: MIT
|
||||
Description: A model to interact with a share service
|
||||
*/
|
||||
|
||||
var ShareServiceModel = function() {
|
||||
this.urlBase = Mojo.Controller.appInfo.serviceURL;
|
||||
this.shortUrlBase = Mojo.Controller.appInfo.shortURL;
|
||||
};
|
||||
|
||||
//Properties
|
||||
ShareServiceModel.prototype.ForceHTTP = false;
|
||||
ShareServiceModel.prototype.UseCustomShare = false;
|
||||
ShareServiceModel.prototype.UseCustomEndpoint = false;
|
||||
ShareServiceModel.prototype.CustomEndpointURL = "";
|
||||
ShareServiceModel.prototype.CustomShortURL = "";
|
||||
ShareServiceModel.prototype.CustomCreateKey = "";
|
||||
ShareServiceModel.prototype.UseCustomClientId = false;
|
||||
ShareServiceModel.prototype.CustomClientId = "";
|
||||
//ShareServiceModel.prototype.ServiceCompatWarning = 0;
|
||||
|
||||
ShareServiceModel.prototype.buildURL = function(username, actionType) {
|
||||
var urlBase = this.urlBase;
|
||||
if (this.UseCustomEndpoint == true && this.CustomEndpointURL != "") {
|
||||
urlBase = this.CustomEndpointURL;
|
||||
}
|
||||
//Make sure we don't end up with double slashes in the built URL if there's a custom endpoint
|
||||
var urlTest = urlBase.split("://");
|
||||
if (urlTest[urlTest.length - 1].indexOf("/") != -1) {
|
||||
urlBase = urlBase.substring(0, urlBase.length - 1);
|
||||
}
|
||||
var path = urlBase + "/" + actionType + ".php";
|
||||
if (username)
|
||||
path += "?username=" + username;
|
||||
if (this.ForceHTTP)
|
||||
path = path.replace ("https:", "http:");
|
||||
return path;
|
||||
}
|
||||
|
||||
ShareServiceModel.prototype.MakeShareURL = function(username, guid, type) {
|
||||
var urlBase = this.shortUrlBase;
|
||||
if (this.CustomShortURL == true && this.CustomShortURL != "") {
|
||||
urlBase = this.CustomShortURL;
|
||||
}
|
||||
if (type.indexOf("image") != -1)
|
||||
urlBase = urlBase + "download.php?";
|
||||
else
|
||||
urlBase = urlBase + "t.php?";
|
||||
var data = username + "|" + guid;
|
||||
data = btoa(data);
|
||||
urlBase = urlBase + data;
|
||||
if (urlBase.indexOf("==") == urlBase.length - 2)
|
||||
urlBase = urlBase.slice(0, urlBase.length - 2)
|
||||
return urlBase;
|
||||
}
|
||||
|
||||
//HTTP request for list files
|
||||
ShareServiceModel.prototype.DoShareListRequest = function(username, credential, callback, errorhandler) {
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
if (!errorhandler) {
|
||||
errorhandler = function(errorText) {
|
||||
Mojo.Log.warn(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: errorText }, "", "");
|
||||
}
|
||||
} else {
|
||||
errorhandler = errorhandler.bind(this);
|
||||
}
|
||||
var useURL = this.buildURL(username, "get-shares");
|
||||
Mojo.Log.info("Calling sharing service at " + useURL + " with key " + this.getCurrentClientKey());
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", useURL);
|
||||
xmlhttp.setRequestHeader("client-id", this.getCurrentClientKey());
|
||||
xmlhttp.setRequestHeader("credential", credential);
|
||||
xmlhttp.send();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (xmlhttp.status >= 400) {
|
||||
errorhandler(xmlhttp.status + " Error getting share list: " + responseObj.error, callback);
|
||||
return false;
|
||||
} else {
|
||||
if (xmlhttp.responseText && xmlhttp.responseText != "") {
|
||||
try {
|
||||
var responseObj = JSON.parse(xmlhttp.responseText);
|
||||
if (responseObj.error) {
|
||||
errorhandler("Share service error: " + responseObj.error, callback);
|
||||
return false;
|
||||
} else {
|
||||
//Mojo.Log.info("Share List success! " + xmlhttp.responseText);
|
||||
if (callback) {
|
||||
callback(responseObj);
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Shares retreived!" }, "", "");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (ex) {
|
||||
errorhandler("Error parsing share list response: " + ex + ", response: " + xmlhttp.responseText, callback);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
errorhandler("Share list response was empty", callback);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
//HTTP request for add file
|
||||
ShareServiceModel.prototype.DoShareAddRequestText = function(content, username, credential, contenttype, callback, errorhandler) {
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
if (!errorhandler) {
|
||||
errorhandler = function(errorText) {
|
||||
Mojo.Log.warn(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: errorText }, "", "");
|
||||
}
|
||||
}
|
||||
var useURL = this.buildURL(username, "share-text");
|
||||
Mojo.Log.info("Adding text share: " + content + " of type " + contenttype + " from URL " + useURL);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("POST", useURL);
|
||||
xmlhttp.setRequestHeader("client-id", this.getCurrentClientKey());
|
||||
xmlhttp.setRequestHeader("credential", credential);
|
||||
xmlhttp.setRequestHeader("content-type", contenttype);
|
||||
xmlhttp.send(content);
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (xmlhttp.status >= 400) {
|
||||
errorhandler(xmlhttp.status + " Error adding share text: " + responseObj.error);
|
||||
return false;
|
||||
} else {
|
||||
Mojo.Log.info("Share service sent response while sharing text: " + xmlhttp.responseText);
|
||||
if (xmlhttp.responseText && xmlhttp.responseText != "") {
|
||||
try {
|
||||
var responseObj = JSON.parse(xmlhttp.responseText);
|
||||
if (responseObj.error) {
|
||||
errorhandler("Error sharing text: " + responseObj.error);
|
||||
return false;
|
||||
} else {
|
||||
Mojo.Log.info("Share text success! " + xmlhttp.responseText);
|
||||
if (callback) {
|
||||
callback(responseObj);
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Content shared!" }, "", "");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (ex) {
|
||||
errorhandler("Error parsing add share response: " + ex);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
errorhandler("Add share response was empty");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
//Upload a file
|
||||
ShareServiceModel.prototype.DoShareAddRequestImage = function (fullFilePath, username, credential, contenttype, callback, errorhandler) {
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
if (!errorhandler) {
|
||||
errorhandler = function(errorText) {
|
||||
Mojo.Log.warn(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: errorText }, "", "");
|
||||
}
|
||||
}
|
||||
var useURL = this.buildURL(username, "share-image");
|
||||
Mojo.Log.info("Adding image share: " + fullFilePath + " of type " + contenttype + " from URL " + useURL);
|
||||
|
||||
this.uploadRequest = new Mojo.Service.Request('palm://com.palm.downloadmanager/', {
|
||||
method: 'upload',
|
||||
parameters: {
|
||||
fileName: fullFilePath,
|
||||
url: useURL,
|
||||
fileLabel: "image",
|
||||
contentType: contenttype,
|
||||
postParameters: [
|
||||
{"key":"username", "data": username},
|
||||
{"key":"credential" , "data": credential},
|
||||
],
|
||||
customHttpHeaders : [
|
||||
'client-id: ' + this.getCurrentClientKey(),
|
||||
],
|
||||
subscribe: true
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
Mojo.Log.info("Upload progress", JSON.stringify(response));
|
||||
if ((response.completed && response.completed == true) || (response.completionCode && response.completionCode != 0)) {
|
||||
if (response.error) {
|
||||
errorhandler(response.error);
|
||||
return false;
|
||||
} else if (response.completionCode && response.completionCode != 0) {
|
||||
var errMsg = "error code " + response.completionCode;
|
||||
switch(Math.abs(response.completionCode)) {
|
||||
case 1:
|
||||
errMsg = "General Error";
|
||||
break;
|
||||
case 2:
|
||||
errMsg = "Connection Timeout";
|
||||
break;
|
||||
case 3:
|
||||
errMsg = "Corrupt File";
|
||||
break;
|
||||
case 4:
|
||||
errMsg = "File System Error";
|
||||
break;
|
||||
case 5:
|
||||
errMsg = "HTTP Error";
|
||||
break;
|
||||
case 6:
|
||||
errMsg = "Connection Offline";
|
||||
break;
|
||||
}
|
||||
errorhandler(errMsg);
|
||||
return false;
|
||||
} else {
|
||||
if (response.responseString) {
|
||||
Mojo.Log.info("Upload response: " + response.responseString);
|
||||
var responseObj = JSON.parse(response.responseString);
|
||||
if (responseObj.error) {
|
||||
errorhandler(responseObj.error);
|
||||
return false;
|
||||
} else {
|
||||
if (callback) {
|
||||
callback(responseObj);
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Image uploaded!" }, "", "");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
errorhandler("Error uploading image: server response was empty");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onFailure: function(response) {
|
||||
errorhandler("Error uploading image share: " + response);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//HTTP request for list files
|
||||
ShareServiceModel.prototype.DoShareDeleteRequest = function(itemid, username, credential, callback, errorhandler) {
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
if (!errorhandler) {
|
||||
errorhandler = function(errorText) {
|
||||
Mojo.Log.warn(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: errorText }, "", "");
|
||||
}
|
||||
}
|
||||
var useURL = this.buildURL(username, "delete-share-item");
|
||||
Mojo.Log.info("Calling sharing service at " + useURL + " for item " + itemid + " with key " + this.getCurrentClientKey());
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", useURL);
|
||||
xmlhttp.setRequestHeader("client-id", this.getCurrentClientKey());
|
||||
xmlhttp.setRequestHeader("credential", credential);
|
||||
xmlhttp.setRequestHeader("itemid", itemid);
|
||||
xmlhttp.send();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (xmlhttp.status >= 400) {
|
||||
errorhandler(xmlhttp.status + " Error deleting share: " + responseObj.error);
|
||||
return false;
|
||||
} else {
|
||||
Mojo.Log.info("Share service sent response while deleting share: " + xmlhttp.responseText);
|
||||
if (xmlhttp.responseText && xmlhttp.responseText != "") {
|
||||
try {
|
||||
var responseObj = JSON.parse(xmlhttp.responseText);
|
||||
if (responseObj.error) {
|
||||
errorhandler("Error deleting share: " + responseObj.error);
|
||||
return false;
|
||||
} else {
|
||||
Mojo.Log.info("Share Delete success! " + xmlhttp.responseText);
|
||||
if (callback) {
|
||||
callback(responseObj);
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Content deleted!" }, "", "");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (ex) {
|
||||
errorhandler("Error parsing delete share response: " + ex);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
errorhandler("Delete share response was empty");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
//HTTP request for new user
|
||||
ShareServiceModel.prototype.DoNewUserRequest = function(username, sharephrase, password, callback, errorhandler) {
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
if (!errorhandler) {
|
||||
errorhandler = function(errorText) {
|
||||
Mojo.Log.warn(errorText);
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: errorText }, "", "");
|
||||
}
|
||||
}
|
||||
var useURL = this.buildURL(null, "new-user");
|
||||
Mojo.Log.info("Creating user: " + username + " with share-phrase " + sharephrase + " and password " + password + " from URL " + useURL);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("POST", useURL);
|
||||
xmlhttp.setRequestHeader("client-id", this.getCurrentClientKey());
|
||||
var request = {
|
||||
"username":username,
|
||||
"sharephrase":sharephrase,
|
||||
"password":password,
|
||||
"createkey":this.getCurrentCreateKey()
|
||||
}
|
||||
xmlhttp.send(JSON.stringify(request));
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (xmlhttp.status >= 400) {
|
||||
errorhandler(xmlhttp.status + " Error creating user: " + responseObj.error);
|
||||
return false;
|
||||
} else {
|
||||
Mojo.Log.info("Share service sent response while creating user: " + xmlhttp.responseText);
|
||||
if (xmlhttp.responseText && xmlhttp.responseText != "") {
|
||||
try {
|
||||
var responseObj = JSON.parse(xmlhttp.responseText);
|
||||
if (responseObj.error) {
|
||||
errorhandler("Error creating user: " + responseObj.error);
|
||||
return false;
|
||||
} else {
|
||||
Mojo.Log.info("New user success! " + xmlhttp.responseText);
|
||||
if (callback) {
|
||||
callback(responseObj);
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "User created!" }, "", "");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (ex) {
|
||||
errorhandler("Error parsing create user response: " + ex);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
errorhandler("Create user response was empty");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
//HTTP request to get Terms and Conditions
|
||||
ShareServiceModel.prototype.GetTnC = function(callback) {
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
|
||||
var useURL = this.buildURL(null, "tandc");
|
||||
Mojo.Log.info("Getting Terms and Conditions with query: " + useURL);
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", useURL);
|
||||
xmlhttp.send();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (callback)
|
||||
callback(xmlhttp.responseText);
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
//HTTP request to get random share phrase
|
||||
ShareServiceModel.prototype.GetRandomWords = function(callback) {
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
|
||||
var theQuery = this.buildURL(null, "random-words");
|
||||
Mojo.Log.info("Getting Random words query: " + theQuery);
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", theQuery);
|
||||
xmlhttp.send();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (callback)
|
||||
callback(xmlhttp.responseText);
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
//HTTP request to get random share phrase
|
||||
ShareServiceModel.prototype.QueryShareData = function(query, callback) {
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
|
||||
var theQuery = query;
|
||||
theQuery = theQuery.replace("download.php", "q.php");
|
||||
theQuery = theQuery.replace("image.php", "q.php");
|
||||
theQuery = theQuery.replace("t.php", "q.php");
|
||||
Mojo.Log.warn("Querying share item with URL: " + theQuery);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", theQuery);
|
||||
xmlhttp.send();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
try {
|
||||
var itemData = JSON.parse(xmlhttp.responseText);
|
||||
if (callback)
|
||||
callback(itemData);
|
||||
} catch (ex) {
|
||||
Mojo.Log.error("Got bad item query response payload: " + ex, xmlhttp.responseText);
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
ShareServiceModel.prototype.getCurrentClientKey = function() {
|
||||
var retVal = atob(appKeys['shareBoardClientKey']);
|
||||
if (this.UseCustomEndpoint) {
|
||||
retVal = this.CustomClientId;
|
||||
Mojo.Log.info("Using custom shareboard client key: " + retVal);
|
||||
}
|
||||
//Mojo.Log.info("Using shareboard client key: " + retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
ShareServiceModel.prototype.getCurrentCreateKey = function() {
|
||||
var retVal = atob(appKeys['shareBoardCreateKey']);
|
||||
if (this.UseCustomEndpoint) {
|
||||
retVal = this.CustomCreateKey;
|
||||
Mojo.Log.info("Using custom shareboard create key: " + retVal);
|
||||
}
|
||||
//Mojo.Log.info("Using shareboard create key: " + retVal);
|
||||
return retVal;
|
||||
}
|
||||
@@ -1,16 +1,42 @@
|
||||
/*
|
||||
System Model
|
||||
Version 1.2
|
||||
Created: 2021
|
||||
Author: Jonathan Wise
|
||||
Version 1.6
|
||||
Created: 2022
|
||||
Author: Jon W
|
||||
License: MIT
|
||||
Description: A generic and re-usable model for accessing webOS system features more easily
|
||||
Privileged functions can only be called if your App ID starts with com.palm
|
||||
*/
|
||||
|
||||
var SystemModel = function() {
|
||||
//** Note: If you synced this file from a common repository, local edits may be over-written! */
|
||||
|
||||
var SystemModel = function() {
|
||||
|
||||
};
|
||||
SystemModel.WOSAPrefs = {};
|
||||
|
||||
//You should probably use Mojo.Environment.DeviceInfo for this
|
||||
// http://sdk.webosarchive.org/docs/docs.html#reference/mojo/classes/mojo-environment.html#summary
|
||||
SystemModel.prototype.DetectDevice = function() {
|
||||
//find out what kind of device this is
|
||||
var deviceType;
|
||||
if (Mojo.Environment.DeviceInfo.platformVersionMajor >= 3) {
|
||||
deviceType = "TouchPad";
|
||||
Mojo.Log.info("Device detected as TouchPad");
|
||||
} else {
|
||||
if (window.screen.width == 800 || window.screen.height == 800) {
|
||||
deviceType = "Pre3";
|
||||
Mojo.Log.info("Device detected as Pre3");
|
||||
} else if ((window.screen.width == 480 || window.screen.height == 480) && (window.screen.width == 320 || window.screen.height == 320)) {
|
||||
deviceType = "Pre";
|
||||
Mojo.Log.info("Device detected as Pre or Pre2");
|
||||
} else {
|
||||
deviceType = "Tiny";
|
||||
Mojo.Log.info("Device detected as Pixi or Veer");
|
||||
}
|
||||
}
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
//Create a named System Alarm using relative time ("in")
|
||||
SystemModel.prototype.SetSystemAlarmRelative = function(alarmName, alarmTime) {
|
||||
@@ -82,15 +108,20 @@ SystemModel.prototype.ClearSystemAlarm = function(alarmName) {
|
||||
|
||||
//Allow the display to sleep
|
||||
SystemModel.prototype.AllowDisplaySleep = function(stageController) {
|
||||
if (!stageController)
|
||||
stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
try {
|
||||
if (!stageController)
|
||||
stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
|
||||
//Tell the System it doesn't have to stay awake any more
|
||||
Mojo.Log.info("Allowing display sleep");
|
||||
//Tell the System it doesn't have to stay awake any more
|
||||
Mojo.Log.info("Allowing display sleep");
|
||||
|
||||
stageController.setWindowProperties({
|
||||
blockScreenTimeout: false
|
||||
});
|
||||
stageController.setWindowProperties({
|
||||
blockScreenTimeout: false
|
||||
});
|
||||
} catch(e) {
|
||||
//If the stage has already gone away, this function will return an error
|
||||
// But it doesn't matter because webOS will perform this function anyway during stage clean-up
|
||||
}
|
||||
}
|
||||
|
||||
//Prevent the display from sleeping
|
||||
@@ -108,6 +139,7 @@ SystemModel.prototype.PreventDisplaySleep = function(stageController) {
|
||||
|
||||
//Show a notification window in its own small stage
|
||||
// Launches with sound: pass true for default, false for no sound, or pass the path to a specific sound file
|
||||
// Note: This implementation will not work for pure background notifications as it requires the app to be active
|
||||
SystemModel.prototype.ShowNotificationStage = function(stageName, sceneName, heightToUse, sound, vibrate) {
|
||||
Mojo.Log.info("Showing notification stage.");
|
||||
//Determine what sound to use
|
||||
@@ -153,14 +185,34 @@ SystemModel.prototype.PlaySound = function(soundName) {
|
||||
}
|
||||
|
||||
//Play an alert sound
|
||||
//Note: If you want more control, include an HTML5 audio tag with the id "audioPlayer"
|
||||
// Otherwise a system function will be used
|
||||
SystemModel.prototype.PlayAlertSound = function(sound) {
|
||||
if (!sound || sound == "") {
|
||||
sound = "Subtle (short)";
|
||||
}
|
||||
if (sound != "off") {
|
||||
var soundPath = "/media/internal/ringtones/" + sound + ".mp3";
|
||||
Mojo.Log.info("trying to play: " + soundPath);
|
||||
Mojo.Controller.getAppController().playSoundNotification("media", soundPath, 2500);
|
||||
if (sound.indexOf("/") != -1)
|
||||
soundPath = sound;
|
||||
|
||||
var audioPlayer = document.getElementById("audioPlayer");
|
||||
if (audioPlayer) {
|
||||
Mojo.Log.info("Playing notification sound " + soundPath + " using audioPlayer element");
|
||||
if (soundPath) {
|
||||
Mojo.Log.info("trying to play audio: " + soundPath);
|
||||
audioPlayer.src = soundPath;
|
||||
audioPlayer.load();
|
||||
}
|
||||
audioPlayer.play();
|
||||
} else {
|
||||
Mojo.Log.warn("No audio element named audioPlayer, using notification sound to play " + soundPath);
|
||||
if (!sound || sound == "") {
|
||||
sound = "Subtle (short)";
|
||||
}
|
||||
Mojo.Log.info("trying to play: " + soundPath);
|
||||
Mojo.Controller.getAppController().playSoundNotification("media", soundPath, 2500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,11 +228,26 @@ SystemModel.prototype.Vibrate = function(vibrate) {
|
||||
} else
|
||||
vibeMax = Number(vibrate);
|
||||
if (vibeMax > 0)
|
||||
vibeInterval = setInterval(doVibrate, 500);
|
||||
vibeInterval = window.setInterval(doVibrate, 500);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//Lock the physical volume buttons to the media volume (instead of default, notification volume)
|
||||
SystemModel.prototype.LockVolumeKeys = function() {
|
||||
Mojo.Log.info("Locking media volume to hardware buttons");
|
||||
this.wakeupRequest = new Mojo.Service.Request("palm://com.palm.audio/media", {
|
||||
method: "lockVolumeKeys",
|
||||
onSuccess: function(response) {
|
||||
Mojo.Log.info("Lock Volume Keys Success", JSON.stringify(response));
|
||||
},
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Lock Volume Keys Failure: ", JSON.stringify(response));
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
//Launch an app
|
||||
SystemModel.prototype.LaunchApp = function(appName, params) {
|
||||
if (!params)
|
||||
@@ -194,12 +261,148 @@ SystemModel.prototype.LaunchApp = function(appName, params) {
|
||||
Mojo.Log.info("App Launch Success", appName, JSON.stringify(response));
|
||||
},
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Alarm Launch Failure", appName, JSON.stringify(response));
|
||||
Mojo.Log.error("App Launch Failure", appName, JSON.stringify(response));
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
//Use in combination with a Touch2Share launch to send a URI to a tapped device
|
||||
SystemModel.prototype.SendDataForTouch2Share = function(url, callback) {
|
||||
if (!url) {
|
||||
Mojo.Log.error("Share URL not supplied");
|
||||
return false;
|
||||
}
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
var params = {data: { target: url, type: "rawdata", mimetype: "text/html" }};
|
||||
Mojo.Log.info("Touch2Share payload is ", JSON.stringify(params));
|
||||
|
||||
this.shareRequest = new Mojo.Service.Request("palm://com.palm.stservice", {
|
||||
method: "shareData",
|
||||
parameters: params,
|
||||
subscribe: true,
|
||||
onSuccess: function(response) {
|
||||
Mojo.Log.info("Touch2Share Success!", JSON.stringify(response));
|
||||
if (callback) {
|
||||
callback(response);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Touch2Share Failure: ", JSON.stringify(response));
|
||||
if (callback) {
|
||||
callback(response);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
//Download a file
|
||||
//A fire-and-forget way to interact with the DownloadManager. The user will get a generic notification when the download is complete.
|
||||
SystemModel.prototype.DownloadFile = function (url, mimetype, pathFromInteral, fileName, subscribe, callback) {
|
||||
if (!url) {
|
||||
Mojo.Log.error("Download URL not supplied");
|
||||
return false;
|
||||
}
|
||||
if (!pathFromInteral){
|
||||
Mojo.Log.error("Save path not supplied");
|
||||
return false;
|
||||
}
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
|
||||
//Figure out what extension to use
|
||||
var ext = "";
|
||||
mimetype = mimetype.toLowerCase();
|
||||
if (mimetype.indexOf("image/") != -1) {
|
||||
if (mimetype == "image/jpeg")
|
||||
ext = "jpg"
|
||||
else {
|
||||
ext = mimetype.split("/");
|
||||
ext = ext[ext.length - 1];
|
||||
}
|
||||
} else if (mimetype == "text/plain") {
|
||||
ext = "txt";
|
||||
} else if (mimetype == "application/json") {
|
||||
ext = "json";
|
||||
} else {
|
||||
if (mimetype.indexOf("/") != -1) {
|
||||
ext = mimetype.split("/");
|
||||
ext = ext[1];
|
||||
}
|
||||
}
|
||||
ext = "." + ext;
|
||||
|
||||
this.downloadRequest = new Mojo.Service.Request('palm://com.palm.downloadmanager/', {
|
||||
method: 'download',
|
||||
parameters: {
|
||||
target: url,
|
||||
mime: mimetype,
|
||||
targetDir : "/media/internal/" + pathFromInteral,
|
||||
targetFilename : fileName + ext,
|
||||
keepFilenameOnRedirect: true,
|
||||
subscribe: subscribe
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
Mojo.Log.info("Download Success!", JSON.stringify(response));
|
||||
if (callback) {
|
||||
callback(response);
|
||||
return true;
|
||||
} else {
|
||||
if (response.completed == true) {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Content downloaded!" }, "", "");
|
||||
}
|
||||
}
|
||||
},
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Download Failure: ", JSON.stringify(response));
|
||||
if (callback) {
|
||||
callback(response);
|
||||
return false;
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Download error:" + JSON.stringify(response) }, "", "");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SystemModel.prototype.LoadWOSAPrefs = function (callback) {
|
||||
if (callback)
|
||||
callback.bind(this);
|
||||
var req = new Ajax.Request("/media/internal/.wosaprefs", {
|
||||
method: 'get',
|
||||
onFailure: function() {
|
||||
Mojo.Log.warn("Could not load .wosaprefs file. Preferences cannot be opened.");
|
||||
callback(null);
|
||||
},
|
||||
on404: function() {
|
||||
Mojo.Log.warn("Could not find .wosaprefs file. Preferences cannot be opened.");
|
||||
callback(null);
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
if (response && response.responseText) {
|
||||
Mojo.Log.info("Loaded .wosaprefs file: " + JSON.stringify(response.responseText));
|
||||
try {
|
||||
prefsObj = JSON.parse(response.responseText);
|
||||
this.WOSAPrefs = prefsObj.preferences;
|
||||
} catch(ex) {
|
||||
Mojo.Log.warn("Could not parse .wosaprefs file. Preferences cannot be opened. " + ex);
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
callback(prefsObj);
|
||||
return;
|
||||
} else {
|
||||
Mojo.Log.warn("Could not read .wosaprefs file. Preferences cannot be opened.");
|
||||
}
|
||||
callback(null);
|
||||
}.bind(this)
|
||||
});
|
||||
}
|
||||
|
||||
//Helper Functions
|
||||
var vibeInterval;
|
||||
var vibeCount = 0;
|
||||
@@ -356,7 +559,7 @@ SystemModel.prototype.SetDisplayState = function(state) {
|
||||
}
|
||||
|
||||
//Set the Notifications-When-Locked state
|
||||
SystemModel.prototype.setShowNotificationsWhenLocked = function(value) {
|
||||
SystemModel.prototype.SetShowNotificationsWhenLocked = function(value) {
|
||||
if (Mojo.Controller.appInfo.id.indexOf("com.palm") != -1) {
|
||||
Mojo.Log.info("Setting Notifications When Locked to " + value);
|
||||
this.service_identifier = 'palm://com.palm.systemservice';
|
||||
@@ -372,7 +575,7 @@ SystemModel.prototype.setShowNotificationsWhenLocked = function(value) {
|
||||
}
|
||||
|
||||
//Set the LED Notification state
|
||||
SystemModel.prototype.setLEDLightNotifications = function(value) {
|
||||
SystemModel.prototype.SetLEDLightNotifications = function(value) {
|
||||
if (Mojo.Controller.appInfo.id.indexOf("com.palm") != -1) {
|
||||
Mojo.Log.info("Setting LED Notifications to " + value);
|
||||
this.service_identifier = 'palm://com.palm.systemservice';
|
||||
@@ -394,7 +597,7 @@ SystemModel.prototype.GetInternetConnectionState = function(callback) {
|
||||
throw ("Privileged system service call not allowed for this App ID!");
|
||||
}
|
||||
Mojo.Log.info("Requesting Internet connection state from Connection Manager");
|
||||
this.connectedRequest = new Mojo.Service.Request("palm://com.palm.connectionamanager", {
|
||||
this.connectedRequest = new Mojo.Service.Request("palm://com.palm.connectionmanager", {
|
||||
method: "getStatus",
|
||||
parameters: {
|
||||
subscribe: false
|
||||
@@ -405,7 +608,7 @@ SystemModel.prototype.GetInternetConnectionState = function(callback) {
|
||||
}
|
||||
|
||||
//Set the WAN state
|
||||
SystemModel.prototype.setWANEnabled = function(value) {
|
||||
SystemModel.prototype.SetWANEnabled = function(value) {
|
||||
var state = value ? 'off' : 'on';
|
||||
if (Mojo.Controller.appInfo.id.indexOf("com.palm") != -1) {
|
||||
Mojo.Log.info("Setting WAN State to " + value);
|
||||
@@ -424,7 +627,7 @@ SystemModel.prototype.setWANEnabled = function(value) {
|
||||
}
|
||||
|
||||
//Set the WIFI state
|
||||
SystemModel.prototype.setWifiEnabled = function(value) {
|
||||
SystemModel.prototype.SetWifiEnabled = function(value) {
|
||||
var state = value ? 'enabled' : 'disabled';
|
||||
if (Mojo.Controller.appInfo.id.indexOf("com.palm") != -1) {
|
||||
Mojo.Log.info("Setting WIFI State to " + state);
|
||||
@@ -457,6 +660,7 @@ SystemModel.prototype.SetBluetoothEnabled = function(value) {
|
||||
}
|
||||
}
|
||||
|
||||
//Helper for Bluetooth functions, do not call directly
|
||||
SystemModel.prototype.bluetoothControlService = function(url, params, cb) {
|
||||
return new Mojo.Service.Request(url, {
|
||||
onSuccess: cb,
|
||||
@@ -465,14 +669,16 @@ SystemModel.prototype.bluetoothControlService = function(url, params, cb) {
|
||||
});
|
||||
}
|
||||
|
||||
SystemModel.prototype.GetInstalledApps = function(callBack) {
|
||||
SystemModel.prototype.GetInstalledApps = function(callback) {
|
||||
if (callback)
|
||||
callback.bind(this);
|
||||
if (Mojo.Controller.appInfo.id.indexOf("com.palm") != -1) {
|
||||
Mojo.Log.info("Getting list of running apps.");
|
||||
Mojo.Log.info("Getting list of installed apps.");
|
||||
this.appRequest = new Mojo.Service.Request("palm://com.palm.applicationManager/listApps", {
|
||||
method: "",
|
||||
parameters: {},
|
||||
onSuccess: callBack,
|
||||
onFailure: callBack
|
||||
onSuccess: callback,
|
||||
onFailure: callback
|
||||
});
|
||||
} else {
|
||||
Mojo.Log.error("Privileged system services can only be called by apps with an ID that starts with 'com.palm'!");
|
||||
@@ -505,6 +711,121 @@ SystemModel.prototype.KillApp = function(appId) {
|
||||
onFailure: function(response) { Mojo.Log.warn("App was not killed!", JSON.stringify(response)); }
|
||||
});
|
||||
} else {
|
||||
Mojo.Log.error("Privileged system services can only be called by apps with an ID that starts with 'com.palm'!");
|
||||
throw ("Privileged system service call not allowed for this App ID!");
|
||||
}
|
||||
}
|
||||
|
||||
SystemModel.prototype.ListHandlersForURL = function(url, callback) {
|
||||
|
||||
if (Mojo.Controller.appInfo.id.indexOf("com.palm") != -1) {
|
||||
if (callback)
|
||||
callback.bind(this);
|
||||
Mojo.Log.info("Listing handlers for URL: " + url);
|
||||
|
||||
this.serviceRequest = new Mojo.Service.Request("palm://com.palm.applicationManager", {
|
||||
method: "listAllHandlersForUrl",
|
||||
parameters: {
|
||||
"url": url
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
//Mojo.Log.info("Handler list success: " + JSON.stringify(response));
|
||||
if (response && response.redirectHandlers) {
|
||||
if (callback)
|
||||
callback(response.redirectHandlers);
|
||||
} else {
|
||||
Mojo.Log.error("Unexpected payload in system service request");
|
||||
}
|
||||
}.bind(this),
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Handler list failure: " + JSON.stringify(response));
|
||||
if (callback)
|
||||
callback(response);
|
||||
}.bind(this)
|
||||
});
|
||||
} else {
|
||||
|
||||
Mojo.Log.error("Privileged system services can only be called by apps with an ID that starts with 'com.palm'!");
|
||||
throw ("Privileged system service call not allowed for this App ID!");
|
||||
}
|
||||
}
|
||||
|
||||
SystemModel.prototype.AddHandlerForURL = function(urlPattern, appId, callback) {
|
||||
|
||||
if (Mojo.Controller.appInfo.id.indexOf("com.palm") != -1) {
|
||||
if (!urlPattern)
|
||||
throw "No urlPattern specified";
|
||||
if (callback)
|
||||
callback.bind(this);
|
||||
if (!appId)
|
||||
appId = Mojo.Controller.appInfo.id;
|
||||
Mojo.Log.info("Add handler for URL: " + urlPattern + " with app " + appId);
|
||||
|
||||
if (urlPattern && urlPattern != "" && appId && appId != "" && appId.indexOf(".") > -1) {
|
||||
this.serviceRequest = new Mojo.Service.Request("palm://com.palm.applicationManager", {
|
||||
method: "addRedirectHandler",
|
||||
parameters: {
|
||||
"appId": appId,
|
||||
"urlPattern": urlPattern,
|
||||
"schemeForm": false,
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
Mojo.Log.info("Handler registration success: " + JSON.stringify(response));
|
||||
if (callback)
|
||||
callback(response);
|
||||
else
|
||||
Mojo.Controller.getAppController().showBanner("URL Helper added: " + appId + ".", { source: 'notification' });
|
||||
}.bind(this),
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Handler registration failure: " + JSON.stringify(response));
|
||||
if (callback)
|
||||
callback(response);
|
||||
else
|
||||
Mojo.Controller.getAppController().showBanner("URL Helper failed: " + appId + ".", { source: 'notification' });
|
||||
|
||||
}.bind(this)
|
||||
});
|
||||
} else {
|
||||
Mojo.Log.error("Invalid parameters specified. Not attempting to add Redirect Handler!");
|
||||
}
|
||||
} else {
|
||||
|
||||
Mojo.Log.error("Privileged system services can only be called by apps with an ID that starts with 'com.palm'!");
|
||||
throw ("Privileged system service call not allowed for this App ID!");
|
||||
}
|
||||
}
|
||||
|
||||
SystemModel.prototype.RemoveHandlerForURL = function(appId, callback) {
|
||||
if (Mojo.Controller.appInfo.id.indexOf("com.palm") != -1) {
|
||||
|
||||
if (!appId)
|
||||
appId = Mojo.Controller.appInfo.id;
|
||||
if (callback)
|
||||
callback.bind(this);
|
||||
Mojo.Log.info("Remove URL handling for app: " + appId);
|
||||
|
||||
this.serviceRequest = new Mojo.Service.Request("palm://com.palm.applicationManager", {
|
||||
method: "removeHandlersForAppId",
|
||||
parameters: {
|
||||
"appId": appId
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
Mojo.Log.info("Handler remove success: " + JSON.stringify(response));
|
||||
if (callback)
|
||||
callback(response);
|
||||
else
|
||||
Mojo.Controller.getAppController().showBanner("URL Helper removed: " + appId + ".", { source: 'notification' });
|
||||
}.bind(this),
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Handler list failure: " + JSON.stringify(response));
|
||||
if (callback)
|
||||
callback(response)
|
||||
else
|
||||
Mojo.Controller.getAppController().showBanner("URL Helper failed: " + appId + ".", { source: 'notification' });
|
||||
}.bind(this)
|
||||
});
|
||||
} else {
|
||||
|
||||
Mojo.Log.error("Privileged system services can only be called by apps with an ID that starts with 'com.palm'!");
|
||||
throw ("Privileged system service call not allowed for this App ID!");
|
||||
}
|
||||
@@ -1,68 +1,36 @@
|
||||
/*
|
||||
Updater Model - Mojo
|
||||
Version 0.3
|
||||
Created: 2020
|
||||
Author: Jonathan Wise
|
||||
Version 1.0
|
||||
Created: 2022
|
||||
Author: Jon W
|
||||
License: MIT
|
||||
Description: A model to check for and get updates from App Museum II web service.
|
||||
Does not require App Museum to be installed, but does require internet access, and Preware to do the actual install.
|
||||
Source: Find the latest version of this library and clean samples of how to use it on GitHub:
|
||||
https://github.com/codepoet80/webos-catalog-frontend/tree/main/Examples
|
||||
Source: Find the latest version of this library and info on how to use it on GitHub:
|
||||
https://github.com/webosarchive/webos-common
|
||||
*/
|
||||
|
||||
//** Note: If you synced this file from a common repository, local edits may be over-written! */
|
||||
|
||||
var UpdaterModel = function() {
|
||||
this.updateURL = "http://appcatalog.webosarchive.com/WebService/getLatestVersionInfo.php?app=";
|
||||
this.updateURL = "http://appcatalog.webosarchive.org/WebService/getLatestVersionInfo.php?app=";
|
||||
this.lastUpdateResponse = null;
|
||||
};
|
||||
|
||||
/* "Public" Updater functions */
|
||||
|
||||
//Check App Museum II web service to see if there are any updates
|
||||
//Gather information and Check App Museum II web service to see if there are any updates
|
||||
UpdaterModel.prototype.CheckForUpdate = function(appName, callback) {
|
||||
|
||||
var currVersion = this.getVersionObject(Mojo.Controller.appInfo.version);
|
||||
Mojo.Log.info("UpdaterModel identified current app " + appName + " version: " + JSON.stringify(currVersion));
|
||||
|
||||
// TODO: It would be nice to use the AppID, instead of an arbitrary name, but the performance
|
||||
// implications are overwhelming since the AppID is not a part of the masterData file.
|
||||
// We could get that from the app with: Mojo.Controller.appInfo.id
|
||||
var updateURL = this.updateURL + encodeURI(appName);
|
||||
|
||||
// set scope for xmlhttp anonymous function callback
|
||||
if (callback)
|
||||
callBack = callback.bind(this);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", updateURL);
|
||||
Mojo.Log.info("Updater calling: " + updateURL);
|
||||
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
xmlhttp.send();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
Mojo.Log.info("Museum responded: " + xmlhttp.responseText);
|
||||
if (xmlhttp.responseText != null && xmlhttp.responseText != "" && xmlhttp.responseText.indexOf("ERROR:") != 1) {
|
||||
var updateResponse = JSON.parse(xmlhttp.responseText);
|
||||
if (updateResponse.version != null) {
|
||||
var museumVersion = this.getVersionObject(updateResponse.version);
|
||||
//Mojo.Log.info("Museum version: " + JSON.stringify(museumVersion));
|
||||
if (this.isVersionHigher(currVersion, museumVersion)) {
|
||||
Mojo.Log.warn("UpdaterModel found an update in webOS App Museum II!");
|
||||
updateResponse.updateFound = true;
|
||||
} else {
|
||||
Mojo.Log.info("UpdaterModel did not find an update in webOS App Museum II!");
|
||||
updateResponse.updateFound = false;
|
||||
}
|
||||
}
|
||||
this.lastUpdateResponse = updateResponse;
|
||||
} else {
|
||||
Mojo.Log.info("UpdaterModel: No useable response from App Museum II update API");
|
||||
}
|
||||
//Mojo.Log.info("New update response object: " + JSON.stringify(updateResponse));
|
||||
if (callback) {
|
||||
callBack(updateResponse);
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
this.deviceInfoRequest = new Mojo.Service.Request("palm://com.palm.preferences/systemProperties", {
|
||||
method: "Get",
|
||||
parameters:{"key": "com.palm.properties.nduid" },
|
||||
onSuccess: this.performIdentifiedUpdateCheck.bind(this, appName, currVersion, callback),
|
||||
onFailure: this.performIdentifiedUpdateCheck.bind(this, appName, currVersion, callback)
|
||||
});
|
||||
}
|
||||
|
||||
//You can optionally call this function if you don't want to handle the user interaction related to prompting for an update
|
||||
@@ -73,7 +41,10 @@ UpdaterModel.prototype.PromptUserForUpdate = function(callback, message) {
|
||||
Mojo.Log.warn("UpdaterModel: Not prompting user for update when no update has been discovered.");
|
||||
} else {
|
||||
if (!message)
|
||||
message = "An update for " + Mojo.Controller.appInfo.title + " was found in App Museum II: <br>" + this.lastUpdateResponse.versionNote + "<br>Do you want to update now?";
|
||||
message = "An update for " + Mojo.Controller.appInfo.title + " was found in App Museum II:<br>" + this.lastUpdateResponse.versionNote + "<br>Do you want to update now?";
|
||||
|
||||
if (callback) // set scope for xmlhttp anonymous function callback
|
||||
callBack = callback.bind(this);
|
||||
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
if (stageController) {
|
||||
@@ -86,8 +57,8 @@ UpdaterModel.prototype.PromptUserForUpdate = function(callback, message) {
|
||||
} else {
|
||||
Mojo.Log.info("User deferred update.");
|
||||
}
|
||||
if (callback)
|
||||
callback(value);
|
||||
if (callBack)
|
||||
callBack(value);
|
||||
},
|
||||
allowHTMLMessage: true,
|
||||
title: $L("Update Available!"),
|
||||
@@ -102,33 +73,83 @@ UpdaterModel.prototype.PromptUserForUpdate = function(callback, message) {
|
||||
}
|
||||
|
||||
//Ask Preware to actually install the update...
|
||||
UpdaterModel.prototype.InstallUpdate = function(callBack) {
|
||||
UpdaterModel.prototype.InstallUpdate = function() {
|
||||
if (!this.lastUpdateResponse) {
|
||||
Mojo.Log.warn("UpdaterModel: Not performing update when no update has been discovered.");
|
||||
} else {
|
||||
var app = this.lastUpdateResponse.downloadURI;
|
||||
Mojo.Log.info("Asking PreWare to perform update to " + app);
|
||||
|
||||
this.prewareRequest = new Mojo.Service.Request("palm://com.palm.applicationManager", {
|
||||
method: "open",
|
||||
parameters: {
|
||||
"id": "org.webosinternals.preware",
|
||||
params: { type: "install", file: app }
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
Mojo.Log.info("Preware launch success", JSON.stringify(response));
|
||||
},
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Preware launch failure, " + app + ":",
|
||||
JSON.stringify(response), response.errorText);
|
||||
}
|
||||
});
|
||||
this.InstallViaPreware(app);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
UpdaterModel.prototype.InstallViaPreware = function(app) {
|
||||
//Ask webOS to launch the PreWare with install url
|
||||
this.prewareRequest = new Mojo.Service.Request("palm://com.palm.applicationManager", {
|
||||
method: "open",
|
||||
parameters: {
|
||||
"id": "org.webosinternals.preware",
|
||||
params: { type: "install", file: app }
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
Mojo.Log.info("Preware launch success", JSON.stringify(response));
|
||||
}.bind(this),
|
||||
onFailure: function(response) {
|
||||
Mojo.Log.error("Preware launch failure, " + app + ":", JSON.stringify(response), response.errorText);
|
||||
}.bind(this)
|
||||
});
|
||||
}
|
||||
|
||||
/* "Private" helper functions */
|
||||
|
||||
//Internal Function that uses the resolved information to actually do the check
|
||||
UpdaterModel.prototype.performIdentifiedUpdateCheck = function(appName, currVersion, callback, response) {
|
||||
// Build appropriate URL for conditions
|
||||
var updateURL = this.updateURL + encodeURI(appName + "/" + Mojo.Controller.appInfo.version);
|
||||
// If we have a device identifier, use that
|
||||
if(response && JSON.stringify(response).indexOf("com.palm.properties.nduid") != -1) {
|
||||
updateURL = updateURL + "&clientid=" + response[Object.keys(response)[0]];
|
||||
}
|
||||
// Send some info about the device (could be used for compat checks)
|
||||
deviceData = Mojo.Environment.DeviceInfo.modelName + "/" + Mojo.Environment.DeviceInfo.platformVersion + "/" + (Mojo.Environment.DeviceInfo.carrierName || "WiFi") + "/" + Mojo.Locale.getCurrentLocale();
|
||||
updateURL = updateURL + "&device=" + encodeURIComponent(deviceData);
|
||||
|
||||
if (callback) // set scope for xmlhttp anonymous function callback
|
||||
callBack = callback.bind(this);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", updateURL);
|
||||
Mojo.Log.info("Updater calling: " + updateURL);
|
||||
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
xmlhttp.send();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
Mojo.Log.info("Museum responded: " + xmlhttp.responseText);
|
||||
if (xmlhttp.responseText != null && xmlhttp.responseText != "" && xmlhttp.responseText.indexOf("ERROR:") != 1) {
|
||||
var updateResponse = JSON.parse(xmlhttp.responseText);
|
||||
if (updateResponse.version != null) {
|
||||
var museumVersion = this.getVersionObject(updateResponse.version);
|
||||
if (this.isVersionHigher(currVersion, museumVersion)) {
|
||||
Mojo.Log.warn("UpdaterModel found an update in webOS App Museum II!");
|
||||
updateResponse.updateFound = true;
|
||||
} else {
|
||||
Mojo.Log.info("UpdaterModel did not find an update in webOS App Museum II!");
|
||||
updateResponse.updateFound = false;
|
||||
}
|
||||
}
|
||||
this.lastUpdateResponse = updateResponse;
|
||||
} else {
|
||||
Mojo.Log.info("UpdaterModel: No useable response from App Museum II update API");
|
||||
}
|
||||
if (callBack) {
|
||||
callBack(updateResponse);
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
//Turn a version string into an object with three independent number values
|
||||
UpdaterModel.prototype.getVersionObject = function(versionNum) {
|
||||
versionNumParts = versionNum.split(".");
|
||||
@@ -158,4 +179,4 @@ UpdaterModel.prototype.isVersionHigher = function(currVersion, compareVersion) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<div class="palm-hasheader" style="margin-bottom:60px">
|
||||
<div id="divShareTitle" class="palm-header center" onclick="Mojo.Controller.stageController.swapScene({ transition: Mojo.Transition.crossFade, name: 'main' });">
|
||||
Share Details
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- only visible in debug mode -->
|
||||
<div class="palm-group" id="divShareInfo" style="display:none">
|
||||
<div class="palm-group-title">
|
||||
<span x-mojo-loc=''>Debug Links</span>
|
||||
</div>
|
||||
<div id="divShareLinks" name="divShareLinks">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group" id="divTextDetail">
|
||||
<div class="palm-group-title">
|
||||
<span x-mojo-loc=''>Content</span>
|
||||
</div>
|
||||
|
||||
<div id="divTextContent" name="divTextContent" style="background-color:white; border: 1px solid dimgray; margin: 0px;">
|
||||
<div id="divImageContent" style="width:100%; margin:auto; align-content: center; text-align: center;margin-top: 6px !important;">
|
||||
<img src="icon-256.png" style="width:128px;height:128px" /><br/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,12 +1,9 @@
|
||||
<div class="dashboard-notification-module">
|
||||
<div class="palm-dashboard-icon-container">
|
||||
|
||||
<div class="dashboard-newitem">
|
||||
<div class="dashboard-newitem" style="display:#{showCount}">
|
||||
<span>#{count}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="dashboard-icon" class="palm-dashboard-icon dashboard-icon-chat">
|
||||
<div id="dashboard-icon" class="palm-dashboard-icon dashboard-icon-download">
|
||||
</div>
|
||||
</div>
|
||||
<div class="palm-dashboard-text-container">
|
||||
@@ -0,0 +1,31 @@
|
||||
<div class="palm-dialog-content">
|
||||
<div id="login-title" class="palm-dialog-title">
|
||||
Log In to a Share Space
|
||||
</div>
|
||||
<div class="palm-dialog-seperator"></div>
|
||||
|
||||
<div class="textfield-group" x-mojo-focus-highlight="true">
|
||||
<div class="title">
|
||||
<div id="txtUsername" name="txtUsername" x-mojo-element="TextField" title="Username"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="textfield-group" x-mojo-focus-highlight="true">
|
||||
<div class="title">
|
||||
<div id="txtCredential" name="txtCredential" x-mojo-element="TextField" title="Credential"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group" id="linkError" style="display:none" name="linkError">
|
||||
<div class="palm-group-title"><span style="color:white">Error</span></div>
|
||||
<div class="errorresponse">
|
||||
There was no usable response from the Service before its timeout.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-dialog-buttons">
|
||||
<div x-mojo-element="Button" id="goButton"></div>
|
||||
<div x-mojo-element="Button" id="cancelButton"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="palm-row" x-mojo-tap-highlight='momentary'>
|
||||
<div class="palm-row-wrapper">
|
||||
<div class="task-row">
|
||||
<div style="height:48px; float:left;"><img class="thumbnail" src="#{thumbnail}" style="width:48px; height: 48px; margin-right: 8px;"></div>
|
||||
<div title="#{guid}"><span style="font-size:18px;">#{timestamp}</span>
|
||||
<p style="margin:0px; padding: 0px;padding-bottom: 3px;">#{contenttype}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="palm-list">
|
||||
#{-listElements}
|
||||
</div>
|
||||
@@ -0,0 +1,17 @@
|
||||
<div class="palm-page-header">
|
||||
<div class="header-icon sharespace"></div>
|
||||
<div class="header-text">
|
||||
<span x-mojo-loc=''>Share Space</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="showShareList" name="showShareList" style="display:none">
|
||||
<div class="palm-group">
|
||||
<div class="palm-group-title"><span x-mojo-loc='' id="spnUsername">Task List</span></div>
|
||||
<div id="shareList" x-mojo-element="List" style="padding: 1px;margin:-12px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="divSpinnerContainer" style="margin-top: 100px; width: 130px;margin-left: auto;margin-right: auto; align-items: center;">
|
||||
<div x-mojo-element="Spinner" class="spinnerClass" id="workingSpinner" name="workingSpinner"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,24 @@
|
||||
<div class="palm-page-header">
|
||||
<div class="header-icon sharespace"></div>
|
||||
<div class="header-text">
|
||||
<span x-mojo-loc=''>Share Space</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group">
|
||||
<div class="palm-group-title" id="divEditTitle">New Content</div>
|
||||
<div class="palm-list">
|
||||
<div class="palm-row single">
|
||||
<div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
|
||||
<div class="title">
|
||||
<div class="search-bar">
|
||||
<div class="textfield-search" id="txtShareContent" x-mojo-element="TextField" style="height: 300px;" title="ShareContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-mojo-element="Button" id="goButton" class="buttonClass" name="goButton"></div>
|
||||
<div x-mojo-element="Button" id="cancelButton" class="buttonClass" name="cancelButton"></div>
|
||||
@@ -0,0 +1,87 @@
|
||||
<div class="palm-page-header">
|
||||
<div class="header-icon sharespace"></div>
|
||||
<div class="header-text">
|
||||
<span x-mojo-loc=''>Share Space - New User</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group">
|
||||
<div class="palm-group-title">
|
||||
<span x-mojo-loc=''>Terms and Conditions (Scroll)</span>
|
||||
</div>
|
||||
<div x-mojo-element="Scroller" class="scrollerClass" id="scrollTnC" name="scrollTnC" style="height:200px;margin:-15px 10px 10px -15px;padding:0px;">
|
||||
<div id="divTnC">
|
||||
<ul>
|
||||
<li>Loading Terms and Conditions...</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div x-mojo-element="Button" id="btnAgree" name="btnAgree" style="margin-left: 20%; margin-right:14%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group" id="divCredentials" style="display:none">
|
||||
<div class="palm-group-title">
|
||||
<span x-mojo-loc=''>Credentials</span>
|
||||
</div>
|
||||
|
||||
<div class="palm-list">
|
||||
|
||||
<div class="palm-row first">
|
||||
<div class="palm-row-wrapper">
|
||||
<div class="title" style="float:left; margin-left: 8px; margin-top: 14px;padding:0px;"><span class="label ">Username</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper" style="height: 12px">
|
||||
<div class="textfield-group" x-mojo-focus-highlight="true">
|
||||
<div class="title">
|
||||
<div id="txtUsername" name="txtUsername" x-mojo-element="TextField" title="Username"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper" style="height: 12px">
|
||||
<div class="title" class="truncating-text" style="float:left; margin-left: 8px; margin-top: 14px;padding:0px"><span class="label ">Share phrase</span></div>
|
||||
<img id="imgTryagain" src="assets/tryagain.png" style="height:24px; width:24px; margin-top: 12px; margin-left: 12px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper">
|
||||
<div id="divSharephrase" style="margin: 12px 14px;font-style: italic;"> </div>
|
||||
<div class="explainer" style="margin-left:10px; padding-bottom: 12px;">Anyone who knows this phrase can share with you.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper" style="height: 12px">
|
||||
<div class="title" class="truncating-text" style="float:left; margin-left: 8px; margin-top: 14px;padding:0px"><span class="label ">Admin Password</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper">
|
||||
<div class="textfield-group" x-mojo-focus-highlight="true">
|
||||
<div class="title">
|
||||
<div id="txtPassword" name="txtPassword" x-mojo-element="TextField" title="Password"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row last">
|
||||
<div class="palm-row-wrapper">
|
||||
<div id="divPasswordInstructions" style="padding:6px 10px 12px 10px;line-height: 16px">
|
||||
<span class="explainer">Keep this one safe, you'll use it to delete shares or configure your space.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div x-mojo-element="Button" id="btnOK" name="btnOK" style="display: none;"></div>
|
||||
<div x-mojo-element="Button" id="btnCancel" name="btnCancel"></div>
|
||||
@@ -0,0 +1,107 @@
|
||||
<div class="palm-hasheader" style="margin-bottom:60px">
|
||||
<div id="watchViewTitle" class="palm-header center" onclick="Mojo.Controller.stageController.popScene();">
|
||||
Preferences
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group">
|
||||
<div class="palm-group-title">
|
||||
<span x-mojo-loc=''>Basic</span>
|
||||
</div>
|
||||
<div class="palm-list" id="listBasic">
|
||||
<div class="palm-row first">
|
||||
<div class="palm-row-wrapper">
|
||||
<div id="listRefresh" x-mojo-element="ListSelector" title="RefreshTimeout" class="right"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper">
|
||||
<div x-mojo-element="ToggleButton" id="toggleAutoDownload" title="UseAutoDownload"></div>
|
||||
<div class="title" style="margin-left: -4px; float:left;"><span class="label">Auto Download</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper">
|
||||
<div id="listAutoDownloadTime" x-mojo-element="ListSelector" title="AutoDownloadTime" class="right"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper">
|
||||
<div class="explanation-text" id="divDownloadExplain">Download features require FileMgr, which you can install from PreWare.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper">
|
||||
<div x-mojo-element="ToggleButton" id="toggleCopyLinkOnShare" title="CopyLinkOnShare"></div>
|
||||
<div class="title" style="margin-left: -4px; float:left;"><span class="label">Copy Link on Share</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row last">
|
||||
<div class="palm-row-wrapper">
|
||||
<div x-mojo-element="ToggleButton" id="toggleForceHTTP" title="ForceHTTP"></div>
|
||||
<div class="title" style="margin-left: -4px; float:left;"><span class="label">Always use HTTP</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group">
|
||||
<div class="palm-group-title">
|
||||
<span x-mojo-loc=''>Self Hosting</span>
|
||||
</div>
|
||||
|
||||
<div class="palm-list">
|
||||
|
||||
<div class="palm-row first">
|
||||
<div class="palm-row-wrapper">
|
||||
<div x-mojo-element="ToggleButton" id="toggleCustomClientId" title="UseCustomClientId"></div>
|
||||
<div class="title" style="margin-left: -4px; float:left;"><span class="label">Custom Client API Key</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper" style="margin:14px 22px 4px 12px">
|
||||
<div id="txtCustomClientId" name="txtCustomClientId" x-mojo-element="TextField" title="CustomClientId"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row last">
|
||||
<div class="palm-row-wrapper">
|
||||
<div x-mojo-element="ToggleButton" id="toggleCustomEndPoint" title="UseCustomEndpoint"></div>
|
||||
<div class="title" style="margin-left: -4px; float:left;"><span class="label">Custom Endpoint</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-mojo-element="Drawer" id="drawerSelfHost" class="drawerClass" name="drawerSelfHost">
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper" style="margin:14px 22px 4px 12px">
|
||||
<div id="txtEndpointURL" name="txtEndpointURL" x-mojo-element="TextField" title="EndpointURL"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper" style="margin:14px 22px 4px 12px">
|
||||
<div id="txtShortURL" name="txtShortURL" x-mojo-element="TextField" title="ShortURL"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row last">
|
||||
<div class="palm-row-wrapper" style="margin:14px 22px 4px 12px">
|
||||
<div id="txtCustomCreateKey" name="txtCustomCreateKey" x-mojo-element="TextField" title="CustomCreateKey"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="explanation-text">For more information on self-hosting, please visit <a href="https://github.com/webosarchive/webos-sharespace">https://github.com/webosarchivewebos-sharespace</a></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div x-mojo-element="Button" id="btnOK" name="btnOK"></div>
|
||||
@@ -7,7 +7,7 @@
|
||||
</div>
|
||||
<div class="palm-header-spacer"></div>
|
||||
|
||||
<div id="data"></div>
|
||||
<div id="data" style="margin-right: 12px"></div>
|
||||
|
||||
<div class="my-scene-fade-bottom" x-mojo-scroll-fade="bottom"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,26 @@
|
||||
<div class="palm-page-header">
|
||||
<div class="header-icon sharespace"></div>
|
||||
<div class="header-text">
|
||||
<span x-mojo-loc=''>Share Space - Welcome</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="welcome">
|
||||
<div class="my-scene-fade-top" x-mojo-scroll-fade="top"></div>
|
||||
|
||||
<h3>Getting Started</h3>
|
||||
<div class="welcome-text">
|
||||
<p>Your Share Space has been created! Keep your credentials somewhere safe:</p>
|
||||
</div>
|
||||
|
||||
<div id="welcome-data" class="welcome-text"></div>
|
||||
|
||||
<div class="welcome-text">
|
||||
<p>Anyone who has your <b>Name</b> and <b>Share Phrase</b> can share content with you from their webOS device, or from the web.</p>
|
||||
<p>Any time content is shared to your Share Space, a public URL will be generated that you can give to others.
|
||||
This URL will contain your Share Space <b>Name</b>, but <i>not</i> your <b>Share Phrase</b>.</p>
|
||||
<p>Only users with your <b>Admin Password</b> can delete content, or manage your Share Space.</p>
|
||||
</div>
|
||||
|
||||
<div class="my-scene-fade-bottom" x-mojo-scroll-fade="bottom"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "com.palm.webos.sharespace",
|
||||
"version": "1.0.3",
|
||||
"vendor": "webOS Archive",
|
||||
"type": "web",
|
||||
"main": "index.html",
|
||||
"title": "Share Space",
|
||||
"icon": "icon.png",
|
||||
"miniicon": "assets/notify.png",
|
||||
"noWindow": true,
|
||||
"splashicon": "icon-256.png",
|
||||
"uiRevision": "2",
|
||||
"serviceURL": "https://share.webosarchive.org/",
|
||||
"shortURL": "https://wosa.link/",
|
||||
"tapToShareSupported": true,
|
||||
"universalSearch": {
|
||||
"action": {
|
||||
"displayName": "New Share",
|
||||
"url": "com.palm.webos.sharespace",
|
||||
"launchParam": {
|
||||
"newshare": "#{searchTerms}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"startupMessage": "<img src='icon.png' style='float:right; margin-left: 6px'>Welcome to ShareSpace -- a powerful app for getting content on and off your webOS device! You can interact with this app from anywhere at <a href='http://share.webosarchive.org'>share.webosarchive.org</a>!<br>Here are some things you can do..."
|
||||
}
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"logLevel": 99,
|
||||
"debuggingEnabled": true,
|
||||
"logLevel": 0,
|
||||
"debuggingEnabled": false,
|
||||
"timingEnabled": false,
|
||||
"logEvents": false,
|
||||
"escapeHTMLInTemplates": true
|
||||
|
After Width: | Height: | Size: 14 KiB |
@@ -3,15 +3,14 @@
|
||||
|
||||
<head>
|
||||
<meta name='viewport' content='height=device-height'>
|
||||
<title>Simple Chat</title>
|
||||
<title>Share Space</title>
|
||||
<script src="/usr/palm/frameworks/mojo/mojo.js" type="text/javascript" x-mojo-version="1"></script>
|
||||
|
||||
<!-- load my additions -->
|
||||
<script src="app/com.jonandnic.mojo.additions.js" type="text/javascript"></script>
|
||||
<script src="app/com.wosa.mojo.additions.js" type="text/javascript"></script>
|
||||
|
||||
<!-- application stylesheet should come in after the one loaded by the framework -->
|
||||
<link href="stylesheets/simplechat.css" media="screen" rel="stylesheet" type="text/css">
|
||||
<link href="emoji.css" rel="stylesheet" type="text/css" />
|
||||
<link href="stylesheets/sharespace.css" media="screen" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -0,0 +1,4 @@
|
||||
var appKeys = {
|
||||
'shareBoardClientKey': 'base64 encode the client key from the server',
|
||||
'shareBoardCreateKey': 'base64 encode the create key from the server (if needed)'
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
# Simple Chat client app for webOS
|
||||
|
||||
SimpleChat client for legacy Palm/HP webOS devices, depends on back-end services listed below.
|
||||
|
||||
Uses [simplechat-service](https://github.com/codepoet80/simplechat-service)
|
||||
|
||||
You can also self-host the services.
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
In the app assistant, we setup some app-wide global objects and handle different kinds of launches, creating and delegating to the main stage
|
||||
*/
|
||||
var appModel = null;
|
||||
var updaterModel = null;
|
||||
var systemModel = null;
|
||||
var MainStageName = "main";
|
||||
var welcomed = false;
|
||||
Mojo.Additions = Additions;
|
||||
|
||||
function AppAssistant() {
|
||||
appModel = new AppModel();
|
||||
updaterModel = new UpdaterModel();
|
||||
systemModel = new SystemModel();
|
||||
serviceModel = new ServiceModel();
|
||||
}
|
||||
|
||||
//This function will handle relaunching the app when an alarm goes off(see the device/alarm scene)
|
||||
AppAssistant.prototype.handleLaunch = function(params) {
|
||||
//Load preferences
|
||||
appModel.LoadSettings();
|
||||
Mojo.Log.info("settings now: " + JSON.stringify(appModel.AppSettingsCurrent));
|
||||
if (!appModel.AppSettingsCurrent["BackgroundUpdate"]) {
|
||||
appModel.AppSettingsCurrent["BackgroundUpdate"] = "00:30:00";
|
||||
appModel.SaveSettings();
|
||||
}
|
||||
|
||||
//get the proxy for the stage in the event it already exists (eg: app is currently open)
|
||||
var mainStage = this.controller.getStageProxy("main");
|
||||
Mojo.Log.info("SimpleChat is Launching! Launch params: " + JSON.stringify(params));
|
||||
|
||||
//Reset alarms
|
||||
systemModel.ClearSystemAlarm("SimpleChat");
|
||||
if (appModel.AppSettingsCurrent["BackgroundUpdate"] && appModel.AppSettingsCurrent["BackgroundUpdate"] != "" && appModel.AppSettingsCurrent["BackgroundUpdate"] != -1)
|
||||
systemModel.SetSystemAlarmRelative("SimpleChat", appModel.AppSettingsCurrent["BackgroundUpdate"]);
|
||||
|
||||
var AppRunning = false;
|
||||
if (mainStage) {
|
||||
Mojo.Log.info("Found existing stage, app was already running");
|
||||
AppRunning = true;
|
||||
} else {
|
||||
Mojo.Log.info("Did not find existing stage, this is a new app launch!");
|
||||
}
|
||||
|
||||
if (AppRunning) //If the stage exists, use it
|
||||
{
|
||||
var stageController = this.controller.getStageController("main");
|
||||
if (!params || params["action"] == undefined) //If no parameters were passed, this is a normal launch
|
||||
{
|
||||
Mojo.Log.info("This is a normal re-launch");
|
||||
stageController.activate(); //bring existing stage into focus
|
||||
return;
|
||||
} else //If parameters were passed, this is a launch from a system alarm
|
||||
{
|
||||
Mojo.Log.info("This is a re-launch with parameters: " + JSON.stringify(params) + ". Safe to ignore, since app is already running.");
|
||||
systemModel.ShowNotificationStage("dashboard", "dashboard/dashboard-scene", 60, false, false);
|
||||
return;
|
||||
}
|
||||
} else //If not, determine if we should make one
|
||||
{
|
||||
if (!params || params["action"] == undefined) //If no parameters were passed, this is a normal launch
|
||||
{
|
||||
var currVersion = Mojo.Controller.appInfo.version;
|
||||
Mojo.Log.info("This is a normal launch of version " + currVersion);
|
||||
|
||||
var stageArguments = { name: MainStageName, lightweight: true };
|
||||
this.controller.createStageWithCallback(stageArguments, function(stageController) {
|
||||
stageController.pushScene(MainStageName);
|
||||
}.bind(this));
|
||||
return;
|
||||
} else //If parameters were passed, this is a launch from a system alarm
|
||||
{
|
||||
|
||||
Mojo.Log.info("This is an alarm launch: " + JSON.stringify(params));
|
||||
/*
|
||||
|
||||
return;*/
|
||||
|
||||
var pushClass0AlertScene = function(stageController) {
|
||||
stageController.pushScene('dashboard', "dashboard/dashboard-scene");
|
||||
}.bind(this);
|
||||
|
||||
Mojo.Controller.getAppController().showBanner("New messages in the chat!", { source: 'notification' });
|
||||
//var stageArguments = { name: MainStageName, lightweight: true };
|
||||
//this.controller.createStageWithCallback(stageArguments, function(stageController) {
|
||||
// Mojo.Controller.appController.closeStage("main");
|
||||
|
||||
//}.bind(this));
|
||||
|
||||
this.controller.createStageWithCallback({
|
||||
name: 'dashboard',
|
||||
lightweight: true,
|
||||
height: 100,
|
||||
soundclass: "assets/silent.mp3"
|
||||
}, pushClass0AlertScene, 'popupalert');
|
||||
|
||||
//systemModel.ShowNotificationStage("dashboard", "dashboard/dashboard-scene", 60, false, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
SystemModel.prototype.ShowNotificationStage = function(stageName, sceneName, heightToUse, sound, vibrate) {
|
||||
Mojo.Log.info("Showing notification stage.");
|
||||
//Determine what sound to use
|
||||
var soundToUse;
|
||||
if (!sound)
|
||||
soundToUse = "assets/silent.mp3";
|
||||
else if (sound == true || sound == "")
|
||||
soundToUse = "/media/internal/ringtones/Dulcimer (short).mp3"
|
||||
else
|
||||
soundToUse = sound;
|
||||
if (vibrate)
|
||||
this.Vibrate(vibrate);
|
||||
|
||||
var stageCallBack = function(stageController) {
|
||||
stageController.pushScene({ name: stageName, sceneTemplate: sceneName });
|
||||
}.bind(this);
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
var stageController = appController.getStageController(stageName);
|
||||
if (stageController) {
|
||||
stageCallBack(stageController);
|
||||
} else {
|
||||
Mojo.Controller.getAppController().createStageWithCallback({
|
||||
name: stageName,
|
||||
lightweight: true,
|
||||
height: heightToUse,
|
||||
sound: soundToUse,
|
||||
clickableWhenLocked: true
|
||||
}, stageCallBack, 'dashboard');
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
This alarm scene is used for Touchpads, which will only pretend to change settings if running in the background
|
||||
Launching this scene forces the Touchpad to wake up to deal with presenting it, and when it does we have a good
|
||||
chance of successfully changing the settings. We can then close this window. All the smarts for this are in stage assistant.
|
||||
*/
|
||||
function DashboardAssistant(argFromPusher) {
|
||||
this.passedArguments = argFromPusher;
|
||||
}
|
||||
|
||||
DashboardAssistant.prototype.setup = function() {
|
||||
Mojo.Log.info("Notification stage setup at " + new Date());
|
||||
this.displayDashboard("SimpleChat", "Checking for new messages...");
|
||||
|
||||
this.serviceEndpointBase = appModel.ServiceEndpointBase;
|
||||
if (appModel.AppSettingsCurrent["UseCustomEndpoint"] && appModel.AppSettingsCurrent["EndpointURL"]) {
|
||||
this.serviceEndpointBase = appModel.AppSettingsCurrent["EndpointURL"];
|
||||
}
|
||||
if (!appModel.AppSettingsCurrent["AlertSound"] || appModel.AppSettingsCurrent["AlertSound"] == "") {
|
||||
appModel.AppSettingsCurrent["AlertSound"] = "Subtle (short)";
|
||||
}
|
||||
serviceModel.getChats(this.serviceEndpointBase, function(response) {
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
if (response != null && response != "") {
|
||||
var responseObj = JSON.parse(response);
|
||||
if (responseObj.status == "error") {
|
||||
Mojo.Log.error("Error message from server during background check: " + responseObj.msg);
|
||||
appController.closeAllStages();
|
||||
} else {
|
||||
if (responseObj.messages && responseObj.messages.length > 0) {
|
||||
var newMessageCount = this.findNewMessageCount(appModel.AppSettingsCurrent["LastKnownMessage"], responseObj.messages);
|
||||
if (newMessageCount > 0) {
|
||||
Mojo.Log.info("Found new chat on server during background check!");
|
||||
this.displayDashboard("SimpleChat", "New messages in the chat!", newMessageCount);
|
||||
//If the main app window is open, it will play a sound. If not, play a sound here.
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
var mainStage = appController.getStageController("main");
|
||||
if (!mainStage) {
|
||||
systemModel.PlayAlertSound(appModel.AppSettingsCurrent["AlertSound"]);
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.info("No new chats on server during background check.");
|
||||
appController.closeStage("dashboard");
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.warn("Chat results were empty during scheduled background check. This is unlikely; server, API or connectivity problem possible");
|
||||
appController.closeStage("dashboard");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.error("No usable response from server during background check: " + response);
|
||||
appController.closeStage("dashboard");
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
//Event handlers
|
||||
Mojo.Event.listen(this.controller.get("dashboardinfo"), Mojo.Event.tap, this.handleTap.bind(this));
|
||||
}
|
||||
|
||||
DashboardAssistant.prototype.findNewMessageCount = function(LastKnownMessage, newMessages) {
|
||||
var actuallyNewMessages = [];
|
||||
var startCounting = false;
|
||||
for (var j = 0; j < newMessages.length; j++) {
|
||||
if (startCounting) {
|
||||
actuallyNewMessages.push(newMessages[j].uid);
|
||||
appModel.AppSettingsCurrent["LastKnownMessage"] = newMessages[j].uid;
|
||||
}
|
||||
if (newMessages[j].uid == LastKnownMessage) {
|
||||
startCounting = true;
|
||||
}
|
||||
}
|
||||
return actuallyNewMessages.length;
|
||||
}
|
||||
|
||||
DashboardAssistant.prototype.handleTap = function(event) {
|
||||
Mojo.Log.info("Dashboard tapped!");
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
var mainStage = appController.getStageProxy("main");
|
||||
if (!mainStage) {
|
||||
systemModel.LaunchApp(Mojo.Controller.appInfo.id);
|
||||
appController.closeAllStages();
|
||||
} else {
|
||||
mainStage.activate();
|
||||
appController.closeStage("dashboard")
|
||||
}
|
||||
}
|
||||
|
||||
DashboardAssistant.prototype.handleDrag = function(event) {
|
||||
var infoElement = this.controller.get("dashboardinfo");
|
||||
infoElement.style.opacity = "0.5"; //TODO: this only seems to effect the icon
|
||||
}
|
||||
|
||||
DashboardAssistant.prototype.handleDragEnd = function(event) {
|
||||
Mojo.Log.info("Dashboard drag end!");
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
appController.closeAllStages();
|
||||
}
|
||||
|
||||
DashboardAssistant.prototype.displayDashboard = function(title, message, count) {
|
||||
var infoElement = this.controller.get("dashboardinfo");
|
||||
|
||||
var info = { title: title, message: message, count: count };
|
||||
var renderedInfo = Mojo.View.render({ object: info, template: "dashboard/item-info" });
|
||||
infoElement.innerHTML = renderedInfo;
|
||||
this.controller.getSceneScroller().mojo.revealTop(true);
|
||||
}
|
||||
|
||||
DashboardAssistant.prototype.deactivate = function(event) {
|
||||
Mojo.Event.stopListening(this.controller.get("dashboardinfo"), Mojo.Event.tap, this.handleTap);
|
||||
}
|
||||
|
||||
// Cleanup anything we did in setup function
|
||||
DashboardAssistant.prototype.cleanup = function() {
|
||||
Mojo.Log.info("notification stage closing at " + new Date());
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/* Copyright 2010 Palm, Inc. All rights reserved. */
|
||||
/*global Mojo, $L, Class, window, document, PalmSystem, AppAssistant, palmGetResource, Foundations, _, */
|
||||
|
||||
var EmoticonPickerDialogAssistant = function(sceneAssistant, onselect) {
|
||||
|
||||
this.sceneAssistant = sceneAssistant;
|
||||
this.controller = sceneAssistant.controller;
|
||||
this.onselect = onselect;
|
||||
};
|
||||
|
||||
EmoticonPickerDialogAssistant.prototype.show = function() {
|
||||
this.controller.showDialog({
|
||||
template: 'main/emoticonpicker-dialog',
|
||||
assistant: this
|
||||
});
|
||||
};
|
||||
|
||||
EmoticonPickerDialogAssistant.prototype.setup = function(widget) {
|
||||
this.widget = widget;
|
||||
var emoTable = this.controller.get('emo-table');
|
||||
var emoticonList = [
|
||||
"B-)",
|
||||
">:(",
|
||||
":'(",
|
||||
":[",
|
||||
":-!",
|
||||
"X(",
|
||||
":@",
|
||||
"o_O",
|
||||
":O",
|
||||
">:-)",
|
||||
"O:)",
|
||||
"<3",
|
||||
":-*",
|
||||
":D",
|
||||
":/",
|
||||
":(",
|
||||
":|",
|
||||
":P",
|
||||
";)",
|
||||
":)"
|
||||
];
|
||||
|
||||
var row = emoTable.insertRow();
|
||||
var insertCell = this.insertCell;
|
||||
emoticonList.forEach(function(emoticon) {
|
||||
if (row.cells.length === 5) {
|
||||
row = emoTable.insertRow(0);
|
||||
}
|
||||
insertCell(row, emoticon);
|
||||
});
|
||||
|
||||
emoTable.addEventListener(Mojo.Event.tap, this.handleEmoticonSelect.bind(this));
|
||||
this.controller.get('cancel_button').addEventListener(Mojo.Event.tap, this.handleClose.bind(this));
|
||||
};
|
||||
|
||||
EmoticonPickerDialogAssistant.prototype.insertCell = function(row, emoticon) {
|
||||
var cell = row.insertCell(0);
|
||||
var MojoHTML = Mojo.Format.runTextIndexer(emoticon.escapeHTML());
|
||||
MojoHTML = MojoHTML.replace("file:///usr/palm/", "");
|
||||
cell.innerHTML = MojoHTML;
|
||||
cell.setAttribute("emo", emoticon);
|
||||
cell.style.height = "40px";
|
||||
};
|
||||
|
||||
EmoticonPickerDialogAssistant.prototype.handleEmoticonSelect = function(event) {
|
||||
event.stopPropagation(); // stop the tap because it causes the underlying text item to lose focus
|
||||
event.preventDefault();
|
||||
|
||||
var td = event.target;
|
||||
if (td && td.tagName !== "TD") {
|
||||
td = event.target.up('td');
|
||||
}
|
||||
|
||||
if (td) {
|
||||
this.onselect(td.getAttribute("emo"));
|
||||
}
|
||||
this.widget.mojo.close();
|
||||
};
|
||||
|
||||
EmoticonPickerDialogAssistant.prototype.handleClose = function(event) {
|
||||
event.stopPropagation(); // stop the tap because it causes the underlying text item to lose focus
|
||||
event.preventDefault();
|
||||
this.widget.mojo.close();
|
||||
};
|
||||
@@ -1,830 +0,0 @@
|
||||
/*
|
||||
SimpleChat client app for webOS.
|
||||
This app depends on a SimpleChat service, provided by webOS Archive at no cost for what remains of the webOS mobile community.
|
||||
*/
|
||||
|
||||
function MainAssistant() {
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
this.doingMessageEdit = false;
|
||||
this.serverRetries = 0;
|
||||
this.serverGiveUp = 4;
|
||||
}
|
||||
|
||||
MainAssistant.prototype.setup = function() {
|
||||
|
||||
// setup message field
|
||||
this.messageFieldModel = {
|
||||
'original': ''
|
||||
};
|
||||
this.messageFieldModel.attributes = {
|
||||
hintText: $L(" Enter a message..."),
|
||||
enterSubmits: false,
|
||||
focus: true,
|
||||
multiline: true,
|
||||
textCase: Mojo.Widget.steModeSentenceCase,
|
||||
focusMode: Mojo.Widget.focusSelectMode,
|
||||
autoReplace: true,
|
||||
autoEmoticons: true,
|
||||
emoticons: true,
|
||||
requiresEnterKey: true,
|
||||
changeOnKeyPress: false
|
||||
};
|
||||
this.controller.setupWidget(
|
||||
'txtMessage',
|
||||
this.messageFieldModel.attributes,
|
||||
this.messageFieldModel
|
||||
);
|
||||
//Loading spinner - with global members for easy toggling later
|
||||
this.spinnerAttrs = {
|
||||
spinnerSize: Mojo.Widget.spinnerSmall
|
||||
};
|
||||
this.spinnerModel = {
|
||||
spinning: false
|
||||
}
|
||||
this.controller.setupWidget('workingSpinner', this.spinnerAttrs, this.spinnerModel);
|
||||
//Chat Log List (starts empty)
|
||||
this.listElement = this.controller.get('chatList');
|
||||
this.listInfoModel = {
|
||||
items: [] //{ uid: "-1", sender: "none", message: "", formattedMessage: "" }
|
||||
};
|
||||
//Chat Log List templates (loads other HTML)
|
||||
this.template = {
|
||||
itemTemplate: 'main/item-template',
|
||||
listTemplate: 'main/list-template',
|
||||
hasNoWidgets: true,
|
||||
swipeToDelete: false,
|
||||
renderLimit: 25,
|
||||
reorderable: false,
|
||||
hasNoWidgets: true,
|
||||
onItemRendered: this.handleItemRendered.bind(this)
|
||||
};
|
||||
this.controller.setupWidget('chatList', this.template, this.listInfoModel);
|
||||
//Scroller
|
||||
this.scrollerModel = {
|
||||
mode: 'vertical',
|
||||
weight: 'light',
|
||||
friction: 'low'
|
||||
};
|
||||
this.controller.setupWidget('chatScroller', {}, this.scrollerModel);
|
||||
//Menu
|
||||
this.appMenuAttributes = { omitDefaultItems: true };
|
||||
this.appMenuModel = {
|
||||
label: "Settings",
|
||||
items: [
|
||||
Mojo.Menu.editItem,
|
||||
{ label: "SimpleChat Info", command: 'do-Info' },
|
||||
{ label: "Change Username", command: 'do-Username' },
|
||||
{ label: "Preferences", command: 'do-Preferences' },
|
||||
{ label: "About", command: 'do-myAbout' }
|
||||
]
|
||||
};
|
||||
this.controller.setupWidget(Mojo.Menu.appMenu, this.appMenuAttributes, this.appMenuModel);
|
||||
//Command Buttons
|
||||
this.cmdMenuAttributes = {
|
||||
spacerHeight: 0,
|
||||
menuClass: 'no-fade'
|
||||
};
|
||||
this.cmdMenuModel = {
|
||||
visible: true,
|
||||
items: [{
|
||||
items: [
|
||||
{ label: 'Emoticon', iconPath: 'assets/emoticon.png', command: 'do-Emoticon' }
|
||||
]
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{ label: 'Send', icon: 'send', command: 'do-Send' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
this.controller.setupWidget(Mojo.Menu.commandMenu, this.cmdMenuAttributes, this.cmdMenuModel);
|
||||
this.menuOn = true;
|
||||
|
||||
/* Always on Event handlers */
|
||||
Mojo.Event.listen(this.controller.get("chatList"), Mojo.Event.listTap, this.handleListClick.bind(this));
|
||||
Mojo.Event.listen(this.controller.stageController.document, Mojo.Event.stageActivate, this.activateWindow.bind(this));
|
||||
Mojo.Event.listen(this.controller.stageController.document, Mojo.Event.stageDeactivate, this.deactivateWindow.bind(this));
|
||||
|
||||
//Check for updates
|
||||
this.checkForUpdates();
|
||||
};
|
||||
|
||||
MainAssistant.prototype.activate = function(event) {
|
||||
//Figure out server info
|
||||
this.serviceEndpointBase = appModel.ServiceEndpointBase;
|
||||
if (appModel.AppSettingsCurrent["UseCustomEndpoint"] && appModel.AppSettingsCurrent["EndpointURL"]) {
|
||||
this.serviceEndpointBase = appModel.AppSettingsCurrent["EndpointURL"];
|
||||
}
|
||||
this.clientId = appModel.ClientId;
|
||||
if (appModel.AppSettingsCurrent["UseClientAPIKey"] && appModel.AppSettingsCurrent["ClientAPIKey"]) {
|
||||
this.clientId = appModel.AppSettingsCurrent["ClientAPIKey"];
|
||||
}
|
||||
//Set an alert sound
|
||||
if (!appModel.AppSettingsCurrent["AlertSound"] || appModel.AppSettingsCurrent["AlertSound"] == "") {
|
||||
appModel.AppSettingsCurrent["AlertSound"] = "Subtle (short)";
|
||||
}
|
||||
//Check for Emoji option
|
||||
if (appModel.AppSettingsCurrent["ShowEmojis"] == null) {
|
||||
Mojo.Log.info("Adding Emoji setting with default value!")
|
||||
appModel.AppSettingsCurrent["ShowEmojis"] = appModel.AppSettingsDefaults["ShowEmojis"];
|
||||
appModel.SaveSettings();
|
||||
}
|
||||
//Init Message memory
|
||||
if (!appModel.AppSettingsCurrent["MyMessages"]) {
|
||||
appModel.AppSettingsCurrent["MyMessages"] = [];
|
||||
}
|
||||
if (appModel.AppSettingsCurrent["LastKnownMessages"]) { //This was the old way, clean it up
|
||||
appModel.AppSettingsCurrent["LastKnownMessages"] = null;
|
||||
}
|
||||
|
||||
//Find out what kind of device this is
|
||||
if (Mojo.Environment.DeviceInfo.platformVersionMajor >= 3) {
|
||||
this.DeviceType = "TouchPad";
|
||||
Mojo.Log.info("Device detected as TouchPad");
|
||||
} else {
|
||||
if (this.controller.window.screen.width == 800 || this.controller.window.screen.height == 800) {
|
||||
this.DeviceType = "Pre3";
|
||||
Mojo.Log.info("Device detected as Pre3");
|
||||
} else if ((this.controller.window.screen.width == 480 || this.controller.window.screen.height == 480) && (this.controller.window.screen.width == 320 || this.controller.window.screen.height == 320)) {
|
||||
this.DeviceType = "Pre";
|
||||
Mojo.Log.warn("Device detected as Pre or Pre2");
|
||||
} else {
|
||||
this.DeviceType = "Tiny";
|
||||
Mojo.Log.warn("Device detected as Pixi or Veer");
|
||||
}
|
||||
}
|
||||
|
||||
//systemModel.PreventDisplaySleep();
|
||||
this.serverRetries = 0;
|
||||
this.pendingMessages = [];
|
||||
this.firstPoll = true;
|
||||
this.startPollingServer();
|
||||
this.handleTextFocus();
|
||||
|
||||
var currVersion = Mojo.Controller.appInfo.version;
|
||||
if (!welcomed && (!appModel.AppSettingsCurrent["LastVersionRun"] || appModel.AppSettingsCurrent["LastVersionRun"] != currVersion)) {
|
||||
this.pausePollingServer();
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ name: "version", disableSceneScroller: false });
|
||||
appModel.AppSettingsCurrent["LastVersionRun"] = currVersion;
|
||||
welcomed = true;
|
||||
} else {
|
||||
//Scale UI for orientation and listen for future orientation changes
|
||||
this.controller.window.addEventListener('resize', this.orientationChanged.bind(this)); //we have to do this for TouchPad because it does not get orientationChanged events
|
||||
this.orientationChanged();
|
||||
|
||||
//Add event handlers
|
||||
Mojo.Event.listen(this.controller.get("chatList"), Mojo.Event.listTap, this.handleListClick.bind(this));
|
||||
Mojo.Event.listenForFocusChanges(this.controller.get("txtMessage"), this.handleTextFocus.bind(this));
|
||||
this.controller.document.getElementById("divComposeTitle").addEventListener("click", this.toggleCommandMenu.bind(this));
|
||||
|
||||
//Figure out if this is our first time
|
||||
if (appModel.AppSettingsCurrent["FirstRun"] || !appModel.AppSettingsCurrent["SenderName"] || (appModel.AppSettingsCurrent["SenderName"] && appModel.AppSettingsCurrent["SenderName"].toLowerCase() == "webos user")) {
|
||||
appModel.AppSettingsCurrent["FirstRun"] = false;
|
||||
this.getUsername();
|
||||
} else {
|
||||
this.controller.get('txtMessage').mojo.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Screen Adjustments */
|
||||
MainAssistant.prototype.handleTextFocus = function(event) {
|
||||
this.adustScrollerForKeyboard(this.lastOrientation);
|
||||
}
|
||||
|
||||
//This is called by Mojo on phones, but has to be manually attached on TouchPad
|
||||
MainAssistant.prototype.orientationChanged = function() {
|
||||
if (this.DeviceType != "TouchPad") {
|
||||
//For phones, it doesn't make sense to allow wide orientations
|
||||
// But we need this for initial setup, so we'll force it to always be tall
|
||||
this.controller.stageController.setWindowOrientation("up");
|
||||
this.scaleScroller("tall")
|
||||
} else {
|
||||
if (this.controller.window.screen.height < this.controller.window.screen.width) { //touchpad orientations are sideways from phones
|
||||
this.scaleScroller("tall");
|
||||
} else {
|
||||
this.scaleScroller("wide");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MainAssistant.prototype.scaleScroller = function(orientation) {
|
||||
if (!this.lastOrientation || orientation != this.lastOrientation) {
|
||||
this.adustScrollerForKeyboard(orientation);
|
||||
this.controller.get('palm_anon_element_0mojo-scene-maintxtMessage-write').rows = "2";
|
||||
this.controller.get('palm_anon_element_0mojo-scene-maintxtMessage-write').setAttribute("x-palm-enable-emoticons", true);
|
||||
}
|
||||
this.lastOrientation = orientation;
|
||||
}
|
||||
|
||||
MainAssistant.prototype.adustScrollerForKeyboard = function(orientation) {
|
||||
//Handle virtual keyboard on Touchpad
|
||||
var bottomBuffer;
|
||||
this.chatScroller = this.controller.get("chatScroller");
|
||||
this.scalingFactor = this.controller.window.zoomFactor || 1;
|
||||
|
||||
if (this.DeviceType == "TouchPad") {
|
||||
if (this.controller.document.activeElement.id == "palm_anon_element_0mojo-scene-maintxtMessage-write")
|
||||
bottomBuffer = 600;
|
||||
else
|
||||
bottomBuffer = 260;
|
||||
} else
|
||||
bottomBuffer = 250;
|
||||
|
||||
if (orientation == "tall")
|
||||
this.scaledHeight = Math.floor(Mojo.Environment.DeviceInfo.screenHeight / this.scalingFactor) - bottomBuffer;
|
||||
else
|
||||
this.scaledHeight = Math.floor(Mojo.Environment.DeviceInfo.screenWidth / this.scalingFactor) - bottomBuffer;
|
||||
|
||||
Mojo.Log.info(this.DeviceType + " orientation is " + orientation + " bottom buffer is: " + bottomBuffer + " scaled height: " + this.scaledHeight);
|
||||
this.chatScroller.style.height = this.scaledHeight + "px";
|
||||
//this.scrollToBottom();
|
||||
|
||||
setTimeout(fixScroll = function() {
|
||||
this.controller.getSceneScroller().mojo.revealTop(true);
|
||||
}.bind(this), 100);
|
||||
}
|
||||
|
||||
/* Start and Stop service polling */
|
||||
MainAssistant.prototype.startPollingServer = function() {
|
||||
this.getChats();
|
||||
var useInt = 10000;
|
||||
if (appModel.AppSettingsCurrent["ForegroundUpdate"])
|
||||
useInt = appModel.AppSettingsCurrent["ForegroundUpdate"];
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
this.controller = stageController.activeScene();
|
||||
this.FileCheckInt = this.controller.window.setInterval(this.getChats.bind(this), useInt);
|
||||
}
|
||||
|
||||
MainAssistant.prototype.pausePollingServer = function() {
|
||||
this.controller.window.clearInterval(this.FileCheckInt);
|
||||
}
|
||||
|
||||
/* UI Handlers */
|
||||
MainAssistant.prototype.handleListClick = function(event) {
|
||||
appModel.LastMessageSelected = event.item;
|
||||
this.listTarget = event.originalEvent.target;
|
||||
|
||||
//Decide what items to put in pop-up menu
|
||||
var popupMenuItems = [];
|
||||
var isMine = false;
|
||||
for (var m = 0; m < appModel.AppSettingsCurrent["MyMessages"].length; m++) {
|
||||
if (appModel.AppSettingsCurrent["MyMessages"][m].uid == appModel.LastMessageSelected.uid)
|
||||
isMine = true;
|
||||
}
|
||||
if (isMine)
|
||||
popupMenuItems.push({ label: 'Edit Message', command: 'do-editMessage' });
|
||||
else {
|
||||
if (event.item.links != null) {
|
||||
popupMenuItems.push({ label: 'Copy Link', command: 'do-copyLink' });
|
||||
popupMenuItems.push({ label: 'Follow Link', command: 'do-followLink' });
|
||||
}
|
||||
popupMenuItems.push({ label: 'Copy Message', command: 'do-copy' });
|
||||
popupMenuItems.push({ label: 'Like', command: 'do-like' });
|
||||
}
|
||||
this.controller.popupSubmenu({
|
||||
onChoose: this.handlePopupChoose.bind(this, event.item),
|
||||
placeNear: this.listTarget,
|
||||
items: popupMenuItems
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
MainAssistant.prototype.handlePopupChoose = function(message, command) {
|
||||
//Mojo.Log.info("Perform: ", command, " on ", message.uid);
|
||||
switch (command) {
|
||||
case "do-copy":
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.setClipboard(appModel.LastMessageSelected.message);
|
||||
Mojo.Controller.getAppController().showBanner("Message copied!", { source: 'notification' });
|
||||
break;
|
||||
case "do-copyLink":
|
||||
var useLink = appModel.LastMessageSelected.links[0];
|
||||
if (useLink.toLowerCase().indexOf("http://") == -1 && useLink.toLowerCase().indexOf("https://") == -1)
|
||||
useLink = "http://" + appModel.LastMessageSelected.links[0];
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.setClipboard(useLink);
|
||||
Mojo.Controller.getAppController().showBanner("Link copied!", { source: 'notification' });
|
||||
break;
|
||||
case "do-followLink":
|
||||
var useLink = appModel.LastMessageSelected.links[0];
|
||||
if (useLink.toLowerCase().indexOf("http://") == -1 && useLink.toLowerCase().indexOf("https://") == -1)
|
||||
useLink = "http://" + appModel.LastMessageSelected.links[0];
|
||||
//TODO: Handle more than one link
|
||||
Mojo.Log.info("Launching browser for URL " + useLink);
|
||||
var parameters = {
|
||||
"id": "com.palm.app.browser",
|
||||
"params": {
|
||||
"target": useLink
|
||||
}
|
||||
}
|
||||
systemModel.LaunchApp("com.palm.app.browser", parameters);
|
||||
break;
|
||||
case "do-editMessage":
|
||||
this.doEditMessage(message);
|
||||
break;
|
||||
case "do-like":
|
||||
this.doLikeMessage(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.handleCommand = function(event) {
|
||||
if (event.type == Mojo.Event.command) {
|
||||
switch (event.command) {
|
||||
case 'do-Emoticon':
|
||||
var controller = this.controller;
|
||||
var onselect = function onEmoticonSelect(emoticon) {
|
||||
controller.document.execCommand("insertText", true, emoticon);
|
||||
};
|
||||
var emoticonPicker = new EmoticonPickerDialogAssistant(this, onselect);
|
||||
emoticonPicker.show();
|
||||
break;
|
||||
case 'do-Send':
|
||||
this.handleSendMessage();
|
||||
break;
|
||||
case 'do-Username':
|
||||
this.getUsername();
|
||||
break;
|
||||
case 'do-Preferences':
|
||||
this.pausePollingServer();
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ name: "preferences", disableSceneScroller: false });
|
||||
break;
|
||||
case 'do-Info':
|
||||
this.pausePollingServer();
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
stageController.pushScene({ name: "version", disableSceneScroller: false });
|
||||
break;
|
||||
case 'do-myAbout':
|
||||
Mojo.Additions.ShowDialogBox("SimpleChat - " + Mojo.Controller.appInfo.version, "SimpleChat client for webOS. Copyright 2021, Jon Wise. Distributed under an MIT License.<br>Source code available at: https://github.com/codepoet80/webos-simplechat");
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MainAssistant.prototype.doEditMessage = function(message) {
|
||||
this.controller.get('txtMessage').mojo.setValue(appModel.LastMessageSelected.message);
|
||||
this.controller.get('spanCompose').innerHTML = "Edit";
|
||||
this.doingMessageEdit = true;
|
||||
}
|
||||
|
||||
MainAssistant.prototype.doLikeMessage = function(message) {
|
||||
//post a like, update message, play a sound?
|
||||
if (!message.likes || message.likes == "" || message.likes == 0)
|
||||
message.likes = 1;
|
||||
else
|
||||
message.likes++;
|
||||
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("chatList");
|
||||
for (var i = 0; i < thisWidgetSetup.model.items.length; i++) {
|
||||
if (thisWidgetSetup.model.items[i].uid == appModel.LastMessageSelected.uid) {
|
||||
thisWidgetSetup.model.items[i].likes = message.likes;
|
||||
thisWidgetSetup.model.items[i].color = "gray";
|
||||
this.controller.get('chatList').mojo.noticeUpdatedItems(i, [thisWidgetSetup.model.items[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
this.likeMessageToService();
|
||||
}
|
||||
|
||||
/* Server Interactions */
|
||||
MainAssistant.prototype.handleSendMessage = function(event) {
|
||||
this.controller.get('txtMessage').mojo.blur();
|
||||
var newMessage = this.controller.get('txtMessage').mojo.getValue();
|
||||
this.disableUI();
|
||||
systemModel.PlaySound("down2");
|
||||
|
||||
if (this.doingMessageEdit) {
|
||||
this.editMessageToService(newMessage);
|
||||
} else {
|
||||
this.postMessageToService(newMessage);
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.postMessageToService = function(newMessage) {
|
||||
//Mojo.Log.info("Sending message:" + newMessage);
|
||||
serviceModel.postChat(appModel.AppSettingsCurrent["SenderName"], newMessage, this.serviceEndpointBase, this.clientId, function(response) {
|
||||
this.controller.get('txtMessage').mojo.setValue("");
|
||||
this.enableUI();
|
||||
try {
|
||||
var responseObj = JSON.parse(response);
|
||||
if (responseObj.error) {
|
||||
//Handle error
|
||||
Mojo.Log.error("Server error returned: " + responseObj.error);
|
||||
} else {
|
||||
Mojo.Log.info("Message accepted by server: " + responseObj.posted); //{ "posted": "604529e19fb7f", "senderKey": "604529e19fb99" }
|
||||
if (responseObj.posted) {
|
||||
Mojo.Log.info("responseObj: " + JSON.stringify(responseObj));
|
||||
var MojoHTML = Mojo.Format.runTextIndexer(newMessage);
|
||||
MojoHTML = MojoHTML.replace("file:///usr/palm/", "");
|
||||
|
||||
var newMsg = {
|
||||
uid: responseObj.posted,
|
||||
sender: appModel.AppSettingsCurrent["SenderName"],
|
||||
message: newMessage,
|
||||
formattedMessage: MojoHTML,
|
||||
timestamp: this.convertTimeStamp(new Date(), false),
|
||||
color: "gray"
|
||||
};
|
||||
if (responseObj.senderKey) {
|
||||
appModel.AppSettingsCurrent["MyMessages"].push({ uid: responseObj.posted, senderKey: responseObj.senderKey })
|
||||
}
|
||||
this.pendingMessages.push(responseObj.posted);
|
||||
|
||||
Mojo.Log.info("MyMessages now: " + JSON.stringify(appModel.AppSettingsCurrent["MyMessages"]));
|
||||
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("chatList");
|
||||
thisWidgetSetup.model.items.push(newMsg);
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
this.scrollToBottom();
|
||||
} else {
|
||||
Mojo.Log.warn("Did not understand server reponse to post!");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
//Handle error
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
MainAssistant.prototype.editMessageToService = function(newMessage) {
|
||||
|
||||
Mojo.Log.info("trying to edit: " + appModel.LastMessageSelected.uid);
|
||||
|
||||
//Set UI back to compose mode
|
||||
this.controller.get('txtMessage').mojo.setValue("");
|
||||
this.controller.get('spanCompose').innerHTML = "Compose";
|
||||
this.doingMessageEdit = false;
|
||||
this.enableUI();
|
||||
|
||||
var editKey; //Make sure we are allowed to edit this item
|
||||
for (var m = 0; m < appModel.AppSettingsCurrent["MyMessages"].length; m++) {
|
||||
if (appModel.AppSettingsCurrent["MyMessages"][m].uid == appModel.LastMessageSelected.uid)
|
||||
editKey = appModel.AppSettingsCurrent["MyMessages"][m].senderKey;
|
||||
}
|
||||
if (editKey) {
|
||||
//Force list item to update with new content (without informing Mojo, so the list doesn't bounce around. Mojo will get informed later)
|
||||
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("chatList");
|
||||
for (var i = 0; i < thisWidgetSetup.model.items.length; i++) {
|
||||
if (thisWidgetSetup.model.items[i].uid == appModel.LastMessageSelected.uid) {
|
||||
thisWidgetSetup.model.items[i].message = newMessage;
|
||||
|
||||
var MojoHTML = Mojo.Format.runTextIndexer(newMessage);
|
||||
MojoHTML = MojoHTML.replace("file:///usr/palm/", "");
|
||||
|
||||
thisWidgetSetup.model.items[i].formattedMessage = MojoHTML;
|
||||
thisWidgetSetup.model.items[i].color = "gray";
|
||||
this.controller.get('chatList').mojo.noticeUpdatedItems(i, [thisWidgetSetup.model.items[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
//Tell server about the edit
|
||||
serviceModel.editChat(appModel.AppSettingsCurrent["SenderName"], newMessage, appModel.LastMessageSelected.uid, editKey, this.serviceEndpointBase, this.clientId, function(response) {
|
||||
try {
|
||||
var responseObj = JSON.parse(response);
|
||||
if (responseObj.error) {
|
||||
Mojo.Log.error("Server error returned: " + responseObj.error);
|
||||
} else {
|
||||
if (responseObj.warning) {
|
||||
Mojo.Log.warn("Warning from server: " + responseObj.warning)
|
||||
} else {
|
||||
Mojo.Log.info("Edit accepted by server: " + responseObj.edited);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
//TODO: Handle error
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.likeMessageToService = function() {
|
||||
Mojo.Log.info("trying to like: " + appModel.LastMessageSelected.uid);
|
||||
|
||||
serviceModel.likeChat(appModel.LastMessageSelected.uid, this.serviceEndpointBase, this.clientId, function(response) {
|
||||
this.enableUI();
|
||||
try {
|
||||
var responseObj = JSON.parse(response);
|
||||
Mojo.Log.info("like response from server: " + response);
|
||||
if (responseObj.error) {
|
||||
Mojo.Log.error("Server error returned: " + responseObj.error);
|
||||
} else {
|
||||
Mojo.Log.info("Like accepted by server: " + responseObj.liked);
|
||||
}
|
||||
} catch (error) {
|
||||
//TODO: Handle error
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
//Send a request to Service to get chat messages
|
||||
MainAssistant.prototype.getChats = function() {
|
||||
if (this.serverRetries <= this.serverGiveUp) {
|
||||
serviceModel.getChats(this.serviceEndpointBase, function(response) {
|
||||
//Mojo.Log.info("getChat response: " + response);
|
||||
if (response != null && response != "") {
|
||||
var responseObj = JSON.parse(response);
|
||||
if (responseObj.status == "error") {
|
||||
Mojo.Log.error("Error message from server while fetch chats: " + responseObj.msg);
|
||||
Mojo.Additions.ShowDialogBox("Server Error", "The server responded to the chat request with: " + responseObj.msg.replace("ERROR: ", ""));
|
||||
} else {
|
||||
if (responseObj.messages && responseObj.messages.length > 0) {
|
||||
this.serverRetries = 0;
|
||||
this.updateChatsList(responseObj.messages);
|
||||
} else {
|
||||
Mojo.Log.warn("Search results were empty. This is unlikely; server, API or connectivity problem possible");
|
||||
Mojo.Additions.ShowDialogBox("No results", "The server did not report any matches for the search.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.error("No usable response from server while fetching chats: " + response);
|
||||
this.serverRetries++;
|
||||
if (this.serverRetries == this.serverGiveUp) {
|
||||
Mojo.Additions.ShowDialogBox("Server Error", "The server did not answer with a usable response to the chat request. Check network connectivity and/or self-host settings and re-launch the app.");
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
//Update the UI with search results from chat request
|
||||
MainAssistant.prototype.updateChatsList = function(results) {
|
||||
|
||||
Mojo.Log.info("Proccessing " + results.length + " chat messages...");
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("chatList");
|
||||
|
||||
//now make the new list
|
||||
var newMessages = [];
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
var MojoHTML = Mojo.Format.runTextIndexer(results[i].message);
|
||||
MojoHTML = MojoHTML.replace("file:///usr/palm/", "");
|
||||
|
||||
newMessages.push({
|
||||
uid: results[i].uid,
|
||||
sender: results[i].sender,
|
||||
message: results[i].message,
|
||||
formattedMessage: MojoHTML,
|
||||
postedFrom: results[i].postedFrom,
|
||||
links: this.detectURLs(results[i].message),
|
||||
timestamp: this.convertTimeStamp(results[i].timestamp, true),
|
||||
likes: results[i].likes,
|
||||
color: "black"
|
||||
});
|
||||
}
|
||||
var scrollPos = this.chatScroller.mojo.getState();
|
||||
|
||||
//Compare the known list to the new list to see if anything has changed...
|
||||
//Delete old messages
|
||||
var deleted = false;
|
||||
for (var m = 0; m < thisWidgetSetup.model.items.length; m++) {
|
||||
var found = false;
|
||||
for (var n = 0; n < newMessages.length; n++) {
|
||||
if (newMessages[n].uid == thisWidgetSetup.model.items[m].uid)
|
||||
found = true;
|
||||
}
|
||||
if (!found) {
|
||||
Mojo.Log.info("Removing deleted message from list at position " + m);
|
||||
this.controller.get('chatList').mojo.noticeRemovedItems(m, 1);
|
||||
thisWidgetSetup.model.items.splice(m, 1);
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
//Update existing messages (content or likes)
|
||||
var updated = false;
|
||||
for (var m = 0; m < thisWidgetSetup.model.items.length; m++) {
|
||||
for (var n = 0; n < newMessages.length; n++) {
|
||||
if (newMessages[n].uid == thisWidgetSetup.model.items[m].uid) {
|
||||
var changed = false;
|
||||
if (newMessages[n].message != thisWidgetSetup.model.items[m].message ||
|
||||
newMessages[n].likes != thisWidgetSetup.model.items[m].likes ||
|
||||
newMessages[n].color != thisWidgetSetup.model.items[m].color) {
|
||||
Mojo.Log.info("Updating message from list at position " + m);
|
||||
Mojo.Log.info("Old Message: " + JSON.stringify(thisWidgetSetup.model.items[m]));
|
||||
thisWidgetSetup.model.items[m] = newMessages[n];
|
||||
this.controller.get('chatList').mojo.noticeUpdatedItems(m, [thisWidgetSetup.model.items[m]]);
|
||||
changed = true;
|
||||
Mojo.Log.info("New Message should be: " + JSON.stringify(newMessages[n]));
|
||||
Mojo.Log.info("New Message is : " + JSON.stringify(thisWidgetSetup.model.items[m]));
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
//Insert new messages
|
||||
var inserted = [];
|
||||
if (thisWidgetSetup.model.items.length > 0) {
|
||||
for (var n = 0; n < newMessages.length; n++) {
|
||||
var found = false;
|
||||
for (var m = 0; m < thisWidgetSetup.model.items.length; m++) {
|
||||
if (thisWidgetSetup.model.items[m].uid == newMessages[n].uid) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
inserted.push(newMessages[n]);
|
||||
Mojo.Log.info("Found new message to add to the list: " + newMessages[n].uid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.info("The message list was empty, pushing entire server payload to the list.");
|
||||
inserted = newMessages;
|
||||
}
|
||||
//Handle UI due to changes
|
||||
if (inserted.length > 0 || updated || deleted) {
|
||||
if (inserted.length > 0) {
|
||||
if (!this.firstPoll) {
|
||||
systemModel.PlayAlertSound(appModel.AppSettingsCurrent["AlertSound"]);
|
||||
var offset = thisWidgetSetup.model.items.length - 1;
|
||||
for (var i = 0; i < inserted.length; i++) {
|
||||
thisWidgetSetup.model.items.push(inserted[i]);
|
||||
}
|
||||
this.controller.get('chatList').mojo.noticeAddedItems(offset, inserted);
|
||||
} else {
|
||||
thisWidgetSetup.model.items = inserted;
|
||||
|
||||
}
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
this.scrollToBottom();
|
||||
}
|
||||
} else {
|
||||
Mojo.Log.info("No changes to apply to list.")
|
||||
}
|
||||
this.firstPoll = false;
|
||||
|
||||
//Also clean-up MyMessage history
|
||||
for (var m = 0; m < appModel.AppSettingsCurrent["MyMessages"].length; m++) {
|
||||
var found = false;
|
||||
for (var n = 0; n < thisWidgetSetup.model.items.length; n++) {
|
||||
if (thisWidgetSetup.model.items[n].uid == appModel.AppSettingsCurrent["MyMessages"][m].uid)
|
||||
found = true;
|
||||
}
|
||||
if (!found) {
|
||||
appModel.AppSettingsCurrent["MyMessages"].splice(m, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Called by Mojo once the list has been painted, gives us an opportunity to force HTML into the message
|
||||
MainAssistant.prototype.handleItemRendered = function(listWidget, itemModel, itemNode) {
|
||||
itemNode.innerHTML = this.unescapeEntities(itemNode.innerHTML);
|
||||
|
||||
//Hide emojis if app settings say to do so
|
||||
if (!appModel.AppSettingsCurrent["ShowEmojis"]) {
|
||||
var emojis = this.controller.document.getElementsByName('emoji');
|
||||
for (var i = 0; i < emojis.length; i++) {
|
||||
emojis[i].style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Used to show or hide command menu buttons
|
||||
MainAssistant.prototype.toggleCommandMenu = function(show) {
|
||||
Mojo.Log.warn("Toggling command menu");
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
if (stageController) {
|
||||
this.controller = stageController.activeScene();
|
||||
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup(Mojo.Menu.commandMenu);
|
||||
var thisWidgetModel = thisWidgetSetup.model;
|
||||
if (!this.menuOn || show == true) {
|
||||
thisWidgetModel.visible = true;
|
||||
this.menuOn = true;
|
||||
this.controller.document.getElementById("imgTwisty").src = "assets/twisty-down.png";
|
||||
} else {
|
||||
thisWidgetModel.visible = false;
|
||||
this.menuOn = false;
|
||||
this.controller.document.getElementById("imgTwisty").src = "assets/twisty-right.png";
|
||||
}
|
||||
this.controller.modelChanged(thisWidgetModel);
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper Functions */
|
||||
MainAssistant.prototype.checkForUpdates = function() {
|
||||
if (!appModel.UpdateCheckDone) {
|
||||
appModel.UpdateCheckDone = true;
|
||||
updaterModel.CheckForUpdate("webOS SimpleChat", function(responseObj) {
|
||||
if (responseObj && responseObj.updateFound) {
|
||||
updaterModel.PromptUserForUpdate(function(response) {
|
||||
if (response)
|
||||
updaterModel.InstallUpdate();
|
||||
}.bind(this));
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.getUsername = function() {
|
||||
var stageController = Mojo.Controller.getAppController().getActiveStageController();
|
||||
if (stageController) {
|
||||
this.controller = stageController.activeScene();
|
||||
this.controller.showDialog({
|
||||
template: 'user/user-scene',
|
||||
preventCancel: true,
|
||||
assistant: new UserAssistant(this, function(val) {
|
||||
Mojo.Log.info("got value from dialog: " + val);
|
||||
}.bind(this)) //since this will be a dialog, not a scene, it must be defined in sources.json without a 'scenes' member
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.scrollToBottom = function() {
|
||||
this.chatScroller.mojo.revealBottom();
|
||||
setTimeout(function() {
|
||||
this.chatScroller.mojo.revealBottom();
|
||||
}.bind(this), 500);
|
||||
//this.controller.get('txtMessage').mojo.focus();
|
||||
}
|
||||
|
||||
MainAssistant.prototype.scrollToPosition = function(scrollPos) {
|
||||
Mojo.Log.info("Scrolling back to: " + JSON.stringify(scrollPos));
|
||||
this.chatScroller.mojo.setState(scrollPos, true);
|
||||
}
|
||||
|
||||
MainAssistant.prototype.unescapeEntities = function(str) {
|
||||
str = str.replace(/>/g, ">");
|
||||
str = str.replace(/</g, "<");
|
||||
return str;
|
||||
}
|
||||
|
||||
MainAssistant.prototype.convertTimeStamp = function(timeStamp, isUTC) {
|
||||
if (isUTC) {
|
||||
var offset = new Date().getTimezoneOffset();
|
||||
timeStamp = Date.parse(timeStamp);
|
||||
timeStamp = timeStamp - ((offset * 60) * 1000);
|
||||
timeStamp = new Date(timeStamp);
|
||||
}
|
||||
timeStamp = timeStamp.toLocaleString();
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
MainAssistant.prototype.detectURLs = function(message) {
|
||||
if (!message) return
|
||||
var urlRegex = /(((https?:\/\/)|(www\.))[^\s]+)/g;
|
||||
return message.match(urlRegex)
|
||||
}
|
||||
|
||||
MainAssistant.prototype.disableUI = function(statusValue) {
|
||||
//start spinner
|
||||
if (!this.spinnerModel.spinning) {
|
||||
this.spinnerModel.spinning = true;
|
||||
this.controller.modelChanged(this.spinnerModel);
|
||||
}
|
||||
}
|
||||
|
||||
MainAssistant.prototype.enableUI = function() {
|
||||
//stop spinner
|
||||
this.spinnerModel.spinning = false;
|
||||
this.controller.modelChanged(this.spinnerModel);
|
||||
this.controller.get('txtMessage').mojo.focus();
|
||||
}
|
||||
|
||||
MainAssistant.prototype.rememberLastMessage = function() {
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("chatList");
|
||||
if (thisWidgetSetup.model.items.length > 0) {
|
||||
appModel.AppSettingsCurrent["LastKnownMessage"] = thisWidgetSetup.model.items[thisWidgetSetup.model.items.length - 1].uid;
|
||||
appModel.SaveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
/* Mojo Lifecycle Stuff */
|
||||
MainAssistant.prototype.activateWindow = function(event) {
|
||||
this.rememberLastMessage();
|
||||
};
|
||||
|
||||
MainAssistant.prototype.deactivateWindow = function(event) {
|
||||
this.rememberLastMessage();
|
||||
};
|
||||
|
||||
MainAssistant.prototype.deactivate = function(event) {
|
||||
/* remove any event handlers you added in activate and do any other cleanup that should happen before
|
||||
this scene is popped or another scene is pushed on top */
|
||||
Mojo.Log.info("Main scene deactivated " + Mojo.Controller.appInfo.id);
|
||||
|
||||
//Remember last known messages
|
||||
this.pausePollingServer();
|
||||
this.rememberLastMessage();
|
||||
|
||||
//Detach UI
|
||||
Mojo.Event.stopListening(this.controller.get("chatList"), Mojo.Event.listTap, this.handleListClick);
|
||||
this.controller.window.removeEventListener('resize', this.orientationChanged);
|
||||
this.controller.document.getElementById("divComposeTitle").removeEventListener("click", this.toggleCommandMenu.bind(this));
|
||||
|
||||
Mojo.Event.stopListening(this.controller.stageController.document, Mojo.Event.stageActivate, this.activateWindow);
|
||||
Mojo.Event.stopListening(this.controller.stageController.document, Mojo.Event.stageDeactivate, this.deactivateWindow);
|
||||
};
|
||||
|
||||
MainAssistant.prototype.cleanup = function(event) {
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
appController.closeAllStages();
|
||||
};
|
||||
@@ -1,296 +0,0 @@
|
||||
function PreferencesAssistant() {
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
}
|
||||
|
||||
PreferencesAssistant.prototype.setup = function() {
|
||||
/* setup widgets here */
|
||||
|
||||
//Timeout picker
|
||||
this.controller.setupWidget("listForegroundUpdate",
|
||||
this.attributes = {
|
||||
label: $L("Foreground Update"),
|
||||
choices: [
|
||||
{ label: "5 seconds", value: 5000 },
|
||||
{ label: "10 seconds", value: 10000 },
|
||||
{ label: "30 second", value: 30000 },
|
||||
{ label: "1 minute", value: 60000 },
|
||||
{ label: "2 minutes", value: 120000 },
|
||||
{ label: "5 minutes", value: 180000 },
|
||||
]
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["ForegroundUpdate"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
var backgroundValue;
|
||||
if (!appModel.AppSettingsCurrent["BackgroundUpdate"] || appModel.AppSettingsCurrent["BackgroundUpdate"] == 0 || appModel.AppSettingsCurrent["BackgroundUpdate"] == "")
|
||||
backgroundValue = "-1";
|
||||
else
|
||||
backgroundValue = appModel.AppSettingsCurrent["BackgroundUpdate"]
|
||||
this.controller.setupWidget("listBackgroundUpdate",
|
||||
this.attributes = {
|
||||
label: $L("Background Update"),
|
||||
choices: [
|
||||
{ label: "Off", value: -1 },
|
||||
{ label: "30 minutes", value: "00:30:00" },
|
||||
{ label: "1 Hour", value: "01:00:00" },
|
||||
{ label: "2 Hours", value: "02:00:00" },
|
||||
{ label: "5 Hours", value: "05:00:00" },
|
||||
]
|
||||
},
|
||||
this.model = {
|
||||
value: backgroundValue,
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//Emoji toggle
|
||||
this.controller.setupWidget("toggleEmojis",
|
||||
this.attributes = {
|
||||
trueValue: true,
|
||||
falseValue: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["ShowEmojis"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//Setup sound picker
|
||||
this.soundChoices = {
|
||||
choices: [
|
||||
{ label: "Choose...", value: "choose" },
|
||||
{ label: "Off", value: "off" }
|
||||
]
|
||||
};
|
||||
if (appModel.AppSettingsCurrent["AlertSound"] != "off") {
|
||||
var useVal = appModel.AppSettingsCurrent["AlertSound"];
|
||||
var labelVal = useVal;
|
||||
if (Mojo.Environment.DeviceInfo.platformVersionMajor < 3) {
|
||||
labelVal = useVal.substring(0, 8) + "...";
|
||||
}
|
||||
this.soundChoices.choices.unshift({ label: labelVal, value: useVal });
|
||||
}
|
||||
this.controller.setupWidget("listAlertSound",
|
||||
this.attributes = this.soundChoices,
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["AlertSound"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//API Toggles
|
||||
this.controller.setupWidget("toggleClientAPI",
|
||||
this.attributes = {
|
||||
trueValue: true,
|
||||
falseValue: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["UseClientAPIKey"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("toggleCustomEndPoint",
|
||||
this.attributes = {
|
||||
trueValue: true,
|
||||
falseValue: false
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["UseCustomEndpoint"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
//API Text fields
|
||||
this.controller.setupWidget("txtClientAPI",
|
||||
this.attributes = {
|
||||
hintText: $L("Your Client Id"),
|
||||
multiline: false,
|
||||
enterSubmits: false,
|
||||
autoReplace: false,
|
||||
focus: false,
|
||||
autoFocus: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["ClientAPIKey"],
|
||||
disabled: !appModel.AppSettingsCurrent["UseClientAPIKey"]
|
||||
}
|
||||
);
|
||||
this.controller.setupWidget("txtEndpointURL",
|
||||
this.attributes = {
|
||||
hintText: $L("http://your-chat-server.com/"),
|
||||
multiline: false,
|
||||
enterSubmits: false,
|
||||
autoReplace: false,
|
||||
textCase: Mojo.Widget.steModeLowerCase
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["EndpointURL"],
|
||||
disabled: !appModel.AppSettingsCurrent["UseCustomEndpoint"]
|
||||
}
|
||||
);
|
||||
//OK Button
|
||||
this.controller.setupWidget("btnOK", { type: Mojo.Widget.activityButton }, { label: "Done", disabled: false });
|
||||
//Menu
|
||||
this.appMenuAttributes = { omitDefaultItems: true };
|
||||
this.appMenuModel = {
|
||||
label: "Settings",
|
||||
items: [
|
||||
Mojo.Menu.editItem,
|
||||
{ label: "Reset Settings", command: 'do-resetSettings' }
|
||||
]
|
||||
};
|
||||
this.controller.setupWidget(Mojo.Menu.appMenu, this.appMenuAttributes, this.appMenuModel);
|
||||
|
||||
/* add event handlers to listen to events from widgets */
|
||||
Mojo.Event.listen(this.controller.get("listForegroundUpdate"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("listBackgroundUpdate"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("toggleEmojis"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("listAlertSound"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("txtClientAPI"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("txtEndpointURL"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("toggleClientAPI"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("toggleCustomEndPoint"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.controller.get("btnOK"), Mojo.Event.tap, this.okClick.bind(this));
|
||||
};
|
||||
|
||||
PreferencesAssistant.prototype.activate = function(event) {
|
||||
/* put in event handlers here that should only be in effect when this scene is active. For
|
||||
example, key handlers that are observing the document */
|
||||
//this.showBetaFeatures();
|
||||
};
|
||||
|
||||
PreferencesAssistant.prototype.showBetaFeatures = function() {
|
||||
//No beta features right now
|
||||
}
|
||||
|
||||
PreferencesAssistant.prototype.handleValueChange = function(event) {
|
||||
|
||||
Mojo.Log.info(event.srcElement.id + " value changed to " + event.value);
|
||||
switch (event.srcElement.id) {
|
||||
case "toggleEmojis":
|
||||
Mojo.Log.info("Should show banner!");
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Re-launch app to apply this setting" }, "", "");
|
||||
break;
|
||||
case "listAlertSound":
|
||||
if (event.value == "choose") {
|
||||
this.setAlarmSound();
|
||||
} else {
|
||||
appModel.AppSettingsCurrent["AlertSound"] = event.value;
|
||||
}
|
||||
break;
|
||||
case "toggleClientAPI":
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("txtClientAPI");
|
||||
thisWidgetSetup.model.disabled = !event.value;
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
if (event.value)
|
||||
this.controller.get('txtClientAPI').mojo.focus();
|
||||
break;
|
||||
case "toggleCustomEndPoint":
|
||||
var thisWidgetSetup = this.controller.getWidgetSetup("txtEndpointURL");
|
||||
thisWidgetSetup.model.disabled = !event.value;
|
||||
this.controller.modelChanged(thisWidgetSetup.model);
|
||||
if (event.value)
|
||||
this.controller.get('txtEndpointURL').mojo.focus();
|
||||
break;
|
||||
case "txtEndpointURL":
|
||||
var lastChar = event.value[event.value.length - 1]
|
||||
if (lastChar != "/") {
|
||||
event.value = event.value + "/";
|
||||
Mojo.Log.warn("Custom end point URL was missing trailing slash, it has been added. Value is now: " + event.value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//We stashed the preference name in the title of the HTML element, so we don't have to use a case statement
|
||||
Mojo.Log.info(event.srcElement.title + " now: " + event.value);
|
||||
appModel.AppSettingsCurrent[event.srcElement.title] = event.value;
|
||||
appModel.SaveSettings();
|
||||
|
||||
//Show/hide beta features
|
||||
this.showBetaFeatures();
|
||||
};
|
||||
|
||||
// opens ringtone picker.
|
||||
PreferencesAssistant.prototype.setAlarmSound = function() {
|
||||
var self = this;
|
||||
var params = {
|
||||
defaultKind: 'ringtone',
|
||||
onSelect: function(file) {
|
||||
var fileToUse = file.fullPath.replace("/media/internal/ringtones/", "").replace(".mp3", "");
|
||||
appModel.AppSettingsCurrent["AlertSound"] = fileToUse;
|
||||
appModel.SaveSettings();
|
||||
|
||||
var useVal = fileToUse;
|
||||
var labelVal = useVal;
|
||||
try {
|
||||
if (Mojo.Environment.DeviceInfo.platformVersionMajor < 3) {
|
||||
labelVal = useVal.substring(0, 8) + "...";
|
||||
}
|
||||
} catch (ex) {
|
||||
Mojo.Log.error("Could not set ringtone value");
|
||||
}
|
||||
|
||||
self.soundChoices.choices[0].label = labelVal;
|
||||
self.soundChoices.choices[0].value = useVal;
|
||||
|
||||
var thisWidgetSetup = self.controller.getWidgetSetup("listAlertSound");
|
||||
var thisWidgetModel = thisWidgetSetup.model;
|
||||
thisWidgetModel.value = fileToUse;
|
||||
|
||||
self.controller.setWidgetModel("listAlertSound", thisWidgetModel);
|
||||
self.controller.modelChanged(thisWidgetModel);
|
||||
|
||||
Mojo.Log.info("alarm sound changed to: " + fileToUse)
|
||||
|
||||
}
|
||||
}
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
var stageController = appController.getStageProxy("main");
|
||||
Mojo.FilePicker.pickFile(params, stageController);
|
||||
}
|
||||
|
||||
//Handle menu and button bar commands
|
||||
PreferencesAssistant.prototype.handleCommand = function(event) {
|
||||
if (event.type == Mojo.Event.command) {
|
||||
switch (event.command) {
|
||||
case 'do-goBack':
|
||||
this.okClick();
|
||||
break;
|
||||
case 'do-resetSettings':
|
||||
appModel.ResetSettings(appModel.AppSettingsDefaults);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PreferencesAssistant.prototype.okClick = function(event) {
|
||||
var appController = Mojo.Controller.getAppController();
|
||||
var stageController = appController.getStageProxy("main");
|
||||
stageController.popScene();
|
||||
}
|
||||
|
||||
PreferencesAssistant.prototype.deactivate = function(event) {
|
||||
/* remove any event handlers you added in activate and do any other cleanup that should happen before
|
||||
this scene is popped or another scene is pushed on top */
|
||||
|
||||
systemModel.ClearSystemAlarm("SimpleChat");
|
||||
if (appModel.AppSettingsCurrent["BackgroundUpdate"] && appModel.AppSettingsCurrent["BackgroundUpdate"] != "" && appModel.AppSettingsCurrent["BackgroundUpdate"] != -1)
|
||||
systemModel.SetSystemAlarmRelative("SimpleChat", appModel.AppSettingsCurrent["BackgroundUpdate"]);
|
||||
|
||||
Mojo.Event.stopListening(this.controller.get("listForegroundUpdate"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("listBackgroundUpdate"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("listAlertSound"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("txtClientAPI"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("toggleClientAPI"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("toggleCustomEndPoint"), Mojo.Event.propertyChange, this.handleValueChange);
|
||||
Mojo.Event.stopListening(this.controller.get("btnOK"), Mojo.Event.tap, this.okClick.bind(this));
|
||||
|
||||
};
|
||||
|
||||
PreferencesAssistant.prototype.cleanup = function(event) {
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
function StageAssistant() {
|
||||
/* this is the creator function for your stage assistant object */
|
||||
}
|
||||
|
||||
StageAssistant.prototype.activate = function() {
|
||||
Mojo.Log.error("Stage activated");
|
||||
stageController = Mojo.Controller.stageController;
|
||||
if (stageController.getScenes().length < 1)
|
||||
stageController.pushScene('main');
|
||||
}
|
||||
|
||||
StageAssistant.prototype.setup = function() {
|
||||
Mojo.Log.info("Stage assistant created!");
|
||||
};
|
||||
@@ -1,79 +0,0 @@
|
||||
function UserAssistant(sceneAssistant, doneCallBack) {
|
||||
this.doneCallBack = doneCallBack;
|
||||
/* this is the creator function for your scene assistant object. It will be passed all the
|
||||
additional parameters (after the scene name) that were passed to pushScene. The reference
|
||||
to the scene controller (this.controller) has not be established yet, so any initialization
|
||||
that needs the scene controller should be done in the setup function below. */
|
||||
Mojo.Log.info("new User assistant exists");
|
||||
this.sceneAssistant = sceneAssistant; //dialog's do not have their own controller, so need access to the launching scene's controller
|
||||
}
|
||||
|
||||
UserAssistant.prototype.setup = function(widget) {
|
||||
/* this function is for setup tasks that have to happen when the scene is first created */
|
||||
this.widget = widget;
|
||||
Mojo.Log.info("User assistant setup");
|
||||
Mojo.Log.info("Current username is: " + appModel.AppSettingsCurrent["SenderName"]);
|
||||
|
||||
/* setup widgets here */
|
||||
this.sceneAssistant.controller.setupWidget("txtUserName",
|
||||
this.attributes = {
|
||||
textFieldName: "userName",
|
||||
hintText: " Enter nickname",
|
||||
property: 'value',
|
||||
multi: false,
|
||||
enterSubmits: true,
|
||||
changeOnKeyPress: false,
|
||||
textReplacement: false,
|
||||
requiresEnterKey: false,
|
||||
focus: true
|
||||
},
|
||||
this.model = {
|
||||
value: appModel.AppSettingsCurrent["SenderName"],
|
||||
disabled: false
|
||||
}
|
||||
);
|
||||
this.sceneAssistant.controller.setupWidget("goButton", { type: Mojo.Widget.defaultButton }, { label: "OK", disabled: false });
|
||||
//this.sceneAssistant.controller.setupWidget("cancelButton", { type: Mojo.Widget.button }, { label: "Cancel", disabled: false });
|
||||
|
||||
/* add event handlers to listen to events from widgets */
|
||||
Mojo.Event.listen(this.sceneAssistant.controller.get("txtUserName"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.listen(this.sceneAssistant.controller.get("goButton"), Mojo.Event.tap, this.handleGoPress.bind(this));
|
||||
//Mojo.Event.listen(this.sceneAssistant.controller.get("cancelButton"), Mojo.Event.tap, this.handleCancelPress.bind(this));
|
||||
};
|
||||
|
||||
UserAssistant.prototype.handleValueChange = function(event) {
|
||||
this.handleGoPress();
|
||||
};
|
||||
|
||||
UserAssistant.prototype.handleGoPress = function(event) {
|
||||
var newName = this.sceneAssistant.controller.get('txtUserName').mojo.getValue();
|
||||
if (newName && newName != "" && newName != " " && newName.toLowerCase() != "webos user") {
|
||||
//Remember the name they entered
|
||||
appModel.AppSettingsCurrent["SenderName"] = newName;
|
||||
appModel.SaveSettings();
|
||||
this.doneCallBack(newName);
|
||||
this.widget.mojo.close();
|
||||
} else {
|
||||
Mojo.Controller.getAppController().showBanner({ messageText: "Provide a unique username!" }, "", "");
|
||||
}
|
||||
}
|
||||
|
||||
UserAssistant.prototype.activate = function(event) {
|
||||
this.sceneAssistant.controller.get('txtUserName').mojo.focus();
|
||||
/* put in event handlers here that should only be in effect when this scene is active. For
|
||||
example, key handlers that are observing the document */
|
||||
};
|
||||
|
||||
UserAssistant.prototype.deactivate = function(event) {
|
||||
/* remove any event handlers you added in activate and do any other cleanup that should happen before
|
||||
this scene is popped or another scene is pushed on top */
|
||||
Mojo.Event.stopListening(this.sceneAssistant.controller.get("txtUserName"), Mojo.Event.propertyChange, this.handleValueChange.bind(this));
|
||||
Mojo.Event.stopListening(this.sceneAssistant.controller.get("goButton"), Mojo.Event.tap, this.handleGoPress.bind(this));
|
||||
//Mojo.Event.stopListening(this.sceneAssistant.controller.get("cancelButton"), Mojo.Event.tap, this.handleCancelPress.bind(this));
|
||||
};
|
||||
|
||||
UserAssistant.prototype.cleanup = function(event) {
|
||||
Mojo.Log.info("user assistant cleaned up");
|
||||
/* this function should do any cleanup needed before the scene is destroyed as
|
||||
a result of being popped off the scene stack */
|
||||
};
|
||||
@@ -1,103 +0,0 @@
|
||||
var ServiceModel = function() {
|
||||
|
||||
};
|
||||
|
||||
ServiceModel.prototype.getChats = function(serviceBase, callback) {
|
||||
serviceURL = serviceBase + "get-chat.php";
|
||||
Mojo.Log.info("Trying to get chats from: " + serviceURL);
|
||||
this.retVal = "";
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", serviceURL);
|
||||
xmlhttp.send();
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (callback)
|
||||
callback(xmlhttp.responseText);
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
ServiceModel.prototype.postChat = function(useSender, useMessage, serviceBase, clientId, callback) {
|
||||
serviceURL = serviceBase + "post-chat.php";
|
||||
var msgToPost = {
|
||||
sender: useSender,
|
||||
message: useMessage
|
||||
}
|
||||
Mojo.Log.info("Posting chat to: " + serviceURL);
|
||||
Mojo.Log.info(JSON.stringify(msgToPost));
|
||||
|
||||
this.retVal = "";
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("POST", serviceURL);
|
||||
xmlhttp.setRequestHeader("Client-Id", clientId);
|
||||
xmlhttp.timeout = 2000;
|
||||
xmlhttp.send(JSON.stringify(msgToPost));
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
Mojo.Log.info("ready state: " + xmlhttp.readyState);
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (callback)
|
||||
callback(xmlhttp.responseText);
|
||||
}
|
||||
}.bind(this);
|
||||
xmlhttp.ontimeout = function() {
|
||||
callback();
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
ServiceModel.prototype.editChat = function(useSender, useMessage, uid, editKey, serviceBase, clientId, callback) {
|
||||
serviceURL = serviceBase + "edit-chat.php";
|
||||
var msgToPost = {
|
||||
sender: useSender,
|
||||
message: useMessage,
|
||||
uid: uid,
|
||||
editKey: editKey
|
||||
}
|
||||
Mojo.Log.info("Edit chat to: " + serviceURL);
|
||||
Mojo.Log.info(JSON.stringify(msgToPost));
|
||||
|
||||
this.retVal = "";
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("POST", serviceURL);
|
||||
xmlhttp.setRequestHeader("Client-Id", clientId);
|
||||
xmlhttp.send(JSON.stringify(msgToPost));
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (callback)
|
||||
callback(xmlhttp.responseText);
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
ServiceModel.prototype.likeChat = function(uid, serviceBase, clientId, callback) {
|
||||
serviceURL = serviceBase + "like-chat.php";
|
||||
var msgToPost = {
|
||||
uid: uid,
|
||||
like: "+1"
|
||||
}
|
||||
Mojo.Log.info("Like chat to: " + serviceURL);
|
||||
Mojo.Log.info(JSON.stringify(msgToPost));
|
||||
|
||||
this.retVal = "";
|
||||
if (callback)
|
||||
callback = callback.bind(this);
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("POST", serviceURL);
|
||||
xmlhttp.setRequestHeader("Client-Id", clientId);
|
||||
xmlhttp.send(JSON.stringify(msgToPost));
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||
if (callback)
|
||||
callback(xmlhttp.responseText);
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
<div>
|
||||
<table width="100%" id="emo-table">
|
||||
</table>
|
||||
|
||||
<div id="cancel_button" class="palm-button" x-mojo-tap-highlight="momentary">
|
||||
<span x-mojo-loc="">Cancel</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +0,0 @@
|
||||
<div class="palm-row" x-mojo-tap-highlight='momentary'>
|
||||
<div class="palm-row-wrapper">
|
||||
<div id="divMsg-#{uid}" class="chat-log" style="color:#{color}"><span class="sender #{postedFrom}">#{sender}:</span> #{formattedMessage}</div>
|
||||
<div class="chat-time">#{timestamp} <span class="likes">#{likes}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="palm-list">
|
||||
<div> #{-listElements}</div>
|
||||
</div>
|
||||
@@ -1,24 +0,0 @@
|
||||
<div class="palm-page-header">
|
||||
<div class="header-icon preferences"></div>
|
||||
<div class="header-text">
|
||||
<span x-mojo-loc='' style="text-transform:none;">webOS SimpleChat 2</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="showChatList" name="showChatList" style="display:block;">
|
||||
<div class="palm-group">
|
||||
<div class="palm-group-title"><span x-mojo-loc=''>Chat Log</span></div>
|
||||
<div x-mojo-element="Scroller" id="chatScroller" class="scrollerClass" name="chatScroller" style="height: 100px;padding: 0px;margin:-8px;">
|
||||
<div id="chatList" x-mojo-element="List"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group" style="min-height:64px">
|
||||
<div class="palm-group-title" id="divComposeTitle"><span x-mojo-loc='' id="spanCompose">Compose</span> <img src="assets/twisty-down.png" id="imgTwisty"></div>
|
||||
<div x-mojo-element="TextField" id="txtMessage" class="textFieldClass" name="txtMessage" style="min-height:56px; background-color:white;border: 1px solid dimgray"></div>
|
||||
<div id="divSpinnerContainer" style="width: 30px;margin-left: auto;margin-right: auto; align-items: center; margin-top:-25px;">
|
||||
<div x-mojo-element="Spinner" class="spinnerClass" id="workingSpinner" name="workingSpinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
<div class="palm-hasheader" style="margin-bottom:60px">
|
||||
<div id="watchViewTitle" class="palm-header center" onclick="Mojo.Controller.stageController.popScene();">
|
||||
Preferences
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group">
|
||||
<div class="palm-group-title">
|
||||
<span x-mojo-loc=''>Basic</span>
|
||||
</div>
|
||||
|
||||
<div class="palm-list" id="divTest">
|
||||
<div class="palm-row first">
|
||||
<div class="palm-row-wrapper">
|
||||
<div id="listForegroundUpdate" x-mojo-element="ListSelector" title="ForegroundUpdate" class="right"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper">
|
||||
<div id="listBackgroundUpdate" x-mojo-element="ListSelector" title="BackgroundUpdate" class="right"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper">
|
||||
<div x-mojo-element="ToggleButton" id="toggleEmojis" title="ShowEmojis"></div>
|
||||
<div class="title" style="margin-left: -4px; float:left;"><span class="label">Discord Emojis</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row last">
|
||||
<div class="palm-row-wrapper">
|
||||
<span x-mojo-loc="" id="SoundOptionLabel" width="100%" class="label truncating-text" style="float:left; min-width:120px; margin-left: 14px; margin-top: 14px;">Alert Sound</span>
|
||||
<div x-mojo-element="ListSelector" id="listAlertSound" class="listselectorClass" style="float:right" name="listAlertSound"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-group">
|
||||
<div class="palm-group-title">
|
||||
<span x-mojo-loc=''>Self Hosting</span>
|
||||
</div>
|
||||
|
||||
<div class="palm-list">
|
||||
|
||||
<div class="palm-row first">
|
||||
<div class="palm-row-wrapper">
|
||||
<div x-mojo-element="ToggleButton" id="toggleClientAPI" title="UseClientAPIKey"></div>
|
||||
<div class="title" style="margin-left: -4px; float:left;"><span class="label">Custom Client Id</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row">
|
||||
<div class="palm-row-wrapper" style="margin:14px 22px 4px 12px">
|
||||
<div id="txtClientAPI" name="txtClientAPI" x-mojo-element="TextField" title="ClientAPIKey"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row first">
|
||||
<div class="palm-row-wrapper">
|
||||
<div x-mojo-element="ToggleButton" id="toggleCustomEndPoint" title="UseCustomEndpoint"></div>
|
||||
<div class="title" style="margin-left: -4px; float:left;"><span class="label">Custom Endpoint URL</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-row last">
|
||||
<div class="palm-row-wrapper" style="margin:14px 22px 4px 12px">
|
||||
<div id="txtEndpointURL" name="txtEndpointURL" x-mojo-element="TextField" title="EndpointURL"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="explanation-text">For more information on self-hosting, please visit <a href="https://github.com/codepoet80/simplechat-service">https://github.com/codepoet80/simplechat-service</a></div>
|
||||
<div x-mojo-element="Button" id="btnOK" name="btnOK"></div>
|
||||
@@ -1,21 +0,0 @@
|
||||
<div class="palm-dialog-content">
|
||||
<div id="hue-title" class="palm-dialog-title">
|
||||
Getting Acquainted
|
||||
</div>
|
||||
<div class="palm-dialog-seperator" style="height: 8px;"></div>
|
||||
<div class="palm-body-text">
|
||||
SimpleChat is a lightweight message board for webOS. It keeps a log of recent messages, and allows you to post public messages.<br> How do you want to identify yourself?
|
||||
</div>
|
||||
|
||||
<div class="textfield-group" x-mojo-focus-highlight="true" id="divUserInfo" style="display:block; margin-left: 15px; margin-right: 15px;">
|
||||
<div class="title">
|
||||
<div id="txtUserName" name="txtUserName" x-mojo-element="TextField" title="senderName"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="palm-dialog-seperator" style="height: 18px;"></div>
|
||||
|
||||
<div class="palm-dialog-buttons">
|
||||
<div x-mojo-element="Button" id="goButton"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"id": "com.jonandnic.simplechat.app",
|
||||
"version": "2.0.0",
|
||||
"vendor": "Jon Wise",
|
||||
"type": "web",
|
||||
"main": "index.html",
|
||||
"noWindow": true,
|
||||
"title": "SimpleChat",
|
||||
"icon": "icon.png",
|
||||
"uiRevision": "2",
|
||||
"theme": "light"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 8.8 KiB |