blob: c16dde4b5349885ce6b37acee459ce0aa5041320 [file] [log] [blame]
<!DOCTYPE html>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-->
<div id="bodydiv" class="body">
<div id="viewform" class="viewform">
<form id="userForm">
<table style="width: 100%;">
<tr><tr><td class="label">Username:</td></tr>
<tr><td><input type="text" id="userName" class="readentry" size="30" readonly="readonly" placeholder="Your username" style="width: 300px;"/></td></tr>
<tr><tr><td class="label">Email:</td></tr>
<tr><td><input type="text" id="userEmail" class="readentry" size="30" readonly="readonly" placeholder="Your email address" style="width: 300px;"/></td></tr>
<tr><tr><td class="label">Picture:</td></tr>
<tr><td><img id="userPicture" style="width: 50px; height: 50px; vertical-align: top;"/><input id="uploadPicture" type="button" class="lightbutton" value="Upload"/><input id="uploadFile" type="file" accept="image/*" style="visibility: hidden;"/><span id="refreshingPicture" class="refreshing" style="display:none;"/></td></tr>
<tr><tr><td class="label">Name:</td></tr>
<tr><td><input type="text" id="userFullname" class="flatentry" size="30" placeholder="Your name" style="width: 300px;"/></td></tr>
<tr><tr><td class="label">Bio:</td></tr>
<tr><td><textarea id="userDescription" class="flatentry" cols="40" rows="3" placeholder="About yourself, in fewer than 120 characters" style="width: 300px;"></textarea></td></tr>
</table>
<br/>
<!--
TODO Disabled for now
<table style="width: 100%;">
<tr>
<th class="thl thr" style="padding-top: 4px; padding-bottom: 4px; padding-left: 2px; padding-right: 2px; ">Calendar</th>
</tr>
</table>
<table>
<tr><td style="padding-right: 2px;"><input type="text" id="sched1" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service1" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="sched2" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service2" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="sched3" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service3" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="sched4" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service4" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="sched5" class="flatentry" size="10" placeholder="Schedule" style="width: 80px;"/></td><td><input type="text" id="service5" class="flatentry" size="2048" placeholder="Service URL" style="width: 200px;"/></td></tr>
</table>
<br/>
<table style="width: 100%;">
<tr>
<th class="thl thr" style="padding-top: 4px; padding-bottom: 4px; padding-left: 2px; padding-right: 2px; ">Key chain</th>
</tr>
</table>
<table>
<tr><td style="padding-right: 2px;"><input type="text" id="name1" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value1" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name2" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value2" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name3" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value3" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name4" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value4" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name5" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value5" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name6" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value6" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name7" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value7" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name8" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value8" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name9" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value9" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
<tr><td style="padding-right: 2px;"><input type="text" id="name10" class="flatentry" size="10" placeholder="Key name" style="width: 80px;"/></td><td><input type="text" id="value10" class="flatentry" size="2048" placeholder="Key value" style="width: 200px;"/></td></tr>
</table>
</form>
<br/>
-->
</div>
<script type="text/javascript">
(function accountbody() {
/**
* Setup page layout.
*/
(function layout() {
document.title = config.windowtitle() + ' - Account';
$('viewhead').innerHTML = '<span class="cmenu">' + username + '</span>' +
'<input type="button" class="redbutton plusminus" style="position: absolute; top: 4px; left: 2px;" id="deleteUser" value="-" title="Delete your account" disabled="true"/>';
if (!ui.isMobile())
$('viewform').className = 'viewform flatscrollbars';
$('userName').value = username;
})();
/**
* Set images.
*/
$('userPicture').src = ui.b64png(appcache.get('/public/user.b64'));
/**
* Initialize service references.
*/
var editorComp = sca.component("Editor");
var user= sca.defun(sca.reference(editorComp, "user"));
var accounts = sca.reference(editorComp, "accounts");
var pictures = sca.reference(editorComp, "pictures");
/**
* The current account entry and corresponding saved XML content.
*/
var savedacctxml = '';
var savedpicxml = '';
/**
* Get and display the user's account.
*/
(function getacct() {
workingstatus(true);
showstatus('Loading');
return accounts.get('', function(doc) {
// Stop now if we didn't get an account
if (doc == null) {
errorstatus('Account info not available');
workingstatus(false);
return false;
}
var acctentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
$('userFullname').value = cadr(assoc("'title", acctentry));
var acct = cadr(assoc("'content", acctentry));
var email = assoc("'email", acct);
$('userEmail').value = isNull(email) || isNull(cdr(email))? (username.indexOf('@') != -1? username : '') : cadr(email);
var desc = assoc("'description", acct);
$('userDescription').innerHTML = isNull(desc) || isNull(cdr(desc))? '' : cadr(desc);
/* TODO disabled for now
var cal = assoc("'calendar", acct);
reduce(function(i, evt) {
var sched = assoc("'@schedule", evt);
var svc = assoc("'@service", evt);
$('sched' + i).value = isNull(sched)? '' : cadr(sched);
$('service' + i).value = isNull(svc)? '' : cadr(svc);
return i + 1;
}, 1, isNull(cal)? mklist() : cadr(cadr(cal)));
var keys = assoc("'keys", acct);
reduce(function(i, key) {
var kn = assoc("'@name", key);
var kv = assoc("'@value", key);
$('name' + i).value = isNull(kn)? '' : cadr(kn);
$('value' + i).value = isNull(kv)? '' : cadr(kv);
return i + 1;
}, 1, isNull(keys)? mklist() : cadr(cadr(keys)));
*/
savedacctxml = car(atom.writeATOMEntry(valuesToElements(mklist(acctentry))));
return true;
});
return true;
})();
/**
* Get and display the user's picture.
*/
(function getpic() {
workingstatus(true);
showstatus('Loading');
return pictures.get('', function(doc) {
// Stop now if we didn't get a picture
if (doc == null) {
errorstatus('Picture not available');
workingstatus(false);
return false;
}
var picentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
savedpicxml = car(atom.writeATOMEntry(valuesToElements(mklist(picentry))));
var content = assoc("'content", picentry);
var picture = assoc("'picture", content);
var img = assoc("'image", picture);
if (!isNull(img))
$('userPicture').src = cadr(img);
onlinestatus();
workingstatus(false);
return true;
});
return true;
})();
/**
* Refresh picture.
*/
var refreshingpic = false;
function refreshpic() {
if (!refreshingpic)
return false;
$('refreshingPicture').style.display = 'inline-block';
return pictures.get('', function(doc) {
if (doc == null) {
errorstatus('Picture not available');
$('refreshingPicture').style.display = 'none';
refreshingpic = false;
return false;
}
var picentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
var content = assoc("'content", picentry);
var picture = assoc("'picture", content);
var token = assoc("'token", picture);
// Update picture
if (isNull(token)) {
var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(picentry))));
savedpicxml = entryxml;
var img = assoc("'image", picture);
if (!isNull(img))
$('userPicture').src = cadr(img);
$('refreshingPicture').style.display = 'none';
refreshingpic = false;
return true;
}
// Refresh in 2 secs
return ui.delay(refreshpic, 2000);
}, 'remote');
return true;
}
/**
* Save the user's account.
*/
function saveacct(entryxml) {
if (isNull(username))
return false;
workingstatus(true);
showstatus('Saving');
savedacctxml = entryxml;
accounts.put('', savedacctxml, function(e) {
if (e) {
showstatus('Local copy');
workingstatus(false);
return false;
}
showstatus('Saved');
workingstatus(false);
return true;
});
return true;
}
/**
* Save the user's picture.
*/
function savepic(entryxml) {
if (isNull(username))
return false;
workingstatus(true);
showstatus('Uploading');
savedpicxml = entryxml;
pictures.put('', savedpicxml, function(e) {
if (e) {
showstatus('Local copy');
workingstatus(false);
return false;
}
showstatus('Uploaded');
workingstatus(false);
return true;
});
return true;
}
/**
* Handle a change event
*/
function onaccountchange() {
// Validate user input
var title = $('userFullname').value;
if (title.length == 0) {
errorstatus('Name cannot be empty');
return false;
}
if (title.length > 40) {
errorstatus('Name cannot be longer than 40 characters');
return false;
}
var email = $('userEmail').value;
var description = $('userDescription').value;
if (description.length > 120) {
errorstatus('Bio cannot be longer than 120 characters');
return false;
}
/* TODO disabled for now
var cal = map(function(i) {
var sched = $('sched' + i).value;
var svc = $('service' + i).value;
return mklist("'event", mklist("'@schedule", sched), mklist("'@service", svc));
}, range(1, 6));
var keys = map(function(i) {
var kn = $('name' + i).value;
var kv = $('value' + i).value;
return mklist("'key", mklist("'@name", kn), mklist("'@value", kv));
}, range(1, 11));
var acctentry = mklist("'entry", mklist("'title", title != ''? title : username), mklist("'id", username),
mklist("'content", mklist("'account", mklist("'email", email), mklist("'description", description), cons("'keys", keys), cons("'calendar", cal))));
*/
var acctentry = mklist("'entry", mklist("'title", title != ''? title : username), mklist("'id", username),
mklist("'content", mklist("'account", mklist("'email", email), mklist("'description", description))));
var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(acctentry))));
if (savedacctxml == entryxml)
return false;
showstatus('Modified');
return saveacct(entryxml);
}
$('userFullname').onchange = onaccountchange;
$('userDescription').onchange = onaccountchange;
/* TODO disabled for now
map(function(i) {
$('sched' + i).onchange = onaccountchange;
$('service' + i).onchange = onaccountchange;
return true;
}, range(1, 6));
map(function(i) {
$('name' + i).onchange = onaccountchange;
$('value' + i).onchange = onaccountchange;
return true;
}, range(1, 11));
*/
/**
* Handle a key event.
*/
var lastkeyup = null;
$('userFullname').onkeyup = $('userDescription').onkeyup = function() {
var t = new Date().getTime();
lastkeyup = t;
ui.async(function() {
return t == lastkeyup? onaccountchange() : true;
}, 2000);
};
/**
* Handle a form submit event.
*/
$('userForm').onsubmit = function() {
onaccountchange();
return false;
};
/**
* Read and upload icon file.
*/
function readpic(files) {
if (!files || files.length == 0)
return false;
if (!files[0].type.match('image.*')) {
errorstatus('Please select an image');
return false;
}
workingstatus(true);
showstatus('Loading');
// Read the selected file into a 50x50 image
return ui.readimage(files[0],
function(e) {
errorstatus('Couldn\'t read the file');
workingstatus(false);
},
function(p) {
showstatus('Loading ' + p + '%');
},
function(url) {
// Update the user picture
$('userPicture').src = url;
showstatus('Loaded');
// Now upload it
ui.async(function() {
var picentry = mklist("'entry", mklist("'title", username), mklist("'id", username), mklist("'author", username), mklist("'content", mklist("'picture", mklist("'image", url))));
var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(picentry))));
if (savedpicxml == entryxml) {
onlinestatus();
workingstatus(false);
return false;
}
return savepic(entryxml);
});
}, 50, 50);
}
/**
* Upload a picture in an email.
*/
function emailpicture() {
// Generate and put a picture email upload token
workingstatus(true);
showstatus('Uploading');
var token = uuid4();
var picentry = mklist("'entry", mklist("'title", username), mklist("'id", username), mklist("'author", username), mklist("'content", mklist("'picture", mklist("'token", token))));
var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(picentry))));
pictures.put('', entryxml, function(e) {
if (e) {
showstatus('Local copy');
workingstatus(false);
return false;
}
workingstatus(false);
// Open the email app
var mailto = safeb64encode('p/' + username + '/' + token);
ui.navigate('mailto:' + mailto + '@' + topdomainname(window.location.hostname) + '?subject=Uploading picture&body=Paste picture here', '_self');
// Refresh app icon
refreshingpic = true;
return ui.delay(refreshpic, 500);
}, 'remote');
}
/**
* Handle picture upload events.
*/
ui.onclick($('uploadPicture'), function(e) {
debug('uploadPicture.onclick()');
if (ui.isMobile() && ((ui.isWebkit() && ui.browserVersion() < 6.0) || (ui.isAndroid() && ui.browserVersion() < 2.2)))
return ui.delay(function() { return emailpicture(); });
return ui.delay(function() { return $('uploadFile').click(); });
});
$('uploadFile').onchange = function(e) {
return readpic(e.target.files);
};
$('userPicture').ondrag = function(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
};
$('userPicture').ondrop = function(e) {
e.stopPropagation();
e.preventDefault();
return readpic(e.dataTransfer.files);
};
})();
</script>
</div>