400 lines
11 KiB
JavaScript
400 lines
11 KiB
JavaScript
/*
|
|
* app.main.js
|
|
* License key generator
|
|
*/
|
|
|
|
/*jslint browser : true, continue : true,
|
|
devel : true, indent : 2, maxerr : 50,
|
|
newcap : true, nomen : true, plusplus : true,
|
|
regexp : true, sloppy : true, vars : false,
|
|
white : true
|
|
*/
|
|
|
|
/*global $, app */
|
|
|
|
app.main = (function () {
|
|
'use strict';
|
|
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
|
|
var
|
|
|
|
stateMap = {},
|
|
configModule, initModule,
|
|
ENTER_KEY = 13, ESCAPE_KEY = 27,
|
|
render,
|
|
onSync, onNextList, onClearDone,
|
|
onInsert, onShowContextMenu, onShowListContextMenu, onNewPriority, onDoneChanged,
|
|
onNewText, onNewListName, onDeleteList;
|
|
|
|
//----------------- END MODULE SCOPE VARIABLES ---------------
|
|
|
|
//------------------- BEGIN UTILITY METHODS ------------------
|
|
///////////////////////////
|
|
// RENDER - DRAW THE LIST
|
|
//
|
|
render = function () {
|
|
|
|
var smallScreen = app.utilB.getMediaSize() == "app-small-mode";
|
|
|
|
|
|
var $l = $('#peck-list');
|
|
var $title = $('#peck-title');
|
|
var $listContextDiv = $('#list-context-div');
|
|
var $newItem =
|
|
$listContextDiv.empty();
|
|
$l.empty();
|
|
$title.text('');
|
|
|
|
var rawList = app.api.getActiveList();
|
|
if (rawList == null) {
|
|
$title.text('?? NO LIST ??');
|
|
$l.append('<li>NO LIST</li>');
|
|
return;
|
|
}
|
|
|
|
var deletedList = rawList.deleted;
|
|
var listDisplayName = rawList.name;
|
|
if (deletedList) {
|
|
listDisplayName = "[" + rawList.name + "] - DELETE NEXT SYNC ";
|
|
$('#new-item').hide();
|
|
$title.addClass('text-danger');
|
|
} else {
|
|
$title.removeClass('text-danger');
|
|
}
|
|
|
|
$title.text(listDisplayName);
|
|
|
|
// Sort by `user` in ascending order and by `age` in descending order.
|
|
var l = _.orderBy(rawList.items, ['priority', 'text'], ['desc', 'asc']);
|
|
|
|
//draw the list
|
|
//{"id":"FmcIT283XkSFxvoyBGCmw","completed":false,"text":"Paper towel","v":3706,"priority":2}
|
|
var len = l.length, i = 0;
|
|
for (i; i < len; i++) {
|
|
var o = l[i];
|
|
if (o.priority > -1) {
|
|
var itemTextSpanClass = '';
|
|
if (!o.text) {
|
|
o.text = "## EMPTY ITEM ###";
|
|
}
|
|
|
|
//3 = old highlight (orangey red) and 2 is default dark green, 1 is black and 0 is faded gray
|
|
switch (o.priority) {
|
|
case 3:
|
|
itemTextSpanClass = 'text-danger';
|
|
break;
|
|
case 2:
|
|
itemTextSpanClass = 'text-primary';
|
|
break;
|
|
case 1:
|
|
itemTextSpanClass = 'text-dark';
|
|
break;
|
|
default:
|
|
itemTextSpanClass = 'text-secondary';
|
|
}
|
|
|
|
if (deletedList) {
|
|
itemTextSpanClass = 'text-warning';
|
|
}
|
|
|
|
if (smallScreen && o.text.length > 30) {
|
|
itemTextSpanClass += ' pl-long-item';
|
|
} else {
|
|
itemTextSpanClass += ' pl-short-item';
|
|
}
|
|
|
|
var listItem;
|
|
if (o.completed || deletedList) {
|
|
|
|
listItem = '<li data-id="' + o.id + '" class="list-group-item text-right pl-done">' +
|
|
'<span id="b' + i + '" class="w-100 ' + itemTextSpanClass + '" >' + o.text + '</span>' +
|
|
'</li>'
|
|
} else {
|
|
|
|
listItem = '<li data-id="' + o.id + '" class="list-group-item">' +
|
|
'<span id="b' + i + '" class="w-100 font-weight-bold ' + itemTextSpanClass + '" >' + o.text + '</span>' +
|
|
'</li>'
|
|
}
|
|
|
|
$l.append(listItem);
|
|
if (!deletedList) {
|
|
$('#b' + i).bind('click', o, onShowContextMenu);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//-------------------- END UTILITY METHODS -------------------
|
|
|
|
|
|
//------------------- BEGIN EVENT HANDLERS -------------------
|
|
//////////////////////////////////////////////////
|
|
//
|
|
onSync = function () {
|
|
$.gevent.publish('app-clear-error');
|
|
|
|
app.api.doSync(function (res) {
|
|
if (res.error) {
|
|
$.gevent.publish('app-show-error', res.msg);
|
|
} else {
|
|
render();
|
|
//alert("Stub: onSync success ");
|
|
return false;
|
|
}
|
|
});
|
|
};
|
|
|
|
//////////////////////////////////////////////////
|
|
// ADVANCE TO NEXT LIST
|
|
//
|
|
onNextList = function (e) {
|
|
app.api.goToNextList();
|
|
render();
|
|
};
|
|
|
|
//////////////////////////////////////////////////
|
|
// Clear completed items
|
|
//
|
|
onClearDone = function (e) {
|
|
var l = app.api.getActiveList();
|
|
if (l == null) {
|
|
return;
|
|
}
|
|
var len = l.items.length, i = 0;
|
|
for (i; i < len; i++) {
|
|
if (l.items[i].completed) {
|
|
l.items[i].priority = -1;
|
|
}
|
|
}
|
|
app.api.replaceActiveList(l);
|
|
render();
|
|
};
|
|
|
|
//////////////////////////////////////////////////
|
|
//
|
|
onInsert = function (e) {
|
|
e.preventDefault();
|
|
|
|
var $input = $(e.target);
|
|
var val = $input.val().trim();
|
|
|
|
if (e.which !== ENTER_KEY || !val) {
|
|
return;
|
|
}
|
|
|
|
//{id: "3GtklnXES0Ox7QrOJpEFRQ", completed: false, text: "No need for lock feature if it's not used", v: 49, priority: 2}
|
|
var newRecord = {
|
|
id: "NEW_" + _.now(),
|
|
completed: false,
|
|
text: val,
|
|
v: 0,
|
|
priority: 1
|
|
};
|
|
|
|
app.api.insertRecordInStore(newRecord);
|
|
$input.val('');
|
|
render();
|
|
return false; //prevent default
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// Show context menu
|
|
//
|
|
onShowContextMenu = function (e) {
|
|
e.preventDefault();
|
|
$('.pl-mnu').remove();
|
|
|
|
|
|
var li = $('li[data-id="' + e.data.id + '"]');
|
|
li.append(Handlebars.templates['app.main.context']({}));
|
|
|
|
var edTxt = $('#edtxt');
|
|
var btnToggleDone = $("#btn-toggle-done");
|
|
|
|
edTxt.val(e.data.text);
|
|
edTxt.keyup(e.data, onNewText);
|
|
btnToggleDone.focus();
|
|
|
|
if (e.data.completed) {
|
|
btnToggleDone.addClass("mdi-checkbox-blank-outline");
|
|
} else {
|
|
btnToggleDone.addClass("mdi-checkbox-marked");
|
|
}
|
|
btnToggleDone.click(e.data, onDoneChanged);
|
|
|
|
$('.ct-btn-priority').click(e.data, onNewPriority);
|
|
|
|
return false;
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// Show LIST context menu
|
|
//
|
|
onShowListContextMenu = function (e) {
|
|
//rename or delete
|
|
e.preventDefault();
|
|
var listContextDiv = $('#list-context-div');
|
|
|
|
//is it already displayed?
|
|
if (listContextDiv.children().length > 0) {
|
|
//div has tags in it, so clear it and return, it's a dismissal
|
|
listContextDiv.empty();
|
|
return false;
|
|
}
|
|
|
|
|
|
listContextDiv.append(Handlebars.templates['app.main.list-context']({}));
|
|
|
|
var edTxt = $('#edtxt');
|
|
var btnDeleteList = $("#btn-delete-list");
|
|
|
|
var rawList = app.api.getActiveList();
|
|
var deletedList = rawList.deleted;
|
|
var $title = $('#peck-title');
|
|
|
|
if (deletedList) {
|
|
btnDeleteList.removeClass('btn-danger').addClass('btn-success');
|
|
btnDeleteList.text('UNDELETE LIST');
|
|
edTxt.hide();
|
|
} else {
|
|
edTxt.val($title.text());
|
|
edTxt.keyup(onNewListName);
|
|
edTxt.focus();
|
|
}
|
|
btnDeleteList.click(onDeleteList);
|
|
|
|
return false;
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//CONTEXT FUNCTIONS HERE
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// CHANGE PRIORITY
|
|
//
|
|
onNewPriority = function (e) {
|
|
//List item id: e.data
|
|
//priority value: e.target.value
|
|
var rec = app.api.getRecordFromStore(e.data.id);
|
|
rec.priority = _.toNumber(e.target.value);
|
|
app.api.replaceRecordInStore(e.data.id, rec);
|
|
render();
|
|
return false;
|
|
};
|
|
|
|
//////////////////////////////////////////////////
|
|
// CHANGE TEXT
|
|
//
|
|
onNewText = function (e) {
|
|
|
|
var newText = e.target.value.trim();
|
|
if (e.which !== ENTER_KEY || !newText) {
|
|
return;
|
|
}
|
|
|
|
var rec = app.api.getRecordFromStore(e.data.id);
|
|
rec.text = newText;
|
|
app.api.replaceRecordInStore(e.data.id, rec);
|
|
render();
|
|
return false;
|
|
};
|
|
|
|
//////////////////////////////////////////////////
|
|
// CHANGE COMPLETED
|
|
//
|
|
onDoneChanged = function (e) {
|
|
//List item id: e.data
|
|
//priority value: e.target.value
|
|
var rec = app.api.getRecordFromStore(e.data.id);
|
|
rec.completed = !rec.completed;
|
|
app.api.replaceRecordInStore(e.data.id, rec);
|
|
render();
|
|
return false;
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// CHANGE TEXT
|
|
//
|
|
onNewListName = function (e) {
|
|
var newText = e.target.value.trim();
|
|
if (e.which !== ENTER_KEY || !newText) {
|
|
return;
|
|
}
|
|
app.api.renameActiveList(newText);
|
|
render();
|
|
return false;
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// CHANGE TEXT
|
|
//
|
|
onDeleteList = function (e) {
|
|
e.preventDefault();
|
|
app.api.toggleDeleteActiveList();
|
|
render();
|
|
return false;
|
|
};
|
|
|
|
|
|
|
|
//-------------------- END EVENT HANDLERS --------------------
|
|
|
|
//------------------- BEGIN PUBLIC METHODS -------------------
|
|
//CONFIGMODULE
|
|
//
|
|
configModule = function (context) {
|
|
stateMap.context = context.context;
|
|
if (stateMap.context.params.id) {
|
|
stateMap.id = stateMap.context.params.id;
|
|
}
|
|
};
|
|
|
|
//INITMODULE
|
|
//
|
|
initModule = function ($container) {
|
|
if (typeof $container === 'undefined') {
|
|
$container = $('#app-shell-main-content');
|
|
}
|
|
$container.html(Handlebars.templates['app.main']({}));
|
|
//Context menu
|
|
app.nav.contextClear();
|
|
////app.nav.setContextTitle("License");
|
|
|
|
//make context menu
|
|
|
|
|
|
//Context menu
|
|
app.nav.contextClear();
|
|
app.nav.contextAddButton('btn-sync', 'Sync', 'sync', onSync);
|
|
app.nav.contextAddButton('btn-clear-done', 'Clear done', 'nuke', onClearDone);
|
|
app.nav.contextAddButton('btn-next', 'List', 'skip-next', onNextList);
|
|
|
|
//bind event handlers
|
|
$('#new-item').keyup(onInsert);
|
|
$('#btn-test').click(onNewPriority);
|
|
|
|
$('#peck-title').bind('click', onShowListContextMenu);
|
|
|
|
|
|
//display the cached data
|
|
render();
|
|
|
|
|
|
};
|
|
|
|
// return public methods
|
|
return {
|
|
configModule: configModule,
|
|
initModule: initModule
|
|
};
|
|
//------------------- END PUBLIC METHODS ---------------------
|
|
}()); |