Browse Source

initial commit of desktop notifications via notify.js by alexgibson

master
Simon Grim 9 years ago
parent
commit
09f4a64980
  1. 1
      following.html
  2. 2
      home.html
  3. 17
      js/interface_common.js
  4. 81
      js/interface_localization.js
  5. 11
      js/mobile_abstract.js
  6. 196
      js/notify.js
  7. 19
      js/options.js
  8. 2
      js/twister_actions.js
  9. 49
      js/twister_newmsgs.js
  10. 1
      login.html
  11. 1
      network.html
  12. 13
      options.html
  13. 1
      profile-edit.html
  14. 2
      theme_nin/css/style.css
  15. 2
      theme_nin/sass/_tabs.sass

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/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>
<script src="js/polyglot.min.js"></script>

2
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/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>
<script src="js/polyglot.min.js"></script>
@ -26,6 +27,7 @@ @@ -26,6 +27,7 @@
<script src="js/interface_common.js"></script>
<script src="js/interface_home.js"></script>
<script src="js/jquery.textcomplete.js"></script>
<script>
$(function(){setTimeout(mensAutocomplete, 800);})
changeStyle();

17
js/interface_common.js

@ -200,6 +200,23 @@ function updateHashtagModal(postboard,hashtag,timeoutArgs) { @@ -200,6 +200,23 @@ function updateHashtagModal(postboard,hashtag,timeoutArgs) {
var resource = $hashtagModalClass.attr("data-resource");
requestHashtag(postboard,hashtag,resource,timeoutArgs);
if( _hashtagPendingPostsUpdated ) {
var desktopNotification = new Notify(polyglot.t('notify_desktop_title'), {
body: 'You got '+polyglot.t("new_posts", _hashtagPendingPostsUpdated)+' in search result.',
icon: '../img/twister_mini.png',
tag: 'twister_notification_new_posts_modal',
timeout: _desktopNotificationTimeout,
notifyClick: function() {
$(".postboard-news").hide();
displayHashtagPending($(".hashtag-modal .postboard-posts"));
}
});
desktopNotification.show();
_hashtagPendingPostsUpdated = 0;
}
// use extended timeout parameters on modal refresh (requires twister_core >= 0.9.14).
// our first query above should be faster (with default timeoutArgs of twisterd),
// then we may possibly collect more posts on our second try by waiting more.

81
js/interface_localization.js

@ -49,6 +49,7 @@ if(preferredLanguage == "en"){ @@ -49,6 +49,7 @@ if(preferredLanguage == "en"){
"Connections:": "Connections: ", // to network
"Connection lost.": "Connection lost.",
"days": "%{smart_count} day |||| %{smart_count} days",
"Desktop notifications": "Desktop notifications",
"Detailed information": "Detailed information",
"DHT network down.": "DHT network down.",
"Direct Messages": "Direct Messages",
@ -92,8 +93,14 @@ if(preferredLanguage == "en"){ @@ -92,8 +93,14 @@ if(preferredLanguage == "en"){
"New direct message...": "New direct message...",
"New Post...": "New Post...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now 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: ",
"Number of CPUs to use": "Number of CPUs to use ",
"Only alphanumeric and underscore allowed.": "Only alphanumeric and underscore allowed.",
@ -184,6 +191,7 @@ if(preferredLanguage == "en"){ @@ -184,6 +191,7 @@ if(preferredLanguage == "en"){
"Ignore": "Ignore",
"Theme": "Theme",
"Keys": "Keys",
"Notifications": "Notifications",
"Sound notifications": "Sound notifications",
"Send key": "Send key",
"Posts display": "Posts display",
@ -322,8 +330,14 @@ if(preferredLanguage == "es"){ @@ -322,8 +330,14 @@ if(preferredLanguage == "es"){
"New direct message...": "Nuevo mensaje directo...",
"New Post...": "Nuevo Post...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now 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: ",
"Number of CPUs to use": "Número de CPUs para utilizar ",
"Only alphanumeric and underscore allowed.": "Sólo alfanuméricos y subrayados permitido.",
@ -550,8 +564,14 @@ if(preferredLanguage == "uk"){ @@ -550,8 +564,14 @@ if(preferredLanguage == "uk"){
"New direct message...": "Нове особисте повідомлення...",
"New Post...": "Нове повідомлення...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Кількість блоків у ланцюгу: ",
"Number of CPUs to use": "Кількість CPUs до використання ",
"Only alphanumeric and underscore allowed.": "Тільки літеро-численні сиволи та нижнє підкреслення дозволені.",
@ -776,8 +796,14 @@ if(preferredLanguage == "zh"){ @@ -776,8 +796,14 @@ if(preferredLanguage == "zh"){
"New direct message...": "新的即时信息...",
"New Post...": "新推文...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "块链中的块数:",
"Number of CPUs to use": "使用CPU数目 ",
"Only alphanumeric and underscore allowed.": "只允许字母和下划线",
@ -1002,8 +1028,14 @@ if(preferredLanguage == "nl"){ @@ -1002,8 +1028,14 @@ if(preferredLanguage == "nl"){
"New direct message...": "Nieuw privébericht...",
"New Post...": "Nieuw bericht...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now 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: ",
"Number of CPUs to use": "Aantal CPUs om te gebruiken ",
"Only alphanumeric and underscore allowed.": "Alleen alphanumeriek en underscore toegestaan.",
@ -1229,8 +1261,14 @@ if(preferredLanguage == "it"){ @@ -1229,8 +1261,14 @@ if(preferredLanguage == "it"){
"New direct message...": "Nuovo messaggio diretto...",
"New Post...": "Nuovo messaggio...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now 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: ",
"Number of CPUs to use": "Numero di processori da usare:",
"Only alphanumeric and underscore allowed.": "Sono permessi solo caratteri alfanumerici e '_'",
@ -1454,8 +1492,14 @@ if(preferredLanguage == "fr"){ @@ -1454,8 +1492,14 @@ if(preferredLanguage == "fr"){
"New direct message...": "Nouveau message privé...",
"New Post...": "Nouveau billets...",
"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",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"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.",
@ -1642,6 +1686,7 @@ if(preferredLanguage == "ru"){ @@ -1642,6 +1686,7 @@ if(preferredLanguage == "ru"){
"Connections:": "Соединений: ",
"Connection lost.": "Соединение с сетью было потеряно.",
"days": "%{smart_count} день |||| %{smart_count} дней",
"Desktop notifications": "Уведомления рабочего стола",
"Detailed information": "Подробная информация",
"DHT network down.": "Недоступна DHT сеть.",
"Direct Messages": "Личные сообщения",
@ -1685,8 +1730,14 @@ if(preferredLanguage == "ru"){ @@ -1685,8 +1730,14 @@ if(preferredLanguage == "ru"){
"New direct message...": "Новое личное сообщение...",
"New Post...": "Новый пост...",
"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": "Твистер не может выполниь уведомление: разрешение не получено. Убедитесь, что в браузере разрешены уведомления для этого домена.",
"notify_desktop_test": "All the twisters gonna twist. Now you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Количество блоков в цепочке: ",
"Number of CPUs to use": "Сколько использовать ядер процессора",
"Only alphanumeric and underscore allowed.": "Разрешены только латинские буквы, цифры и подчеркивания.",
@ -1917,8 +1968,14 @@ if(preferredLanguage == "de"){ @@ -1917,8 +1968,14 @@ if(preferredLanguage == "de"){
"New direct message...": "Neue Direktnachricht...",
"New Post...": "Neuer Post...",
"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",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"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.",
@ -2145,8 +2202,14 @@ if(preferredLanguage == "ja"){ @@ -2145,8 +2202,14 @@ if(preferredLanguage == "ja"){
"New direct message...": "ダイレクトメッセージ...",
"New Post...": "投稿する",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "全ブロック数: ",
"Number of CPUs to use": "利用するCPUの数",
"Only alphanumeric and underscore allowed.": "アルファベットとアンダースコア(_)が利用可能です",
@ -2370,8 +2433,14 @@ if(preferredLanguage == "pt-BR"){ @@ -2370,8 +2433,14 @@ if(preferredLanguage == "pt-BR"){
"New direct message...": "Nova mensagem direta...",
"New Post...": "Nova Postagem...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now you are welcome too.",
"notify_desktop_title": "Watch out, it's twister over here!",
"Number of blocks in block chain:": "Número de blocos: ",
"Number of CPUs to use": "Número de CPUs a serem utilizados ",
"Only alphanumeric and underscore allowed.": "Permitido apenas caracteres alfanuméricos e underscore '_'.",
@ -2599,8 +2668,14 @@ if(preferredLanguage == "tr"){ @@ -2599,8 +2668,14 @@ if(preferredLanguage == "tr"){
"New direct message...": "Yeni direk mesaj...",
"New Post...": "Yeni gönderi...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now 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ı: ",
"Number of CPUs to use": "Kullanılacak CPU sayısı ",
"Only alphanumeric and underscore allowed.": "Sadece harf ve alt çizgi kullanılabilir.",
@ -2825,8 +2900,14 @@ if(preferredLanguage == "cs"){ @@ -2825,8 +2900,14 @@ if(preferredLanguage == "cs"){
"New direct message...": "Nová přímá zpráva...",
"New Post...": "Nový příspěvek...",
"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. Try to change browser permissions for this domain.",
"notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied. Check out browser's policy for this domain.",
"notify_desktop_test": "All the twisters gonna twist. Now 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: ",
"Number of CPUs to use": "Kolik jader procesoru použít? ",
"Only alphanumeric and underscore allowed.": "Povolena jsou jen písmena, čísla a podtržítko.",

11
js/mobile_abstract.js

@ -102,6 +102,17 @@ var MAL = function() @@ -102,6 +102,17 @@ var MAL = function()
newTweetsBar.fadeIn("slow");
newTweetsBarMenu.text(String(newPosts));
newTweetsBarMenu.addClass("show");
var desktopNotification = new Notify(polyglot.t('notify_desktop_title'), {
body: 'You got '+polyglot.t("new_posts", newPosts)+' in postboard.',
icon: '../img/twister_mini.png',
tag: 'twister_notification_new_postboard',
timeout: _desktopNotificationTimeout,
notifyClick: function() {
requestTimelineUpdate("latest",postsPerRefresh,followingUsers,promotedPostsOnly);
}
});
desktopNotification.show();
} else {
newTweetsBar.hide();
newTweetsBar.text("");

196
js/notify.js

@ -0,0 +1,196 @@ @@ -0,0 +1,196 @@
/*
* Author: Alex Gibson
* https://github.com/alexgibson/notify.js
* License: MIT license
*/
(function(global, factory) {
if (typeof define === 'function' && define.amd) {
// AMD environment
define(function() {
return factory(global, global.document);
});
} else if (typeof module !== 'undefined' && module.exports) {
// CommonJS environment
module.exports = factory(global, global.document);
} else {
// Browser environment
global.Notify = factory(global, global.document);
}
} (typeof window !== 'undefined' ? window : this, function (w, d) {
'use strict';
function isFunction (item) {
return typeof item === 'function';
}
function Notify(title, options) {
if (typeof title !== 'string') {
throw new Error('Notify(): first arg (title) must be a string.');
}
this.title = title;
this.options = {
icon: '',
body: '',
tag: '',
notifyShow: null,
notifyClose: null,
notifyClick: null,
notifyError: null,
permissionGranted: null,
permissionDenied: null,
timeout: null
};
this.permission = null;
if (!Notify.isSupported) {
return;
}
//User defined options for notification content
if (typeof options === 'object') {
for (var i in options) {
if (options.hasOwnProperty(i)) {
this.options[i] = options[i];
}
}
//callback when notification is displayed
if (isFunction(this.options.notifyShow)) {
this.onShowCallback = this.options.notifyShow;
}
//callback when notification is closed
if (isFunction(this.options.notifyClose)) {
this.onCloseCallback = this.options.notifyClose;
}
//callback when notification is clicked
if (isFunction(this.options.notifyClick)) {
this.onClickCallback = this.options.notifyClick;
}
//callback when notification throws error
if (isFunction(this.options.notifyError)) {
this.onErrorCallback = this.options.notifyError;
}
}
}
// true if the browser supports HTML5 Notification
Notify.isSupported = 'Notification' in w;
// true if the permission is not granted
Notify.needsPermission = !(Notify.isSupported && Notification.permission === 'granted');
// returns current permission level ('granted', 'default', 'denied' or null)
Notify.permissionLevel = (Notify.isSupported ? Notification.permission : null);
// asks the user for permission to display notifications. Then calls the callback functions is supplied.
Notify.requestPermission = function (onPermissionGrantedCallback, onPermissionDeniedCallback) {
if (!Notify.isSupported) {
return;
}
w.Notification.requestPermission(function (perm) {
switch (perm) {
case 'granted':
Notify.needsPermission = false;
if (isFunction(onPermissionGrantedCallback)) {
onPermissionGrantedCallback();
}
break;
case 'denied':
if (isFunction(onPermissionDeniedCallback)) {
onPermissionDeniedCallback();
}
break;
}
});
};
Notify.prototype.show = function () {
if (!Notify.isSupported) {
return;
}
this.myNotify = new Notification(this.title, {
'body': this.options.body,
'tag' : this.options.tag,
'icon' : this.options.icon
});
if (this.options.timeout && !isNaN(this.options.timeout)) {
setTimeout(this.close.bind(this), this.options.timeout * 1000);
}
this.myNotify.addEventListener('show', this, false);
this.myNotify.addEventListener('error', this, false);
this.myNotify.addEventListener('close', this, false);
this.myNotify.addEventListener('click', this, false);
};
Notify.prototype.onShowNotification = function (e) {
if (this.onShowCallback) {
this.onShowCallback(e);
}
};
Notify.prototype.onCloseNotification = function (e) {
if (this.onCloseCallback) {
this.onCloseCallback(e);
}
this.destroy();
};
Notify.prototype.onClickNotification = function (e) {
if (this.onClickCallback) {
this.onClickCallback(e);
}
};
Notify.prototype.onErrorNotification = function (e) {
if (this.onErrorCallback) {
this.onErrorCallback(e);
}
this.destroy();
};
Notify.prototype.destroy = function () {
this.myNotify.removeEventListener('show', this, false);
this.myNotify.removeEventListener('error', this, false);
this.myNotify.removeEventListener('close', this, false);
this.myNotify.removeEventListener('click', this, false);
};
Notify.prototype.close = function () {
this.myNotify.close();
};
Notify.prototype.handleEvent = function (e) {
switch (e.type) {
case 'show':
this.onShowNotification(e);
break;
case 'close':
this.onCloseNotification(e);
break;
case 'click':
this.onClickNotification(e);
break;
case 'error':
this.onErrorNotification(e);
break;
}
};
return Notify;
}));

19
js/options.js

@ -2,6 +2,8 @@ $(function() { @@ -2,6 +2,8 @@ $(function() {
});
var _desktopNotificationTimeout = 4; // it should be an option
var TwisterOptions = function()
{
this.getOption = function(optionName, defaultValue) {
@ -88,6 +90,20 @@ var TwisterOptions = function() @@ -88,6 +90,20 @@ var TwisterOptions = function()
player[0].play();
}
this.notificationDesktopTest = function() {
$('#notifications-desktop-test').on('click', function(){
var desktopNotification = new Notify(polyglot.t('notify_desktop_title'), {
body: polyglot.t('notify_desktop_test'),
icon: '../img/twister_mini.png',
tag: 'twister_notification_test',
timeout: _desktopNotificationTimeout,
notifyError: function() { alert(polyglot.t('notify_desktop_error')); },
permissionDenied: function() { alert(polyglot.t('notify_desktop_perm_denied')); }
});
desktopNotification.show();
})
}
this.keysSendDefault = "ctrlenter";
this.keysSend = function() {
$('#keysOpt select')[0].value = $.Options.getOption('keysSend',this.keysSendDefault);
@ -338,6 +354,7 @@ var TwisterOptions = function() @@ -338,6 +354,7 @@ var TwisterOptions = function()
this.InitOptions = function() {
this.soundNotifOptions();
this.volumeControl();
this.notificationDesktopTest();
this.keysSend();
this.setLang();
this.setTheme();
@ -365,7 +382,7 @@ function localizeLabels() @@ -365,7 +382,7 @@ function localizeLabels()
{
$("label[for=tab_language]").text(polyglot.t("Language"));
$("label[for=t-2]").text(polyglot.t("Theme"));
$("label[for=t-3]").text(polyglot.t("Sound"));
$("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-6]").text(polyglot.t("Users"));

2
js/twister_actions.js

@ -14,6 +14,7 @@ var maxExpandPost = 8; @@ -14,6 +14,7 @@ var maxExpandPost = 8;
var maxExpandPostTop = 4;
var _hashtagProcessedMap = {};
var _hashtagPendingPosts = [];
var _hashtagPendingPostsUpdated = 0;
var autoUpdateHashtag = false;
// ----------------
@ -335,6 +336,7 @@ function processHashtag(postboard, hashtag, data) { @@ -335,6 +336,7 @@ function processHashtag(postboard, hashtag, data) {
if( !(key in _hashtagProcessedMap) ) {
_hashtagProcessedMap[key] = true;
_hashtagPendingPosts.push(data[i]);
_hashtagPendingPostsUpdated++;
}
}

49
js/twister_newmsgs.js

@ -11,6 +11,8 @@ var _lastMentionTime = 0; @@ -11,6 +11,8 @@ var _lastMentionTime = 0;
var _newMentions = 0;
var _lastLocalMentionId = -1;
var PURGE_OLD_MENTIONS_TIMEOUT = 3600 * 24 * 30; // one month
var _newMentionsUpdated = false;
var _newDMsUpdated = false;
// process a mention received to check if it is really new
function processMention(user, mentionTime, data) {
@ -19,12 +21,11 @@ function processMention(user, mentionTime, data) { @@ -19,12 +21,11 @@ function processMention(user, mentionTime, data) {
if( mentionTime > curTime + 3600 * 2 ) {
console.log("mention from the future will be ignored");
} else {
var newMentionsUpdated = false;
if( !(key in _knownMentions) ) {
// mention must be somewhat recent compared to last known one to be considered new
if( mentionTime + 3600 * 24 * 3 > _lastMentionTime ) {
_newMentions++;
newMentionsUpdated = true;
_newMentionsUpdated = true;
_lastMentionTime = Math.max(mentionTime,_lastMentionTime);
data["isNew"] = true;
}
@ -32,9 +33,6 @@ function processMention(user, mentionTime, data) { @@ -32,9 +33,6 @@ function processMention(user, mentionTime, data) {
purgeOldMentions();
saveMentionsToStorage();
}
if( newMentionsUpdated ) {
$.MAL.soundNotifyMentions();
}
}
}
@ -96,6 +94,40 @@ function requestMentionsCount() { @@ -96,6 +94,40 @@ function requestMentionsCount() {
}
}, {},
[10000,2000,3]); // use extended timeout parameters (requires twister_core >= 0.9.14)
if( _newMentionsUpdated ) {
_newMentionsUpdated = false;
$.MAL.soundNotifyMentions();
var desktopNotification = new Notify(polyglot.t('notify_desktop_title'), {
body: 'You got '+polyglot.t('new_mentions', _newMentions)+'.',
icon: '../img/twister_mini.png',
tag: 'twister_notification_new_mentions',
timeout: _desktopNotificationTimeout,
notifyClick: openMentionsModal
});
desktopNotification.show();
}
// was moved here from requestDMsCount() because that is not ticking right
// we would place it with other notifications into separate notification center
if( _newDMsUpdated ) {
_newDMsUpdated = false;
$.MAL.soundNotifyDM();
var desktopNotification = new Notify(polyglot.t('notify_desktop_title'), {
body: 'You got '+polyglot.t('new_direct_messages', getNewDMsCount())+'.',
icon: '../img/twister_mini.png',
tag: 'twister_notification_new_DMs',
timeout: _desktopNotificationTimeout,
notifyClick: function() {
window.location.hash = '#directmessages';
}
});
desktopNotification.show();
}
}
function resetMentionsCount() {
@ -154,23 +186,22 @@ function requestDMsCount() { @@ -154,23 +186,22 @@ function requestDMsCount() {
twisterRpc("getdirectmsgs", [defaultScreenName, 1, followList],
function(req, dmUsers) {
var updated = false;
for( var u in dmUsers ) {
if( dmUsers.hasOwnProperty(u) ) {
var dmData = dmUsers[u][0];
if( (u in _lastDMIdPerUser) && (u in _newDMsPerUser) ) {
if( dmData.id != _lastDMIdPerUser[u] ) {
_newDMsPerUser[u] += (dmData.id - _lastDMIdPerUser[u]);
updated = true;
_newDMsUpdated = true;
}
} else {
_newDMsPerUser[u] = dmData.id+1;
updated = true;
_newDMsUpdated = true;
}
_lastDMIdPerUser[u] = dmData.id;
}
}
if( updated ) {
if( _newDMsUpdated ) {
saveDMsToStorage();
$.MAL.updateNewDMsUI(getNewDMsCount());
}

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/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>
<script src="js/twister_network.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/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>
<script src="js/twister_user.js"></script>

13
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/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>
<script src="js/twister_network.js"></script>
@ -18,6 +19,7 @@ @@ -18,6 +19,7 @@
<script src="js/interface_login.js"></script>
<script src="js/polyglot.min.js"></script>
<script src="js/interface_localization.js"></script>
<script>$(function(){
initInterfaceCommon();
$.Options.InitOptions();})
@ -54,7 +56,7 @@ @@ -54,7 +56,7 @@
<input id="t-2" name="option_tab" type="radio" class="selectable_theme theme_nin"/>
<label for="t-2" class="tabs selectable_theme theme_nin">Theme</label>
<input id="t-3" name="option_tab" type="radio" class="selectable_theme theme_nin"/>
<label for="t-3" class="tabs selectable_theme theme_nin">Sound</label>
<label for="t-3" class="tabs selectable_theme theme_nin">Notifications</label>
<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"/>
@ -108,8 +110,7 @@ @@ -108,8 +110,7 @@
</div>
</div>
<div class="sounds">
<div class="notifications">
<div class="module">
<p class="label"> Sound notifications </p>
<div>
@ -141,6 +142,12 @@ @@ -141,6 +142,12 @@
<audio id="player"></audio>
</div>
</div>
<div class="module">
<p class="label"> Desktop notifications </p>
<div>
<button id="notifications-desktop-test">Test</button>
</div>
</div>
</div>
<div class="keys">

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/notify.js"></script>
<script src="js/mobile_abstract.js"></script>
<script src="js/twister_io.js"></script>
<script src="js/polyglot.min.js"></script>

2
theme_nin/css/style.css

@ -1704,7 +1704,7 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab @@ -1704,7 +1704,7 @@ button.disabled:hover, .mini-profile-actions span.disabled:hover, a.button.disab
visibility: hidden;
}
/* line 39, ../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 .sounds, .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 .postboard-display, .options input#t-6:checked ~ .tab-content .users {
position: relative;
z-index: 10;
opacity: 1;

2
theme_nin/sass/_tabs.sass

@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
input
&#tab_language:checked ~ .tab-content .language,
&#t-2:checked ~ .tab-content .theme,
&#t-3:checked ~ .tab-content .sounds,
&#t-3:checked ~ .tab-content .notifications,
&#t-4:checked ~ .tab-content .keys,
&#t-5:checked ~ .tab-content .postboard-display,
&#t-6:checked ~ .tab-content .users

Loading…
Cancel
Save