Browse Source

merging language overide and post formating from calm

master
Miguel Freitas 11 years ago
parent
commit
69671adf5b
  1. 1
      home.html
  2. 171
      js/calm.js
  3. 32
      js/interface_localization.js
  4. 554
      js/jquery.textcomplete.js
  5. 3
      js/options.js
  6. 67
      js/twister_formatpost.js
  7. 1
      js/twister_network.js
  8. 1
      network.html
  9. 120
      options.html
  10. 1
      profile-edit.html

1
home.html

@ -44,6 +44,7 @@
<a href="#" class="mini-profile-name">Fulano da Silva</a> <a href="#" class="mini-profile-name">Fulano da Silva</a>
<span class="mini-profile-view">View</span> <span class="mini-profile-view">View</span>
</div> </div>
<a class="dropdown-menu-item" href="options.html">Options</a>
<a class="dropdown-menu-item" href="profile-edit.html">Setup account</a> <a class="dropdown-menu-item" href="profile-edit.html">Setup account</a>
<a class="dropdown-menu-item" href="following.html">Following users</a> <a class="dropdown-menu-item" href="following.html">Following users</a>
<a class="dropdown-menu-item" href="network.html">Network config</a> <a class="dropdown-menu-item" href="network.html">Network config</a>

171
js/calm.js

