Skip to content

Commit 4e6acec

Browse files
committed
TagHandler finished
1 parent 86bcf83 commit 4e6acec

File tree

7 files changed

+108
-68
lines changed

7 files changed

+108
-68
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import TagHandler from "./TagHandler.js";
2+
3+
class InputHandler {
4+
/**
5+
*
6+
* @param {object} options
7+
* @param {"edit"|"cron"|timer} options.type
8+
* @param {M.Modal} options.windowModal
9+
* @param {Element} options.textarea
10+
*/
11+
constructor(options) {
12+
this.type = options.type;
13+
const modalEl = options.windowModal.el;
14+
this.tagHandlers = [...modalEl.querySelectorAll(".tag_wrapper")].map(el => new TagHandler({
15+
elementWrapper: el,
16+
dataset: el.classList.contains("channels_wrapper") ? document.channels : document.users,
17+
textarea: el.parentElement.querySelector("textarea"),
18+
type: el.classList.contains("channels_wrapper") ? "channel" : "user",
19+
extentDataset: el.classList.contains("users_wrapper") ? document.roles : undefined,
20+
}));
21+
}
22+
23+
24+
sendRequest() {
25+
26+
}
27+
}
28+
29+
export default InputHandler;

public/js/dashboard/TagHandler.js

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
/**
2-
* @param {Object} options
3-
* @param {Element} options.textarea
4-
* @param {Array} options.dataset
5-
* @param {Element} options.elementWrapper
6-
* @param {"channel"|"user"} options.type
7-
*/
1+
const USER_TAG = "@";
2+
const CHANNEL_TAG = "#";
3+
const ROLE_TAG = "@&";
84
class TagHandler {
95
/**
10-
* @param {Object} options
6+
* Class to handle tags, the user type includes also roles
7+
* @param {object} options
118
* @param {Element} options.textarea
129
* @param {Array} options.dataset
10+
* @param {Array} [options.extentDataset]
1311
* @param {Element} options.elementWrapper
1412
* @param {"channel"|"user"} options.type
1513
*/
1614
constructor(options) {
1715
this.type = options.type;
1816
this.wrapper = options.elementWrapper;
19-
this.data = options.dataset;
17+
this.data = options.extentDataset ? [...options.dataset, ...options.extentDataset] : options.dataset;
18+
this.extentData = options.extentDataset;
2019
this.textarea = options.textarea;
2120

2221
this.textarea.addEventListener("input", () => this.onInputTextarea(this.textarea.value));
@@ -32,7 +31,7 @@ class TagHandler {
3231
*/
3332
onInputTextarea(data) {
3433
const lastChar = data.charAt(this.textarea.value.length-1);
35-
if ((this.type == "user" && lastChar == "@") || (this.type == "channel" && lastChar == "#")) {
34+
if ((this.type == "user" && lastChar == USER_TAG) || (this.type == "channel" && lastChar == CHANNEL_TAG)) {
3635
this.wrapper.classList.remove("scale-out");
3736
this.wrapper.classList.add("scale-in");
3837
this.clear();
@@ -49,15 +48,19 @@ class TagHandler {
4948
}
5049
}
5150

51+
/**
52+
*
53+
* @param {Event} event
54+
*/
5255
onKeyPressedTextarea(event) {
5356
if (!this.wrapper.classList.contains("scale-in")) return; //Si la fenêtre est pas affiché on fait rien
5457
//Sinon on fait un déplacement gauche/droite/haut/bas des flêches pour sélectionner les tags
5558
if (event.keyCode == 40 || event.keyCode == 39) {
5659
event.preventDefault();
57-
this.moveTagRight(this.wrapper);
60+
this.moveTagRight();
5861
} else if (event.keyCode == 38 || event.keyCode == 37) {
5962
event.preventDefault();
60-
this.moveTagLeft(this.wrapper);
63+
this.moveTagLeft();
6164
} else if (event.keyCode == 13) {
6265
event.preventDefault();
6366
this.wrapper.querySelector(".selected").click();
@@ -70,28 +73,30 @@ class TagHandler {
7073
*/
7174
onElClick(element) {
7275
const text = element.innerText;
73-
this.textarea.value = this.textarea.value.substring(0, this.textarea.value.lastIndexOf(this.type == "user" ? "@" : "#")) + text;
76+
this.textarea.value = this.textarea.value.substring(0, this.textarea.value.lastIndexOf(this.type == "user" ? USER_TAG : CHANNEL_TAG)) + text;
7477
M.textareaAutoResize(this.textarea);
7578
this.wrapper.classList.remove("scale-in");
7679
this.wrapper.classList.add("scale-out");
77-
this.wrapper.querySelector(".selected").classList.remove("selected");
80+
if (this.wrapper.querySelector(".selected"))
81+
this.wrapper.querySelector(".selected").classList.remove("selected");
7882
}
7983
/**
8084
*
8185
* Method to filter the tag list
8286
* @param {string} textContent
8387
*/
8488
filter(textContent) {
85-
const query = textContent.substring(textContent.lastIndexOf(this.type == "user" ? "@" : "#")+1, textContent.length);
89+
const query = textContent.substring(textContent.lastIndexOf(this.type == "user" ? USER_TAG : CHANNEL_TAG)+1, textContent.length);
8690
console.log(this.data, query);
8791
const elsToHide = this.data.filter(el => {
88-
const name = el.name || el.username || el.nickname;
92+
const name = el.name || el.nickname || el.username;
8993
return !name.toLowerCase().includes(query.toLowerCase());
9094
});
9195
const elsToShow = this.data.filter(el => {
92-
const name = el.name || el.username || el.nickname;
96+
const name = el.name || el.nickname || el.username;
9397
return name.toLowerCase().includes(query.toLowerCase());
9498
});
99+
console.log(elsToShow, elsToHide);
95100
elsToHide.forEach(el => this.wrapper.querySelector('div[data-id="'+el.id+'"]').classList.add("hidden"));
96101
elsToShow.forEach(el => this.wrapper.querySelector('div[data-id="'+el.id+'"]').classList.remove("hidden"));
97102
}
@@ -156,5 +161,23 @@ class TagHandler {
156161
}
157162
}
158163
}
164+
165+
/**
166+
* @param {string} textContent
167+
* @returns {string} converted text
168+
*/
169+
replaceTag(textContent) {
170+
for (const el of this.data) {
171+
if (this.type == "user") {
172+
if (this.extentData.includes(el)) //If the el is in the extent data we put the roles
173+
textContent = textContent.replace(`@${el.nickname || el.username || el.name}`, `<${ROLE_TAG}${el.id}>`);
174+
else
175+
textContent = textContent.replace(`@${el.nickname || el.username || el.name}`, `<${USER_TAG}${el.id}>`);
176+
}
177+
else
178+
textContent = textContent.replace(`#${el.nickname || el.username || el.name}`, `<${CHANNEL_TAG}${el.id}>`);
179+
}
180+
return textContent;
181+
}
159182
}
160183
export default TagHandler;

public/js/dashboard/VueDashboard.js

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,33 @@ class VueDashboard {
6767
yearRange: 1,
6868
defaultDate: new Date(),
6969
});
70-
document.querySelectorAll(".channels_wrapper").forEach(el => new TagHandler({
70+
M.FormSelect.init(document.querySelectorAll("select"));
71+
this.initTagHandlers();
72+
this.addEventListener();
73+
}
74+
75+
initTagHandlers() {
76+
this.timerTagWrappers = [...document.querySelectorAll("#addTimer .channels_wrapper, #addTimer .users_wrapper")].map(el => new TagHandler({
7177
elementWrapper: el,
72-
dataset: document.channels,
78+
dataset: el.classList.contains("channels_wrapper") ? document.channels : document.users,
7379
textarea: el.parentElement.querySelector("textarea"),
74-
type: "channel"
80+
type: el.classList.contains("channels_wrapper") ? "channel" : "user",
81+
extentDataset: el.classList.contains("users_wrapper") ? document.roles : undefined,
7582
}));
76-
document.querySelectorAll(".users_wrapper").forEach(el => new TagHandler({
83+
this.cronTagWrappers = [...document.querySelectorAll("#add_cron .channels_wrapper, #add_cron .users_wrapper")].map(el => new TagHandler({
7784
elementWrapper: el,
78-
dataset: document.users,
85+
dataset: el.classList.contains("channels_wrapper") ? document.channels : document.users,
7986
textarea: el.parentElement.querySelector("textarea"),
80-
type: "user"
87+
type: el.classList.contains("channels_wrapper") ? "channel" : "user",
88+
extentDataset: el.classList.contains("users_wrapper") ? document.roles : undefined,
89+
}));
90+
this.editMessageWrappers = [...document.querySelectorAll("#editMessage .channels_wrapper, #editMessage .users_wrapper")].map(el => new TagHandler({
91+
elementWrapper: el,
92+
dataset: el.classList.contains("channels_wrapper") ? document.channels : document.users,
93+
textarea: el.parentElement.querySelector("textarea"),
94+
type: el.classList.contains("channels_wrapper") ? "channel" : "user",
95+
extentDataset: el.classList.contains("users_wrapper") ? document.roles : undefined,
8196
}));
82-
M.FormSelect.init(document.querySelectorAll("select"));
83-
this.addEventListener();
8497
}
8598

8699
addEventListener() {
@@ -141,14 +154,11 @@ class VueDashboard {
141154
//Pour chaque element selectionné (on a juste le nom)
142155
this.daySelectWrapper.querySelectorAll(".selected").forEach((el) => {
143156
//Pour chaque element proposé (nom + valeur)
144-
console.log(el);
145157
document.querySelectorAll("#daySelect option").forEach((inputEl) => {
146-
console.log(inputEl);
147158
if (el.textContent == inputEl.textContent)
148159
selectedDays[inputEl.value] = inputEl.textContent;
149160
});
150161
});
151-
console.log(selectedDays);
152162
if (selectedDays.length > 0) {
153163
desc += " on " + Object.values(selectedDays).join(", ");
154164
cron[4] = Object.keys(selectedDays).join(",");
@@ -200,16 +210,8 @@ class VueDashboard {
200210
const formData = new FormData();
201211
const content = this.form.elements.namedItem("content").value;
202212
let sysContent = content;
203-
document.channels.forEach(el => {
204-
sysContent = sysContent.replace("#"+el.name, "<#"+el.id+">");
205-
});
206-
document.users.forEach(el => {
207-
const name = el.nickname || el.username;
208-
sysContent = sysContent.replace("@"+name, "<@"+el.id+">");
209-
});
210-
document.roles.forEach(el => {
211-
sysContent = sysContent.replace("@"+el.username, "<@&"+el.id+">");
212-
});
213+
for (const tagHandler of this.cronTagWrappers)
214+
sysContent = tagHandler.replaceTag(sysContent);
213215
formData.append("frequency", desc);
214216
formData.append("cron", cron.join(" "));
215217
formData.append("content", content);
@@ -278,16 +280,8 @@ class VueDashboard {
278280
const channel_id = this.formTimer.elements.namedItem("channelSelectTimer").value;
279281

280282
let sysContent = content;
281-
document.channels.forEach(el => {
282-
sysContent = sysContent.replace("#"+el.name, "<#"+el.id+">");
283-
});
284-
document.users.forEach(el => {
285-
const name = el.nickname || el.username;
286-
sysContent = sysContent.replace("@"+name, "<@"+el.id+">");
287-
});
288-
document.roles.forEach(el => {
289-
sysContent = sysContent.replace("@"+el.username, "<@&"+el.id+">");
290-
});
283+
for (const tagHandler of this.timerTagWrappers)
284+
sysContent = tagHandler.replaceTag(sysContent);
291285
formData.append("content", content);
292286
formData.append("sys_content", sysContent);
293287
formData.append("timestamp", timestamp);
@@ -379,21 +373,14 @@ class VueDashboard {
379373
document.querySelector(".guild-timezone h5").textContent = "Timezone : " + timezone;
380374
this.timezoneModal.close();
381375
}
376+
382377
async onConfirmUpdateMessage() {
383378
const message = document.querySelector("#contentEdit").value;
384379
const formData = new FormData();
385380

386381
let sysContent = message;
387-
document.channels.forEach(el => {
388-
sysContent = sysContent.replace("#"+el.name, "<#"+el.id+">");
389-
});
390-
document.users.forEach(el => {
391-
const name = el.nickname || el.username;
392-
sysContent = sysContent.replace("@"+name, "<@"+el.id+">");
393-
});
394-
document.roles.forEach(el => {
395-
sysContent = sysContent.replace("@"+el.username, "<@&"+el.id+">");
396-
});
382+
for(const el of this.editMessageWrappers)
383+
sysContent = el.replaceTag(sysContent);
397384

398385
formData.append("content", message);
399386
formData.append("msg_id", this.idToRemove);
@@ -413,5 +400,7 @@ class VueDashboard {
413400
document.getElementById(this.idToRemove).querySelector(".description").textContent = message;
414401
}
415402
}
416-
417-
window.addEventListener("DOMContentLoaded", e => new VueDashboard());
403+
(function() {
404+
"use strict";
405+
window.addEventListener("DOMContentLoaded", e => new VueDashboard());
406+
})();

views/components/add_schedule_window.ejs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<textarea id="content" name="content" class="materialize-textarea" required minlength="1"
77
maxlength="2000"></textarea>
88
<label for="content">Message's content</label>
9-
<div class="users_wrapper scale-out">
9+
<div class="users_wrapper scale-out tag_wrapper">
1010
<% people_list.concat(roles_list).forEach((el, index) => { %>
1111
<div class="user_el waves-effect waves-light" data-id="<%= el.id %>"
1212
nickname="<%= (el.nickname || el.username) %>">
@@ -20,7 +20,7 @@
2020
@here
2121
</div>
2222
</div>
23-
<div class="channels_wrapper scale-out">
23+
<div class="channels_wrapper scale-out tag_wrapper">
2424
<% channel_list.forEach((el, index) => { %>
2525
<div class="channel_el waves-effect waves-light" data-id="<%= el.id %>">
2626
#<%= el.name %>

views/components/add_timer_window.ejs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<div class="input-field col s12 section">
66
<textarea id="contentTimer" name="contentTimer" class="materialize-textarea" required minlength="1" maxlength="2000"></textarea>
77
<label for="contentTimer">Message's content</label>
8-
<div class="users_wrapper scale-out">
8+
<div class="users_wrapper scale-out tag_wrapper">
99
<% people_list.concat(roles_list).forEach((el, index) => { %>
1010
<div class="user_el waves-effect waves-light" data-id="<%= el.id %>"
1111
nickname="<%= (el.nickname || el.username) %>">
@@ -19,7 +19,7 @@
1919
@here
2020
</div>
2121
</div>
22-
<div class="channels_wrapper scale-out">
22+
<div class="channels_wrapper scale-out tag_wrapper">
2323
<% channel_list.forEach((el, index) => { %>
2424
<div class="channel_el waves-effect waves-light" data-id="<%= el.id %>">
2525
#<%= el.name %>

views/components/edit_message_window.ejs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<textarea id="contentEdit" name="contentTimerEdit" class="materialize-textarea" required minlength="1"
77
maxlength="2000"></textarea>
88
<label for="contentEdit">Message's content</label>
9-
<div class="users_wrapper scale-out">
9+
<div class="users_wrapper scale-out tag_wrapper">
1010
<% people_list.concat(roles_list).forEach((el, index) => { %>
1111
<div class="user_el waves-effect waves-light" data-id="<%= el.id %>"
1212
nickname="<%= (el.nickname || el.username) %>">
@@ -20,7 +20,7 @@
2020
@here
2121
</div>
2222
</div>
23-
<div class="channels_wrapper scale-out">
23+
<div class="channels_wrapper scale-out tag_wrapper">
2424
<% channel_list.forEach((el, index) => { %>
2525
<div class="channel_el waves-effect waves-light" data-id="<%= el.id %>">
2626
#<%= el.name %>

views/dashboard.ejs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@
2929
<% include ../public/images/timezone.svg %>
3030
<h5 style="max-width: 80%;">
3131
<% if (guildTimezone) {%>
32-
<span>Timezone :</span> <%= guildTimezone%>
32+
<%= guildTimezone%>
3333
<% } else {%>
34-
<span>Timezone :</span>
3534
No timezone has been set ! Default set to UTC
3635
<% } %>
3736
</h5>

0 commit comments

Comments
 (0)