Skip to content

Commit fce3f5f

Browse files
committed
-Added 'forceCopy' to NotificationAsset, this is for development purposes.
-Added new params for viewAllSelector and viewUnreadSelector, this allow an ID to be passed to trigger a poll of notifications for either ALL or Unread only. -Update Nofitications.js, updateCounters() now calls countUnread() to count only unread notifications. Updated ajax callback methods. -Added javascript support to Eclipse project.
1 parent 4d84c07 commit fce3f5f

File tree

6 files changed

+204
-78
lines changed

6 files changed

+204
-78
lines changed

.gitignore

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,61 @@ composer.phar
33

44
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
55
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
6-
# composer.lock
6+
# composer.lock
7+
8+
9+
.metadata
10+
bin/
11+
tmp/
12+
*.tmp
13+
*.bak
14+
*.swp
15+
*~.nib
16+
local.properties
17+
.settings/
18+
.loadpath
19+
.recommenders
20+
21+
# External tool builders
22+
.externalToolBuilders/
23+
24+
# Locally stored "Eclipse launch configurations"
25+
*.launch
26+
27+
# PyDev specific (Python IDE for Eclipse)
28+
*.pydevproject
29+
30+
# CDT-specific (C/C++ Development Tooling)
31+
.cproject
32+
33+
# CDT- autotools
34+
.autotools
35+
36+
# Java annotation processor (APT)
37+
.factorypath
38+
39+
# PDT-specific (PHP Development Tools)
40+
.buildpath
41+
42+
# sbteclipse plugin
43+
.target
44+
45+
# Tern plugin
46+
.tern-project
47+
48+
# TeXlipse plugin
49+
.texlipse
50+
51+
# STS (Spring Tool Suite)
52+
.springBeans
53+
54+
# Code Recommenders
55+
.recommenders/
56+
57+
# Annotation Processing
58+
.apt_generated/
59+
60+
# Scala IDE specific (Scala & Java development for Eclipse)
61+
.cache-main
62+
.scala_dependencies
63+
.worksheet

.project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
1818
</buildSpec>
1919
<natures>
2020
<nature>org.eclipse.php.core.PHPNature</nature>
21+
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
2122
</natures>
2223
</projectDescription>

