Merge branch 'playbook'

Conflicts:
	app/appinfo.json
	app/index.html
	pkg/packageinfo.json

Merged development branch for PlayBook support.
This commit is contained in:
Morgan McMillian 2012-03-17 17:32:47 -04:00
commit 823ff70f8a
12 changed files with 334 additions and 45 deletions

View file

@ -1,6 +1,6 @@
{ {
"id": "com.monkeystew.todotxtenyo.beta", "id": "com.monkeystew.todotxtenyo.beta",
"version": "0.1.1", "version": "0.2.0",
"vendor": "Monkeystew", "vendor": "Monkeystew",
"type": "web", "type": "web",
"main": "index.html", "main": "index.html",

View file

@ -16,6 +16,11 @@
appInstance.renderInto(document.body); appInstance.renderInto(document.body);
</script> </script>
<div id="history" style="display: none"> <div id="history" style="display: none">
<div class="version">0.2.0</div>
<ul>
<li>Intial BlackBerry PlayBook support.</li>
<li>Insert for project, context, and priority on add or edit.</li>
</ul>
<div class="version">0.1.1</div> <div class="version">0.1.1</div>
<ul> <ul>
<li>Bugfix: race condition when deleting certain entries.</li> <li>Bugfix: race condition when deleting certain entries.</li>

View file

@ -141,10 +141,16 @@ enyo.kind({
this.requestToken = tokens[1].split("=")[1]; this.requestToken = tokens[1].split("=")[1];
console.log("...launching browser window..."); console.log("...launching browser window...");
this.$.launch.call({ if (this.owner.os == "BlackBerry") {
var args = new blackberry.invoke.BrowserArguments(url);
blackberry.invoke.invoke(
blackberry.invoke.APP_BROWSER, args);
} else {
this.$.launch.call({
"id": "com.palm.app.browser", "id": "com.palm.app.browser",
"params": {"target": url} "params": {"target": url}
}); });
}
} }
}, },

View file

@ -22,9 +22,33 @@ enyo.kind({
"onSave": "" "onSave": ""
}, },
components: [ components: [
{name: "insertPopup", kind: "ModalDialog", dismissWithClick: true,
{flex: 1, kind: "Scroller", components: [ layoutKind: "VFlexLayout", height: "60%",
{kind: "RichText", name: "tododetail"}, contentHeight: "100%", onClose: "closePopup",
components: [
{flex: 1, name: "iscroller", kind: "Scroller",
components: [
{name: "projects", kind: "RowGroup", caption: "Projects"},
{name: "contexts", kind: "RowGroup", caption: "Contexts"}
]}
]},
{name: "filterToolbar", kind: "Toolbar", pack: "justify", className: "enyo-toolbar-light",
components: [
{kind: "RadioGroup", name: "priGroup",
onChange: "setPriority", components: [
{caption: "-", value: "-"},
{caption: "A", value: "A"},
{caption: "B", value: "B"},
{caption: "C", value: "C"},
{caption: "D", value: "D"},
{caption: "E", value: "E"}
]},
{kind: "Button", caption: "+", onclick: "showInsert"}
]
},
{flex: 1, name: "scroller", kind: "Scroller", components: [
{kind: "RichText", name: "tododetail", richContent: false,
className: "enyo-box-input"},
]}, ]},
{name: "editToolbar", kind: "Toolbar", pack: "justify", className: "enyo-toolbar-light", {name: "editToolbar", kind: "Toolbar", pack: "justify", className: "enyo-toolbar-light",
components: [ components: [
@ -35,6 +59,65 @@ enyo.kind({
] ]
} }
] ],
setPriority: function(inSender) {
var pri = inSender.getValue();
var val = this.$.tododetail.getValue();
val = val.replace(/^\([A-E]\)\s/,"")
if (pri.match(/[A-E]/)) {
this.$.tododetail.setValue(
"(" + pri + ") " + val);
} else {
this.$.tododetail.setValue( val );
}
},
showInsert: function() {
this.$.insertPopup.openAtCenter();
this.projectList = this.owner.$.listView.getProjectList();
for (i=0; i<this.projectList.length; i++) {
var project = this.projectList[i];
var name = project.replace(/^\+/,"PRJ_");
this.$.projects.createComponent(
{content: project, name: name, owner: this,
onclick: "insert"}
);
}
this.$.projects.render();
this.contextList = this.owner.$.listView.getContextList();
for (i=0; i<this.contextList.length; i++) {
var context = this.contextList[i];
var name = context.replace(/^@/,"CTX_");
this.$.contexts.createComponent(
{content: context, name: name, owner: this,
onclick: "insert"}
);
}
this.$.contexts.render();
this.$.iscroller.render();
},
closePopup: function() {
for (i=0; i<this.projectList.length; i++) {
var name = this.projectList[i].replace(/^\+/,"PRJ_");
eval("this.$."+name+".destroy()");
}
this.$.projects.render();
for (i=0; i<this.contextList.length; i++) {
var name = this.contextList[i].replace(/^@/,"CTX_");
eval("this.$."+name+".destroy()");
}
this.$.contexts.render();
this.$.tododetail.forceFocus();
this.$.insertPopup.close();
},
insert: function(inSender, inEvent) {
var val = this.$.tododetail.getValue();
this.$.tododetail.setValue(val + " " + inSender.content);
this.closePopup();
this.$.tododetail.forceFocus();
}
}); });

