Skip to content

Commit b887a00

Browse files
committed
chrome: clean code and add a button to create a conversation
1 parent 0d41075 commit b887a00

File tree

4 files changed

+165
-128
lines changed

4 files changed

+165
-128
lines changed

Google Chrome/notifier.js

Lines changed: 145 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,191 @@
1-
/*
2-
* Global letiables
3-
*/
4-
let _notifCounter = 0
5-
const _delayUpdate = 60 * 1000
6-
// Used by the popup
7-
let _currentDom = null
8-
let _contentDiv = null
9-
// If the user is connected
10-
let _connected = false
11-
// If we want to see popup letiables
12-
let _showNotification = false
1+
/* global chrome XMLHttpRequest:true */
2+
/* eslint-disable no-console */
3+
const debugMode = false
4+
const NOT_CONNECTED = 401
5+
const CONNECTED = 200
6+
7+
// TODO move this
8+
var connected = false
9+
var notifCounter = 0
10+
var currentDom = null
11+
let contentDiv = null
12+
13+
// Load preferences
14+
const updateDelay = 60 * 1000
15+
let showPopupNotification = false
1316
chrome.storage.local.get('notify', (res) => {
14-
_showNotification = res.notify || false
17+
showPopupNotification = res.notify || false
1518
})
16-
// If we are in debug mode
17-
const _debug = true
18-
let baseUrl = 'https://zestedesavoir.com/'
19-
const _token = 'zds-notifier'
20-
if (_debug) baseUrl = 'https://beta.zestedesavoir.com/'
2119

22-
function escapeHTML (str) { return str.replace(/[&''<>]/g, (m) => escapeHTML.replacements[m]) }
23-
escapeHTML.replacements = { '&': '&amp', '\'': '&quot', '"': '&#39', '<': '&lt', '>': '&gt' }
20+
let baseUrl = 'https://zestedesavoir.com/'
21+
if (debugMode) baseUrl = 'https://beta.zestedesavoir.com/'
22+
const token = 'zds-notifier'
2423

