Files
mythoughts/masks/write.html

288 lines
8.1 KiB
HTML
Executable File

<div id="write">
<div id="write_feedback"></div>
<div id="editor_container">
<div id="editor_content">
<div id="context"></div>
<div id="editor" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></div>
</div>
</div>
<div id="nav">
<div class="nav-elem prev"><a class="fal fa-fw fa-prev"></a></div>
<div class="nav-elem curr"></div>
<div class="nav-elem next"><a class="fal fa-fw fa-next"></a></div>
</div>
</div>
<script type="text/javascript">
oMyThoughts.pageInit = function(asHash, bFirstPage)
{
self.vars('id', 0);
self.vars('default_text', "\n");
self.vars('quill_page', 0);
self.vars('keystrokes', 0);
self.vars('saving', false);
//DOM
self.vars('editor', $('#editor_content'));
//Quill Engine
oQuill = new Quill('#editor', {
theme: 'bubble',
placeholder: 'What\'s on your mind?',
modules:
{
toolbar: [['bold', 'italic', 'underline'], [{ 'list': 'ordered'}, { 'list': 'bullet' }], ['clean']]
}
});
//Add last thought
setLastContent(oQuill, function(){
setPageHeight();
moveToPage('last');
});
//Key strokes & mouse Events
$('#editor').keydown(function(e){
if($.inArray(e.which, [13, 37, 38, 39, 40]) != -1) onChange('', '', 'user', e);
else if(e.which==33) $('.prev').click();
else if(e.which==34) $('.next').click();
});
oQuill.on('text-change', onChange);
$(window).mousewheel(function(turn, iDelta) {
var iNewPage = self.vars('quill_page') + ((iDelta > 0)?-1:1);
moveToPage(iNewPage);
return false;
});
//Page buttons
$('.prev').click(function(){moveToPage(self.vars('quill_page')-1);});
$('.next').click(function(){moveToPage(self.vars('quill_page')+1);});
//Init
oQuill.focus();
};
oMyThoughts.onFeedback = function(sType, sMsg)
{
var $Feedback = $('#write_feedback');
$Feedback
.stop()
.fadeOut($Feedback.is(':empty')?0:'fast', function(){
$(this)
.empty()
.append($('<span>', {'class':sType}).text(sMsg))
.fadeIn('fast');
});
};
oMyThoughts.onQuitPage = function()
{
return save(true);
};
function setPageHeight()
{
var $Page = $('#editor_container');
var iHeight = $Page.height();
var iLineHeight = parseInt($('#editor p').css('line-height'));
var iMaxHeight = Math.floor(iHeight / iLineHeight) * iLineHeight;
$Page.height(iMaxHeight+'px');
self.vars('line-height', iLineHeight);
self.vars('page-height', iMaxHeight);
}
function setLastContent(oQuill, fCallback)
{
getInfo
(
'load',
function(sDesc, asData)
{
if(asData.ops.length != 1 || asData.ops[0].insert != '' && false) {
var $Date = $('<p>', {'class':'entry_date'}).text(asData.created_f);
var $Sep = $('<div>', {'class':'entry_sep'})
.text('~')
.click(function(){oQuill.focus();});
oQuill.setContents(asData.ops);
$('#context')
.append($('#editor .ql-editor').html())
.append($Date)
.append($Sep);
oQuill.setContents([]);
}
else oQuill.focus();
if(typeof fCallback == 'function') fCallback();
},
{id: 'last'}
);
}
function onChange(delta, oldDelta, sSource, e)
{
if(sSource == 'user')
{
var range = oQuill.getSelection();
if(range)
{
//sCursorPos = '';
var bSelection = (typeof e != 'undefined')?e.shiftKey:false;
var oSelBound = oQuill.getBounds(range.index, range.length);
var oEditorCurBound = { top: self.vars('page-height') * self.vars('quill_page'),
bottom: self.vars('page-height') * (self.vars('quill_page') + 1)};
//console.log('oEditorCurBound: top='+oEditorCurBound.top+' bottom='+oEditorCurBound.bottom);
//console.log('---------------------');
//console.log('range.length = '+range.length);
//console.log('oSelBound: top='+oSelBound.top+' bottom='+oSelBound.bottom);
//Detecting new selection & saving original line
if(!self.tmp('line') && bSelection) self.tmp('line', $.extend({}, oSelBound));
else if(!bSelection) self.tmp('line', false);
//Detecting navigating back to original line
var bReset = (self.tmp('line') && self.tmp('line').top == oSelBound.top && self.tmp('line').bottom == oSelBound.bottom);
//Anticipating arrows (downside of using keydown event)
if(e)
{
switch(e.which)
{
case 13: //Enter
case 40: //Down
if(bSelection) {
if(bReset) sCursorPos = 'last';
if(sCursorPos == 'last') { //Downwards selection, expanding
oSelBound.bottom += self.vars('line-height');
}
else { //Upwards selection, reducing
oSelBound.top += self.vars('line-height');
}
}
else oSelBound.bottom += self.vars('line-height');
break;
case 38: //Up
if(bSelection) {
if(bReset) sCursorPos = 'first';
if(sCursorPos == 'last') { //Downwards selection, reducing
oSelBound.bottom -= self.vars('line-height');
}
else { //Upwards selection, expanding
oSelBound.top -= self.vars('line-height');
}
}
else oSelBound.top = Math.max(0, oSelBound.top - self.vars('line-height'));
break;
case 37: //Left
if(bReset && bSelection) sCursorPos = 'first';
oSelBound = oQuill.getBounds(Math.max(0, range.index - 1), range.length);
break;
case 39: //Right
if(bReset && bSelection) sCursorPos = 'last';
oSelBound = oQuill.getBounds(range.index + 1, range.length);
break;
}
}
else incKeyStrokes();
//console.log('oSelBound: top='+oSelBound.top+' bottom='+oSelBound.bottom);
var sNewPage = self.vars('quill_page');
if( oSelBound.top < oEditorCurBound.top && (!bSelection || sCursorPos == 'first') ||
oSelBound.bottom < oEditorCurBound.top && (!bSelection || sCursorPos == 'last')) {
sNewPage--;
}
else if(oSelBound.bottom > oEditorCurBound.bottom && (!bSelection || sCursorPos == 'last') ||
oSelBound.top > oEditorCurBound.bottom && (!bSelection || sCursorPos == 'first')) {
sNewPage++;
}
moveToPage(sNewPage);
}
}
}
function moveToPage(iNewPage)
{
var iContentHeight = self.vars('editor').height();
var iLastPage = Math.floor(iContentHeight / self.vars('page-height'));
if(iNewPage=='last') iNewPage = iLastPage;
if(iNewPage >= 0 && iNewPage <= iLastPage)
{
if(iNewPage!=self.vars('quill_page'))
{
var iOldPage = self.vars('quill_page');
self.vars('quill_page', iNewPage);
//Page Position
var iOffset = self.vars('quill_page') * self.vars('page-height') * -1;
self.vars('editor').css('top', iOffset);
}
//Page Number
//$('.curr').text(self.vars('quill_page') + 1);
//Detect First/Last Page
$('.prev').toggleClass('visible', self.vars('quill_page')!=0);
$('.next').toggleClass('visible', self.vars('quill_page')!=iLastPage);
}
}
function incKeyStrokes()
{
self.vars('keystrokes', self.vars('keystrokes') + 1);
save();
}
function save(bForce)
{
if(typeof oSaveTimer != 'undefined') clearTimeout(oSaveTimer);
var bSave = (self.vars('keystrokes') % 20 == 0 || bForce);
if(bSave) {
if(self.vars('saving')) {
oSaveTimer = setTimeout(function(){save(true);}, 500);
}
else {
self.vars('saving', true);
var sContent = oQuill.getContents().ops;
if(!isQuillEmpty() || self.vars('id') != 0) {
oMyThoughts.onFeedback('info', 'Saving...');
getInfo(
'update',
function(sDesc, asData) {
if(self.vars('id') == 0) oMyThoughts.updateSideMenu();
self.vars('id', asData.id);
oMyThoughts.feedback('notice', 'Thought saved ('+asData.led.substr(11, 5)+')');
self.vars('saving', false);
},
{
id: self.vars('id'),
content: sContent
},
function(sError) {
oMyThoughts.feedback('error', 'Not saved! An error occured: '+sError);
self.vars('saving', false);
oSaveTimer = setTimeout(save, 1000);
},
'POST'
);
}
}
}
else {
oSaveTimer = setTimeout(function(){save(true);}, 1000*10);
}
return true;
}
function isQuillEmpty() {
const rEmpty = /^(<p>(<br>|<br\/>|<br\s\/>|\s+|)<\/p>|)$/gm;
return rEmpty.test(oQuill.getText().trim());
}
</script>