Adding ClientId; Adding Teacher Panel to start/end event recording
parent
fb3d497aa3
commit
53d1767a2d
|
@ -12,9 +12,6 @@ dist
|
|||
# misc
|
||||
.DS_Store
|
||||
|
||||
# config
|
||||
config.json
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
"author": "Your Name",
|
||||
|
||||
"permissions": [
|
||||
"storage"
|
||||
"storage",
|
||||
"alarms"
|
||||
],
|
||||
|
||||
"host_permissions": [
|
||||
"http://localhost:5000/*"
|
||||
"http://localhost:5000/*",
|
||||
"https://zpdai.rkg.lv/*"
|
||||
],
|
||||
|
||||
"content_security_policy": {
|
||||
|
|
62
options.js
62
options.js
|
@ -1,3 +1,5 @@
|
|||
const browserAPI = typeof browser !== 'undefined' ? browser : chrome;
|
||||
|
||||
function saveOptions(event) {
|
||||
event.preventDefault();
|
||||
const serverUrl = document.querySelector("#server-url").value;
|
||||
|
@ -8,20 +10,62 @@ function saveOptions(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
browser.storage.sync.set({ serverUrl, password }).then(() => {
|
||||
const status = document.querySelector("#status");
|
||||
status.textContent = "Настройки сохранены!";
|
||||
setTimeout(() => (status.textContent = ""), 2000);
|
||||
if (typeof browser !== 'undefined') {
|
||||
browserAPI.storage.sync.set({ serverUrl, password })
|
||||
.then(() => {
|
||||
showStatus("Настройки сохранены!");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Ошибка сохранения настроек:", error);
|
||||
showStatus("Ошибка сохранения!", true);
|
||||
});
|
||||
} else {
|
||||
browserAPI.storage.sync.set({ serverUrl, password }, () => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error("Ошибка сохранения настроек:", chrome.runtime.lastError);
|
||||
showStatus("Ошибка сохранения!", true);
|
||||
} else {
|
||||
showStatus("Настройки сохранены!");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function restoreOptions() {
|
||||
browser.storage.sync.get(["serverUrl", "password"]).then((result) => {
|
||||
const serverUrl = result.serverUrl || "http://localhost:5000/submit";
|
||||
const password = result.password || "";
|
||||
document.querySelector("#server-url").value = serverUrl;
|
||||
document.querySelector("#password").value = password;
|
||||
if (typeof browser !== 'undefined') {
|
||||
browserAPI.storage.sync.get(["serverUrl", "password"])
|
||||
.then((result) => {
|
||||
updateFormFields(result);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Ошибка загрузки настроек:", error);
|
||||
updateFormFields({});
|
||||
});
|
||||
} else {
|
||||
browserAPI.storage.sync.get(["serverUrl", "password"], (result) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error("Ошибка загрузки настроек:", chrome.runtime.lastError);
|
||||
updateFormFields({});
|
||||
} else {
|
||||
updateFormFields(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateFormFields(result) {
|
||||
document.querySelector("#server-url").value = result.serverUrl || "http://localhost:5000/submit";
|
||||
document.querySelector("#password").value = result.password || "";
|
||||
}
|
||||
|
||||
function showStatus(message, isError = false) {
|
||||
const status = document.querySelector("#status");
|
||||
status.textContent = message;
|
||||
status.style.color = isError ? "red" : "green";
|
||||
setTimeout(() => {
|
||||
status.textContent = "";
|
||||
status.style.color = "";
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", restoreOptions);
|
||||
|
|
167
src/borderify.js
167
src/borderify.js
|
@ -1,8 +1,39 @@
|
|||
const browserAPI = typeof browser !== 'undefined' ? browser : chrome;
|
||||
|
||||
let serverUrl = "http://localhost:5000/submit";
|
||||
let password = "";
|
||||
let clientId = null;
|
||||
let isRecording = false;
|
||||
let checkInterval = null;
|
||||
let currentSessionId = null;
|
||||
|
||||
|
||||
function loadSettings() {
|
||||
return browser.storage.sync.get(["serverUrl", "password"]).then((result) => {
|
||||
return new Promise((resolve) => {
|
||||
if (typeof browser !== 'undefined') {
|
||||
browserAPI.storage.sync.get(["serverUrl", "password"])
|
||||
.then((result) => {
|
||||
processSettings(result);
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Ошибка загрузки настроек:", error);
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
browserAPI.storage.sync.get(["serverUrl", "password"], (result) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error("Ошибка загрузки настроек:", chrome.runtime.lastError);
|
||||
} else {
|
||||
processSettings(result);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function processSettings(result) {
|
||||
if (result.serverUrl) {
|
||||
serverUrl = result.serverUrl;
|
||||
console.log("URL сервера загружен из настроек:", serverUrl);
|
||||
|
@ -10,30 +41,35 @@ function loadSettings() {
|
|||
if (result.password) {
|
||||
password = result.password;
|
||||
console.log("Пароль загружен из настроек.");
|
||||
}
|
||||
}
|
||||
|
||||
function handleClientId() {
|
||||
if (typeof browser !== 'undefined') {
|
||||
browserAPI.storage.sync.get("clientId")
|
||||
.then((result) => {
|
||||
if (result.clientId) {
|
||||
clientId = result.clientId;
|
||||
console.log("ID клиента загружен:", clientId);
|
||||
} else {
|
||||
return fetch(browser.runtime.getURL("config.json"))
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Ошибка загрузки config.json: ${response.statusText}`);
|
||||
generateAndSaveId();
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(config => {
|
||||
serverUrl = config.FLASK_SERVER_URL;
|
||||
password = config.PASSWORD || password;
|
||||
console.log("URL сервера успешно загружен:", serverUrl);
|
||||
.catch(console.error);
|
||||
} else {
|
||||
browserAPI.storage.sync.get("clientId", (result) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error("Ошибка загрузки ID клиента:", chrome.runtime.lastError);
|
||||
} else if (result.clientId) {
|
||||
clientId = result.clientId;
|
||||
console.log("ID клиента загружен:", clientId);
|
||||
} else {
|
||||
generateAndSaveId();
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.error("Ошибка загрузки URL сервера:", error);
|
||||
});
|
||||
}
|
||||
|
||||
loadSettings();
|
||||
|
||||
|
||||
let clientId = null;
|
||||
|
||||
function generateUUID() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
||||
const r = (Math.random() * 16) | 0;
|
||||
|
@ -42,20 +78,55 @@ function generateUUID() {
|
|||
});
|
||||
}
|
||||
|
||||
browser.storage.sync.get("clientId").then((result) => {
|
||||
if (result.clientId) {
|
||||
clientId = result.clientId;
|
||||
console.log("ID клиента загружен:", clientId);
|
||||
} else {
|
||||
function generateAndSaveId() {
|
||||
clientId = generateUUID();
|
||||
browser.storage.sync.set({ clientId }).then(() => {
|
||||
if (typeof browser !== 'undefined') {
|
||||
browserAPI.storage.sync.set({ clientId })
|
||||
.then(() => console.log("ID клиента создан и сохранен:", clientId))
|
||||
.catch(console.error);
|
||||
} else {
|
||||
browserAPI.storage.sync.set({ clientId }, () => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error("Ошибка сохранения ID клиента:", chrome.runtime.lastError);
|
||||
} else {
|
||||
console.log("ID клиента создан и сохранен:", clientId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.error("Ошибка загрузки ID клиента:", error);
|
||||
}
|
||||
|
||||
|
||||
async function checkSessionStatus() {
|
||||
try {
|
||||
const statusUrl = 'http://127.0.0.1:5000/api/session_status';
|
||||
const response = await fetch(statusUrl, {
|
||||
headers: { 'X-Password': password }
|
||||
});
|
||||
|
||||
const { active, session_id } = await response.json();
|
||||
|
||||
if (active && !isRecording) {
|
||||
startRecording(session_id);
|
||||
} else if (!active && isRecording) {
|
||||
stopRecording();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка проверки сессии:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function startRecording(sessionId) {
|
||||
isRecording = true;
|
||||
currentSessionId = sessionId;
|
||||
console.log('Запись действий начата для сессии:', sessionId);
|
||||
}
|
||||
|
||||
function stopRecording() {
|
||||
isRecording = false;
|
||||
currentSessionId = null;
|
||||
console.log('Запись действий остановлена');
|
||||
}
|
||||
|
||||
|
||||
function createEventJSON(eventType, data) {
|
||||
const timeStamp = new Date().toISOString();
|
||||
|
@ -71,10 +142,8 @@ function createEventJSON(eventType, data) {
|
|||
|
||||
|
||||
async function sendDataToServer(eventData) {
|
||||
if (!serverUrl || !password) {
|
||||
console.error("URL сервера или пароль не заданы. Проверьте настройки.");
|
||||
return;
|
||||
}
|
||||
if (!isRecording || !serverUrl || !password) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(serverUrl, {
|
||||
method: 'POST',
|
||||
|
@ -82,7 +151,10 @@ async function sendDataToServer(eventData) {
|
|||
'Content-Type': 'application/json',
|
||||
'X-Password': password,
|
||||
},
|
||||
body: JSON.stringify(eventData),
|
||||
body: JSON.stringify({
|
||||
...eventData,
|
||||
session_id: currentSessionId
|
||||
})
|
||||
});
|
||||
|
||||
const responseData = await response.json();
|
||||
|
@ -96,8 +168,24 @@ async function sendDataToServer(eventData) {
|
|||
}
|
||||
}
|
||||
|
||||
function debounce(func, delay) {
|
||||
let timeout;
|
||||
return function(...args) {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => func(...args), delay);
|
||||
};
|
||||
}
|
||||
|
||||
async function initialize() {
|
||||
await loadSettings();
|
||||
handleClientId();
|
||||
|
||||
checkInterval = setInterval(checkSessionStatus, 5000);
|
||||
checkSessionStatus();
|
||||
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (!isRecording) return;
|
||||
const key = event.key;
|
||||
const code = event.code;
|
||||
let description;
|
||||
|
@ -119,22 +207,16 @@ document.addEventListener("keydown", (event) => {
|
|||
|
||||
|
||||
document.addEventListener("mousedown", (event) => {
|
||||
if (!isRecording) return;
|
||||
const eventData = createEventJSON('mousedown', { button: event.button, description: `Клик мышью: ${event.button}` });
|
||||
console.log("Событие mousedown:", JSON.stringify(eventData));
|
||||
sendDataToServer(eventData);
|
||||
});
|
||||
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return function(...args) {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => func.apply(this, args), wait);
|
||||
};
|
||||
}
|
||||
|
||||
let accumulatedPixels = 0;
|
||||
|
||||
const handleWheel = debounce((event) => {
|
||||
if (!isRecording) return;
|
||||
const direction = accumulatedPixels > 0 ? "вниз" : "вверх";
|
||||
const pixels = Math.abs(accumulatedPixels);
|
||||
|
||||
|
@ -145,9 +227,10 @@ const handleWheel = debounce((event) => {
|
|||
accumulatedPixels = 0;
|
||||
}, 200);
|
||||
|
||||
document.addEventListener("wheel", (event) => { accumulatedPixels += event.deltaY; handleWheel(event);});
|
||||
document.addEventListener("wheel", (event) => { if (!isRecording) return; accumulatedPixels += event.deltaY; handleWheel(event);});
|
||||
|
||||
document.addEventListener("click", (event) => {
|
||||
if (!isRecording) return;
|
||||
const eventType = 'click';
|
||||
const clickedElement = event.target;
|
||||
const tag = clickedElement.tagName;
|
||||
|
@ -187,6 +270,7 @@ function navigateWithPromise(href) {
|
|||
|
||||
|
||||
document.addEventListener("copy", (event) => {
|
||||
if (!isRecording) return;
|
||||
const selectedText = window.getSelection().toString();
|
||||
|
||||
let outputText = selectedText.length > 50 ? selectedText.substring(0, 49) + '…' : selectedText;
|
||||
|
@ -197,3 +281,6 @@ document.addEventListener("copy", (event) => {
|
|||
sendDataToServer(eventData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initialize();
|
Loading…
Reference in New Issue