Browse Source

added better notifications

Nathaniel van Diepen 10 năm trước cách đây
mục cha
commit
6ea50c2eb3
5 tập tin đã thay đổi với 225 bổ sung1 xóa
  1. 3 0
      bugs.webapp
  2. 13 0
      css/ui.notify.css
  3. 15 0
      index.php
  4. 38 1
      js/index.js
  5. 156 0
      js/jquery.notify.js

+ 3 - 0
bugs.webapp

@@ -17,4 +17,7 @@
 		"navigation": false
 	},
 	"fullscreen": "true"
+	"permissions": {
+		"desktop-notification":{}
+	}
 }

+ 13 - 0
css/ui.notify.css

@@ -0,0 +1,13 @@
+.ui-notify { width:350px; position:fixed; top:10px; right:10px; }
+.ui-notify-message { padding:10px; margin-bottom:15px; -moz-border-radius:8px; -webkit-border-radius:8px; border-radius:8px }
+.ui-notify-message h1 { font-size:14px; margin:0; padding:0 }
+.ui-notify-message p { margin:3px 0; padding:0; line-height:18px }
+.ui-notify-message:last-child { margin-bottom:0 }
+.ui-notify-message-style { background:#000; background:rgba(0,0,0,0.8); -moz-box-shadow: 0 0 6px #000; -webkit-box-shadow: 0 0 6px #000; box-shadow: 0 0 6px #000; }
+.ui-notify-message-style h1 { color:#fff; font-weight:bold }
+.ui-notify-message-style p { color:#fff }
+.ui-notify-close { color:#fff; text-decoration:underline }
+.ui-notify-click { cursor:pointer }
+.ui-notify-cross { margin-top:-4px; float:right; cursor:pointer; text-decoration:none; font-size:12px; font-weight:bold; text-shadow:0 1px 1px #fff; padding:2px }
+.ui-notify-cross:hover { color:#ffffab }
+.ui-notify-cross:active { position:relative; top:1px }

+ 15 - 0
index.php

@@ -78,6 +78,7 @@
 		<link rel="shortcut icon" href="img/favicon.ico" />
 		<link rel="icon" type="image/png" href="img/favicon-60.png" />
 		<link href="css/jquery-ui.css" rel="stylesheet" type="text/css"/>
+		<link href="css/ui.notify.css" rel="stylesheet" type="text/css"/>
 		<link href="css/style.css" rel="stylesheet" type="text/css"/>
 		<title>Bugs</title>
 		<script src="js/modernizr.js"></script>
@@ -120,6 +121,7 @@
 		<script src="js/jquery.cookie.js"></script>
 		<script src="js/jquery.nicescroll.js"></script>
 		<script src="js/jquery.timeago.js"></script>
+		<script src="js/jquery.notify.js"></script>
 		<script src="js/shortcut.js"></script>
 		<script src="js/index.js"></script>
 	</head>
@@ -135,5 +137,18 @@
 				<textarea name="message"></textarea>
 			</form>
 		</div>
+		<div id="notification-container" style="display:none;">
+			<div id="basic-template">
+				<a class="ui-notify-cross ui-notify-close" href="#">
+					x
+				</a>
+				<h1>
+					#{title}
+				</h1>
+				<p>
+					#{text}
+				</p>
+			</div>
+		</div>
 	</body>
 </html>

+ 38 - 1
js/index.js

@@ -534,6 +534,40 @@
 				render.dialog('#dialog',title,callback);
 			}
 		},
+		notify = window.notify = function(title,text,onclick,onclose){
+			var notification;
+			if(exists(window.Notification)&&!exists(window.webkitNotifications)&&!flag('default_notify')){
+				if(Notification.permission === 'denied'){
+					flag('default_notify',true);
+					notify(title,text,onclick,onclose);
+				}else if(Notification.permission === 'granted'){
+					notification = new Notification(title,{
+						body: text,
+						icon: 'favicon.ico'
+					});
+					notification.onclick = onclick;
+					notification.onclose = onclose;
+				}else{
+					Notification.requestPermission(function(p){
+						console.log('permission for notify: '+p);
+						Notification.permission = p;
+						notify(title,text,onclick,onclose);
+					});
+				}
+			}else if(exists(window.navigator.mozNotification)){
+				notification = window.navigator.mozNotification.createNotification(title,text,'favicon.ico');
+				notification.onclick = onclick;
+				notification.onclose = onclose;
+				notification.show();
+			}else{
+				$('#notification-container').notify('create',{
+					title: title,
+					text: text,
+					click: onclick,
+					close: onclose
+				});
+			}
+		},
 		loading = function(state){
 			if(!flag('ignore_statechange')){
 				state = exists(state)?state:false;
@@ -621,6 +655,7 @@
 				return getState.call(History);
 			}
 		};
+		$('#notification-container').notify();
 		(function notifications(){
 			var context = State;
 			context.type = 'action';
@@ -632,7 +667,9 @@
 			apiCall(context,function(d){
 				if(!exists(d.error)){
 					if(d.count>0 && $.localStorage('last_pm_check') < d.timestamp){
-						alert('You have '+d.count+' new message'+(d.count>1?'s':''));
+						notify('Alert','You have '+d.count+' new message'+(d.count>1?'s':''),function(){
+							loadState('page-messages');
+						});
 					}
 					$('.topbar-notifications').css('display',d.count>0?'':'none').text('('+d.count+')');
 					$.localStorage('last_pm_check',d.timestamp);

+ 156 - 0
js/jquery.notify.js

@@ -0,0 +1,156 @@
+/* jQuery Notify UI Widget 1.5 by Eric Hynds
+ * http://www.erichynds.com/jquery/a-jquery-ui-growl-ubuntu-notification-widget/
+ *
+ * Depends:
+ *   - jQuery 1.4+
+ *   - jQuery UI 1.8 widget factory
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+*/
+(function($){
+
+  $.widget("ech.notify", {
+
+    options: {
+      speed: 500,
+      expires: 5000,
+      stack: "below",
+      custom: false,
+      queue: false
+    },
+
+    _create: function(){
+      var self = this;
+      this.templates = {};
+      this.keys = [];
+
+      // build and save templates
+      this.element.addClass("ui-notify").children().addClass("ui-notify-message ui-notify-message-style").each(function(i){
+        var key = this.id || i;
+        self.keys.push(key);
+        self.templates[key] = $(this).removeAttr("id").wrap("<div></div>").parent().html(); // because $(this).andSelf().html() no workie
+      }).end().empty().show();
+    },
+
+    create: function(template, msg, opts){
+      if(typeof template === "object"){
+        opts = msg;
+        msg = template;
+        template = null;
+      }
+
+      var tpl = this.templates[ template || this.keys[0]];
+
+      // remove default styling class if rolling w/ custom classes
+      if(opts && opts.custom){
+        tpl = $(tpl).removeClass("ui-notify-message-style").wrap("<div></div>").parent().html();
+      }
+
+      this.openNotifications = this.openNotifications || 0;
+
+      // return a new notification instance
+      return new $.ech.notify.instance(this)._create(msg, $.extend({}, this.options, opts), tpl);            
+    }
+  });
+
+  // instance constructor
+  $.extend($.ech.notify, {
+    instance: function(widget){
+      this.__super = widget;
+      this.isOpen = false;
+    }
+  });
+
+  // instance methods
+  $.extend($.ech.notify.instance.prototype, {
+
+    _create: function(params, options, template){
+      this.options = options;
+
+      var self = this,
+
+      // build html template
+      html = template.replace(/#(?:\{|%7B)(.*?)(?:\}|%7D)/g, function($1, $2){
+        return ($2 in params) ? params[$2] : '';
+      }),
+
+      // the actual message
+      m = (this.element = $(html)),
+
+      // close link
+      closelink = m.find(".ui-notify-close");
+
+      // clickable?
+      if(typeof this.options.click === "function"){
+        m.addClass("ui-notify-click").bind("click", function(e){
+          self._trigger("click", e, self);
+        });
+      }
+
+      // show close link?
+      if(closelink.length){
+        closelink.bind("click", function(){
+          self.close();
+          return false;
+        });
+      }
+
+      this.__super.element.queue("notify", function(){
+        self.open();
+
+        // auto expire?
+        if(typeof options.expires === "number" && options.expires > 0){
+          setTimeout($.proxy(self.close, self), options.expires);
+        }
+      });
+
+      if(!this.options.queue || this.__super.openNotifications <= this.options.queue - 1) {
+        this.__super.element.dequeue("notify");
+      }
+
+      return this;
+    },
+
+    close: function(){
+      var speed = this.options.speed;
+
+      this.element.fadeTo(speed, 0).slideUp(speed, $.proxy(function(){
+        this._trigger("close");
+        this.isOpen = false;
+        this.element.remove();
+        this.__super.openNotifications -= 1;
+        this.__super.element.dequeue("notify");
+      }, this));
+
+      return this;
+    },
+
+    open: function(){
+      if(this.isOpen || this._trigger("beforeopen") === false){
+        return this;
+      }
+
+      var self = this;
+
+      this.__super.openNotifications += 1;
+
+      this.element[this.options.stack === "above" ? "prependTo" : "appendTo"](this.__super.element).css({ display:"none", opacity:"" }).fadeIn(this.options.speed, function(){
+        self._trigger("open");
+        self.isOpen = true;
+      });
+
+      return this;
+    },
+
+    widget: function(){
+      return this.element;
+    },
+
+    _trigger: function(type, e, instance){
+      return this.__super._trigger.call( this, type, e, instance );
+    }
+  });
+
+})(jQuery);