@ -0,0 +1,171 @@
$(function(){
$('.dropdown-menu').on('keydown', function(e){
e = event || window.event;
e.stopPropagation();
})
$('.post-text').on('click', 'a', function(e){
e.stopPropagation();
});
$('#showqr').on('click', function(){
if($('#qrcode img')[0]) return;
var skey = document.getElementById('skey').innerText;
new QRCode(document.getElementById("qrcode"), skey);
});
function dhtIndicatorBg(){
var bgcolor = '';
if(twisterDhtNodes <= 10){bgcolor = '#770900'
}else if(twisterDhtNodes <= 20){bgcolor = '#773400'
}else if(twisterDhtNodes <= 30){bgcolor = '#774c00'
}else if(twisterDhtNodes <= 40){bgcolor = '#776400'
}else if(twisterDhtNodes <= 50){bgcolor = '#707500'
}else if(twisterDhtNodes <= 60){bgcolor = '#3f6900'
}else if(twisterDhtNodes <= 70){bgcolor = '#005f15'
}else if(twisterDhtNodes >= 71){bgcolor = '#009922'
}
$('.userMenu-dhtindicator').animate({'background-color': bgcolor });
};
setTimeout(dhtIndicatorBg, 300);
setTimeout(function() {setInterval(dhtIndicatorBg, 2000)}, 400);
})
function modalDMIntr() {
$(".cancel").on('click', function(event){
if(!$(event.target).hasClass("cancel")) return;
if($(".modal-content").attr("style") != undefined){$(".modal-content").removeAttr("style")};
$('.modal-back').css('display', 'none');
});
$('.modal-back').on('click', function(){
if($('.modal-content .direct-messages-list')[0]) return;
directMessagesPopup();
$(".modal-content").removeAttr("style");
});
};
//sound notifications
function soundNotifOptions() {
if(!localStorage['sndDM']) localStorage['sndDM'] = false;
if(!localStorage['sndMention']) localStorage['sndMention'] = false;
$('#notifyForm select').each(function(){
this.value = localStorage[this.id];
});
var player = $('#player');
player[0].pause();
$('#player').empty();
$('form#notifyForm').on('change','select',function(){
localStorage.setItem(this.id, this.value);
if(this.value == false) {player[0].pause(); return;}
if (player[0].canPlayType('audio/mpeg;')) {
player.attr('type', 'audio/mpeg');
player.attr('src', 'sound/'+this.value+'.mp3');
} else {
player.attr('type', 'audio/ogg');
player.attr('src', 'sound/'+this.value+'.ogg');
}
player[0].play();
});
}
function volumeControl () {
var playerVol = $('#playerVol');
playerVol[0].value = localStorage[playerVol[0].id] ? localStorage[playerVol[0].id] : 100;
$('.volValue').text((localStorage[playerVol[0].id] * 100).toFixed());
playerVol.on('change',function(){
localStorage.setItem(this.id, this.value);
$('#player')[0].volume = (this.value);
$('.volValue').text((this.value * 100).toFixed());
});
}
function DMsNotif() {
if(localStorage['sndDM'] == "false") return;
var player = $('#player');
$('#player').empty();
if (player[0].canPlayType('audio/mpeg;')) {
player.attr('type', 'audio/mpeg');
player.attr('src', 'sound/'+localStorage['sndDM']+'.mp3');
} else {
player.attr('type', 'audio/ogg');
player.attr('src', 'sound/'+localStorage['sndDM']+'.ogg');
}
player[0].volume = localStorage['playerVol'];
player[0].play();
}
function mensNotif() {
if(localStorage['sndMention'] == "false") return;
var player = $('#player');
$('#playerSec').empty();
if (player[0].canPlayType('audio/mpeg;')) {
player.attr('type', 'audio/mpeg');
player.attr('src', 'sound/'+localStorage['sndMention']+'.mp3');
} else {
player.attr('type', 'audio/ogg');
player.attr('src', 'sound/'+localStorage['sndMention']+'.ogg');
}
player[0].volume = localStorage['playerVol'];
player[0].play();
};
function keysSend() {
if(!localStorage['keysSend']) localStorage['keysSend'] = 1;
$('#keysOpt select')[0].value = localStorage['keysSend'];
$('#keysOpt select').on('change', function(){
localStorage[this.id] = this.value;
})
}
function mensAutocomplete() {
var storFollArr = JSON.parse(localStorage[localStorage.defaultScreenName]), suggests = [];
for(var i = 0; i < storFollArr.followingUsers.length; i++){
if(storFollArr.followingUsers[i] == localStorage.defaultScreenName) continue;
suggests.push(storFollArr.followingUsers[i]);
}
suggests.reverse();
$('textarea').textcomplete([
{ // html
mentions: suggests,
match: /\B@(\w*)$/,
search: function (term, callback) {
callback($.map(this.mentions, function (mention) {
return mention.indexOf(term) === 0 ? mention : null;
}));
},
index: 1,
replace: function (mention) {
return '@' + mention + ' ';
}
}
])
}
function setLang() {
$('#language').val(localStorage['locLang'] || 'auto')
$('#language').on('change', function(){
localStorage['locLang'] = $(this).val();
})
}
function InitOptions () {
soundNotifOptions();
volumeControl();
keysSend();
setLang();
}
function homeIntInit () {
modalDMIntr ();
setTimeout(mensAutocomplete, 800);
}

32
js/interface_localization.js