2524
/**
26-
* getNotificationsFromAPI
27-
*/
25+
* Get notifications from https://zestedesavoir.com via the API
26+
*/
2827
function getNotificationsFromAPI () {
29-
_contentDiv = document.createElement('div')
30-
const target = baseUrl + 'api/notifications/?page_size=30&ordering=-pubdate&Authorization=' + _token
28+
contentDiv = document.createElement('div')
29+
const options = `page_size=30&ordering=-pubdate&Authorization=${token}`
30+
const target = `${baseUrl}api/notifications/?${options}`
31+
// TODO use fetch instead
3132
const xhr = new XMLHttpRequest()
3233
xhr.open('GET', target, true)
3334
xhr.onload = function (e) {
3435
if (xhr.readyState === 4) {
3536
const result = xhr.status
36-
if (result === 401) {
37-
_connected = false
38-
if (_debug) console.log('Not connected')
39-
// Change popup image
40-
chrome.browserAction.setIcon({path:'icons/notconnected.png'})
41-
} else if (result === 200) {
42-
_connected = true
37+
if (result === NOT_CONNECTED) {
38+
connected = false
39+
if (debugMode) console.log('Not connected')
40+
chrome.browserAction.setIcon({path: 'icons/notconnected.png'})
41+
} else if (result === CONNECTED) {
42+
connected = true
4343
const rootDOM = JSON.parse(xhr.response)
4444
if (rootDOM.details) {
45-
if (_debug) console.log('Error while parsing')
45+
if (debugMode) console.log('can\'t parse incorrect JSON')
4646
} else {
47-
// Get new notifications
48-
const resultsNotification = rootDOM.results
49-
let countNotifications = 0
50-
for (let notif = 0; notif < resultsNotification.length; ++notif) {
51-
// If a notification is new we have is_read === False
52-
if (!resultsNotification[notif].is_read) {
53-
countNotifications += 1
54-
const titleNotif = resultsNotification[notif].title
55-
const senderNotif = resultsNotification[notif].sender.username
56-
const senderAvatarNotif = resultsNotification[notif].sender.avatar_url
57-
const dateNotif = resultsNotification[notif].pubdate
58-
const date = new Date((dateNotif || '').replace(/-/g, '/').replace(/[TZ]/g, ' '))
59-
let minutes = `${date.getMinutes()}`
60-
if (minutes.length < 2) {
61-
minutes = `0${minutes}`
62-
}
63-
let formatedDate = `le ${[date.getDate(),
64-
date.getMonth() + 1].join('/')} à ${[date.getHours(),
65-
minutes].join('h')}`
66-
const actualDate = new Date()
67-
if (date.getDate() === actualDate.getDate() &&
68-
date.getMonth() === actualDate.getMonth() &&
69-
date.getYear() === actualDate.getYear()) {
70-
formatedDate = 'Aujourd\'hui'
71-
} else {
72-
const yesterday = actualDate
73-
yesterday.setDate(actualDate.getDate() - 1)
74-
if (date.getDate() === yesterday.getDate() &&
75-
date.getMonth() === yesterday.getMonth() &&
76-
date.getYear() === yesterday.getYear()) {
77-
formatedDate = 'Hier'
78-
}
79-
}
80-
const urlNotif = `https://zestedesavoir.com${resultsNotification[notif].url}`
81-
if (_debug) console.log(`${urlNotif} by ${senderNotif}`)
82-
addNotification(titleNotif, senderNotif, senderAvatarNotif, formatedDate, urlNotif)
83-
}
84-
}
85-
// Notify the user
86-
if (countNotifications > _notifCounter) {
87-
if (_debug) console.log(`Nouvelles notifications : ${countNotifications}`)
88-
chrome.browserAction.setIcon({path: 'icons/icone_n_20.png'})
89-
const title = 'Zds-notificateur : Nouvelle notification !'
90-
let content = `Vous avez ${countNotifications} notification`
91-
if (countNotifications > 1) content += 's'
92-
notifyMe(title, content)
93-
} else if (countNotifications === 0) {
94-
chrome.browserAction.setIcon({path: 'icons/clem_48.png'})
95-
}
96-
_notifCounter = countNotifications
47+
parseNotifications(rootDOM.results)
9748
}
98-
} else if (_debug) {
49+
} else if (debugMode) {
9950
console.log(result)
10051
}
10152
}
10253

103-
104-
if (!_notifCounter) {
105-
const divNoNotif = document.createElement('div')
106-
divNoNotif.id = 'noNotif'
107-
divNoNotif.innerHTML = 'Aucune notification'
108-
_contentDiv.appendChild(divNoNotif)
109-
if (_debug) console.log('Aucune notification')
110-
}
111-
const body = document.body
112-
body.appendChild(_contentDiv)
113-
// Remove useless nodes
114-
while (body.childNodes.length > 2) {
115-
body.removeChild(body.childNodes[1])
116-
}
117-
_currentDom = body
54+
buildPopup()
11855
}
11956

12057
xhr.onerror = function (e) {
12158
console.error(xhr.statusText)
122-
_connected = false
59+
connected = false
12360
}
12461
xhr.send(null)
12562
}
12663

127-
/*
128-
* Add a notification to the DOM
129-
*/
130-
function addNotification (title, sender, senderAvatar, date, url) {
131-
// Design popup
132-
const a = document.createElement('a')
133-
a.href = url
134-
a.target = '_blank'
135-
const divNotif = document.createElement('div')
136-
divNotif.id = 'notification'
137-
const imgAvatar = document.createElement('img')
138-
imgAvatar.src = senderAvatar
64+
/**
65+
* Build the DOM of the popup
66+
*/
67+
function buildPopup () {
68+
if (!notifCounter) {
69+
const divNoNotif = document.createElement('div')
70+
divNoNotif.id = 'noNotif'
71+
divNoNotif.innerText = 'Aucune notification'
72+
contentDiv.appendChild(divNoNotif)
73+
if (debugMode) console.log(divNoNotif.innerText)
74+
}
75+
const body = document.body
76+
body.appendChild(contentDiv)
77+
// Remove useless nodes
78+
while (body.childNodes.length > 2) {
79+
body.removeChild(body.childNodes[1])
80+
}
81+
currentDom = body
82+
}
83+
84+
/**
85+
* Parse the JSON returned by the API
86+
* @param results the JSON object
87+
*/
88+
function parseNotifications (results) {
89+
// Get new notifications
90+
let notificationsCounter = 0
91+
for (const notif of results) {
92+
// If a notification is new we have is_read === False
93+
if (!notif.is_read) {
94+
notificationsCounter += 1
95+
const title = notif.title
96+
const author = notif.sender.username
97+
const authorAvatar = notif.sender.avatar_url
98+
99+
const urlNotif = `${baseUrl}${notif.url}`
100+
if (debugMode) console.log(`${urlNotif} by ${author}`)
101+
addNotification(title, author, authorAvatar, formatDate(notif.pubdate), urlNotif)
102+
}
103+
}
104+
// Notify the user
105+
if (notificationsCounter > notifCounter) {
106+
if (debugMode) console.log(`New notification: ${notificationsCounter}`)
107+
chrome.browserAction.setIcon({path: 'icons/icone_n_20.png'})
108+
const title = 'Zds-notificateur : Nouvelle notification !'
109+
let content = `Vous avez ${notificationsCounter} notification`
110+
if (notificationsCounter > 1) content += 's'
111+
popupNotification(title, content)
112+
} else if (notificationsCounter === 0) {
113+
chrome.browserAction.setIcon({path: 'icons/clem_48.png'})
114+
}
115+
notifCounter = notificationsCounter
116+
}
117+
118+
/**
119+
* Pretty print a publication date
120+
* @param pubdate
121+
*/
122+
function formatDate (pubdate) {
123+
const date = new Date((pubdate || '').replace(/-/g, '/').replace(/[TZ]/g, ' '))
124+
125+
const actualDate = new Date()
126+
if (date.toDateString() === actualDate.toDateString()) {
127+
return 'Aujourd\'hui'
128+
}
129+
130+
const yesterday = actualDate
131+
yesterday.setDate(actualDate.getDate() - 1)
132+
if (date.toDateString() === yesterday.toDateString()) {
133+
return 'Hier'
134+
}
135+
136+
let minutes = `${date.getMinutes()}`
137+
if (minutes.length < 2) {
138+
minutes = `0${minutes}`
139+
}
140+
const shortDate = [date.getDate(), date.getMonth() + 1].join('/')
141+
const time = [date.getHours(), minutes].join('h')
142+
return `le ${shortDate} à ${time}`
143+
}
144+
145+
/**
146+
* Add a notification entry
147+
* @param title of the subject
148+
* @param author
149+
* @param authorAvatar
150+
* @param date
151+
* @param url
152+
*/
153+
function addNotification (title, author, authorAvatar, date, url) {
139154
const divBlocNotif = document.createElement('div')
140155
divBlocNotif.id = 'blocNotif'
141156
const divDate = document.createElement('div')
142157
divDate.id = 'date'
143-
divDate.innerHTML = escapeHTML(date)
158+
divDate.innerText = date
144159
const divPseudo = document.createElement('div')
145160
divPseudo.id = 'pseudo'
146-
divPseudo.innerHTML = escapeHTML(sender)
161+
divPseudo.innerText = author
147162
const divTitle = document.createElement('div')
148163
divTitle.id = 'title'
149-
divTitle.innerHTML = escapeHTML(title)
164+
divTitle.innerText = title
165+
const imgAvatar = document.createElement('img')
166+
imgAvatar.src = authorAvatar
167+
const divNotif = document.createElement('div')
168+
divNotif.id = 'notification'
169+
const a = document.createElement('a')
170+
a.href = url
171+
a.target = '_blank' // Open the notification in a new window
150172

151173
divBlocNotif.appendChild(divDate)
152174
divBlocNotif.appendChild(divPseudo)
153175
divBlocNotif.appendChild(divTitle)
154176
divNotif.appendChild(imgAvatar)
155177
divNotif.appendChild(divBlocNotif)
156178
a.appendChild(divNotif)
157-
_contentDiv.appendChild(a)
179+
contentDiv.appendChild(a)
158180
}
159181

160-
/*
161-
* Create a notification
162-
*/
163-
function notifyMe (title, content) {
164-
if (_showNotification) {
182+
/**
183+
* Show a popup notification
184+
* @param title of the popup
185+
* @param content
186+
*/
187+
function popupNotification (title, content) {
188+
if (showPopupNotification) {
165189
chrome.notifications.create({
166190
'type': 'basic',
167191
'iconUrl': chrome.extension.getURL('icons/icone_n_20.png'),
@@ -172,5 +196,5 @@ function notifyMe (title, content) {
172196
}
173197

174198
// Update the popup
175-
setInterval(getNotificationsFromAPI, _delayUpdate)
199+
setInterval(getNotificationsFromAPI, updateDelay)
176200
getNotificationsFromAPI()

Google Chrome/popup/notifier.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
const _notifications = document.getElementById('notificationList')
1+
/* global chrome close:true */
2+
/* eslint no-undef: "error" */
3+
const notificationsList = document.getElementById('notificationList')
24

35
function updateUI () {
4-
if (chrome.extension.getBackgroundPage()._connected) {
6+
if (chrome.extension.getBackgroundPage().connected) {
57
const notConnectedDiv = document.getElementById('notConnected')
68
notConnectedDiv.style.display = 'none'
7-
const bgNodes = chrome.extension.getBackgroundPage()._currentDom.lastChild.cloneNode(true)
8-
_notifications.appendChild(bgNodes)
9+
const bgNodes = chrome.extension.getBackgroundPage().currentDom.lastChild.cloneNode(true)
10+
notificationsList.appendChild(bgNodes)
911
} else {
1012
const connectedDiv = document.getElementById('connected')
1113
connectedDiv.style.display = 'none'
@@ -17,9 +19,9 @@ function sleep (time) {
1719
return new Promise((resolve) => setTimeout(resolve, time))
1820
}
1921

20-
_notifications.addEventListener('click', function () {
22+
notificationsList.addEventListener('click', function () {
2123
sleep(2000).then(() => {
22-
if (chrome.extension.getBackgroundPage()._notifCounter !== 0) {
24+
if (chrome.extension.getBackgroundPage().notifCounter !== 0) {
2325
close()
2426
}
2527
chrome.extension.getBackgroundPage().getNotificationsFromAPI()

Google Chrome/popup/notifier_popup.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,11 @@ a
142142
text-align: center;
143143
padding: 10px;
144144
}
145+
146+
.pm-new
147+
{
148+
float: right;
149+
margin-top: -23px;
150+
margin-right: 5px;
151+
margin-left: -28px;
152+
}

Google Chrome/popup/notifier_popup.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99
<div id="notificationList">
1010
</div>
1111
<div id="button"><a target="_blank" href="https://zestedesavoir.com/notifications/">Toutes les notifications</a></div>
12+
<a href="https://zestedesavoir.com/mp/creer/" class="pm-new" title="Envoyer un nouveau message privé">
13+
<img src="../icons/pm_new.png"/>
14+
</a>
1215
</div>
1316
<div id="notConnected">
1417
<div id="home_clem"><img src="https://zestedesavoir.com/static/images/home-clem.4a2f792744c9.png"/></div>
1518
<div id="payload">«Vous zestes les bienvenus.»</div>
1619
<a target="_blank" href="https://zestedesavoir.com/membres/connexion/?next=/"><div id="button">Connexion</div></a>
1720
</div>
18-
<script src="popup/notifier.js"></script>
21+
<script src="notifier.js"></script>
1922
</body>
2023
</html>

0 commit comments

Comments
 (0)