View file

@ -23,6 +23,9 @@ enyo.kind({
sortOrder: "pri", sortOrder: "pri",
cacheChanges: "NO", cacheChanges: "NO",
searchFilter: null, searchFilter: null,
priorityList: [],
projectList: [],
contextList: [],
sortedList: undefined sortedList: undefined
}, },
events: { events: {
@ -32,31 +35,44 @@ enyo.kind({
}, },
components: [ components: [
{name: "todoPopup", kind: "ModalDialog", components: [ {name: "todoPopup", kind: "ModalDialog", dismissWithClick: true,
{kind: "Button", caption: "Complete", onclick: "completeTodoItem"}, onClose: "closePopup", components: [
{kind: "Button", caption: "Prioritize", onclick: "showPriList"}, {kind: "RowGroup", components: [
{kind: "Button", caption: "Update", onclick: "updateTodoItem"}, {content:"Complete", onclick:"completeTodoItem",
{kind: "Button", caption: "Delete", onclick: "deleteTodoItem"}, style: "text-align:center"},
{kind: "Button", caption: "Dismiss", onclick: "closePopup"} {content:"Prioritize", onclick:"showPriList",
style: "text-align:center"},
{content:"Update", onclick:"updateTodoItem",
style: "text-align:center"},
{content:"Delete", onclick:"deleteTodoItem",
style: "text-align:center"}
]}
]}, ]},
{name: "completedPopup", kind: "ModalDialog", components: [ {name: "completedPopup", kind: "ModalDialog",
{kind: "Button", caption: "Undo Complete", onclick: "undoCompleteTodoItem"}, dismissWithClick: true, onClose: "closePopup", components: [
{kind: "Button", caption: "Delete", onclick: "deleteTodoItem"}, {kind: "RowGroup", components: [
{kind: "Button", caption: "Dismiss", onclick: "closePopup"} {content:"Undo Complete",
onclick:"undoCompleteTodoItem",
style: "text-align:center"},
{content:"Delete", onclick:"deleteTodoItem",
style: "text-align:center"}
]}
]}, ]},
{name: "priorityPopup", kind: "ModalDialog", components: [ {name: "priorityPopup", kind: "ModalDialog",
{kind: "HtmlContent", content: "Select priority"}, dismissWithClick: true, onClose: "closePopup", components: [
{kind: "RadioGroup", name: "priGroup", onChange: "setPriority", components: [ {kind: "RowGroup", caption:"Select Priority", components: [
{caption: "-", value: "-"}, {kind: "RadioGroup", name: "priGroup",
{caption: "A", value: "A"}, onChange: "setPriority", components: [
{caption: "B", value: "B"}, {caption: "-", value: "-"},
{caption: "C", value: "C"}, {caption: "A", value: "A"},
{caption: "D", value: "D"}, {caption: "B", value: "B"},
{caption: "E", value: "E"} {caption: "C", value: "C"},
]}, {caption: "D", value: "D"},
{kind: "Button", caption: "Dismiss", onclick: "closePopup"} {caption: "E", value: "E"}
]}
]}
]}, ]},
{kind: "SearchInput", name: "searchbox", onchange: "searchList", onCancel: "clearSearch"}, {kind: "SearchInput", name: "searchbox", onchange: "searchList", onCancel: "clearSearch", className: "enyo-box-input"},
{flex: 1, kind: "Scroller", name: "scroller", components: [ {flex: 1, kind: "Scroller", name: "scroller", components: [
{kind: "VirtualRepeater", name: "todoList", {kind: "VirtualRepeater", name: "todoList",
onSetupRow: "getTodoList", onclick: "todoTap", onSetupRow: "getTodoList", onclick: "todoTap",
@ -105,6 +121,35 @@ enyo.kind({
var r = this.sortedList[inIndex]; var r = this.sortedList[inIndex];
if (r) { if (r) {
//TODO: currently not used, is it needed in future?
if (this.priorityListReset) {
this.priorityList = [];
this.priorityListReset = false;
}
if (r.pri) {
if (this.priorityList.indexOf(r.pri[0]) == -1)
this.priorityList.push(r.pri[0]);
} //TODO: end quetionable code
if (this.projectListReset) {
this.projectList = [];
this.projectListReset = false;
}
var project = r.detail.match(/\+[^\s]+/);
if (project) {
project = project[0].replace(/\./,"");
if (this.projectList.indexOf(project) == -1)
this.projectList.push(project);
}
if (this.contextListReset) {
this.contextList = [];
this.contextListReset = false;
}
var context = r.detail.match(/\@[^\s]+/);
if (context) {
context = context[0].replace(/\./,"");
if (this.contextList.indexOf(context) == -1)
this.contextList.push(context);
}
var filtered = false; var filtered = false;
var s = r.detail.replace(/^x\s/,""); var s = r.detail.replace(/^x\s/,"");
var s = s.replace(/^\([A-E]\)\s/,""); var s = s.replace(/^\([A-E]\)\s/,"");
@ -134,6 +179,9 @@ enyo.kind({
this.$.todoRow.hide(); this.$.todoRow.hide();
} }
return true; return true;
} else {
this.priorityListReset = true;
this.projectListReset = true;
} }
}, },
@ -194,6 +242,13 @@ enyo.kind({
}, },
updateTodoItem: function() { updateTodoItem: function() {
if (this.owner.todoList[this.selectedId].pri) {
var pri = this.owner.todoList[this.selectedId].pri[0];
pri = pri.replace(/^\(([A-E])\)\s.*$/,"$1");
this.owner.$.editView.$.priGroup.setValue(pri);
} else {
this.owner.$.editView.$.priGroup.setValue("-");
}
this.owner.$.editView.$.tododetail.setValue(this.owner.todoList[this.selectedId].detail); this.owner.$.editView.$.tododetail.setValue(this.owner.todoList[this.selectedId].detail);
this.replaceItem = true; this.replaceItem = true;
this.owner.showEditView(); this.owner.showEditView();
@ -259,8 +314,8 @@ enyo.kind({
this.$.todoPopup.close(); this.$.todoPopup.close();
this.$.completedPopup.close(); this.$.completedPopup.close();
this.$.priorityPopup.close(); this.$.priorityPopup.close();
this.selectedIndex = null; //this.selectedIndex = null;
this.selectedId = null; //this.selectedId = null;
this.$.todoList.render(); this.$.todoList.render();
}, },

View file

@ -82,7 +82,7 @@ enyo.kind({
} }
]}, ]},
{kind: "Item", layoutKind: "HFlexLayout", {kind: "Item", layoutKind: "HFlexLayout",
name: "dboxpathselect", showing: true, name: "dboxpathselect", showing: false,
components: [ components: [
{flex: 1, kind: "Input", name: "dboxpath", {flex: 1, kind: "Input", name: "dboxpath",
preferenceProperty: "dboxpath", preferenceProperty: "dboxpath",
@ -137,7 +137,11 @@ enyo.kind({
if (inSender.preferenceProperty == "storage") { if (inSender.preferenceProperty == "storage") {
if (value == "file") { if (value == "file") {
//this.$.todoFilePicker.pickFile(); //this.$.todoFilePicker.pickFile();
var mypath = "/media/internal/todo/todo.txt" if (this.owner.os == "BlackBerry") {
var mypath = this.owner.dirs.shared.documents.path + "/todo/todo.txt";
} else {
var mypath = "/media/internal/todo/todo.txt"
}
this.owner.preferences["filepath"] = mypath; this.owner.preferences["filepath"] = mypath;
this.$.filepath.setValue(mypath); this.$.filepath.setValue(mypath);
this.$.filepath.render(); this.$.filepath.render();

View file

@ -26,9 +26,9 @@ enyo.kind({
{caption: "Preferences", onclick: "showPrefView"}, {caption: "Preferences", onclick: "showPrefView"},
{caption: "About", onclick: "showAbout"} {caption: "About", onclick: "showAbout"}
]}, ]},
{kind: "Popup", name: "about", layoutKind: "VFlexLayout", {kind: "ModalDialog", name: "about", layoutKind: "VFlexLayout",
contentHeight: "100%", height: "80%", width: "80%", contentHeight: "100%", height: "80%", width: "80%",
components: [ dismissWithClick: true, components: [
{name: "aboutTitle", content: ""}, {name: "aboutTitle", content: ""},
{content: "by Morgan McMillian"}, {content: "by Morgan McMillian"},
{kind: "Divider", caption: "Version History"}, {kind: "Divider", caption: "Version History"},
@ -44,7 +44,8 @@ enyo.kind({
{name: "viewTitle", kind: "HtmlContent", {name: "viewTitle", kind: "HtmlContent",
className: "todo-view-title", content: ""} className: "todo-view-title", content: ""}
]}, ]},
{flex: 1, kind: "Pane", onSelectView: "viewSelected", components: [ {flex: 1, kind: "Pane", onSelectView: "viewSelected",
transitionKind: enyo.transitions.Simple, components: [
{name: "listView", kind: "TodoList", onEdit: "showEditView", {name: "listView", kind: "TodoList", onEdit: "showEditView",
onPrefs: "showPrefView", onReload: "refreshTodo" onPrefs: "showPrefView", onReload: "refreshTodo"
}, },
@ -88,7 +89,23 @@ enyo.kind({
], ],
ready: function() { ready: function() {
this.$.getConn.call();
if (window.PalmSystem) {
this.$.getConn.call();
this.os = "webOS";
} else if (window.blackberry) {
this.os = "BlackBerry";
this.dirs = blackberry.io.dir.appDirs;
// hack for RichText not working properly
this.$.editView.$.tododetail.destroy();
this.$.editView.$.scroller.createComponent(
{kind: "Input", name: "tododetail",
className: "enyo-box-input", owner:this.$.editView}
);
this.$.editView.render();
} else {
this.os = "unknown";
}
this.preferences = localStorage.getItem("TodoPreferences"); this.preferences = localStorage.getItem("TodoPreferences");
if (this.preferences == undefined) { if (this.preferences == undefined) {
@ -124,7 +141,14 @@ enyo.kind({
this.$.viewTitle.setContent("[offline]"); this.$.viewTitle.setContent("[offline]");
} }
this.$.makeDir.call({ path: "/media/internal/todo" }); if (this.os == "BlackBerry") {
var path = this.dirs.shared.documents.path + "/todo";
if (!blackberry.io.dir.exists(path)) {
blackberry.io.dir.createNewDir(path);
}
} else {
this.$.makeDir.call({ path: "/media/internal/todo" });
}
this.todoList = []; this.todoList = [];
this.refreshTodo(); this.refreshTodo();
@ -183,6 +207,7 @@ enyo.kind({
this.$.viewTitle.setContent("update task"); this.$.viewTitle.setContent("update task");
} else { } else {
this.$.viewTitle.setContent("add task"); this.$.viewTitle.setContent("add task");
this.$.editView.$.priGroup.setValue("-");
} }
this.$.editView.$.tododetail.forceFocus(); this.$.editView.$.tododetail.forceFocus();
}, },
@ -213,12 +238,17 @@ enyo.kind({
}, },
closeView: function() { closeView: function() {
this.$.listView.setReplaceItem(false);
this.$.editView.$.tododetail.setValue(""); this.$.editView.$.tododetail.setValue("");
this.$.pane.selectViewByName("listView"); this.$.pane.selectViewByName("listView");
}, },
parseFile: function(path, file) { parseFile: function(path, file) {
var todofile = file.content.split("\n"); if (file.content != undefined) {
todofile = file.content.split("\n");
} else {
todofile = "";
}
this.todoList = []; this.todoList = [];
for (line in todofile) { for (line in todofile) {
if (todofile[line]) { if (todofile[line]) {
@ -242,8 +272,15 @@ enyo.kind({
for (item in list) { for (item in list) {
data = data + list[item].detail + "\n"; data = data + list[item].detail + "\n";
} }
this.$.writeFile.call({ if (this.os == "BlackBerry") {
path: path, content: data }); if (blackberry.io.file.exists(path)) {
blackberry.io.file.deleteFile(path);
}
blackberry.io.file.saveFile(path,
blackberry.utils.stringToBlob(data));
} else {
this.$.writeFile.call({ path: path, content: data });
}
if (this.preferences["storage"] == "dropbox" && if (this.preferences["storage"] == "dropbox" &&
this.preferences["offline"] == false && this.preferences["offline"] == false &&
@ -285,7 +322,20 @@ enyo.kind({
}, },
getLocalFile: function() { getLocalFile: function() {
this.$.readFile.call({ path: this.preferences["filepath"] }); var path = this.preferences["filepath"];
if (this.os == "BlackBerry") {
if (blackberry.io.file.exists(path)) {
blackberry.io.file.readFile(path,
function(fpath, blob) {
var data = blackberry.utils.blobToString(blob);
appInstance.parseFile(null, {content: data});
}
);
}
} else {
this.$.readFile.call({ path: path });
//this.$.readFile.call({ path: this.preferences["filepath"] });
}
}, },
loadDropbox: function(inSender, inResponse, inRequest) { loadDropbox: function(inSender, inResponse, inRequest) {
@ -297,15 +347,25 @@ enyo.kind({
}, },
resetPreferences: function() { resetPreferences: function() {
localStorage.clear();
this.preferences = new Object(); this.preferences = new Object();
this.preferences["storage"] = "file"; this.preferences["storage"] = "file";
this.preferences["offline"] = true; this.preferences["offline"] = true;
this.preferences["filepath"] = "/media/internal/todo/todo.txt";
this.preferences["dboxpath"] = "/todo"; this.preferences["dboxpath"] = "/todo";
if (this.os == "BlackBerry") {
var path = this.dirs.shared.documents.path + "/todo/todo.txt";
this.preferences["filepath"] = path;
} else {
this.preferences["filepath"] = "/media/internal/todo/todo.txt";
}
// reset the preferences pane
this.$.preferenceView.$.offline.setChecked(true); this.$.preferenceView.$.offline.setChecked(true);
this.$.preferenceView.$.dboxlogout.hide(); this.$.preferenceView.$.dboxlogout.hide();
this.$.preferenceView.$.dboxpathselect.hide(); this.$.preferenceView.$.dboxpathselect.hide();
this.$.preferenceView.$.filepathselect.show(); this.$.preferenceView.$.filepathselect.show();
// save preferences
localStorage.setItem("TodoPreferences", JSON.stringify(this.preferences)); localStorage.setItem("TodoPreferences", JSON.stringify(this.preferences));
}, },

View file

@ -33,3 +33,4 @@
} }
.ver-history { font-size: 16px; } .ver-history { font-size: 16px; }
.version { font-weight: bold;} .version { font-weight: bold;}
.enyo-modaldialog > * { height:100%; }

33
bbww/appindex.html Normal file
View file

@ -0,0 +1,33 @@
<!doctype html>
<html>
<head>
<title>Todo.txt Enyo</title>
<meta name="viewport" content="height=device-height,width=device-width">
<script src="enyo-1.0-r1/framework/enyo.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
var appInstance = enyo.create({kind: "TodoTxt"});
if (window.PalmSystem && enyo.windowParams) {
appInstance.setLaunchParams(enyo.windowParams);
}
appInstance.renderInto(document.body);
</script>
<div id="history" style="display: none">
<div class="version">0.2.0</div>
<ul>
<li>Intial BlackBerry PlayBook support.</li>
<li>Insert for project, context, and priority on add or edit.</li>
</ul>
<div class="version">0.1.1</div>
<ul>
<li>Bugfix: race condition when deleting certain entries.</li>
</ul>
<div class="version">0.1.0</div>
<ul>
<li>Initial open source and beta release.</li>
</ul>
</div>
</body>
</html>

43
bbww/config.xml Normal file
View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Widget Configuration Reference:
http://docs.blackberry.com/en/developers/deliverables/15274/
-->
<widget xmlns="http://www.w3.org/ns/widgets"
xmlns:rim="http://www.blackberry.com/ns/widgets"
version="0.2.0">
<name>Todo.txt Enyo</name>
<author href="http://monkeystew.org" rim:copyright="Copyright 2012 Morgan McMillian">Morgan McMillian</author>
<description>
A mobile application for managing your todo.txt file written using the EnyoJS framework.
</description>
<license href="http://www.apache.org/licenses/LICENSE-2.0">
</license>
<feature id="blackberry.io.dir" required="true" version="1.0.0.0" />
<feature id="blackberry.io.file" required="true" version="1.0.0.0" />
<feature id="blackberry.utils" required="true" version="1.0.0.0" />
<feature id="blackberry.invoke" required="true" version="1.0.0.0" />
<!-- PhoneGap API -->
<access subdomains="true" uri="file:///store/home" />
<access subdomains="true" uri="file:///SDCard" />
<!-- Expose access to all URIs, including the file and http protocols -->
<access subdomains="true" uri="*" />
<icon src="icon.png" />
<content src="appindex.html" />
<rim:permissions>
<rim:permit>access_shared</rim:permit>
</rim:permissions>
</widget>

View file

@ -3,7 +3,7 @@
"package_format_version": 2, "package_format_version": 2,
"loc_name": "Todo.txt Enyo", "loc_name": "Todo.txt Enyo",
"icon": "icon.png", "icon": "icon.png",
"version": "0.1.1", "version": "0.2.0",
"vendor": "Monkeystew", "vendor": "Monkeystew",
"app": "com.monkeystew.todotxtenyo.beta", "app": "com.monkeystew.todotxtenyo.beta",
"services": ["com.monkeystew.todotxtenyo.beta.service"] "services": ["com.monkeystew.todotxtenyo.beta.service"]

View file

@ -9,7 +9,6 @@ ReadFileAssistant.prototype.run = function(future) {
fs.readFile(path, 'utf8', function(err,data) { fs.readFile(path, 'utf8', function(err,data) {
//future.result = { path: path, content: data }; //future.result = { path: path, content: data };
setTimeout(function () { setTimeout(function () {
console.log("delay test...");
future.result = { path: path, content: data }; future.result = { path: path, content: data };
}, 100); }, 100);
}); });