Browse Source

Merge pull request #232 from slr/tasty-language-filter

language filtering and other various things for timeline updating
master
miguelfreitas 10 years ago
parent
commit
9075230455
  1. 27
      css/style.css
  2. 1
      following.html
  3. 1
      home.html
  4. 1
      js/franc.js
  5. 76
      js/interface_home.js
  6. 400
      js/interface_localization.js
  7. 57
      js/mobile_abstract.js
  8. 130
      js/options.js
  9. 32
      js/twister_actions.js
  10. 18
      js/twister_formatpost.js
  11. 180
      js/twister_timeline.js
  12. 1
      login.html
  13. 1
      network.html
  14. 47
      options.html
  15. 1
      profile-edit.html
  16. 30
      theme_calm/css/style.css
  17. 45
      theme_nin/css/style.css
  18. 28
      theme_nin/sass/_tabs.sass
  19. 25
      theme_nin/sass/style.sass
  20. 1
      tmobile.html

27
css/style.css

@ -1898,8 +1898,7 @@ ol.toptrends-list { @@ -1898,8 +1898,7 @@ ol.toptrends-list {
box-shadow: 0 0 10px rgba(0, 0, 0, .3 );
}
.volValue {
vertical-align: top;
.volValue, #filterLangAccuracyVal {
font: 12px "Open Sans", sans-serif;
}
@ -1915,6 +1914,30 @@ ol.toptrends-list { @@ -1915,6 +1914,30 @@ ol.toptrends-list {
-ms-transition: height 1s linear;
}
.options input[type='checkbox'] {
cursor: pointer;
vertical-align: sub;
}
.options input[type='range'] {
cursor: pointer;
vertical-align: -16px;
}
.options #filterLangList {
width: 80%;
}
.langFilterSimData {
color: rgba( 0, 0, 0, .7 );
font: 10px "Open Sans", sans-serif;
text-align: center;
}
.langFilterSimData em {
color: rgba( 227, 79, 66, .7 );
}
/*************************************
*********** FOLLOWING PAGE ***********
**************************************/

1
following.html

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
<script src="js/jquery.jsonrpcclient.js"></script>
<script src="js/jquery.storageapi.js"></script>
<script src="js/options.js"></script>
<script src="js/franc.js"></script>
<script src="js/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>

1
home.html

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
<script src="js/jquery.jsonrpcclient.js"></script>
<script src="js/jquery.storageapi.js"></script>
<script src="js/options.js"></script>
<script src="js/franc.js"></script>
<script src="js/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>

1
js/franc.js

File diff suppressed because one or more lines are too long

76
js/interface_home.js

@ -17,7 +17,7 @@ var InterfaceFunctions = function() @@ -17,7 +17,7 @@ var InterfaceFunctions = function()
var newPosts = parseInt($(".userMenu .menu-news").text());
if (!newPosts)
newPosts = postsPerRefresh;
requestTimelineUpdate("latest",newPosts,followingUsers,promotedPostsOnly);
requestTimelineUpdate('pending',newPosts,followingUsers,promotedPostsOnly);
});
// Add refresh posts for home link in menu
@ -25,7 +25,7 @@ var InterfaceFunctions = function() @@ -25,7 +25,7 @@ var InterfaceFunctions = function()
var newPosts = parseInt($(".userMenu .menu-news").text());
if (!newPosts)
newPosts = postsPerRefresh;
requestTimelineUpdate("latest",newPosts,followingUsers,promotedPostsOnly);
requestTimelineUpdate('pending',newPosts,followingUsers,promotedPostsOnly);
});
$( ".promoted-posts-only").click(function() {
@ -67,22 +67,6 @@ var InterfaceFunctions = function() @@ -67,22 +67,6 @@ var InterfaceFunctions = function()
$(".dropdown-menu-following").attr("href","#");
$(".dropdown-menu-following").bind("click", function()
{ alert(polyglot.t("You are not following anyone because you are not logged in."))} );
twisterRpc("gettrendinghashtags", [10],
function(args, ret) {
for( var i = 0; i < ret.length; i++ ) {
var $li = $("<li>");
var hashtagLinkTemplate = $("#hashtag-link-template").clone(true);
hashtagLinkTemplate.removeAttr("id");
hashtagLinkTemplate.attr("href",$.MAL.hashtagUrl(ret[i]));
hashtagLinkTemplate.text("#"+ret[i]);
$li.append(hashtagLinkTemplate);
$(".toptrends-list").append($li);
}
}, {},
function(args, ret) {
console.log("Error with gettrendinghashtags. Older twister daemon?");
}, {});
}
else
{
@ -119,23 +103,6 @@ var InterfaceFunctions = function() @@ -119,23 +103,6 @@ var InterfaceFunctions = function()
setTimeout("getRandomFollowSuggestion(processSuggestion)", 1000);
setTimeout("getRandomFollowSuggestion(processSuggestion)", 1000);
twisterRpc("gettrendinghashtags", [10],
function(args, ret) {
for( var i = 0; i < ret.length; i++ ) {
var $li = $("<li>");
var hashtagLinkTemplate = $("#hashtag-link-template").clone(true);
hashtagLinkTemplate.removeAttr("id");
hashtagLinkTemplate.attr("href",$.MAL.hashtagUrl(ret[i]));
hashtagLinkTemplate.text("#"+ret[i]);
$li.append(hashtagLinkTemplate);
$(".toptrends-list").append($li);
}
}, {},
function(args, ret) {
console.log("Error with gettrendinghashtags. Older twister daemon?");
}, {});
if( args.cbFunc )
args.cbFunc(args.cbArg);
}, {cbFunc:cbFunc, cbArg:cbArg});
@ -154,9 +121,48 @@ var InterfaceFunctions = function() @@ -154,9 +121,48 @@ var InterfaceFunctions = function()
});
});
}
setTimeout(updateTrendingHashtags, 1000);
if ($.Options.getTopTrendsAutoUpdateOpt() === 'enable' && $.Options.getTopTrendsAutoUpdateTimerOpt() > 0)
setInterval(updateTrendingHashtags, $.Options.getTopTrendsAutoUpdateTimerOpt()*1000);
}
};
function updateTrendingHashtags() {
twisterRpc('gettrendinghashtags', [10],
function(args, ret) {
$('.toptrends-list').empty();
//console.log('hashtags trends: '+ret);
for( var i = 0; i < ret.length; i++ ) {
if ($.Options.getFilterLangOpt() !== 'disable' && $.Options.getFilterLangForTopTrendsOpt())
var langFilterData = filterLang(ret[i]);
if (typeof(langFilterData) === 'undefined' || langFilterData['pass'] || $.Options.getFilterLangSimulateOpt()) {
var $li = $('<li>');
var hashtagLinkTemplate = $('#hashtag-link-template').clone(true);
hashtagLinkTemplate.removeAttr('id');
hashtagLinkTemplate.attr('href',$.MAL.hashtagUrl(ret[i]));
hashtagLinkTemplate.text('#'+ret[i]);
$li.append(hashtagLinkTemplate);
if ($.Options.getFilterLangOpt() !== 'disable' && $.Options.getFilterLangSimulateOpt()) {
if (typeof(langFilterData) !== 'undefined') {
$li.append(' <span class="langFilterSimData"><em>'+((langFilterData['pass']) ? polyglot.t('passed') : polyglot.t('blocked'))+'</em>: '+langFilterData['prob'][0].toString()+'</span>');
} else {
$li.append(' <span class="langFilterSimData"><em>'+polyglot.t('not analyzed')+'</em></span>');
}
}
$('.toptrends-list').append($li);
}
}
}, {},
function(args, ret) {
console.log('Error with gettrendinghashtags. Older twister daemon?');
}, {}
);
};
//***********************************************
//******************* INIT **************
//***********************************************

400
js/interface_localization.js