assets/NotificationAsset.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ class NotificationAsset extends AssetBundle
2222
];
2323
public $depends = [
2424
'yii\web\JqueryAsset',
25-
'cbtech\notification_system\assets\ToastrAsset'
25+
'cbtech\notification_system\assets\ToastrAsset'
2626
// 'yii\jui\JuiAsset',
2727
];
2828
public $publishOptions = [
29+
'forceCopy' => true,
2930
'only'=>[
3031
'js/*',
3132
'css/*'

controllers/NotificationsController.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,22 @@ public function init()
3838
* @param int $seen Whether to show already seen notifications
3939
* @return array
4040
*/
41-
public function actionPoll($read = 0)
41+
public function actionPoll($all = 0)
4242
{
4343
// \Yii::error($this->notificationClass);
4444
// $read = $read ? 1 : 0;
4545
// \Yii::error($read);
4646
/** @var Notification $class */
4747
$class = $this->notificationClass;
48-
$models = $class::find()
49-
->where(['user_id' => $this->user_id])
50-
->andWhere(['or', ["read"=>intval($read)], ['flashed'=>0]])
51-
->orderBy('created_at DESC')
52-
->all();
48+
$models = $class::find()->where(['user_id' => $this->user_id]);
49+
if($all == 0){
50+
$models->andWhere(['or', ["read"=>0], ['flashed'=>0]]);
51+
}else{
52+
$models->andWhere(['or', ["read"=>0],["read"=>1], ['flashed'=>0]]);
53+
}
54+
$models = $models->orderBy('created_at DESC')
55+
->all();
56+
5357
$results = [];
5458
// \Yii::error(print_r($models,true));
5559
foreach ($models as $model) {
@@ -65,6 +69,7 @@ public function actionPoll($read = 0)
6569
'key' => $model->key,
6670
'key_id' => $model->key_id,
6771
'flashed' => $model->flashed,
72+
'read' => $model->read,
6873
'date' => $model->created_at,
6974
];
7075
}

js/Notifications.js

Lines changed: 118 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//(function ( $ ) {
22

33
var Notifications = (function(options) {
4+
5+
this.currentNotifications = [];
46

57
// function notify(){ //This syntax makes the function callable only from within the class.
68
this.notify = function(notification){ //This syntax makes the function callable by the object (this)
@@ -62,6 +64,7 @@
6264
counters: [],
6365
markAllSeenSelector: null,
6466
deleteAllSelector: null,
67+
viewAllSelector: null,
6568
listSelector: null,
6669
listItemTemplate:
6770
'<div class="notificationRow" id="notification_{id}">' +
@@ -82,55 +85,87 @@
8285
}
8386
}, options);
8487

85-
this.poll = function(){
86-
$.ajax({
87-
url: this.opts.pollUrl,
88-
method: "GET",
89-
data: {read:0},
90-
dataType: "json",
91-
// complete: setTimeout(function() {
92-
// self.poll(this.opts)
88+
this.poll = function(all=0){
89+
$.ajax({
90+
url: this.opts.pollUrl,
91+
method: "GET",
92+
data: {all:all},
93+
dataType: "json",
94+
// complete: setTimeout(function() {
95+
// self.poll(all)
9396
// }, this.opts.pollInterval),
9497
// timeout: opts.xhrTimeout
95-
})
96-
.complete(function(json){
97-
console.log(json.responseJSON);
98-
var notifications = json.responseJSON;
99-
var rows = "";
100-
101-
// Update all counters
102-
for (var i = 0; i < opts.counters.length; i++) {
103-
if ($(opts.counters[i]).text() != notifications.length) {
104-
$(opts.counters[i]).text(notifications.length);
105-
}
98+
})
99+
.done(function(data, textStatus, jqXHR){
100+
var notifications = jqXHR.responseJSON;
101+
currentNotifications = notifications;
102+
processNotifications();
103+
});
104+
}
105+
106+
this.processNotifications = function(){
107+
var rows = "";
108+
109+
updateCounters();
110+
111+
for(i in currentNotifications){
112+
var notification = currentNotifications[i];
113+
if(notification.flashed == 0){
114+
notify(notification);
115+
}
116+
rows += renderRow(notification);
117+
}
118+
if(opts.listSelector != null && opts.listSelector != ""){
119+
$(opts.listSelector).empty().append(rows);
120+
}
121+
}
122+
123+
this.updateCounters = function(){
124+
var unreadCount = countUnread();
125+
// Update all counters
126+
for (var i = 0; i < opts.counters.length; i++) {
127+
if ($(opts.counters[i]).text() != unreadCount) {
128+
$(opts.counters[i]).text(unreadCount);
106129
}
107-
108-
for(i in notifications){
109-
var notification = notifications[i];
110-
if(notification.flashed == 0){
111-
notify(notification);
112-
}
113-
rows += renderRow(notification);
114-
}
115-
if(opts.listSelector != null && opts.listSelector != ""){
116-
$(opts.listSelector).empty().append(rows);
117-
}
118-
});
130+
}
131+
}
132+
133+
this.countUnread = function(){
134+
var count = 0;
135+
for(i in currentNotifications){
136+
var notification = currentNotifications[i];
137+
if(notification.read == 0){
138+
count += 1;
139+
}
140+
}
141+
return count;
142+
}
143+
144+
this.getNotificationIndex = function(id){
145+
for(i in currentNotifications){
146+
if(currentNotifications[i].id == id){
147+
return i;
148+
}
149+
}
119150
}
120151

121152
this.markAsRead = function(id){
122-
console.log(id);
123-
$.ajax({
124-
url: this.opts.markAsReadUrl,
125-
method: "GET",
126-
data: {id:id},
127-
dataType: "json"
128-
})
129-
.complete(function(json){
130-
if($("#notification_"+id).length){
131-
$("#notification_"+id).slideUp();
132-
}
133-
});
153+
console.log(id);
154+
$.ajax({
155+
url: this.opts.markAsReadUrl,
156+
method: "GET",
157+
data: {id:id},
158+
dataType: "json"
159+
})
160+
.done(function(data, textStatus, jqXHR){
161+
if($("#notification_"+id).length){
162+
$("#notification_"+id).slideUp();
163+
}
164+
//Remove the notification from the currentNotifications array.
165+
var index = getNotificationIndex(id);
166+
currentNotifications.splice(index,1);
167+
updateCounters();
168+
});
134169
}
135170

136171
this.markAsUnread = function(){
@@ -146,32 +181,34 @@
146181
}
147182

148183
this.flash = function(notification){
149-
$.ajax({
150-
url: this.opts.flashUrl,
151-
method: "GET",
152-
data: {id:notification.id},
153-
dataType: "json"
154-
})
155-
.complete(function(json){
156-
157-
});
184+
$.ajax({
185+
url: this.opts.flashUrl,
186+
method: "GET",
187+
data: {id:notification.id},
188+
dataType: "json"
189+
})
190+
.done(function(data, textStatus, jqXHR){
191+
//Update reference in currentNotifications array.
192+
var index = getNotificationIndex(notification.id);
193+
currentNotifications[index].flashed = 1;
194+
});
158195
}
159196

160197
this.renderRow = function(notification){
161-
var html = "";
162-
if(notification.url != null && notification.url != ""){
163-
html += "<div onclick='window.location=\"" + notification.url + "\"'>";
164-
}else{
165-
html += "<div>";
166-
}
167-
168-
html += self.opts.listItemTemplate;
169-
html += "</div>";
170-
html = html.replace(/\{id}/g, notification.id);
171-
html = html.replace(/\{title}/g, notification.title);
172-
html = html.replace(/\{body}/g, notification.body);
173-
html = html.replace(/\{read}/g, '<span onclick="markAsRead(' + notification.id + ');" class="notification-seen glyphicon glyphicon-ok" data-keepOpenOnClick></span>');
174-
html = html.replace(/\{delete}/g, '<span onclick="" class="notification-delete glyphicon glyphicon-remove" data-keepOpenOnClick></span>');
198+
var html = "";
199+
if(notification.url != null && notification.url != ""){
200+
html += "<div >";
201+
}else{
202+
html += "<div>";
203+
}
204+
205+
html += self.opts.listItemTemplate;
206+
html += "</div>";
207+
html = html.replace(/\{id}/g, notification.id);
208+
html = html.replace(/\{title}/g, notification.title);
209+
html = html.replace(/\{body}/g, notification.body);
210+
html = html.replace(/\{read}/g, '<span onclick="markAsRead(' + notification.id + ');" class="notification-seen glyphicon glyphicon-ok" data-keepOpenOnClick></span>');
211+
html = html.replace(/\{delete}/g, '<span onclick="" class="notification-delete glyphicon glyphicon-remove" data-keepOpenOnClick></span>');
175212
// html = html.replace(/\{timeago}/g, '<span class="notification-timeago">' + notification.timeago +'</span>');
176213

177214
return html;
@@ -180,9 +217,21 @@
180217
// notify();
181218

182219
$(document).ready(function(){
183-
$(document).delegate("ul.dropdown-menu [data-keepOpenOnClick]", "click", function(e) {
184-
e.stopPropagation();
185-
});
220+
$(document).delegate("ul.dropdown-menu [data-keepOpenOnClick]", "click", function(e) {
221+
e.stopPropagation();
222+
});
223+
224+
if(self.opts.viewAllSelector != null && self.opts.viewAllSelector != ""){
225+
$(self.opts.viewAllSelector).click(function(){
226+
poll(1); //Poll for all notifications.
227+
});
228+
}
229+
230+
if(self.opts.viewUnreadSelector != null && self.opts.viewUnreadSelector != ""){
231+
$(self.opts.viewUnreadSelector).click(function(){
232+
poll(0); //Poll for unread notifications.
233+
});
234+
}
186235
});
187236

188237
return this;

widgets/NotificationsWidget.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ class NotificationsWidget extends Widget
6767
* @var string The list item HTML template
6868
*/
6969
public $listItemTemplate = null;
70+
71+
public $viewAllSelector = null;
72+
73+
public $viewUnreadSelector = null;
7074

7175

7276
public function init()
@@ -150,8 +154,17 @@ public function registerAssets()
150154
// $params['listItemBeforeRender'] = $this->listItemBeforeRender;
151155
// }
152156
}
157+
158+
if($this->viewAllSelector){
159+
$params["viewAllSelector"] = $this->viewAllSelector;
160+
}
161+
162+
if($this->viewUnreadSelector){
163+
$params["viewUnreadSelector"] = $this->viewUnreadSelector;
164+
}
165+
153166
$js = 'var notificationSystem = Notifications(' . Json::encode($params,JSON_PRETTY_PRINT) . ');
154-
notificationSystem.poll();';
167+
notificationSystem.poll(0);';
155168
$view->registerJs($js);
156169
}
157170
}

0 commit comments

Comments
 (0)