Skip to content

Commit ea51b60

Browse files
authored
Merge pull request #5 from Elariondakta/viewDashboard-splitting
View dashboard splitting
2 parents ecac390 + 96f21d0 commit ea51b60

File tree

7 files changed

+510
-352
lines changed

7 files changed

+510
-352
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const rootUrl = window.location.protocol + "//" + window.location.hostname + ":" +window.location.port;
2+
class QueryHandler {
3+
/**
4+
* @callback requestCallback
5+
* @param {Response} response
6+
*/
7+
/**
8+
* Send request to add a cron request
9+
* @function addCron
10+
* @param {object} params
11+
* @param {string} params.frequency
12+
* @param {string} params.cron
13+
* @param {strign} params.content
14+
* @param {string} params.sys_content
15+
* @param {string} params.channel_id
16+
* @param {string} params.guild_id
17+
* @param {requestCallback} callback
18+
*/
19+
static addCron(params, callback) {
20+
const formData = new FormData();
21+
for (const key of Object.keys(params))
22+
formData.append(key, params[key]);
23+
24+
fetch("/ajax/add_schedule", {
25+
method: "POST",
26+
body: formData,
27+
}).then(callback);
28+
}
29+
30+
/**
31+
* @function addTimer
32+
* @param {object} params
33+
* @param {string} params.content
34+
* @param {string} params.sys_content
35+
* @param {string} params.timestamp
36+
* @param {string} params.description
37+
* @param {string} params.channel_id
38+
* @param {string} params.guild_id
39+
* @param {requestCallback} callback
40+
*/
41+
static addTimer(params, callback) {
42+
const formData = new FormData();
43+
for (const key in params)
44+
formData.append(key, params[key]);
45+
46+
fetch("/ajax/add_timer", {
47+
method: "POST",
48+
body: formData,
49+
}).then(callback);
50+
}
51+
52+
/**
53+
* Update the timezone of the server
54+
* @function setTimezone
55+
* @param {object} params
56+
* @param {string} params.guild_id
57+
* @param {string} params.utc_offset
58+
* @param {string} params.timezone
59+
*/
60+
static async setTimezone(params) {
61+
const urlSearchParams = new URLSearchParams();
62+
for (const key in params)
63+
urlSearchParams.append(key, params[key]);
64+
const url = new URL(`${rootUrl}/ajax/set_timezone`);
65+
url.search = urlSearchParams.toString();
66+
return await fetch(url);
67+
}
68+
69+
/**
70+
* Update the desired content of a message
71+
* @function updateMsg
72+
* @param {object} params
73+
* @param {string} params.content
74+
* @param {string} params.sys_content
75+
* @param {string} params.msg_id
76+
* @param {string} params.guild_id
77+
*/
78+
static async updateMsg(params) {
79+
const formData = new FormData();
80+
for (const key in params)
81+
formData.append(key, params[key]);
82+
return await fetch("/ajax/set_message", {
83+
body: formData,
84+
method: "POST"
85+
});
86+
}
87+
88+
/**
89+
* Remove the desired message
90+
* @param {object} params
91+
* @param {string} params.id message id to remove
92+
* @param {string} params.guild_id
93+
*/
94+
static async removeMsg(params) {
95+
const urlSearchParams = new URLSearchParams();
96+
for (const key in params)
97+
urlSearchParams.append(key, params[key]);
98+
const url = new URL(`${rootUrl}/ajax/remove_message`);
99+
url.search = urlSearchParams.toString();
100+
return await fetch(url);
101+
}
102+
}
103+
104+
export default QueryHandler;