@ -6,21 +6,25 @@
// translators: add your language code here such as "es" for Spanish, "ru" for Russian // translators: add your language code here such as "es" for Spanish, "ru" for Russian
var knownLanguages = ["en","es","nl","it","fr","ru","de","zh","ja","pt-BR"]; var knownLanguages = ["en","es","nl","it","fr","ru","de","zh","ja","pt-BR"];
// detect language with JavaScript if(!localStorage['locLang'] || localStorage['locLang'] == 'auto'){
var preferredLanguage = window.navigator.userLanguage || window.navigator.language || "en"; if(!localStorage['locLang']) localStorage['locLang'] = 'auto';
if(knownLanguages.indexOf(preferredLanguage) > -1){ // detect language with JavaScript
// en for en or similar preferredLanguage = window.navigator.userLanguage || window.navigator.language || "en";
preferredLanguage = preferredLanguage; if(knownLanguages.indexOf(preferredLanguage) > -1){
} // en for en or similar
else if(knownLanguages.indexOf(preferredLanguage.split("-")[0]) > -1){ preferredLanguage = preferredLanguage;
// en for en-US or similar }
preferredLanguage = preferredLanguage.split("-")[0]; else if(knownLanguages.indexOf(preferredLanguage.split("-")[0]) > -1){
} // en for en-US or similar
else{ preferredLanguage = preferredLanguage.split("-")[0];
// did not find match }
preferredLanguage = "en"; else{
// did not find match
preferredLanguage = "en";
}
}else{
preferredLanguage = localStorage['locLang'];
} }
// set up Polyglot // set up Polyglot
polyglot = new Polyglot(); polyglot = new Polyglot();
var wordset = {}; var wordset = {};

554
js/jquery.textcomplete.js

@ -0,0 +1,554 @@
/*!
* jQuery.textcomplete.js
*
* Repositiory: https://github.com/yuku-t/jquery-textcomplete
* License: MIT
* Author: Yuku Takahashi
*/
;(function ($) {
'use strict';
/**
* Exclusive execution control utility.
*/
var lock = function (func) {
var free, locked;
free = function () { locked = false; };
return function () {
var args;
if (locked) return;
locked = true;
args = toArray(arguments);
args.unshift(free);
func.apply(this, args);
};
};
/**
* Convert arguments into a real array.
*/
var toArray = function (args) {
var result;
result = Array.prototype.slice.call(args);
return result;
};
/**
* Get the styles of any element from property names.
*/
var getStyles = (function () {
var color;
color = $('<div></div>').css(['color']).color;
if (typeof color !== 'undefined') {
return function ($el, properties) {
return $el.css(properties);
};
} else { // for jQuery 1.8 or below
return function ($el, properties) {
var styles;
styles = {};
$.each(properties, function (i, property) {
styles[property] = $el.css(property);
});
return styles;
};
}
})();
/**
* Default template function.
*/
var identity = function (obj) { return obj; };
/**
* Memoize a search function.
*/
var memoize = function (func) {
var memo = {};
return function (term, callback) {
if (memo[term]) {
callback(memo[term]);
} else {
func.call(this, term, function (data) {
memo[term] = (memo[term] || []).concat(data);
callback.apply(null, arguments);
});
}
};
};
/**
* Determine if the array contains a given value.
*/
var include = function (array, value) {
var i, l;
if (array.indexOf) return array.indexOf(value) != -1;
for (i = 0, l = array.length; i < l; i++) {
if (array[i] === value) return true;
}
return false;
};
/**
* Textarea manager class.
*/
var Completer = (function () {
var html, css, $baseWrapper, $baseList, _id;
html = {
wrapper: '<div class="textcomplete-wrapper"></div>',
list: '<ul class="dropdown-menu"></ul>'
};
css = {
wrapper: {
position: 'relative'
},
list: {
position: 'absolute',
top: 0,
left: 0,
zIndex: '100',
display: 'none'
}
};
$baseWrapper = $(html.wrapper).css(css.wrapper);
$baseList = $(html.list).css(css.list);
_id = 0;
function Completer($el) {
var focus;
this.el = $el.get(0); // textarea element
focus = this.el === document.activeElement;
// Cannot wrap $el at initialize method lazily due to Firefox's behavior.
this.$el = wrapElement($el); // Focus is lost
this.id = 'textComplete' + _id++;
this.strategies = [];
if (focus) {
this.initialize();
this.$el.focus();
} else {
this.$el.one('focus.textComplete', $.proxy(this.initialize, this));
}
}
/**
* Completer's public methods
*/
$.extend(Completer.prototype, {
/**
* Prepare ListView and bind events.
*/
initialize: function () {
var $list, globalEvents;
$list = $baseList.clone();
this.listView = new ListView($list, this);
this.$el
.before($list)
.on({
'keyup.textComplete': $.proxy(this.onKeyup, this),
'keydown.textComplete': $.proxy(this.listView.onKeydown,
this.listView)
});
globalEvents = {};
globalEvents['click.' + this.id] = $.proxy(this.onClickDocument, this);
globalEvents['keyup.' + this.id] = $.proxy(this.onKeyupDocument, this);
$(document).on(globalEvents);
},
/**
* Register strategies to the completer.
*/
register: function (strategies) {
this.strategies = this.strategies.concat(strategies);
},
/**
* Show autocomplete list next to the caret.
*/
renderList: function (data) {
if (this.clearAtNext) {
this.listView.clear();
this.clearAtNext = false;
}
if (data.length) {
if (!this.listView.shown) {
this.listView
.setPosition(this.getCaretPosition())
.clear()
.activate();
this.listView.strategy = this.strategy;
}
data = data.slice(0, this.strategy.maxCount);
this.listView.render(data);
}
if (!this.listView.data.length && this.listView.shown) {
this.listView.deactivate();
}
},
searchCallbackFactory: function (free) {
var self = this;
return function (data, keep) {
self.renderList(data);
if (!keep) {
// This is the last callback for this search.
free();
self.clearAtNext = true;
}
};
},
/**
* Keyup event handler.
*/
onKeyup: function (e) {
var searchQuery, term;
if (this.skipSearch(e)) { return; }
searchQuery = this.extractSearchQuery(this.getTextFromHeadToCaret());
if (searchQuery.length) {
term = searchQuery[1];
if (this.term === term) return; // Ignore shift-key or something.
this.term = term;
this.search(searchQuery);
} else {
this.term = null;
this.listView.deactivate();
}
},
/**
* Suppress searching if it returns true.
*/
skipSearch: function (e) {
if (this.skipNextKeyup) {
this.skipNextKeyup = false;
return true;
}
switch (e.keyCode) {
case 40:
case 38:
return true;
}
},
onSelect: function (value) {
var pre, post, newSubStr;
pre = this.getTextFromHeadToCaret();
post = this.el.value.substring(this.el.selectionEnd);
newSubStr = this.strategy.replace(value);
if ($.isArray(newSubStr)) {
post = newSubStr[1] + post;
newSubStr = newSubStr[0];
}
pre = pre.replace(this.strategy.match, newSubStr);
this.$el.val(pre + post)
.trigger('change')
.trigger('textComplete:select', value);
this.el.focus();
this.el.selectionStart = this.el.selectionEnd = pre.length;
this.skipNextKeyup = true;
},
/**
* Global click event handler.
*/
onClickDocument: function (e) {
if (e.originalEvent && !e.originalEvent.keepTextCompleteDropdown) {
this.listView.deactivate();
}
},
/**
* Global keyup event handler.
*/
onKeyupDocument: function (e) {
if (this.listView.shown && e.keyCode === 27) { // ESC
this.listView.deactivate();
this.$el.focus();
}
},
/**
* Remove all event handlers and the wrapper element.
*/
destroy: function () {
var $wrapper;
this.$el.off('.textComplete');
$(document).off('.' + this.id);
if (this.listView) { this.listView.destroy(); }
$wrapper = this.$el.parent();
$wrapper.after(this.$el).remove();
this.$el.data('textComplete', void 0);
this.$el = null;
},
// Helper methods
// ==============
/**
* Returns caret's relative coordinates from textarea's left top corner.
*/
getCaretPosition: function () {
// Browser native API does not provide the way to know the position of
// caret in pixels, so that here we use a kind of hack to accomplish
// the aim. First of all it puts a div element and completely copies
// the textarea's style to the element, then it inserts the text and a
// span element into the textarea.
// Consequently, the span element's position is the thing what we want.
if (this.el.selectionEnd === 0) return;
var properties, css, $div, $span, position, dir;
dir = this.$el.attr('dir') || this.$el.css('direction');
properties = ['border-width', 'font-family', 'font-size', 'font-style',
'font-variant', 'font-weight', 'height', 'letter-spacing',
'word-spacing', 'line-height', 'text-decoration', 'text-align',
'width', 'padding-top', 'padding-right', 'padding-bottom',
'padding-left', 'margin-top', 'margin-right', 'margin-bottom',
'margin-left'
];
css = $.extend({
position: 'absolute',
overflow: 'auto',
'white-space': 'pre-wrap',
top: 0,
left: -9999,
direction: dir
}, getStyles(this.$el, properties));
$div = $('<div></div>').css(css).text(this.getTextFromHeadToCaret());
$span = $('<span></span>').text('.').appendTo($div);
this.$el.before($div);
position = $span.position();
position.top += $span.height() - this.$el.scrollTop();
if (dir === 'rtl') { position.left -= this.listView.$el.width(); }
$div.remove();
return position;
},
getTextFromHeadToCaret: function () {
var text, selectionEnd, range;
selectionEnd = this.el.selectionEnd;
if (typeof selectionEnd === 'number') {
text = this.el.value.substring(0, selectionEnd);
} else if (document.selection) {
range = this.el.createTextRange();
range.moveStart('character', 0);
range.moveEnd('textedit');
text = range.text;
}
return text;
},
/**
* Parse the value of textarea and extract search query.
*/
extractSearchQuery: function (text) {
// If a search query found, it returns used strategy and the query
// term. If the caret is currently in a code block or search query does
// not found, it returns an empty array.
var i, l, strategy, match;
for (i = 0, l = this.strategies.length; i < l; i++) {
strategy = this.strategies[i];
match = text.match(strategy.match);
if (match) { return [strategy, match[strategy.index]]; }
}
return [];
},
search: lock(function (free, searchQuery) {
var term;
this.strategy = searchQuery[0];
term = searchQuery[1];
this.strategy.search(term, this.searchCallbackFactory(free));
})
});
/**
* Completer's private functions
*/
var wrapElement = function ($el) {
return $el.wrap($baseWrapper.clone().css('display', $el.css('display')));
};
return Completer;
})();
/**
* Dropdown menu manager class.
*/
var ListView = (function () {
function ListView($el, completer) {
this.data = [];
this.$el = $el;
this.index = 0;
this.completer = completer;
this.$el.on('click.textComplete', 'li.textcomplete-item',
$.proxy(this.onClick, this));
}
$.extend(ListView.prototype, {
shown: false,
render: function (data) {
var html, i, l, index, val;
html = '';
for (i = 0, l = data.length; i < l; i++) {
val = data[i];
if (include(this.data, val)) continue;
index = this.data.length;
this.data.push(val);
html += '<li class="textcomplete-item" data-index="' + index + '"><a>';
html += this.strategy.template(val);
html += '</a></li>';
if (this.data.length === this.strategy.maxCount) break;
}
this.$el.append(html);
if (!this.data.length) {
this.deactivate();
} else {
this.activateIndexedItem();
}
},
clear: function () {
this.data = [];
this.$el.html('');
this.index = 0;
return this;
},
activateIndexedItem: function () {
this.$el.find('.active').removeClass('active');
this.getActiveItem().addClass('active');
},
getActiveItem: function () {
return $(this.$el.children().get(this.index));
},
activate: function () {
if (!this.shown) {
this.$el.show();
this.completer.$el.trigger('textComplete:show');
this.shown = true;
}
return this;
},
deactivate: function () {
if (this.shown) {
this.$el.hide();
this.completer.$el.trigger('textComplete:hide');
this.shown = false;
this.data = this.index = null;
}
return this;
},
setPosition: function (position) {
this.$el.css(position);
return this;
},
select: function (index) {
var self = this;
this.completer.onSelect(this.data[index]);
// Deactive at next tick to allow other event handlers to know whether
// the dropdown has been shown or not.
setTimeout(function () { self.deactivate(); }, 0);
},
onKeydown: function (e) {
if (!this.shown) return;
if (e.keyCode === 38) { // UP
e.preventDefault();
if (this.index === 0) {
this.index = this.data.length-1;
} else {
this.index -= 1;
}
this.activateIndexedItem();
} else if (e.keyCode === 40) { // DOWN
e.preventDefault();
if (this.index === this.data.length - 1) {
this.index = 0;
} else {
this.index += 1;
}
this.activateIndexedItem();
} else if (e.keyCode === 13 || e.keyCode === 9) { // ENTER or TAB
e.preventDefault();
this.select(parseInt(this.getActiveItem().data('index'), 10));
}
},
onClick: function (e) {
var $e = $(e.target);
e.originalEvent.keepTextCompleteDropdown = true;
if (!$e.hasClass('textcomplete-item')) {
$e = $e.parents('li.textcomplete-item');
}
this.select(parseInt($e.data('index'), 10));
},
destroy: function () {
this.deactivate();
this.$el.off('click.textComplete').remove();
this.$el = null;
}
});
return ListView;
})();
$.fn.textcomplete = function (strategies) {
var i, l, strategy, dataKey;
dataKey = 'textComplete';
if (strategies === 'destroy') {
return this.each(function () {
var completer = $(this).data(dataKey);
if (completer) { completer.destroy(); }
});
}
for (i = 0, l = strategies.length; i < l; i++) {
strategy = strategies[i];
if (!strategy.template) {
strategy.template = identity;
}
if (strategy.index == null) {
strategy.index = 2;
}
if (strategy.cache) {
strategy.search = memoize(strategy.search);
}
strategy.maxCount || (strategy.maxCount = 10);
}
return this.each(function () {
var $this, completer;
$this = $(this);
completer = $this.data(dataKey);
if (!completer) {
completer = new Completer($this);
$this.data(dataKey, completer);
}
completer.register(strategies);
});
};
})(window.jQuery || window.Zepto);

3
js/options.js

@ -0,0 +1,3 @@
$(function() {
});

67
js/twister_formatpost.js

@ -98,7 +98,7 @@ function postToElem( post, kind ) {
elem.find(".post-context").show(); elem.find(".post-context").show();
var retweetedByElem = elem.find(".post-retransmited-by"); var retweetedByElem = elem.find(".post-retransmited-by");
retweetedByElem.attr("href", $.MAL.userUrl(retweeted_by)); retweetedByElem.attr("href", $.MAL.userUrl(retweeted_by));
retweetedByElem.text(retweeted_by); retweetedByElem.text('@'+retweeted_by);
} }
return elem; return elem;
@ -143,8 +143,11 @@ function htmlFormatMsg( msg, output, mentions ) {
var tmp; var tmp;
var match = null; var match = null;
var index; var index;
var reAll = new RegExp("(#|@|http[s]?://)"); var strUrlRegexp = "http[s]?://";
var reHttp = new RegExp("http[s]?://"); var strEmailRegexp = "\\S+@\\S+\\.\\S+";
var reAll = new RegExp("(?:^|[ \\n\\t.,:\\/?!])(#|@|" + strUrlRegexp + "|" + strEmailRegexp + ")");
var reHttp = new RegExp(strUrlRegexp);
var reEmail = new RegExp(strEmailRegexp);
msg = escapeHtmlEntities(msg); msg = escapeHtmlEntities(msg);
@ -152,9 +155,10 @@ function htmlFormatMsg( msg, output, mentions ) {
match = reAll.exec(msg); match = reAll.exec(msg);
if( match ) { if( match ) {
if( match[0] == "@" ) { index = (match[0] === match[1]) ? match.index : match.index + 1;
output.append(msg.substr(0, match.index)); if( match[1] == "@" ) {
tmp = msg.substr(match.index+1); output.append(msg.substr(0, index));
tmp = msg.substr(index+1);
var username = _extractUsername(tmp); var username = _extractUsername(tmp);
if( username.length ) { if( username.length ) {
if( mentions.indexOf(username) < 0 ) if( mentions.indexOf(username) < 0 )
@ -167,11 +171,14 @@ function htmlFormatMsg( msg, output, mentions ) {
msg = tmp.substr(String(username).length); msg = tmp.substr(String(username).length);
continue; continue;
} }
output.append('@');
msg = tmp;
continue;
} }
if( reHttp.exec(match[0]) ) { if( reHttp.exec(match[1]) ) {
output.append(msg.substr(0, match.index)); output.append(msg.substr(0, index));
tmp = msg.substring(match.index); tmp = msg.substring(index);
var space = tmp.indexOf(" "); var space = tmp.indexOf(" ");
var url; var url;
if( space != -1 ) url = tmp.substring(0,space); else url = tmp; if( space != -1 ) url = tmp.substring(0,space); else url = tmp;
@ -186,11 +193,29 @@ function htmlFormatMsg( msg, output, mentions ) {
continue; continue;
} }
} }
if( reEmail.exec(match[1]) ) {
output.append(msg.substr(0, index));
tmp = msg.substring(index);
var space = tmp.indexOf(" ");
var email;
if( space != -1 ) email = tmp.substring(0,space); else email = tmp;
if( email.length ) {
var extLinkTemplate = $("#external-page-link-template").clone(true);
extLinkTemplate.removeAttr("id");
extLinkTemplate.attr("href","mailto:" + email);
extLinkTemplate.text(email);
extLinkTemplate.attr("title",email);
output.append(extLinkTemplate);
msg = tmp.substr(String(email).length);
continue;
}
}
if( match[0] == "#" ) { if( match[1] == "#" ) {
output.append(msg.substr(0, match.index)); output.append(msg.substr(0, index));
tmp = msg.substr(match.index+1); tmp = msg.substr(index+1);
var hashtag = _extractUsername(tmp); var hashtag = _extractHashtag(tmp);
if( hashtag.length ) { if( hashtag.length ) {
var hashtagLinkTemplate = $("#hashtag-link-template").clone(true); var hashtagLinkTemplate = $("#hashtag-link-template").clone(true);
hashtagLinkTemplate.removeAttr("id"); hashtagLinkTemplate.removeAttr("id");
@ -200,6 +225,9 @@ function htmlFormatMsg( msg, output, mentions ) {
msg = tmp.substr(String(hashtag).length); msg = tmp.substr(String(hashtag).length);
continue; continue;
} }
output.append('#');
msg = tmp;
continue;
} }
} }
@ -225,6 +253,19 @@ function _extractUsername(s) {
return username.toLowerCase(); return username.toLowerCase();
} }
// internal function for htmlFormatMsg
function _extractHashtag(s) {
var hashtag = "";
for( var i = 0; i < s.length; i++ ) {
if( " \n\t.,:/?!".indexOf(s[i]) < 0 ) {
hashtag += s[i];
} else {
break;
}
}
return hashtag;
}
function escapeHtmlEntities(str) { function escapeHtmlEntities(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
} }

1
js/twister_network.js

@ -30,6 +30,7 @@ function requestNetInfo(cbFunc, cbArg) {
$(".known-peers").text(twisterdAddrman); $(".known-peers").text(twisterdAddrman);
$(".blocks").text(twisterdBlocks); $(".blocks").text(twisterdBlocks);
$(".dht-nodes").text(twisterDhtNodes); $(".dht-nodes").text(twisterDhtNodes);
$(".userMenu-dhtindicator a").text(twisterDhtNodes);
$(".version").text(twisterDisplayVersion); $(".version").text(twisterDisplayVersion);
if( !twisterdConnections ) { if( !twisterdConnections ) {

1
network.html

@ -46,6 +46,7 @@
<a href="#" class="mini-profile-name">Fulano da Silva</a> <a href="#" class="mini-profile-name">Fulano da Silva</a>
<span class="mini-profile-view">View</span> <span class="mini-profile-view">View</span>
</div> </div>
<a class="dropdown-menu-item" href="options.html">Options</a>
<a class="dropdown-menu-item" href="profile-edit.html">Setup account</a> <a class="dropdown-menu-item" href="profile-edit.html">Setup account</a>
<a class="dropdown-menu-item" href="following.html">Following users</a> <a class="dropdown-menu-item" href="following.html">Following users</a>
<a class="dropdown-menu-item" href="network.html">Network config</a> <a class="dropdown-menu-item" href="network.html">Network config</a>

120
options.html

@ -0,0 +1,120 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>twister login</title>
<link rel="stylesheet" href="css/style.css" type="text/css"/>
<script src="js/jquery.min.js"></script>
<script src="js/jQueryPlugins.js"></script>
<script src="js/jquery.json-2.4.js"></script>
<script src="js/jquery.jsonrpcclient.js"></script>
<script src="js/jquery.storageapi.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>
<script src="js/twister_network.js"></script>
<script src="js/twister_user.js"></script>
<script src="js/interface_common.js"></script>
<script src="js/interface_login.js"></script>
<script src="js/polyglot.min.js"></script>
<script src="js/interface_localization.js"></script>
<script src="js/calm.js"></script>
<script src="js/options.js"></script>
<script>$(function(){
initInterfaceCommon();
InitOptions();})
</script>
</head>
<body>
<!-- MENU SUPERIOR INIT -->
<nav class="userMenu">
<ul>
<li class="userMenu-home"><a href="home.html"></a></li>
<li class="userMenu-options current"><a href="options.html">Options</a></li>
<li class="userMenu-config">
<a class="userMenu-config-dropdown" href="#">
<div class="config-menu dialog-modal">
<a class="dropdown-menu-item" href="options.html">Options</a>
<a class="dropdown-menu-item" href="network.html">Network config</a>
<a class="dropdown-menu-item" href="profile-edit.html">Setup account</a>
<a class="dropdown-menu-item" href="following.html">Following users</a>
<a class="dropdown-menu-item" href="login.html">Change user</a>
</div>
</a>
</li>
</ul>
</nav>
<div class="wrapper">
<div class="language">
<div class="module">
<p> Use language </p>
<div>
<form action="" id="choseLanguage">
<select name="" id="language">
<option value="auto">Auto</option>
<option value="en">English</option>
<option value="ru">Russian</option>
<option value="zh">Chinese</option>
<option value="de">German</option>
<option value="fr">French</option>
<option value="it">Italian</option>
<option value="nl">Dutch</option>
</select>
</form>
</div>
</div>
</div>
<div class="sounds">
<div class="module">
<p> Sound notifications </p>
<div>
<form action="" id="notifyForm">
<p>Mentions</p>
<select name="" id="sndMention" class="sndOpt">
<option value="false">none</option>
<option value="1">beat</option>
<option value="2">pip</option>
<option value="3">vibro</option>
<option value="4">flip</option>
<option value="5">click</option>
</select><br>
<p>Direct Messages</p>
<select name="" id="sndDM" class="sndOpt">
<option value="false">none</option>
<option value="1">beat</option>
<option value="2">pip</option>
<option value="3">vibro</option>
<option value="4">flip</option>
<option value="5">click</option>
</select>
<input type="range" name="playerVol" id="playerVol" min="0" max="1" step="0.01"><span class="volValue">0</span>
</form>
<audio id="player"></audio>
</div>
</div>
</div>
<div class="keys">
<div class="module">
<p> Keys </p>
<div>
<form action="" id="keysOpt">
<p>Send key</p>
<select name="" id="keysSend">
<option value="1">Enter</option>
<option value="2">Ctrl/Cmd+Enter</option>
</select>
</form>
</div>
</div>
</div>
</div>
</body>
</html>

1
profile-edit.html

@ -46,6 +46,7 @@
<a href="#" class="mini-profile-name">Fulano da Silva</a> <a href="#" class="mini-profile-name">Fulano da Silva</a>
<span class="mini-profile-view">View</span> <span class="mini-profile-view">View</span>
</div> </div>
<a class="dropdown-menu-item" href="options.html">Options</a>
<a class="dropdown-menu-item" href="profile-edit.html">Setup account</a> <a class="dropdown-menu-item" href="profile-edit.html">Setup account</a>
<a class="dropdown-menu-item" href="following.html">Following users</a> <a class="dropdown-menu-item" href="following.html">Following users</a>
<a class="dropdown-menu-item" href="network.html">Network config</a> <a class="dropdown-menu-item" href="network.html">Network config</a>

Loading…
Cancel
Save