@ -38,6 +38,7 @@ if(preferredLanguage == "en"){ @@ -38,6 +38,7 @@ if(preferredLanguage == "en"){
"ajax_error": "Ajax error: %{error}", // JavaScript error
"All users publicly followed by": "All users publicly followed by",
"Available": "Available", // username is available
"Appearance": "Appearance",
"Block chain information": "Block chain information",
"Block chain is up-to-date, twister is ready to use!": "Block chain is up-to-date, twister is ready to use!",
"Block generation": "Block generation ",
@ -94,13 +95,14 @@ if(preferredLanguage == "en"){ @@ -94,13 +95,14 @@ if(preferredLanguage == "en"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} new post |||| %{smart_count} new posts",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "nobody", // used to promote a post without attaching the user
"Not available": "Not available", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Number of blocks in block chain: ",
@ -140,6 +142,7 @@ if(preferredLanguage == "en"){ @@ -140,6 +142,7 @@ if(preferredLanguage == "en"){
"Type message here": "Type message here",
"Unfollow": "Unfollow",
"Update": "Update",
"Auto updating": "Automatic updating",
"Updating status...": "Updating status...", // status of block chain
"user_not_yet_accepted": "Other peers have not yet accepted this new user.\n" +
"Unfortunately it is not possible to save profile\n" +
@ -235,7 +238,28 @@ if(preferredLanguage == "en"){ @@ -235,7 +238,28 @@ if(preferredLanguage == "en"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "second(s)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "only positive numbers are allowed!",
"Language filtering": "Language filtering",
"By blacklist": "By blacklist",
"By whitelist": "By whitelist",
"Comma separated ISO 639-3 language codes": "Comma separated ISO 639-3 language codes",
"Accuracy": "Accuracy",
"Simulation mode": "Simulation mode",
"This post is treated by language filter": "This post is %{treated} by language filter.",
"blocked": "blocked",
"passed": "passed",
"not analyzed": "not analyzed",
"Reason: this": "Reason: %{this}",
"this doesnt contain that": "%{this} does not contain %{that}",
"this is undefined": "%{this} is undefined",
"blacklist": "blacklist",
"whitelist": "whitelist",
"language of this": "language of this",
"its undefined language": "it is undefined language",
"its this, blacklisted": "it is %{this}, blacklisted",
"its this, whitelisted": "it is %{this}, whitelisted",
"Most possible language: this": "Most possible language: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -284,6 +308,7 @@ if(preferredLanguage == "es"){ @@ -284,6 +308,7 @@ if(preferredLanguage == "es"){
"ajax_error": "Error ajax: %{error}", // JavaScript error
"All users publicly followed by": "Todos los usuarios seguidos públicamente por",
"Available": "Disponible", // username is available
"Appearance": "Appearance",
"Block chain information": "Información de la cadena de bloques",
"Block chain is up-to-date, twister is ready to use!": "La cadena de bloques está puesta al día, twister está listo para usar!",
"Block generation": "Generación de bloques ",
@ -340,13 +365,14 @@ if(preferredLanguage == "es"){ @@ -340,13 +365,14 @@ if(preferredLanguage == "es"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} nuevo post |||| %{smart_count} nuevos posts",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "Nadie", // used to promote a post without attaching the user
"Not available": "No disponible", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Número de bloques en la cadena de bloques: ",
@ -386,6 +412,7 @@ if(preferredLanguage == "es"){ @@ -386,6 +412,7 @@ if(preferredLanguage == "es"){
"Type message here": "Escriba el mensaje aquí",
"Unfollow": "Dejar de seguir",
"Update": "Actualizar",
"Auto updating": "Auto updating",
"Updating status...": "Actualización del estado ...", // status of block chain
"user_not_yet_accepted": "Otros pares no han aceptado este nuevo usuario.\n" +
"Por desgracia, no es posible guardar el perfil\n" +
@ -481,7 +508,28 @@ if(preferredLanguage == "es"){ @@ -481,7 +508,28 @@ if(preferredLanguage == "es"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hora(s)",
"second(s)": "segundo(s)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "only positive numbers are allowed!",
"Language filtering": "Language filtering",
"By blacklist": "By blacklist",
"By whitelist": "By whitelist",
"Comma separated ISO 639-3 language codes": "Comma separated ISO 639-3 language codes",
"Accuracy": "Accuracy",
"Simulation mode": "Simulation mode",
"This post is treated by language filter": "This post is %{treated} by language filter.",
"blocked": "blocked",
"passed": "passed",
"not analyzed": "not analyzed",
"Reason: this": "Reason: %{this}",
"this doesnt contain that": "%{this} does not contain %{that}",
"this is undefined": "%{this} is undefined",
"blacklist": "blacklist",
"whitelist": "whitelist",
"language of this": "language of this",
"its undefined language": "it is undefined language",
"its this, blacklisted": "it is %{this}, blacklisted",
"its this, whitelisted": "it is %{this}, whitelisted",
"Most possible language: this": "Most possible language: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -527,6 +575,7 @@ if(preferredLanguage == "uk"){ @@ -527,6 +575,7 @@ if(preferredLanguage == "uk"){
"ajax_error": "Помилка Ajax: %{error}", // JavaScript error
"All users publicly followed by": "Усі публічні користувачі яких читають",
"Available": "Доступний", // username is available
"Appearance": "Appearance",
"Block chain information": "Інформація про ланцюжок блоків",
"Block chain is up-to-date, twister is ready to use!": "Ланцюг блоків оновлено, twister готовий до використання!",
"Block generation": "Генерація блоку ",
@ -584,13 +633,14 @@ if(preferredLanguage == "uk"){ @@ -584,13 +633,14 @@ if(preferredLanguage == "uk"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} нове повідомлення |||| %{smart_count} нових повідомлень",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "nobody", // used to promote a post without attaching the user
"Not available": "Не доступне", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Кількість блоків у ланцюгу: ",
@ -630,6 +680,7 @@ if(preferredLanguage == "uk"){ @@ -630,6 +680,7 @@ if(preferredLanguage == "uk"){
"Type message here": "Напишіть повідомлення тут",
"Unfollow": "Відписатись",
"Update": "Оновити",
"Auto updating": "Auto updating",
"Updating status...": "Оновлення статусу...", // status of block chain
"user_not_yet_accepted": "Інші піри ще не прийняли цього користувача.\n" +
"Нажаль, у цьому стані не можливо зберегти профіль\n" +
@ -724,7 +775,28 @@ if(preferredLanguage == "uk"){ @@ -724,7 +775,28 @@ if(preferredLanguage == "uk"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "second(s)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "only positive numbers are allowed!",
"Language filtering": "Language filtering",
"By blacklist": "By blacklist",
"By whitelist": "By whitelist",
"Comma separated ISO 639-3 language codes": "Comma separated ISO 639-3 language codes",
"Accuracy": "Accuracy",
"Simulation mode": "Simulation mode",
"This post is treated by language filter": "This post is %{treated} by language filter.",
"blocked": "blocked",
"passed": "passed",
"not analyzed": "not analyzed",
"Reason: this": "Reason: %{this}",
"this doesnt contain that": "%{this} does not contain %{that}",
"this is undefined": "%{this} is undefined",
"blacklist": "blacklist",
"whitelist": "whitelist",
"language of this": "language of this",
"its undefined language": "it is undefined language",
"its this, blacklisted": "it is %{this}, blacklisted",
"its this, whitelisted": "it is %{this}, whitelisted",
"Most possible language: this": "Most possible language: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -770,6 +842,7 @@ if(preferredLanguage == "zh"){ @@ -770,6 +842,7 @@ if(preferredLanguage == "zh"){
"ajax_error": "Ajax错误: %{error}", // JavaScript error
"All users publicly followed by": "所有用户均被关注",
"Available": "可用", // username is available
"Appearance": "外观",
"Block chain information": "块链信息",
"Block chain is up-to-date, twister is ready to use!": "块链已经更新,Twister已经可以使用!",
"Block generation": "块生成器 ",
@ -824,15 +897,16 @@ if(preferredLanguage == "zh"){ @@ -824,15 +897,16 @@ if(preferredLanguage == "zh"){
"New direct message...": "新的即时信息...",
"New Post...": "新推文...",
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in postboard": "在时间线里",
"in search result": "在搜索结果里",
"in top trends": "在热词趋势里",
"new_posts": "%{smart_count} 新推文",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "nobody", // used to promote a post without attaching the user
"Not available": "用户名不可用", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "块链中的块数:",
@ -872,6 +946,7 @@ if(preferredLanguage == "zh"){ @@ -872,6 +946,7 @@ if(preferredLanguage == "zh"){
"Type message here": "输入消息内容",
"Unfollow": "取消关注",
"Update": "更新",
"Auto updating": "自动更新",
"Updating status...": "更新状态中...", // status of block chain
"user_not_yet_accepted": "其他节点还没有接受新用户。\n" +
"很抱歉,现在你还不能保存你的个人简介\n" +
@ -966,7 +1041,28 @@ if(preferredLanguage == "zh"){ @@ -966,7 +1041,28 @@ if(preferredLanguage == "zh"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "second(s)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "只允许正数字!",
"Language filtering": "语言过滤",
"By blacklist": "用黑名单",
"By whitelist": "用白名单",
"Comma separated ISO 639-3 language codes": "英文逗号分隔的 ISO 639-3 语言代码",
"Accuracy": "严格度",
"Simulation mode": "模拟模式",
"This post is treated by language filter": "这条推文被语言过滤器 %{treated} .",
"blocked": "阻止",
"passed": "放行",
"not analyzed": "未被分析",
"Reason: this": "原因: %{this}",
"this doesnt contain that": "%{this} 不包含 %{that}",
"this is undefined": "%{this} 未定义",
"blacklist": "黑名单",
"whitelist": "白名单",
"language of this": "此语言",
"its undefined language": "它是未识别语言",
"its this, blacklisted": "它是 %{this}, 被黑名单",
"its this, whitelisted": "它是 %{this}, 被白名单",
"Most possible language: this": "最可能的语言: %{this}",
"Scope of usage": "使用范围",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -1012,6 +1108,7 @@ if(preferredLanguage == "nl"){ @@ -1012,6 +1108,7 @@ if(preferredLanguage == "nl"){
"ajax_error": "Ajax error: %{error}", // JavaScript error
"All users publicly followed by": "Alle gebruikers openbaarlijk gevolgd door",
"Available": "Beschikbaar", // username is available
"Appearance": "Appearance",
"Block chain information": "Block chain informatie",
"Block chain is up-to-date, twister is ready to use!": "Block chain is up-to-date, twister is klaar voor gebruik!",
"Block generation": "Block productie",
@ -1068,13 +1165,14 @@ if(preferredLanguage == "nl"){ @@ -1068,13 +1165,14 @@ if(preferredLanguage == "nl"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} nieuw bericht |||| %{smart_count} nieuwe berichten",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "nobody", // used to promote a post without attaching the user
"Not available": "Niet beschikbaar", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Aantal blocks in block chain: ",
@ -1114,6 +1212,7 @@ if(preferredLanguage == "nl"){ @@ -1114,6 +1212,7 @@ if(preferredLanguage == "nl"){
"Type message here": "Type bericht hier",
"Unfollow": "Ontvolgen",
"Update": "Update",
"Auto updating": "Auto updating",
"Updating status...": "Status aan het updaten...", // status of block chain
"user_not_yet_accepted": "Other peers have not yet accepted this new user.\n" +
"Unfortunately it is not possible to save profile\n" +
@ -1209,7 +1308,28 @@ if(preferredLanguage == "nl"){ @@ -1209,7 +1308,28 @@ if(preferredLanguage == "nl"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "seconde(n)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "only positive numbers are allowed!",
"Language filtering": "Language filtering",
"By blacklist": "By blacklist",
"By whitelist": "By whitelist",
"Comma separated ISO 639-3 language codes": "Comma separated ISO 639-3 language codes",
"Accuracy": "Accuracy",
"Simulation mode": "Simulation mode",
"This post is treated by language filter": "This post is %{treated} by language filter.",
"blocked": "blocked",
"passed": "passed",
"not analyzed": "not analyzed",
"Reason: this": "Reason: %{this}",
"this doesnt contain that": "%{this} does not contain %{that}",
"this is undefined": "%{this} is undefined",
"blacklist": "blacklist",
"whitelist": "whitelist",
"language of this": "language of this",
"its undefined language": "it is undefined language",
"its this, blacklisted": "it is %{this}, blacklisted",
"its this, whitelisted": "it is %{this}, whitelisted",
"Most possible language: this": "Most possible language: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -1255,6 +1375,7 @@ if(preferredLanguage == "it"){ @@ -1255,6 +1375,7 @@ if(preferredLanguage == "it"){
"ajax_error": "Errore AJAX: %{error}", // JavaScript error
"All users publicly followed by": "Utenti seguiti pubblicamente da",
"Available": "Disponibile", // username is available
"Appearance": "Appearance",
"Block chain information": "Informazioni sulla catena di blocchi",
"Block chain is up-to-date, twister is ready to use!": "Catena di blocchi aggiornata, Twister è pronto per l'uso!",
"Block generation": "Generatore di blocchi:",
@ -1311,13 +1432,14 @@ if(preferredLanguage == "it"){ @@ -1311,13 +1432,14 @@ if(preferredLanguage == "it"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} nuovo messaggio |||| %{smart_count} nuovi messaggi",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "nessuno", // used to promote a post without attaching the user
"Not available": "Non disponibile", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Numero di blocchi nella catena: ",
@ -1356,6 +1478,7 @@ if(preferredLanguage == "it"){ @@ -1356,6 +1478,7 @@ if(preferredLanguage == "it"){
"Type message here": "Scrivi qui",
"Unfollow": "Smetti di seguire",
"Update": "Aggiorna",
"Auto updating": "Auto updating",
"Updating status...": "Aggiornamento in corso...", // status of block chain
"user_not_yet_accepted": "Gli altri nodi non hanno ancora accettato il nuovo utente.\n" +
"Al momento non puoi salvare il profilo o spedire messaggi.\n" +
@ -1449,7 +1572,28 @@ if(preferredLanguage == "it"){ @@ -1449,7 +1572,28 @@ if(preferredLanguage == "it"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "secondo(i)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "only positive numbers are allowed!",
"Language filtering": "Language filtering",
"By blacklist": "By blacklist",
"By whitelist": "By whitelist",
"Comma separated ISO 639-3 language codes": "Comma separated ISO 639-3 language codes",
"Accuracy": "Accuracy",
"Simulation mode": "Simulation mode",
"This post is treated by language filter": "This post is %{treated} by language filter.",
"blocked": "blocked",
"passed": "passed",
"not analyzed": "not analyzed",
"Reason: this": "Reason: %{this}",
"this doesnt contain that": "%{this} does not contain %{that}",
"this is undefined": "%{this} is undefined",
"blacklist": "blacklist",
"whitelist": "whitelist",
"language of this": "language of this",
"its undefined language": "it is undefined language",
"its this, blacklisted": "it is %{this}, blacklisted",
"its this, whitelisted": "it is %{this}, whitelisted",
"Most possible language: this": "Most possible language: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -1496,6 +1640,7 @@ if(preferredLanguage == "fr"){ @@ -1496,6 +1640,7 @@ if(preferredLanguage == "fr"){
"ajax_error": "Erreur ajax: %{error}", // JavaScript error
"All users publicly followed by": "Tous les utilisateurs suivis publiquement par",
"Available": "Disponible", // username is available
"Appearance": "Apparence",
"Block chain information": "Informations à propos de la chaîne de blocs",
"Block chain is up-to-date, twister is ready to use!": "La chaîne de blocs est à jour, Twister est maintenant fonctionnel!",
"Block generation": "Production de blocs",
@ -1549,18 +1694,19 @@ if(preferredLanguage == "fr"){ @@ -1549,18 +1694,19 @@ if(preferredLanguage == "fr"){
"Network status": "État du réseau",
"New direct message...": "Nouveau message privé...",
"New Post...": "Nouveau billets...",
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"You got": "Tu as",
"in postboard": "sur le postboard",
"in search result": "dans les résultats de recherche",
"in top trends": "dans les top trends",
"new_posts": "%{smart_count} nouveau billet |||| %{smart_count} nouveaux billets",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"new_mentions": "%{smart_count} nouvelle mention |||| %{smart_count} nouvelles mentions",
"new_direct_messages": "%{smart_count} nouveau message privé |||| %{smart_count} nouveaux messages privés",
"nobody": "nobody", // used to promote a post without attaching the user
"Not available": "Non disponible", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"notify_desktop_error": "Impossible d'afficher les notifications: une erreur inconnue est survenue.",
"notify_desktop_perm_denied": "Impossible d'afficher les notifications: autorisation refusée.\n\nSi tu souhaites afficher les notifications, autorise le %{this_domain} dans les paramêtres de ton navigateur.",
"notify_desktop_test": "All the twisters gonna twist.\nBienvenue à toi!",
"notify_desktop_title": "Youhou! Ça bouge sur ton twister!",
"Number of blocks in block chain:": "Nombre de blocs dans la chaîne de blocs: ",
"Number of CPUs to use": "Nombre de processeurs à utiliser",
"Only alphanumeric and underscore allowed.": "Seuls les caractères alphanumériques et la barre de soulignement sont permis.",
@ -1598,6 +1744,7 @@ if(preferredLanguage == "fr"){ @@ -1598,6 +1744,7 @@ if(preferredLanguage == "fr"){
"Type message here": "Tapez votre message ici",
"Unfollow": "Se désabonner",
"Update": "Mettre à jour",
"Auto updating": "Mise à jour automatique",
"Updating status...": "Mise à jour du statut...", // status of block chain
"user_not_yet_accepted": "Les autres pairs n'ont pas encore accepté ce nouvel utilisateur.\n" +
"Malheureusement, il n'est pas possible d'enregistrer le profil\n" +
@ -1693,7 +1840,28 @@ if(preferredLanguage == "fr"){ @@ -1693,7 +1840,28 @@ if(preferredLanguage == "fr"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "seconde(s)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "Seuls les nombres >= 0 sont autorisés!",
"Language filtering": "Filtre par langue",
"By blacklist": "Par blacklist",
"By whitelist": "Par liste blanche",
"Comma separated ISO 639-3 language codes": "Codes ISO 639-3 séparés par une virgule",
"Accuracy": "Précision",
"Simulation mode": "Mode simulation",
"This post is treated by language filter": "Ce post est %{treated} par le filtre de langue.",
"blocked": "bloqué",
"passed": "transmis",
"not analyzed": "non analysé",
"Reason: this": "Raison: %{this}",
"this doesnt contain that": "%{this} ne contient pas %{that}",
"this is undefined": "%{this} est indéfini",
"blacklist": "blacklist",
"whitelist": "liste blanche",
"language of this": "Langue",
"its undefined language": "Langue indéfinie",
"its this, blacklisted": "C'est %{this}, sur blacklist",
"its this, whitelisted": "C'est %{this}, sur liste blanche",
"Most possible language: this": "Langue la plus probable: %{this}",
"Scope of usage": "Champ d'application",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -1741,6 +1909,7 @@ if(preferredLanguage == "ru"){ @@ -1741,6 +1909,7 @@ if(preferredLanguage == "ru"){
"ajax_error": "Ajax ошибка: %{error}", // JavaScript error
"All users publicly followed by": "Все публичные пользователи на которых подписан",
"Available": "Доступно",
"Appearance": "Отображение",
"Block chain information": "Информация цепочки блоков",
"Block chain is up-to-date, twister is ready to use!": "Цепочка блоков обновлена, twister готов к использованию!",
"Block generation": "Майнинг блоков ",
@ -1797,13 +1966,14 @@ if(preferredLanguage == "ru"){ @@ -1797,13 +1966,14 @@ if(preferredLanguage == "ru"){
"You got": "У вас",
"in postboard": "в ленте",
"in search result": "в результатах поиска",
"in top trends": "в топе трендов",
"new_posts": "%{smart_count} новый пост |||| %{smart_count} новых постов",
"new_mentions": "%{smart_count} новое упоминание |||| %{smart_count} новых упоминаний",
"new_direct_messages": "%{smart_count} новое личное сообщение |||| %{smart_count} новых личных сообщений",
"nobody": "Анонимно", // used to promote a post without attaching the user
"Not available": "Недоступно",
"notify_desktop_error": "Твистер не может выполнить уведомление: произошла неизвестная ошибка.",
"notify_desktop_perm_denied": "Твистер не может выполнить уведомление: разрешение не получено.\n\nЧтобы получать уведомления, разрешите их для этого домена в настройках вашего браузера.",
"notify_desktop_perm_denied": "Твистер не может выполнить уведомление: разрешение не получено.\n\nЧтобы получать уведомления, разрешите их для %{this_domain} в настройках вашего браузера.",
"notify_desktop_test": "Одна лягушка сказала:\n'если не буду квакать — лопну'.\nВы нужны нам, берегите себя.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Количество блоков в цепочке: ",
@ -1843,6 +2013,7 @@ if(preferredLanguage == "ru"){ @@ -1843,6 +2013,7 @@ if(preferredLanguage == "ru"){
"Type message here": "Сообщение...",
"Unfollow": "Отписаться",
"Update": "Обновить",
"Auto updating": "Автоматическое обновление",
"Updating status...": "Обновление информации...", // status of block chain
"user_not_yet_accepted": "Другие участники сети еще не получили информацию о новом пользователе.\n" +
"К сожалению, сейчас вы не можете редактировать ваш профиль\n" +
@ -1938,7 +2109,28 @@ if(preferredLanguage == "ru"){ @@ -1938,7 +2109,28 @@ if(preferredLanguage == "ru"){
"Show if the original is older than": "Показывать если исходное сообщение старше",
"hour(s)": "час(ов)",
"second(s)": "секунд(а,ы)",
"only numbers are allowed!": "только числа!",
"only positive numbers!": "разрешены только положительные числа!",
"Language filtering": "Ограничение языковым фильтром",
"By blacklist": "С помощью чёрного списка",
"By whitelist": "С помощью белого списка",
"Comma separated ISO 639-3 language codes": "Соответствующие ISO 639-3 языковые коды, разделённые запятыми",
"Accuracy": "Точность",
"Simulation mode": "Режим симуляции",
"This post is treated by language filter": "Этот пост %{treated} языковым фильтром.",
"blocked": "запрещён",
"passed": "разрешён",
"not analyzed": "не обработан",
"Reason: this": "Причина: %{this}",
"this doesnt contain that": "%{this} не содержит %{that}",
"this is undefined": "%{this} не определён",
"blacklist": "чёрный список",
"whitelist": "белый список",
"language of this": "такой язык",
"its undefined language": "язык не определён",
"its this, blacklisted": "это %{this}, есть в чёрном списке",
"its this, whitelisted": "это %{this}, есть в белом списке",
"Most possible language: this": "Наиболее вероятный язык: %{this}",
"Scope of usage": "Область применения",
"Show with every user name": "Показывать везде около имени пользователя",
"Show at profile modal only": "Показывать только в окне профиля",
"Show if a user follows me": "Показывать подписан ли пользователь на меня",
@ -1989,6 +2181,7 @@ if(preferredLanguage == "de"){ @@ -1989,6 +2181,7 @@ if(preferredLanguage == "de"){
"ajax_error": "Ajax error: %{error}", // JavaScript error
"All users publicly followed by": "Alle öffentlich gefolgten Benutzer von",
"Available": "Verfügbar", // username is available
"Appearance": "Aussehen",
"Block chain information": "Block-Chain Informationen",
"Block chain is up-to-date, twister is ready to use!": "Block-Chain ist aktuell, twister ist benutzbar!",
"Block generation": "Block-Generierung ",
@ -2042,18 +2235,19 @@ if(preferredLanguage == "de"){ @@ -2042,18 +2235,19 @@ if(preferredLanguage == "de"){
"Network status": "Netzwerkstatus",
"New direct message...": "Neue Direktnachricht...",
"New Post...": "Neuer Post...",
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"You got": "Du hast",
"in postboard": "in der Timeline",
"in search result": "in den Suchergebnissen",
"in top trends": "in den Top Trends",
"new_posts": "%{smart_count} neuer Post |||| %{smart_count} neue Posts",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"new_mentions": "%{smart_count} neue Erwähnung |||| %{smart_count} neue Erwähnungen",
"new_direct_messages": "%{smart_count} neue Direktnachricht |||| %{smart_count} neue Direktnachrichten",
"nobody": "nobody", // used to promote a post without attaching the user
"Not available": "Nicht verfügbar", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"notify_desktop_error": "Twister kann keine Desktop-Meldungen anzeigen: ein unbekannter Fehler trat auf.",
"notify_desktop_perm_denied": "Twister kann keine Desktop-Meldungen anzeigen: Keine Berechtigung.\n\nWenn Du Meldungen angezeigt haben möchtest, erlaube sie für %{this_domain} in den Einstellungen Deines Browsers.",
"notify_desktop_test": "All die Twisterer werden twisten..\nDu bist nun auch willkommen!",
"notify_desktop_title": "Achtung, hier ist Twister am Gange!",
"Number of blocks in block chain:": "Anzahl der Blöcke in der Block-Chain: ",
"Number of CPUs to use": "Anzahl der zu benutzenden CPU's ",
"Only alphanumeric and underscore allowed.": "Nur Buchstaben, Zahlen und Unterstrich erlaubt.",
@ -2091,6 +2285,7 @@ if(preferredLanguage == "de"){ @@ -2091,6 +2285,7 @@ if(preferredLanguage == "de"){
"Type message here": "Nachricht hier eingeben",
"Unfollow": "Nicht mehr folgen",
"Update": "Aktualisieren",
"Auto updating": "Automatsiche Aktualisierung",
"Updating status...": "Status wird aktualisiert...", // status of block chain
"user_not_yet_accepted": "Andere Peers haben diesen Benutzter noch nicht akzeptiert.\n" +
"Leider ist es nicht möglich, das Profil zu speichern\n" +
@ -2187,7 +2382,28 @@ if(preferredLanguage == "de"){ @@ -2187,7 +2382,28 @@ if(preferredLanguage == "de"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "Sekunde(n)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "nur positive Zahlen erlaubt!",
"Language filtering": "Sprachfilterung",
"By blacklist": "Mittels schwarzer Liste",
"By whitelist": "Mittels weißer Liste",
"Comma separated ISO 639-3 language codes": "Komma getrennte ISO 639-3 Sprachcodes",
"Accuracy": "Genauigkeit",
"Simulation mode": "Simulationsmodus",
"This post is treated by language filter": "Diese Nachricht ist mittels Sprachfilter %{treated}",
"blocked": "blockiert",
"passed": "weitergeleitet",
"not analyzed": "nicht anylysiert",
"Reason: this": "Ursache: %{this}",
"this doesnt contain that": "%{this} dies enthält %{that} nicht",
"this is undefined": "%{this} ist nicht definiert",
"blacklist": "schwarze Liste",
"whitelist": "weiße Liste",
"language of this": "Die Sprache des Folgenden",
"its undefined language": "es handelt sich um eine undefinierte Sprache",
"its this, blacklisted": "es ist %{this}, aus der schwarzen Liste",
"its this, whitelisted": "es ist %{this}, aus der weißen Liste",
"Most possible language: this": "Die wahrscheinlichste Sprache: %{this}",
"Scope of usage": "Anwendungsbereich",
"Show with every user name": "Zeige mit jedem Benutzernamen",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Zeige an, wenn mir ein Benutzer folgt",
@ -2233,6 +2449,7 @@ if(preferredLanguage == "ja"){ @@ -2233,6 +2449,7 @@ if(preferredLanguage == "ja"){
"ajax_error": "AJAXエラー: %{error}", // JavaScript error
"All users publicly followed by": "このユーザがフォローを公開している",
"Available": "Available", // username is available
"Appearance": "Appearance",
"Block chain information": "ブロックチェイン",
"Block chain is up-to-date, twister is ready to use!": "ブロックチェインは最新の状態です。",
"Block generation": "ブロック生成",
@ -2289,13 +2506,14 @@ if(preferredLanguage == "ja"){ @@ -2289,13 +2506,14 @@ if(preferredLanguage == "ja"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} 新投稿 |||| %{smart_count} 新投稿",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "ナナシ", // used to promote a post without attaching the user
"Not available": "使用中", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "全ブロック数: ",
@ -2335,6 +2553,7 @@ if(preferredLanguage == "ja"){ @@ -2335,6 +2553,7 @@ if(preferredLanguage == "ja"){
"Type message here": "ここにメッセージを書いてね",
"Unfollow": "解除",
"Update": "アップデート",
"Auto updating": "Auto updating",
"Updating status...": "ブロックチェーンを更新中…", // status of block chain
"user_not_yet_accepted": "この新ユーザーが他のピアーにまだ認証されていない。\n" +
"なので、プロファイルの保存やメッセージの投稿は現在不可能です。\n" +
@ -2427,7 +2646,28 @@ if(preferredLanguage == "ja"){ @@ -2427,7 +2646,28 @@ if(preferredLanguage == "ja"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "second(s)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "only positive numbers are allowed!",
"Language filtering": "Language filtering",
"By blacklist": "By blacklist",
"By whitelist": "By whitelist",
"Comma separated ISO 639-3 language codes": "Comma separated ISO 639-3 language codes",
"Accuracy": "Accuracy",
"Simulation mode": "Simulation mode",
"This post is treated by language filter": "This post is %{treated} by language filter.",
"blocked": "blocked",
"passed": "passed",
"not analyzed": "not analyzed",
"Reason: this": "Reason: %{this}",
"this doesnt contain that": "%{this} does not contain %{that}",
"this is undefined": "%{this} is undefined",
"blacklist": "blacklist",
"whitelist": "whitelist",
"language of this": "language of this",
"its undefined language": "it is undefined language",
"its this, blacklisted": "it is %{this}, blacklisted",
"its this, whitelisted": "it is %{this}, whitelisted",
"Most possible language: this": "Most possible language: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -2474,6 +2714,7 @@ if(preferredLanguage == "pt-BR"){ @@ -2474,6 +2714,7 @@ if(preferredLanguage == "pt-BR"){
"ajax_error": "Erro Ajax: %{error}", // JavaScript error
"All users publicly followed by": "Todos os usuários seguidos publicamente por",
"Available": "Disponível", // username is available
"Appearance": "Appearance",
"Block chain information": "Informações da Cadeia de Blocos",
"Block chain is up-to-date, twister is ready to use!": "A Cadeida de Blocos está sincronizada, Twister está pronto para uso!",
"Block generation": "Geração de blocos ",
@ -2530,13 +2771,14 @@ if(preferredLanguage == "pt-BR"){ @@ -2530,13 +2771,14 @@ if(preferredLanguage == "pt-BR"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} nova postagem |||| %{smart_count} novas postagens",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "nobody", // used to promote a post without attaching the user
"Not available": "Indisponível", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Número de blocos: ",
@ -2577,6 +2819,7 @@ if(preferredLanguage == "pt-BR"){ @@ -2577,6 +2819,7 @@ if(preferredLanguage == "pt-BR"){
"Type message here": "Escreva sua mensagem aqui",
"Unfollow": "Deixar de seguir",
"Update": "Atualizar",
"Auto updating": "Auto updating",
"Updating status...": "Atualizando estado da Cadeia de Blocos...", // status of block chain
"user_not_yet_accepted": "Outros nós ainda não aceitaram este novo usuário.\n" +
"Infelizmente não é possível salvar o perfil\n" +
@ -2673,7 +2916,28 @@ if(preferredLanguage == "pt-BR"){ @@ -2673,7 +2916,28 @@ if(preferredLanguage == "pt-BR"){
"Show if the original is older than": "Show if the original is older than",
"hour(s)": "hour(s)",
"second(s)": "segundo(s)",
"only numbers are allowed!": "only numbers are allowed!",
"only positive numbers!": "only positive numbers are allowed!",
"Language filtering": "Language filtering",
"By blacklist": "By blacklist",
"By whitelist": "By whitelist",
"Comma separated ISO 639-3 language codes": "Comma separated ISO 639-3 language codes",
"Accuracy": "Accuracy",
"Simulation mode": "Simulation mode",
"This post is treated by language filter": "This post is %{treated} by language filter.",
"blocked": "blocked",
"passed": "passed",
"not analyzed": "not analyzed",
"Reason: this": "Reason: %{this}",
"this doesnt contain that": "%{this} does not contain %{that}",
"this is undefined": "%{this} is undefined",
"blacklist": "blacklist",
"whitelist": "whitelist",
"language of this": "language of this",
"its undefined language": "it is undefined language",
"its this, blacklisted": "it is %{this}, blacklisted",
"its this, whitelisted": "it is %{this}, whitelisted",
"Most possible language: this": "Most possible language: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Show with every user name",
"Show at profile modal only": "Show at profile modal only",
"Show if a user follows me": "Show if a user follows me",
@ -2719,6 +2983,7 @@ if(preferredLanguage == "tr"){ @@ -2719,6 +2983,7 @@ if(preferredLanguage == "tr"){
"ajax_error": "Ajax hatası: %{error}", // JavaScript error
"All users publicly followed by": "Açık olarak takip edilen tüm kullanıcılar",
"Available": "Kullanılabilir", // username is available
"Appearance": "Appearance",
"Block chain information": "Blok zincir bilgisi",
"Block chain is up-to-date, twister is ready to use!": "Blok zinciri güncel, twister kullanıma hazır!",
"Block generation": "Blok üretimi ",
@ -2775,13 +3040,14 @@ if(preferredLanguage == "tr"){ @@ -2775,13 +3040,14 @@ if(preferredLanguage == "tr"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} yeni gönederi |||| %{smart_count} yeni gönderi",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "hiçkimse", // used to promote a post without attaching the user
"Not available": "Kullanılamaz", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Blok zincirindeki blok sayısı: ",
@ -2821,6 +3087,7 @@ if(preferredLanguage == "tr"){ @@ -2821,6 +3087,7 @@ if(preferredLanguage == "tr"){
"Type message here": "Mesajı buraya yazınız",
"Unfollow": "Takibi bırak",
"Update": "Güncelle",
"Auto updating": "Auto updating",
"Updating status...": "Durum güncelleniyor...", // status of block chain
"user_not_yet_accepted": "Diğer eşler bu yeni kullanıcıyı henüz kabul etmediler.\n" +
"Malesef profili kaydetmek ya da bu durumda\n" +
@ -2915,7 +3182,28 @@ if(preferredLanguage == "tr"){ @@ -2915,7 +3182,28 @@ if(preferredLanguage == "tr"){
"Show if the original is older than": "Orjinali yandaki süreden daha eskiyse göster",
"hour(s)": "saat",
"second(s)": "saniye",
"only numbers are allowed!": "sadece rakam girilebilir!",
"only positive numbers!": "sadece rakam girilebilir!",
"Language filtering": "Dile göre süzme",
"By blacklist": "Kara liste ile",
"By whitelist": "Beyaz liste ile",
"Comma separated ISO 639-3 language codes": "Virgülle ayrılmış ISO 639-3 dil kodları",
"Accuracy": "Hassasiyet",
"Simulation mode": "Benzetim yap",
"This post is treated by language filter": "Bu gönderi dil süzgeci tarafından %{treated}.",
"blocked": "engellendi",
"passed": "kabul edildi",
"not analyzed": "incelenmedi",
"Reason: this": "Sebep: %{this}",
"this doesnt contain that": "%{that} %{this} tarafından kapsanmıyor",
"this is undefined": "%{this} is undefined",
"blacklist": "beyaz liste",
"whitelist": "kara liste",
"language of this": "dili",
"its undefined language": "belirsiz dil",
"its this, blacklisted": "%{this}, engellendi",
"its this, whitelisted": "%{this}, kabul edildi",
"Most possible language: this": "Muhtemel dil: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Tüm kullanıcı adlarının yanında göster",
"Show at profile modal only": "Sadece profilinde göster",
"Show if a user follows me": "Bir kullanıcının beni takip edip etmediğini göster",
@ -2961,6 +3249,7 @@ if(preferredLanguage == "cs"){ @@ -2961,6 +3249,7 @@ if(preferredLanguage == "cs"){
"ajax_error": "Ajax chyba: %{error}", // JavaScript error
"All users publicly followed by": "Všichni uživatelé, které veřejně sleduje",
"Available": "Je volná", // username is available
"Appearance": "Appearance",
"Block chain information": "Informace o blockchainu",
"Block chain is up-to-date, twister is ready to use!": "Blockchain je aktuální, twister je připraven k použití!",
"Block generation": "Generování bloků ",
@ -3017,13 +3306,14 @@ if(preferredLanguage == "cs"){ @@ -3017,13 +3306,14 @@ if(preferredLanguage == "cs"){
"You got": "You got",
"in postboard": "in postboard",
"in search result": "in search result",
"in top trends": "in top trends",
"new_posts": "%{smart_count} nový příspěvek |||| %{smart_count} nové příspěvky |||| %{smart_count} nových příspěvků",
"new_mentions": "%{smart_count} new mention |||| %{smart_count} new mentions",
"new_direct_messages": "%{smart_count} new direct message |||| %{smart_count} new direct messages",
"nobody": "nikdo", // used to promote a post without attaching the user
"Not available": "Tuto přezdívku již někdo používá", // username is not available
"notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for this domain in settings of your browser.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.",
"notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Počet bloků v blockchainu: ",
@ -3063,6 +3353,7 @@ if(preferredLanguage == "cs"){ @@ -3063,6 +3353,7 @@ if(preferredLanguage == "cs"){
"Type message here": "Sem napište příspěvek",
"Unfollow": "Přestat sledovat",
"Update": "Aktualizovat",
"Auto updating": "Auto updating",
"Updating status...": "Aktualizuji stav...", // status of block chain
"user_not_yet_accepted": "Ostatní uzly ještě nepřijaly tohoto nového uživatele.\n" +
"Proto zatím není možné uložit profil nebo vkládat příspěvky.\n" +
@ -3156,7 +3447,28 @@ if(preferredLanguage == "cs"){ @@ -3156,7 +3447,28 @@ if(preferredLanguage == "cs"){
"Show if the original is older than": "Ukázat pokud je už originál starší než",
"hour(s)": "hodin",
"second(s)": "vteřinou(ami)",
"only numbers are allowed!": "povolena jsou jen čísla!",
"only positive numbers!": "povolena jsou jen čísla!",
"Language filtering": "Language filtering",
"By blacklist": "By blacklist",
"By whitelist": "By whitelist",
"Comma separated ISO 639-3 language codes": "Comma separated ISO 639-3 language codes",
"Accuracy": "Accuracy",
"Simulation mode": "Simulation mode",
"This post is treated by language filter": "This post is %{treated} by language filter.",
"blocked": "blocked",
"passed": "passed",
"not analyzed": "not analyzed",
"Reason: this": "Reason: %{this}",
"this doesnt contain that": "%{this} does not contain %{that}",
"this is undefined": "%{this} is undefined",
"blacklist": "blacklist",
"whitelist": "whitelist",
"language of this": "language of this",
"its undefined language": "it is undefined language",
"its this, blacklisted": "it is %{this}, blacklisted",
"its this, whitelisted": "it is %{this}, whitelisted",
"Most possible language: this": "Most possible language: %{this}",
"Scope of usage": "Scope of usage",
"Show with every user name": "Ukázat u každé přezdívky",
"Show at profile modal only": "Ukázat jen v okně profilu",
"Show if a user follows me": "Ukazovat, zda mně uživatel sleduje",

57
js/mobile_abstract.js

@ -105,7 +105,7 @@ var MAL = function() @@ -105,7 +105,7 @@ var MAL = function()
if ($.Options.getShowDesktopNotifPostsOpt() === 'enable') {
this.showDesktopNotif(false, polyglot.t('You got')+' '+polyglot.t('new_posts', newPosts)+' '+polyglot.t('in postboard')+'.', false,'twister_notification_new_posts', $.Options.getShowDesktopNotifPostsTimerOpt(), (function() {
requestTimelineUpdate('latest',this,followingUsers,promotedPostsOnly);
requestTimelineUpdate('pending',this,followingUsers,promotedPostsOnly);
}).bind(newPosts), false)
}
} else {
@ -488,3 +488,58 @@ var MAL = function() @@ -488,3 +488,58 @@ var MAL = function()
jQuery.MAL = new MAL;
function filterLang(string) {
var langFilterMode = $.Options.getFilterLangOpt();
if (langFilterMode !== 'disable') {
var langFilterSubj = '';
var langFilterProb = [];
var langFilterPass = true;
var langFilterReason = '';
var langFilterList = $.Options.getFilterLangListOpt();
if (langFilterList.length > 0) {
var langFilterAccuracy = $.Options.getFilterLangAccuracyOpt();
langFilterPass = (langFilterMode === 'whitelist') ? false : true;
langFilterReason = polyglot.t('this doesnt contain that', {'this': polyglot.t(langFilterMode), 'that': polyglot.t('language of this')});
// before detection attempts we cut out any mentions and links, and replace _ with space
langFilterSubj = string.replace(/@\S\w*|https?:\/\/\S*/g, '').replace(/_+/g, ' ')
// replace zero-width word boundaries, such as between letters from different alphabets [or other symbols], with spaces
// FIXME not so good idea because 'Za pomocą białej listy' may turn into 'Za pomoc ą bia ł ej listy' for e.g.
// FIXME but first one was recognized as 'hrv' and second as 'pol' and you know it's 'pol' actually
.replace(/\b/g, ' ')
// cut out some more symbols
.replace(/[#\[\]\(\)\{\}\-\+\=\^\:\;\\\/]/g, '')
// clear unwanted spaces
.replace(/\s+/g, ' ').trim();
langFilterProb = franc.all(langFilterSubj, {'minLength': 2}); // FIXME minLength may become configurable option at some time
for (var i = 0; i < langFilterProb.length; i++) {
if (langFilterProb[i][1] > langFilterAccuracy) {
if (langFilterProb[i][0] === 'und') { // e.g. digits-only string will be detected as undefined and thereby will be allowed
langFilterPass = true;
langFilterReason = polyglot.t('its undefined language');
break;
} else if (langFilterList.indexOf(langFilterProb[i][0]) > -1) {
if (langFilterMode === 'whitelist') {
langFilterPass = true;
langFilterReason = polyglot.t('its this, whitelisted', {'this': '\''+langFilterProb[i][0]+'\''});
break;
} else {
langFilterPass = false;
langFilterReason = polyglot.t('its this, blacklisted', {'this': '\''+langFilterProb[i][0]+'\''});
break;
}
}
}
}
} else {
langFilterReason = polyglot.t('this is undefined', {'this': polyglot.t(langFilterMode)});
}
//console.log('langFilter | status: '+((langFilterPass === true) ? polyglot.t('passed') : polyglot.t('blocked'))+' | reason: '+langFilterReason+' | subject: \''+langFilterSubj+'\'');
return {'subj': langFilterSubj, 'prob': langFilterProb, 'pass': langFilterPass, 'reason': langFilterReason};
}
}

130
js/options.js

@ -212,7 +212,7 @@ var TwisterOptions = function() @@ -212,7 +212,7 @@ var TwisterOptions = function()
this.setTestDesktopNotif = function() {
$('#testDesktopNotif').on('click', function() {
$.MAL.showDesktopNotif(false, polyglot.t('notify_desktop_test'), false,'twister_notification_test', false, false, function() { alert(polyglot.t('notify_desktop_perm_denied')) })
$.MAL.showDesktopNotif(false, polyglot.t('notify_desktop_test'), false,'twister_notification_test', false, false, function() { alert(polyglot.t('notify_desktop_perm_denied', {'this_domain': document.domain})) })
})
}
@ -372,6 +372,36 @@ var TwisterOptions = function() @@ -372,6 +372,36 @@ var TwisterOptions = function()
});
}
this.getTopTrendsAutoUpdateOpt = function() {
return this.getOption('TopTrendsAutoUpdate', 'enable');
}
this.setTopTrendsAutoUpdateOpt = function () {
function TopTrendsAutoUpdateCfg() {
if ($.Options.getTopTrendsAutoUpdateOpt() === 'enable') {
$('#TopTrendsAutoUpdateOpt')[0].style.display= 'inline';
} else {
$('#TopTrendsAutoUpdateOpt')[0].style.display= 'none';
}
}
$('#TopTrendsAutoUpdate').val(this.getTopTrendsAutoUpdateOpt());
TopTrendsAutoUpdateCfg();
$('#TopTrendsAutoUpdate').on('change', function() {
$.Options.setOption(this.id, this.value);
TopTrendsAutoUpdateCfg();
});
}
this.getTopTrendsAutoUpdateTimerOpt = function () {
return parseInt(this.getOption('TopTrendsAutoUpdateTimer', '120'));
}
this.setTopTrendsAutoUpdateTimerOpt = function () {
$('#TopTrendsAutoUpdateTimer')[0].value = this.getTopTrendsAutoUpdateTimerOpt().toString();
$('#TopTrendsAutoUpdateTimer').on('keyup', function () {setElemValNumeric(this, polyglot.t('second(s)'));});
}
this.getSplitPostsOpt = function (){
return $.Options.getOption('splitPosts', 'disable');
}
@ -434,6 +464,89 @@ var TwisterOptions = function() @@ -434,6 +464,89 @@ var TwisterOptions = function()
return $.Options.getOption('isFollowingMe');
};
this.getFilterLangOpt = function() {
return this.getOption('filterLang','disable');
}
this.setFilterLangOpt = function () {
function filterLangListCont() {
if ( $.Options.getFilterLangOpt() !== 'disable' ) {
$('#filterLangListCont')[0].style.display= 'block';
} else {
$('#filterLangListCont')[0].style.display= 'none';
}
}
$('#filterLang').val(this.getFilterLangOpt());
filterLangListCont();
$('#filterLang').on('change', function() {
$.Options.setOption(this.id, this.value);
filterLangListCont();
});
}
this.getFilterLangListOpt = function () {
return this.getOption('filterLangList', '').replace(/\s+/g, '').split(/\s*,\s*/);
}
this.setFilterLangListOpt = function () {
$('#filterLangList').val(this.getFilterLangListOpt());
$('#filterLangList').on('keyup', function () {$.Options.setOption(this.id, this.value);});
}
this.getFilterLangAccuracyOpt = function () {
return parseFloat(this.getOption('filterLangAccuracy', '0.82'));
}
this.setFilterLangAccuracyOpt = function () {
$('#filterLangAccuracy').val(this.getFilterLangAccuracyOpt());
$('#filterLangAccuracyVal').text(this.getFilterLangAccuracyOpt());
$('#filterLangAccuracy').on('change', function () {
$.Options.setOption(this.id, this.value);
$('#filterLangAccuracyVal').text(this.value);
});
}
this.getFilterLangForPostboardOpt = function () {
return this.getOption('filterLangForPostboard', true);
}
this.setFilterLangForPostboardOpt = function () {
$('#filterLangForPostboard').prop('checked', this.getFilterLangForPostboardOpt());
$('#filterLangForPostboard').on('click', function () {$.Options.setOption(this.id, this.checked);});
}
this.getFilterLangForSearchingOpt = function () {
return this.getOption('filterLangForSearching', true);
}
this.setFilterLangForSearchingOpt = function () {
$('#filterLangForSearching').prop('checked', this.getFilterLangForSearchingOpt());
$('#filterLangForSearching').on('click', function () {$.Options.setOption(this.id, this.checked);});
}
this.getFilterLangForTopTrendsOpt = function () {
return this.getOption('filterLangForTopTrends', true);
}
this.setFilterLangForTopTrendsOpt = function () {
$('#filterLangForTopTrends').prop('checked', this.getFilterLangForTopTrendsOpt());
$('#filterLangForTopTrends').on('click', function () {$.Options.setOption(this.id, this.checked);});
}
this.getFilterLangSimulateOpt = function () {
return this.getOption('filterLangSimulate', true);
}
this.setFilterLangSimulateOpt = function () {
$('#filterLangSimulate').prop('checked', this.getFilterLangSimulateOpt());
$('#filterLangSimulate').on('click', function () {$.Options.setOption(this.id, this.checked);});
}
this.setIsFollowingMeOpt = function () {
$('#isFollowingMe')[0].value = this.getIsFollowingMeOpt();
@ -478,23 +591,32 @@ var TwisterOptions = function() @@ -478,23 +591,32 @@ var TwisterOptions = function()
this.setConvertFractionsOpt();
this.setUseProxyOpt();
this.setUseProxyForImgOnlyOpt();
this.setTopTrendsAutoUpdateOpt();
this.setTopTrendsAutoUpdateTimerOpt();
this.setSplitPostsOpt();
this.setHideRepliesOpt();
this.setHideCloseRTsHourOpt();
this.setHideCloseRTsOpt();
this.setFilterLangOpt();
this.setFilterLangListOpt();
this.setFilterLangAccuracyOpt();
this.setFilterLangForPostboardOpt();
this.setFilterLangForSearchingOpt();
this.setFilterLangForTopTrendsOpt();
this.setFilterLangSimulateOpt();
this.setIsFollowingMeOpt();
this.setDMCopySelfOpt();
}
function setElemValNumeric(elem, mes) {
//var elem = $(elem_nm);
if (/^\d+$/.test(elem.value)) {
if (/^\d+$/.test(elem.value) && parseFloat(elem.value) > 0) {
elem.style.backgroundColor = '';
$.Options.setOption(elem.id, elem.value);
$(elem).next('span').text(mes);
} else {
elem.style.backgroundColor = '#f00';
$(elem).next('span').text(polyglot.t('only numbers are allowed!'));
$(elem).next('span').text(polyglot.t('only positive numbers!'));
}
};
}
@ -507,7 +629,7 @@ function localizeLabels() @@ -507,7 +629,7 @@ function localizeLabels()
$("label[for=t-2]").text(polyglot.t("Theme"));
$("label[for=t-3]").text(polyglot.t("Notifications"));
$("label[for=t-4]").text(polyglot.t("Keys"));
$("label[for=t-5]").text(polyglot.t("Postboard"));
$("label[for=t-5]").text(polyglot.t("Appearance"));
$("label[for=t-6]").text(polyglot.t("Users"));
}

32
js/twister_actions.js

@ -226,6 +226,9 @@ function requestPostRecursively(containerToAppend,username,resource,count,useGet @@ -226,6 +226,9 @@ function requestPostRecursively(containerToAppend,username,resource,count,useGet
function newPostMsg(msg, $postOrig) {
if( lastPostId != undefined ) {
if ( typeof _sendedPostIDs !== 'undefined' )
_sendedPostIDs.push(lastPostId + 1);
var params = [defaultScreenName, lastPostId + 1, msg]
if( $postOrig.length ) {
params.push($postOrig.attr('data-screen-name'));
@ -235,7 +238,6 @@ function newPostMsg(msg, $postOrig) { @@ -235,7 +238,6 @@ function newPostMsg(msg, $postOrig) {
function(arg, ret) { incLastPostId(); }, null,
function(arg, ret) { var msg = ("message" in ret) ? ret.message : ret;
alert(polyglot.t("ajax_error", { error: msg })); }, null);
setTimeout('requestTimelineUpdate("latest",1,["'+defaultScreenName+'"],promotedPostsOnly)', 1000);
} else {
alert(polyglot.t("Internal error: lastPostId unknown (following yourself may fix!)"));
}
@ -250,13 +252,15 @@ function newRtMsg($postOrig) { @@ -250,13 +252,15 @@ function newRtMsg($postOrig) {
var rtObj = { sig_userpost :sig_userpost, userpost : userpost };
if( lastPostId != undefined ) {
if ( typeof _sendedPostIDs !== 'undefined' )
_sendedPostIDs.push(lastPostId + 1);
var params = [defaultScreenName, lastPostId+1, rtObj]
twisterRpc("newrtmsg", params,
function(arg, ret) { incLastPostId(); }, null,
function(arg, ret) { var msg = ("message" in ret) ? ret.message : ret;
alert(polyglot.t("ajax_error", { error: msg })); }, null);
setTimeout('requestTimelineUpdate("latest",1,["'+defaultScreenName+'"],promotedPostsOnly)', 1000);
} else {
alert(polyglot.t("Internal error: lastPostId unknown (following yourself may fix!)"));
}
@ -336,6 +340,22 @@ function processHashtag(postboard, hashtag, data) { @@ -336,6 +340,22 @@ function processHashtag(postboard, hashtag, data) {
var key = userpost["n"] + ";" + userpost["time"];
if( !(key in _hashtagProcessedMap) ) {
_hashtagProcessedMap[key] = true;
if ($.Options.getFilterLangOpt() !== 'disable' && $.Options.getFilterLangForSearchingOpt()) {
if (typeof(userpost['rt']) !== 'undefined') {
var msg = userpost['rt']['msg'];
} else {
var msg = userpost['msg'];
}
langFilterData = filterLang(msg);
if ($.Options.getFilterLangSimulateOpt()) {
data[i]['langFilter'] = langFilterData;
} else {
if (!langFilterData['pass'])
continue;
}
}
_hashtagPendingPosts.push(data[i]);
_hashtagPendingPostsUpdated++;
}
@ -359,8 +379,11 @@ function processHashtag(postboard, hashtag, data) { @@ -359,8 +379,11 @@ function processHashtag(postboard, hashtag, data) {
function displayHashtagPending(postboard) {
for( var i = 0; i < _hashtagPendingPosts.length; i++ ) {
var streamPost = postToElem(_hashtagPendingPosts[i], "original");
var timePost = _hashtagPendingPosts[i]["userpost"]["time"];
var post = _hashtagPendingPosts[i];
//console.log(post);
var streamPost = postToElem(post, "original");
var timePost = post["userpost"]["time"];
streamPost.attr("data-time",timePost);
var streamItems = postboard.children();
if( streamItems.length == 0) {
@ -385,4 +408,3 @@ function displayHashtagPending(postboard) { @@ -385,4 +408,3 @@ function displayHashtagPending(postboard) {
$.MAL.postboardLoaded();
_hashtagPendingPosts = [];
}

18
js/twister_formatpost.js

@ -119,8 +119,24 @@ function postToElem( post, kind, promoted ) { @@ -119,8 +119,24 @@ function postToElem( post, kind, promoted ) {
retweetedByElem.text('@'+retweeted_by);
}
if (typeof(promoted) !== 'undefined' && promoted)
if (typeof(promoted) !== 'undefined' && promoted) {
elem.find('.post-propagate').remove();
} else {
if ($.Options.getFilterLangOpt() !== 'disable' && $.Options.getFilterLangSimulateOpt()) {
// FIXME it's must be stuff from template actually
if (typeof(post['langFilter']) !== 'undefined') {
if (typeof(post['langFilter']['prob'][0]) !== 'undefined')
var mlm = ' // '+polyglot.t('Most possible language: this', {'this': '<em>'+post['langFilter']['prob'][0].toString()+'</em>'});
else
var mlm = '';
elem.append('<div class="langFilterSimData">'+polyglot.t('This post is treated by language filter', {'treated': '<em>'+((post['langFilter']['pass']) ? polyglot.t('passed') : polyglot.t('blocked'))+'</em>'})+'</div>');
elem.append('<div class="langFilterSimData">'+polyglot.t('Reason: this', {'this': '<em>'+post['langFilter']['reason']+'</em>'})+mlm+'</div>');
} else {
elem.append('<div class="langFilterSimData">'+polyglot.t('This post is treated by language filter', {'treated': '<em>'+polyglot.t('not analyzed')+'</em>'})+'</div>');
}
}
}
return elem;
}

180
js/twister_timeline.js

@ -12,7 +12,8 @@ var _idTrackerMap = {}; @@ -12,7 +12,8 @@ var _idTrackerMap = {};
var _idTrackerSpam = new idTrackerObj();
var _lastHaveMap = {};
var _refreshInProgress = false;
var _newPostsPending = 0;
var _newPostsPending = [];
var _sendedPostIDs = [];
var timelineLoaded = false;
/* object to keep tracking of post ids for a given user, that is, which
@ -79,7 +80,6 @@ function requestObj(users, mode, count, getspam) @@ -79,7 +80,6 @@ function requestObj(users, mode, count, getspam)
this.mode = mode; // 'latest', 'latestFirstTime' or 'older'
this.count = count;
this.getspam = getspam;
this.updateReportNewPosts = (users.toString() === defaultScreenName || mode === 'older') ? false : true;
// getRequest method returns the list parameter expected by getposts rpc
this.getRequest = function() {
@ -112,23 +112,24 @@ function requestObj(users, mode, count, getspam) @@ -112,23 +112,24 @@ function requestObj(users, mode, count, getspam)
// doneReportProcessing is called after an getposts response is processed
// mode changing may require a new request (to fill gaps)
this.doneReportProcessing = function(receivedCount) {
if (receivedCount === this.count) {
if (receivedCount >= this.count) {
this.mode = 'done';
} else {
if (this.mode === 'latest' || this.mode === 'latestFirstTime') {
this.mode = 'fillgap';
} else if (this.mode === 'fillgap') {
this.mode = 'older';
} else if (this.mode === 'older')
this.mode = 'done';
}
//console.log('we got '+receivedCount+' posts from requested '+this.count+', status of processing is "'+this.mode+'"');
}
//console.log('we got '+receivedCount+' posts from requested '+this.count+', status of processing: '+this.mode);
}
}
// json rpc with requestObj as parameter
function requestGetposts(req)
{
//console.log('requestGetposts');
//console.log(req);
var r = req.getRequest();
if( !req.getspam ) {
if( r.length ) {
@ -148,15 +149,49 @@ function requestGetposts(req) @@ -148,15 +149,49 @@ function requestGetposts(req)
// request if needed
function processReceivedPosts(req, posts)
{
//console.log('processReceivedPosts:');
//console.log(posts);
//hiding posts can cause empty postboard, so we have to track the count...
var p2a = posts.length;
for( var i = 0; i < posts.length; i++ ) {
var post = posts[i];
if (willBeHidden(post)) {
p2a--;
continue;
if (willBeHidden(posts[i])) {
req.reportProcessedPost(posts[i]["userpost"]["n"],posts[i]["userpost"]["k"], true)
posts.splice(i, 1);
i--;
}
}
showPosts(req, posts);
req.doneReportProcessing(posts.length);
//if the count of recieved posts less or equals to requested then...
if (req.mode === 'done') {
timelineLoaded = true;
$.MAL.postboardLoaded();
_refreshInProgress = false;
} else {
//we will request more older post...
req.count -= posts.length;
if (req.count > 0) {
//console.log('we are requesting '+req.count+' more posts...');
setTimeout((function (){requestGetposts(this)}).bind(req), 1000);
} else {
timelineLoaded = true;
$.MAL.postboardLoaded();
_refreshInProgress = false;
}
}
}
function showPosts(req, posts)
{
//console.log('showPosts:');
//console.log(req);
//console.log(posts);
var streamItemsParent = $.MAL.getStreamPostsParent();
for( var i = 0; i < posts.length; i++ ) {
if ( req.users.indexOf(posts[i]['userpost']['n']) > -1 ) {
var post = posts[i];
//console.log(post);
var streamPost = postToElem(post, "original", req.getspam);
var timePost = post["userpost"]["time"];
streamPost.attr("data-time",timePost);
@ -166,7 +201,6 @@ function processReceivedPosts(req, posts) @@ -166,7 +201,6 @@ function processReceivedPosts(req, posts)
// insert the post in timeline ordered by (you guessed) time
// FIXME: lame! searching everything everytime. please optimize!
var streamItemsParent = $.MAL.getStreamPostsParent();
var streamItems = streamItemsParent.children();
if( streamItems.length == 0) {
// timeline is empty
@ -185,49 +219,14 @@ function processReceivedPosts(req, posts) @@ -185,49 +219,14 @@ function processReceivedPosts(req, posts)
break;
}
}
if( j == streamItems.length ) {
// no older posts in stream, so post is to be inserted below
if( req.mode == "older" || req.mode == "latestFirstTime" ) {
// note: when filling gaps, the post must be discarded (not
// shown) since it can never be older than what we already
// have on timeline. this is a problem due to requesting from
// several users at the same time, as some older posts might
// be included to complete the <count> in getposts because
// other users may have already been excluded by since_id.
streamItemsParent.append( streamPost );
streamPostAppended = true;
}
}
}
if (!streamPostAppended)
streamItemsParent.append( streamPost );
if( streamPostAppended ) {
streamPostAppended = true;
streamPost.show();
}
req.reportProcessedPost(post["userpost"]["n"],post["userpost"]["k"], streamPostAppended);
}
req.doneReportProcessing(p2a);
if (req.updateReportNewPosts) {
_newPostsPending = 0; // FIXME maybe we need updating here instead this zeroing
$.MAL.reportNewPosts(_newPostsPending);
}
//if the count of recieved posts less then or equals to requested...
if (req.mode === 'done') {
timelineLoaded = true;
$.MAL.postboardLoaded();
_refreshInProgress = false;
} else {
//we will request more older post...
req.count -= p2a;
if (req.count > 0) {
//console.log('we are requesting '+req.count+' more posts...');
requestGetposts(req);
} else {
timelineLoaded = true;
$.MAL.postboardLoaded();
_refreshInProgress = false;
}
}
}
@ -241,7 +240,16 @@ function requestTimelineUpdate(mode, count, timelineUsers, getspam) @@ -241,7 +240,16 @@ function requestTimelineUpdate(mode, count, timelineUsers, getspam)
_refreshInProgress = true;
if( timelineUsers.length ) {
var req = new requestObj(timelineUsers, mode, count, getspam);
if (mode === 'pending') {
req.mode = 'latest';
showPosts(req, _newPostsPending);
_newPostsPending = [];
$.MAL.reportNewPosts(_newPostsPending.length);
$.MAL.postboardLoaded();
_refreshInProgress = false;
} else {
requestGetposts(req);
}
} else {
console.log("requestTimelineUpdate: not following any users");
}
@ -284,6 +292,8 @@ function processLastHave(userHaves) @@ -284,6 +292,8 @@ function processLastHave(userHaves)
// now do a getposts to confirm the number of new haves with are effectively new public posts
if( newPostsLocal ) {
//console.log('processLastHave(): requesting '+newPostsLocal);
//console.log(reqConfirmNewPosts);
twisterRpc("getposts", [newPostsLocal, reqConfirmNewPosts],
function(expected, posts) {processNewPostsConfirmation(expected, posts);}, newPostsLocal,
function(req, ret) {console.log("ajax error:" + ret);}, null);
@ -293,24 +303,35 @@ function processLastHave(userHaves) @@ -293,24 +303,35 @@ function processLastHave(userHaves)
// callback for getposts to update the number of new pending posts not shown in timeline
function processNewPostsConfirmation(expected, posts)
{
//we don't want to produce alert for the posts that won't be displayed
var pnp = 0;
//console.log('we got '+posts.length+' posts from expected '+expected+' for confirmation');
//console.log(posts);
// we want to report about new posts that would be displayed
var rnp = 0;
// we want to display sended posts immediately
var sendedPostsPending = [];
for( var i = posts.length-1; i >= 0; i-- ) {
if (willBeHidden(posts[i]) || posts[i]['userpost']['n'] === defaultScreenName) {
pnp++;
if ( !willBeHidden(posts[i]) ) {
if ( _sendedPostIDs.indexOf(posts[i]['userpost']['k']) > -1 ) {
sendedPostsPending.push(posts[i]);
} else {
_newPostsPending.push(posts[i]);
rnp++;
}
}
_newPostsPending += posts.length - pnp;
if( _newPostsPending ) {
$.MAL.reportNewPosts(_newPostsPending);
}
if ( rnp > 0 ) {
$.MAL.reportNewPosts(_newPostsPending.length);
}
if ( sendedPostsPending.length > 0 ) {
var req = new requestObj([defaultScreenName],'latest',sendedPostsPending.length,promotedPostsOnly);
showPosts(req, sendedPostsPending);
}
if( posts.length < expected ) {
// new DMs have probably been produced by users we follow.
// check with getdirectmsgs
requestDMsCount();
}
// TODO: possibly cache this response
}
function timelineChangedUser()
@ -319,17 +340,31 @@ function timelineChangedUser() @@ -319,17 +340,31 @@ function timelineChangedUser()
_idTrackerSpam = new idTrackerObj();
_lastHaveMap = {};
_refreshInProgress = false;
_newPostsPending = 0;
_newPostsPending = [];
_sendedPostIDs = [];
timelineLoaded = false;
}
function willBeHidden(post){
var msg = post['userpost']['msg'];
var hidden = false;
if (post['userpost']['n'] === defaultScreenName)
return false;
if (typeof(post['userpost']['rt']) !== 'undefined') {
// hope it is not too egocentric to overcome HideCloseRTsOpt this way
if (post['userpost']['rt']['n'] === defaultScreenName)
return false;
if ($.Options.getHideCloseRTsOpt() != 'disable' &&
followingUsers.indexOf(post['userpost']['rt']['n']) > -1 &&
parseInt(post['userpost']['time']) - parseInt(post['userpost']['rt']['time']) < $.Options.getHideCloseRTsHourOpt() * 3600)
{
return true;
}
var msg = post['userpost']['rt']['msg'];
} else {
var msg = post['userpost']['msg'];
if ($.Options.getHideRepliesOpt() !== 'disable' &&
/^\@/.test(msg) &&
!(new RegExp('@' + defaultScreenName + '( |,|;|\\.|:|\\/|\\?|\\!|\\\\|\'|"|\\n|\\t|$)').test(msg)))
@ -338,20 +373,19 @@ function willBeHidden(post){ @@ -338,20 +373,19 @@ function willBeHidden(post){
($.Options.getHideRepliesOpt() === 'following' &&
followingUsers.indexOf(msg.substring(1, msg.search(/ |,|;|\.|:|\/|\?|\!|\\|'|"|\n|\t|$/))) === -1 ))
{
hidden = true;
return true;
}
}
}
if (typeof(post['userpost']['rt']) !== 'undefined' &&
$.Options.getHideCloseRTsOpt() != 'disable' &&
followingUsers.indexOf(post['userpost']['rt']['n']) > -1 &&
parseInt(post['userpost']['time']) - parseInt(post['userpost']['rt']['time']) < $.Options.getHideCloseRTsHourOpt() * 3600)
{
if (hidden)
return false;
else
if ($.Options.getFilterLangOpt() !== 'disable' && $.Options.getFilterLangForPostboardOpt()) {
post['langFilter'] = filterLang(msg);
if (!post['langFilter']['pass'] && !$.Options.getFilterLangSimulateOpt()) {
// TODO maybe we need a counter of posts blocked by language filter and even caching of them and button to show?
//console.log('post by @'+post['userpost']['n']+' was hidden because it didn\'t passed by language filter:');
return true;
}
}
return hidden;
return false;
}

1
login.html

@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
<script src="js/jquery.jsonrpcclient.js"></script>
<script src="js/jquery.storageapi.js"></script>
<script src="js/options.js"></script>
<script src="js/franc.js"></script>
<script src="js/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>

1
network.html

@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
<script src="js/jquery.jsonrpcclient.js"></script>
<script src="js/jquery.storageapi.js"></script>
<script src="js/options.js"></script>
<script src="js/franc.js"></script>
<script src="js/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>

47
options.html

@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
<script src="js/jquery.jsonrpcclient.js"></script>
<script src="js/jquery.storageapi.js"></script>
<script src="js/options.js"></script>
<script src="js/franc.js"></script>
<script src="js/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>
@ -60,7 +61,7 @@ @@ -60,7 +61,7 @@
<input id="t-4" name="option_tab" type="radio" class="selectable_theme theme_nin"/>
<label for="t-4" class="tabs selectable_theme theme_nin">Keys</label>
<input id="t-5" name="option_tab" type="radio" class="selectable_theme theme_nin"/>
<label for="t-5" class="tabs selectable_theme theme_nin">Postboard</label>
<label for="t-5" class="tabs selectable_theme theme_nin">Appearance</label>
<input id="t-6" name="option_tab" type="radio" class="selectable_theme theme_nin" />
<label for="t-6" class="tabs selectable_theme theme_nin">Users</label>
@ -214,7 +215,7 @@ @@ -214,7 +215,7 @@
</div>
</div>
<div class="postboard-display">
<div class="appearance">
<div class="module">
<p class="label label-h"> Postboard displays </p>
<div class="container">
@ -240,6 +241,33 @@ @@ -240,6 +241,33 @@
</form>
</div>
</div>
<div class="module">
<p class="label label-h">Language filtering</p>
<div class="container">
<form action="" id="filterLangOpt">
<p>
<select name="" id="filterLang">
<option value="disable">Disable</option>
<option value="blacklist">By blacklist</option>
<option value="whitelist">By whitelist</option>
</select>
</p>
<div id="filterLangListCont" class="container">
<p class="label">Comma separated ISO 639-3 language codes</p>
<p><input type="text" id="filterLangList" class="container" /></p>
<p class="label">Accuracy</p>
<p><input type="range" id="filterLangAccuracy" class="container" min="0" max="1" step="0.005"><span id="filterLangAccuracyVal" class="container"></span></p>
<p><span class="label">Scope of usage</span></p>
<div class="container">
<p><span class="label">in postboard</span> <input type="checkbox" id="filterLangForPostboard" /></p>
<p><span class="label">in search result</span> <input type="checkbox" id="filterLangForSearching" /></p>
<p><span class="label">in top trends</span> <input type="checkbox" id="filterLangForTopTrends" /></p>
</div>
<p><span class="label">Simulation mode</span> <input type="checkbox" id="filterLangSimulate" /></p>
</div>
</form>
</div>
</div>
<div class="module">
<p class="label label-h"> Posts display </p>
<div class="container">
@ -272,6 +300,21 @@ @@ -272,6 +300,21 @@
</form>
</div>
</div>
<div class="module">
<p class="label label-h"> Top Trends </p>
<div id="TopTrendsAutoUpdateCont" class="container">
<form>
<p class="label">Auto updating</p>
<select id="TopTrendsAutoUpdate" class="container">
<option value="enable">Enable</option>
<option value="disable">Disable</option>
</select>
<div id="TopTrendsAutoUpdateOpt" class="container">
<input type="text" id="TopTrendsAutoUpdateTimer" maxlength="6" size="6"/> <span class="label">second(s)</span>
</div>
</form>
</div>
</div>
<div class="post-editor">
<div class="module">

1
profile-edit.html

@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
<script src="js/jquery.jsonrpcclient.js"></script>
<script src="js/jquery.storageapi.js"></script>
<script src="js/options.js"></script>
<script src="js/franc.js"></script>
<script src="js/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>

30
theme_calm/css/style.css

@ -2327,7 +2327,7 @@ textarea.splited-post { @@ -2327,7 +2327,7 @@ textarea.splited-post {
.options .module select {
padding: 0px 30px 0px 10px;
text-align: center;
text-align: left;
background: #fff url(../img/form-arrow-down-black.png) no-repeat right center;
border: 1px solid #ccc;
-webkit-border-radius: 4px;
@ -2343,8 +2343,7 @@ textarea.splited-post { @@ -2343,8 +2343,7 @@ textarea.splited-post {
/* end */
}
.volValue {
vertical-align: top;
.volValue, #filterLangAccuracyVal {
font: 12px "Open Sans", sans-serif;
}
@ -2360,6 +2359,31 @@ textarea.splited-post { @@ -2360,6 +2359,31 @@ textarea.splited-post {
-ms-transition: height 1s linear;
}
.options input[type='checkbox'] {
cursor: pointer;
vertical-align: sub;
}
.options input[type='range'] {
cursor: pointer;
vertical-align: -16px;
}
.options #filterLangList {
width: 80%;
text-align: left;
}
.langFilterSimData {
color: rgba( 0, 0, 0, .7 );
font: 10px "Open Sans", sans-serif;
text-align: center;
}
.langFilterSimData em {
color: #768fce;
}
/*************************************
*********** FOLLOWING PAGE ***********
**************************************/

45
theme_nin/css/style.css

@ -1738,8 +1738,13 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab @@ -1738,8 +1738,13 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab
/* line 14, ../sass/_tabs.sass */
.options .container
{
margin: 5px 0px 5px 10px;
margin: 5px 0px 5px 12px;
}
.options button, .options input, .options select {
font-size: 13px;
}
/* line 9, ../sass/_tabs.sass */
.options input[type=radio] {
display: none !important;
@ -1747,17 +1752,17 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab @@ -1747,17 +1752,17 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab
opacity: 0;
}
/* line 17, ../sass/_tabs.sass */
.options .postboard-display div {
.options .appearance div {
clear: both;
}
/* line 19, ../sass/_tabs.sass */
.options .postboard-display div div {
.options .appearance div div {
float: left;
clear: none;
padding: 10px;
}
/* line 23, ../sass/_tabs.sass */
.options .postboard-display div div .label {
.options .appearance div div .label {
font-weight: 400;
}
/* line 27, ../sass/_tabs.sass */
@ -1778,7 +1783,7 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab @@ -1778,7 +1783,7 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab
visibility: hidden;
}
/* line 42, ../sass/_tabs.sass */
.options input#tab_language:checked ~ .tab-content .language, .options input#t-2:checked ~ .tab-content .theme, .options input#t-3:checked ~ .tab-content .notifications, .options input#t-4:checked ~ .tab-content .keys, .options input#t-5:checked ~ .tab-content .postboard-display, .options input#t-6:checked ~ .tab-content .users {
.options input#tab_language:checked ~ .tab-content .language, .options input#t-2:checked ~ .tab-content .theme, .options input#t-3:checked ~ .tab-content .notifications, .options input#t-4:checked ~ .tab-content .keys, .options input#t-5:checked ~ .tab-content .appearance, .options input#t-6:checked ~ .tab-content .users {
position: relative;
z-index: 10;
opacity: 1;
@ -1804,6 +1809,36 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab @@ -1804,6 +1809,36 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab
color: #66686B;
}
.options input[type='checkbox'] {
cursor: pointer;
vertical-align: sub;
}
.options input[type='range'] {
cursor: pointer;
vertical-align: -16px;
}
.options #filterLangList {
width: 90%;
}
.options #filterLangListCont div,.options #TopTrendsAutoUpdateCont div {
float: none;
padding: 0px 4px;
}
.langFilterSimData {
color: rgba( 0, 0, 0, .7 );
font: 10px "Open Sans", sans-serif;
text-align: center;
}
.langFilterSimData em {
color: #B4C669;
}
/* line 19, ../sass/style.sass */
.promoted-posts-only {
margin: 0 0;

28
theme_nin/sass/_tabs.sass

@ -1,28 +1,30 @@ @@ -1,28 +1,30 @@
.options
position: relative
.label-h
font-weight: 700
button, input, select
font-size: 13px
label
cursor: pointer
.label-h
font-weight: 700
input[type=radio]
display: none!important
visibility: hidden
opacity: 0
.container
margin: 5px 0px 5px 10px
input[type='checkbox']
cursor: pointer
vertical-align: sub
.postboard-display div
clear: both
div
float: left
clear: none
padding: 10px
.label
font-weight: 400
input[type='range']
cursor: pointer
vertical-align: -16px
.container
margin: 5px 0px 5px 12px
.tab-content
background: $bloc-background-color
@ -43,7 +45,7 @@ @@ -43,7 +45,7 @@
&#t-2:checked ~ .tab-content .theme,
&#t-3:checked ~ .tab-content .notifications,
&#t-4:checked ~ .tab-content .keys,
&#t-5:checked ~ .tab-content .postboard-display,
&#t-5:checked ~ .tab-content .appearance,
&#t-6:checked ~ .tab-content .users
position: relative
z-index: 10

25
theme_nin/sass/style.sass

@ -1081,9 +1081,22 @@ ol.toptrends-list @@ -1081,9 +1081,22 @@ ol.toptrends-list
/* Options*/
.options
.appearance div
clear: both
div
float: left
clear: none
padding: 10px
.label
font-weight: 400
#filterLangList
width: 90%
#filterLangListCont div, #TopTrendsAutoUpdateCont div
float: none
padding: 0px 4px
.suboptions
margin: 5px 30px
@ -1139,5 +1152,15 @@ ul.dropdown-menu @@ -1139,5 +1152,15 @@ ul.dropdown-menu
-o-transition: all 200ms
transition: all 200ms
/* Language filter messages */
.langFilterSimData
color: rgba( 0, 0, 0, .7 )
font: 10px "Open Sans", sans-serif
text-align: center
.langFilterSimData em
color: #B4C669
@import _responsive

1
tmobile.html

@ -28,6 +28,7 @@ @@ -28,6 +28,7 @@
<script src="js/jquery.jsonrpcclient.js"></script>
<script src="js/jquery.storageapi.js"></script>
<script src="js/options.js?vr=10"></script>
<script src="js/franc.js"></script>
<script src="js/notify.js"></script>
<script src="js/mobile_abstract.js?vr=10"></script>
<script src="js/twister_io.js?vr=10"></script>

Loading…
Cancel
Save