public/js/dashboard/TagHandler.js

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
const USER_TAG = "@";
2+
const CHANNEL_TAG = "#";
3+
const ROLE_TAG = "@&";
4+
class TagHandler {
5+
/**
6+
* Class to handle tags, the user type includes also roles
7+
* @param {object} options
8+
* @param {Element} options.textarea
9+
* @param {Array} options.dataset
10+
* @param {Array} [options.extentDataset]
11+
* @param {Element} options.elementWrapper
12+
* @param {"channel"|"user"} options.type
13+
*/
14+
constructor(options) {
15+
this.type = options.type;
16+
this.wrapper = options.elementWrapper;
17+
this.data = options.extentDataset ? [...options.dataset, ...options.extentDataset] : options.dataset;
18+
this.extentData = options.extentDataset;
19+
this.textarea = options.textarea;
20+
21+
this.textarea.addEventListener("input", () => this.onInputTextarea(this.textarea.value));
22+
this.textarea.addEventListener("keydown", event => this.onKeyPressedTextarea(event));
23+
this.wrapper.querySelectorAll("div").forEach(
24+
el => el.addEventListener("click", () => this.onElClick(el)));
25+
}
26+
27+
/**
28+
* Method triggered when the user input something in the textarea
29+
* if a @ or a # is written the tag window will be shown
30+
* @param {string} data content of the textarea
31+
*/
32+
onInputTextarea(data) {
33+
const lastChar = data.charAt(this.textarea.value.length-1);
34+
if ((this.type == "user" && lastChar == USER_TAG) || (this.type == "channel" && lastChar == CHANNEL_TAG)) {
35+
this.wrapper.classList.remove("scale-out");
36+
this.wrapper.classList.add("scale-in");
37+
this.clear();
38+
} else if ((lastChar == " " || lastChar == "") && this.wrapper.classList.contains("scale-in")) {
39+
this.wrapper.classList.remove("scale-in");
40+
this.wrapper.classList.add("scale-out");
41+
this.clear();
42+
if (this.wrapper.querySelector(".selected"))
43+
this.wrapper.querySelector(".selected").classList.remove("selected");
44+
} else if (this.wrapper.classList.contains("scale-in")) {
45+
this.filter(data);
46+
if (this.wrapper.querySelector(".selected"))
47+
this.wrapper.querySelector(".selected").classList.remove("selected");
48+
}
49+
}
50+
51+
/**
52+
*
53+
* @param {Event} event
54+
*/
55+
onKeyPressedTextarea(event) {
56+
if (!this.wrapper.classList.contains("scale-in")) return; //Si la fenêtre est pas affiché on fait rien
57+
//Sinon on fait un déplacement gauche/droite/haut/bas des flêches pour sélectionner les tags
58+
if (event.keyCode == 40 || event.keyCode == 39) {
59+
event.preventDefault();
60+
this.moveTagRight();
61+
} else if (event.keyCode == 38 || event.keyCode == 37) {
62+
event.preventDefault();
63+
this.moveTagLeft();
64+
} else if (event.keyCode == 13) {
65+
event.preventDefault();
66+
this.wrapper.querySelector(".selected").click();
67+
}
68+
}
69+
70+
/**
71+
* If a tag element is clicked
72+
* @param {Element} element element clicked
73+
*/
74+
onElClick(element) {
75+
const text = element.innerText;
76+
this.textarea.value = this.textarea.value.substring(0, this.textarea.value.lastIndexOf(this.type == "user" ? USER_TAG : CHANNEL_TAG)) + text;
77+
M.textareaAutoResize(this.textarea);
78+
this.wrapper.classList.remove("scale-in");
79+
this.wrapper.classList.add("scale-out");
80+
if (this.wrapper.querySelector(".selected"))
81+
this.wrapper.querySelector(".selected").classList.remove("selected");
82+
}
83+
/**
84+
*
85+
* Method to filter the tag list
86+
* @param {string} textContent
87+
*/
88+
filter(textContent) {
89+
const query = textContent.substring(textContent.lastIndexOf(this.type == "user" ? USER_TAG : CHANNEL_TAG)+1, textContent.length);
90+
const elsToHide = this.data.filter(el => {
91+
const name = el.name || el.nickname || el.username;
92+
return !name.toLowerCase().includes(query.toLowerCase());
93+
});
94+
const elsToShow = this.data.filter(el => {
95+
const name = el.name || el.nickname || el.username;
96+
return name.toLowerCase().includes(query.toLowerCase());
97+
});
98+
elsToHide.forEach(el => this.wrapper.querySelector('div[data-id="'+el.id+'"]').classList.add("hidden"));
99+
elsToShow.forEach(el => this.wrapper.querySelector('div[data-id="'+el.id+'"]').classList.remove("hidden"));
100+
}
101+
102+
clear() {
103+
this.wrapper.querySelectorAll(".hidden").forEach(el => el.classList.remove("hidden"));
104+
}
105+
106+
moveTagRight() {
107+
const selected = this.wrapper.querySelector(".selected");
108+
if (selected) {
109+
//If there is a element after
110+
if (selected.nextElementSibling) {
111+
//We iterate the tag list and we find the next element shown to add the selected class
112+
for (let i = Array.prototype.indexOf.call(this.wrapper.children, selected)+1; i < this.wrapper.children.length; i++) {
113+
const el = this.wrapper.children[i];
114+
if (!el.classList.contains("hidden")) {
115+
el.classList.add("selected");
116+
selected.classList.remove("selected");
117+
break;
118+
}
119+
}
120+
} else { //If there is no element after we select the first one
121+
for (let el of this.wrapper.children) {
122+
if (!el.classList.contains("hidden")) {
123+
selected.classList.remove("selected");
124+
el.classList.add("selected");
125+
break;
126+
}
127+
}
128+
}
129+
} else {
130+
//if there is nothing selected we select the first one
131+
for (let el of this.wrapper.children) {
132+
if (!el.classList.contains("hidden")) {
133+
el.classList.add("selected");
134+
break;
135+
}
136+
}
137+
}
138+
}
139+
moveTagLeft() {
140+
const selected = this.wrapper.querySelector(".selected");
141+
if (selected) {
142+
if (selected.previousElementSibling) {
143+
for (let i = Array.prototype.indexOf.call(this.wrapper.children, selected)-1; i >= 0; i--) {
144+
const el = this.wrapper.children[i];
145+
if (!el.classList.contains("hidden")) {
146+
el.classList.add("selected");
147+
selected.classList.remove("selected");
148+
break;
149+
}
150+
}
151+
}
152+
} else {
153+
for (let i = this.wrapper.children.length-1; i >= 0; i--) {
154+
const el = this.wrapper.children[i];
155+
if (!el.classList.contains("hidden")) {
156+
el.classList.add("selected");
157+
break;
158+
}
159+
}
160+
}
161+
}
162+
163+
/**
164+
* @param {string} textContent
165+
* @returns {string} converted text
166+
*/
167+
replaceTag(textContent) {
168+
for (const el of this.data) {
169+
if (this.type == "user") {
170+
if (this.extentData.includes(el)) //If the el is in the extent data we put the roles
171+
textContent = textContent.replace(`@${el.nickname || el.username || el.name}`, `<${ROLE_TAG}${el.id}>`);
172+
else
173+
textContent = textContent.replace(`@${el.nickname || el.username || el.name}`, `<${USER_TAG}${el.id}>`);
174+
}
175+
else
176+
textContent = textContent.replace(`#${el.nickname || el.username || el.name}`, `<${CHANNEL_TAG}${el.id}>`);
177+
}
178+
return textContent;
179+
}
180+
}
181+
export default TagHandler;

0 commit comments

Comments
 (0)