prettier formatage

This commit is contained in:
yoannchb-pro
2024-02-28 19:07:19 -05:00
parent 8c364e286b
commit 6a5e1eb8c3
40 changed files with 1666 additions and 1295 deletions
+418 -1
View File
File diff suppressed because one or more lines are too long
+26 -26
View File
@@ -1,26 +1,26 @@
{
"manifest_version": 3,
"name": "MoodleGPT",
"version": "1.0.4",
"description": "Hidden chat-gpt for your moodle quiz",
"permissions": ["storage"],
"action": {
"default_icon": "icon.png",
"default_popup": "./popup/index.html"
},
"icons": {
"16": "icon.png",
"32": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"content_scripts": [
{
"matches": ["*://*/**/mod/quiz/*", "*://*/mod/quiz/*", "file:///*"],
"js": ["MoodleGPT.js"],
"run_at": "document_end"
}
]
}
{
"manifest_version": 3,
"name": "MoodleGPT",
"version": "1.0.4",
"description": "Hidden chat-gpt for your moodle quiz",
"permissions": ["storage"],
"action": {
"default_icon": "icon.png",
"default_popup": "./popup/index.html"
},
"icons": {
"16": "icon.png",
"32": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"content_scripts": [
{
"matches": ["*://*/**/mod/quiz/*", "*://*/mod/quiz/*", "file:///*"],
"js": ["MoodleGPT.js"],
"run_at": "document_end"
}
]
}
+148 -154
View File
@@ -1,154 +1,148 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MoodleGPT</title>
<link rel="stylesheet" href="style.css" />
<!-- Should always be at the top -->
<script src="./js/utils.js" defer></script>
<script src="./js/index.js" defer></script>
<script src="./js/modeHandler.js" defer></script>
<script src="./js/gptVersion.js" defer></script>
<script src="./js/version.js" defer></script>
<link rel="icon" type="image/png" href="../icon.png" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
</head>
<body>
<main>
<div class="line center" style="margin-top: 1rem; margin-bottom: 1rem">
<a
target="_blank"
rel="noopener noreferrer"
href="https://www.flaticon.com/free-icons/mortarboard"
title="Mortarboard icons created by itim2101 - Flaticon"
><img src="../icon.png" alt="icon"
/></a>
<div class="col center title">
<h1>MoodleGPT</h1>
<p id="version"></p>
</div>
</div>
<div class="line center">
<label for="apiKey" class="textLabel"
>Api Key<span class="required">*</span>:</label
>
<input id="apiKey" type="text" />
</div>
<div class="line center">
<label for="model" class="textLabel"
>GPT Model<span class="required">*</span>:</label
>
<input id="model" type="text" />
<i
id="reloadModel"
class="fa-solid fa-rotate-right"
disabled
title="Provide an api key first"
></i>
</div>
<div class="line center">
<label for="code" class="textLabel">Code:</label>
<input id="code" type="text" />
</div>
<div class="line mt">
<i class="fa-solid fa-robot"></i>
<p>Mode:</p>
</div>
<div class="line">
<ul id="mode" class="line center">
<li><button value="autocomplete">autocomplete</button></li>
<li>
<button value="clipboard" class="not-selected">clipboard</button>
</li>
<li>
<button value="question-to-answer" class="not-selected">
question to answer
</button>
</li>
</ul>
</div>
<div class="line mt">
<i class="fa-solid fa-gear"></i>
<p>Settings:</p>
</div>
<div class="line center" style="gap: 2rem">
<div class="col">
<div class="line">
<input id="logs" type="checkbox" />
<label for="logs">Console logs</label>
</div>
<div class="line">
<input id="title" type="checkbox" checked />
<label for="title">Title indication</label>
</div>
<div class="line">
<input id="cursor" type="checkbox" checked />
<label for="cursor">Cursor indication</label>
</div>
<div class="line">
<input id="timeout" type="checkbox" checked />
<label for="timeout">Request timeout</label>
</div>
</div>
<div class="col">
<div class="line">
<input id="typing" type="checkbox" />
<label for="typing">Typing effect</label>
</div>
<div class="line">
<input id="mouseover" type="checkbox" />
<label for="mouseover">Mouseover effect</label>
</div>
<div class="line">
<input id="infinite" type="checkbox" />
<label for="infinite">Infinite try</label>
</div>
<div class="line">
<input id="history" type="checkbox" />
<label for="history">Save history</label>
</div>
</div>
</div>
<p id="message">Message</p>
<div class="line center">
<button class="save">Save</button>
</div>
<div class="line center">
<a
href="https://www.buymeacoffee.com/yoannchbpro"
target="_blank"
rel="noopener noreferrer"
>
Donate
</a>
<a
href="https://github.com/yoannchb-pro/MoodleGPT"
target="_blank"
rel="noopener noreferrer"
>
See the documentation
</a>
<a
href="https://github.com/yoannchb-pro/MoodleGPT/issues"
target="_blank"
rel="noopener noreferrer"
>
Need Help
</a>
</div>
</main>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MoodleGPT</title>
<link rel="stylesheet" href="style.css" />
<!-- Should always be at the top -->
<script src="./js/utils.js" defer></script>
<script src="./js/index.js" defer></script>
<script src="./js/modeHandler.js" defer></script>
<script src="./js/gptVersion.js" defer></script>
<script src="./js/version.js" defer></script>
<link rel="icon" type="image/png" href="../icon.png" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
</head>
<body>
<main>
<div class="line center" style="margin-top: 1rem; margin-bottom: 1rem">
<a
target="_blank"
rel="noopener noreferrer"
href="https://www.flaticon.com/free-icons/mortarboard"
title="Mortarboard icons created by itim2101 - Flaticon"
><img src="../icon.png" alt="icon"
/></a>
<div class="col center title">
<h1>MoodleGPT</h1>
<p id="version"></p>
</div>
</div>
<div class="line center">
<label for="apiKey" class="textLabel">Api Key<span class="required">*</span>:</label>
<input id="apiKey" type="text" />
</div>
<div class="line center">
<label for="model" class="textLabel">GPT Model<span class="required">*</span>:</label>
<input id="model" type="text" />
<i
id="reloadModel"
class="fa-solid fa-rotate-right"
disabled
title="Provide an api key first"
></i>
</div>
<div class="line center">
<label for="code" class="textLabel">Code:</label>
<input id="code" type="text" />
</div>
<div class="line mt">
<i class="fa-solid fa-robot"></i>
<p>Mode:</p>
</div>
<div class="line">
<ul id="mode" class="line center">
<li><button value="autocomplete">autocomplete</button></li>
<li>
<button value="clipboard" class="not-selected">clipboard</button>
</li>
<li>
<button value="question-to-answer" class="not-selected">question to answer</button>
</li>
</ul>
</div>
<div class="line mt">
<i class="fa-solid fa-gear"></i>
<p>Settings:</p>
</div>
<div class="line center" style="gap: 2rem">
<div class="col">
<div class="line">
<input id="logs" type="checkbox" />
<label for="logs">Console logs</label>
</div>
<div class="line">
<input id="title" type="checkbox" checked />
<label for="title">Title indication</label>
</div>
<div class="line">
<input id="cursor" type="checkbox" checked />
<label for="cursor">Cursor indication</label>
</div>
<div class="line">
<input id="timeout" type="checkbox" checked />
<label for="timeout">Request timeout</label>
</div>
</div>
<div class="col">
<div class="line">
<input id="typing" type="checkbox" />
<label for="typing">Typing effect</label>
</div>
<div class="line">
<input id="mouseover" type="checkbox" />
<label for="mouseover">Mouseover effect</label>
</div>
<div class="line">
<input id="infinite" type="checkbox" />
<label for="infinite">Infinite try</label>
</div>
<div class="line">
<input id="history" type="checkbox" />
<label for="history">Save history</label>
</div>
</div>
</div>
<p id="message">Message</p>
<div class="line center">
<button class="save">Save</button>
</div>
<div class="line center">
<a
href="https://www.buymeacoffee.com/yoannchbpro"
target="_blank"
rel="noopener noreferrer"
>
Donate
</a>
<a
href="https://github.com/yoannchb-pro/MoodleGPT"
target="_blank"
rel="noopener noreferrer"
>
See the documentation
</a>
<a
href="https://github.com/yoannchb-pro/MoodleGPT/issues"
target="_blank"
rel="noopener noreferrer"
>
Need Help
</a>
</div>
</main>
</body>
</html>
+15 -15
View File
@@ -1,49 +1,49 @@
"use strict";
'use strict';
/**
* Get the last ChatGPT version
*/
function getLastChatGPTVersion() {
const apiKeySelector = document.querySelector("#apiKey");
const reloadModel = document.querySelector("#reloadModel");
const apiKeySelector = document.querySelector('#apiKey');
const reloadModel = document.querySelector('#reloadModel');
let apiKey = apiKeySelector.value;
// If the api key is set we enable the button to get the last chatgpt version
function checkFiledApiKey() {
if (apiKey) {
reloadModel.removeAttribute("disabled");
reloadModel.setAttribute("title", "Get last ChatGPT version");
reloadModel.removeAttribute('disabled');
reloadModel.setAttribute('title', 'Get last ChatGPT version');
return;
}
reloadModel.setAttribute("disabled", true);
reloadModel.setAttribute("title", "Provide an api key first");
reloadModel.setAttribute('disabled', true);
reloadModel.setAttribute('title', 'Provide an api key first');
}
checkFiledApiKey();
// Check if the api key is set
apiKeySelector.addEventListener("input", function () {
apiKeySelector.addEventListener('input', function () {
apiKey = apiKeySelector.value.trim();
checkFiledApiKey();
});
// Event listener to handle a click on the relaod icon button
reloadModel.addEventListener("click", async function () {
reloadModel.addEventListener('click', async function () {
if (!apiKey) return;
try {
const req = await fetch("https://api.openai.com/v1/models", {
const req = await fetch('https://api.openai.com/v1/models', {
headers: {
Authorization: `Bearer ${apiKey}`,
},
Authorization: `Bearer ${apiKey}`
}
});
const rep = await req.json();
const model = rep.data.find((model) => model.id.startsWith("gpt"));
document.querySelector("#model").value = model.id;
const model = rep.data.find(model => model.id.startsWith('gpt'));
document.querySelector('#model').value = model.id;
} catch (err) {
console.error(err);
showMessage({ msg: "Failed to fetch last ChatGPT version", error: true });
showMessage({ msg: 'Failed to fetch last ChatGPT version', error: true });
}
});
}
+31 -34
View File
@@ -1,38 +1,39 @@
const saveBtn = document.querySelector(".save");
const saveBtn = document.querySelector('.save');
/* inputs id */
const inputsText = ["apiKey", "code", "model"];
const inputsText = ['apiKey', 'code', 'model'];
const inputsCheckbox = [
"logs",
"title",
"cursor",
"typing",
"mouseover",
"infinite",
"timeout",
"history",
'logs',
'title',
'cursor',
'typing',
'mouseover',
'infinite',
'timeout',
'history'
];
/* Save the configuration */
saveBtn.addEventListener("click", function () {
const [apiKey, code, model] = inputsText.map((selector) =>
document.querySelector("#" + selector).value.trim()
saveBtn.addEventListener('click', function () {
const [apiKey, code, model] = inputsText.map(selector =>
document.querySelector('#' + selector).value.trim()
);
const [logs, title, cursor, typing, mouseover, infinite, timeout, history] = inputsCheckbox.map(
selector => {
const element = document.querySelector('#' + selector);
return element.checked && element.parentElement.style.display !== 'none';
}
);
const [logs, title, cursor, typing, mouseover, infinite, timeout, history] =
inputsCheckbox.map((selector) => {
const element = document.querySelector("#" + selector);
return element.checked && element.parentElement.style.display !== "none";
});
if (!apiKey || !model) {
showMessage({ msg: "Please complete all the form", error: true });
showMessage({ msg: 'Please complete all the form', error: true });
return;
}
if (code.length > 0 && code.length < 3) {
showMessage({
msg: "The code should at least contain 3 characters",
error: true,
msg: 'The code should at least contain 3 characters',
error: true
});
return;
}
@@ -50,15 +51,15 @@ saveBtn.addEventListener("click", function () {
infinite,
timeout,
history,
mode: actualMode,
},
mode: actualMode
}
});
showMessage({ msg: "Configuration saved" });
showMessage({ msg: 'Configuration saved' });
});
/* we load back the configuration */
chrome.storage.sync.get(["moodleGPT"]).then(function (storage) {
chrome.storage.sync.get(['moodleGPT']).then(function (storage) {
const config = storage.moodleGPT;
if (config) {
@@ -66,21 +67,17 @@ chrome.storage.sync.get(["moodleGPT"]).then(function (storage) {
actualMode = config.mode;
for (const mode of modes) {
if (mode.value === config.mode) {
mode.classList.remove("not-selected");
mode.classList.remove('not-selected');
} else {
mode.classList.add("not-selected");
mode.classList.add('not-selected');
}
}
}
inputsText.forEach((key) =>
config[key]
? (document.querySelector("#" + key).value = config[key])
: null
);
inputsCheckbox.forEach(
(key) => (document.querySelector("#" + key).checked = config[key] || "")
inputsText.forEach(key =>
config[key] ? (document.querySelector('#' + key).value = config[key]) : null
);
inputsCheckbox.forEach(key => (document.querySelector('#' + key).checked = config[key] || ''));
}
handleModeChange();
+12 -14
View File
@@ -1,15 +1,15 @@
"use strict";
'use strict';
const mode = document.querySelector("#mode");
const modes = mode.querySelectorAll("button");
const mode = document.querySelector('#mode');
const modes = mode.querySelectorAll('button');
let actualMode = "autocomplete";
let actualMode = 'autocomplete';
/* inputs id that need to be disabled for a specific mode */
const disabledForThisMode = {
autocomplete: [],
clipboard: ["typing", "mouseover"],
"question-to-answer": ["typing", "infinite", "mouseover"],
clipboard: ['typing', 'mouseover'],
'question-to-answer': ['typing', 'infinite', 'mouseover']
};
/**
@@ -17,27 +17,25 @@ const disabledForThisMode = {
*/
function handleModeChange() {
const needDisable = disabledForThisMode[actualMode];
const dontNeedDisable = inputsCheckbox.filter(
(input) => !needDisable.includes(input)
);
const dontNeedDisable = inputsCheckbox.filter(input => !needDisable.includes(input));
for (const id of needDisable) {
document.querySelector("#" + id).parentElement.style.display = "none";
document.querySelector('#' + id).parentElement.style.display = 'none';
}
for (const id of dontNeedDisable) {
document.querySelector("#" + id).parentElement.style.display = null;
document.querySelector('#' + id).parentElement.style.display = null;
}
}
/* Mode handler */
for (const button of modes) {
button.addEventListener("click", function () {
button.addEventListener('click', function () {
const value = button.value;
actualMode = value;
for (const mode of modes) {
if (mode.value !== value) {
mode.classList.add("not-selected");
mode.classList.add('not-selected');
} else {
mode.classList.remove("not-selected");
mode.classList.remove('not-selected');
}
}
handleModeChange();
+5 -5
View File
@@ -1,12 +1,12 @@
"use strict";
'use strict';
/**
* Show message into the popup
*/
function showMessage({ msg, error, infinite }) {
const message = document.querySelector("#message");
message.style.color = error ? "red" : "limegreen";
const message = document.querySelector('#message');
message.style.color = error ? 'red' : 'limegreen';
message.textContent = msg;
message.style.display = "block";
if (!infinite) setTimeout(() => (message.style.display = "none"), 5000);
message.style.display = 'block';
if (!infinite) setTimeout(() => (message.style.display = 'none'), 5000);
}
+15 -18
View File
@@ -1,7 +1,7 @@
"use strict";
'use strict';
const CURRENT_VERSION = "1.0.4";
const versionDisplay = document.querySelector("#version");
const CURRENT_VERSION = '1.0.4';
const versionDisplay = document.querySelector('#version');
/**
* Get the last version from the github
@@ -9,7 +9,7 @@ const versionDisplay = document.querySelector("#version");
*/
async function getLastVersion() {
const req = await fetch(
"https://raw.githubusercontent.com/yoannchb-pro/MoodleGPT/main/package.json"
'https://raw.githubusercontent.com/yoannchb-pro/MoodleGPT/main/package.json'
);
const rep = await req.json();
return rep.version;
@@ -23,34 +23,31 @@ async function getLastVersion() {
*/
function setVersion(version, isCurrent = true) {
if (isCurrent) {
versionDisplay.textContent = "v" + version;
versionDisplay.textContent = 'v' + version;
return;
}
const link = document.createElement("a");
link.href = "https://github.com/yoannchb-pro/MoodleGPT";
link.rel = "noopener noreferrer";
link.target = "_blank";
link.textContent = "v" + version;
const link = document.createElement('a');
link.href = 'https://github.com/yoannchb-pro/MoodleGPT';
link.rel = 'noopener noreferrer';
link.target = '_blank';
link.textContent = 'v' + version;
versionDisplay.appendChild(link);
versionDisplay.appendChild(document.createTextNode(" is now available !"));
versionDisplay.appendChild(document.createTextNode(' is now available !'));
}
/**
* Check if the extension neeed an update or not
*/
async function notifyUpdate() {
const lastVersion = await getLastVersion().catch((err) => {
const lastVersion = await getLastVersion().catch(err => {
console.error(err);
return CURRENT_VERSION;
});
const lastVertionSplitted = lastVersion.split(".");
const currentVersionSplitted = CURRENT_VERSION.split(".");
const minVersionLength = Math.min(
lastVertionSplitted.length,
currentVersionSplitted.length
);
const lastVertionSplitted = lastVersion.split('.');
const currentVersionSplitted = CURRENT_VERSION.split('.');
const minVersionLength = Math.min(lastVertionSplitted.length, currentVersionSplitted.length);
for (let i = 0; i < minVersionLength; ++i) {
if (parseInt(lastVertionSplitted[i]) > parseInt(currentVersionSplitted[i]))
+146 -146
View File
@@ -1,146 +1,146 @@
@font-face {
font-family: Segeo UI;
src: url(../../fonts/Segoe\ UI.ttf);
}
:root {
--bg-color: #121212;
--color: #fff;
--btn-color: #7f39fb;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: "Segeo UI", sans-serif;
color: var(--color);
}
body {
min-height: 100vh;
background-color: var(--bg-color);
display: flex;
justify-content: center;
align-items: center;
}
main {
display: flex;
flex-direction: column;
align-items: center;
padding: 0.75rem;
gap: 0.4rem;
text-align: center;
width: 22rem;
}
img {
width: 5rem;
}
a {
color: var(--btn-color);
margin: 0;
}
.line {
display: flex;
flex-direction: row;
width: 100%;
gap: 0.5rem;
}
.center {
justify-content: center;
align-items: center;
}
.line .textLabel {
width: 5rem;
text-align: left;
text-transform: uppercase;
}
.line .textLabel .required {
color: var(--btn-color);
font-weight: bold;
}
.line input[type="text"],
.line input[type="password"] {
flex: 1 1;
border: thin solid var(--color);
padding: 0.3rem 0.5rem;
border-radius: 0.2rem;
outline-color: transparent;
background-color: transparent;
}
.line input[type="checkbox"] {
accent-color: var(--btn-color);
}
.col {
display: flex;
flex-direction: column;
text-align: left;
}
.save {
border: none;
background-color: var(--btn-color);
padding: 0.5rem 2rem;
margin-top: 1rem;
cursor: pointer;
border-radius: 0.2rem;
font-size: 1.5rem;
margin-bottom: 0.75rem;
}
.mt {
margin-top: 1rem;
}
.not-selected {
opacity: 0.4;
}
#mode li {
list-style: none;
flex-grow: 1;
}
#mode {
flex-wrap: wrap;
}
#mode button {
background-color: var(--btn-color);
border: none;
text-align: center;
padding: 0.3rem 0.75rem;
cursor: pointer;
width: 100%;
border-radius: 0.5rem;
text-transform: uppercase;
}
#version {
font-size: 0.75rem;
}
#message {
display: none;
margin-top: 0.75rem;
margin-bottom: -0.25rem;
}
#reloadModel {
cursor: pointer;
}
#reloadModel[disabled] {
cursor: not-allowed;
opacity: 0.75;
}
@font-face {
font-family: Segeo UI;
src: url(../../fonts/Segoe\ UI.ttf);
}
:root {
--bg-color: #121212;
--color: #fff;
--btn-color: #7f39fb;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: 'Segeo UI', sans-serif;
color: var(--color);
}
body {
min-height: 100vh;
background-color: var(--bg-color);
display: flex;
justify-content: center;
align-items: center;
}
main {
display: flex;
flex-direction: column;
align-items: center;
padding: 0.75rem;
gap: 0.4rem;
text-align: center;
width: 22rem;
}
img {
width: 5rem;
}
a {
color: var(--btn-color);
margin: 0;
}
.line {
display: flex;
flex-direction: row;
width: 100%;
gap: 0.5rem;
}
.center {
justify-content: center;
align-items: center;
}
.line .textLabel {
width: 5rem;
text-align: left;
text-transform: uppercase;
}
.line .textLabel .required {
color: var(--btn-color);
font-weight: bold;
}
.line input[type='text'],
.line input[type='password'] {
flex: 1 1;
border: thin solid var(--color);
padding: 0.3rem 0.5rem;
border-radius: 0.2rem;
outline-color: transparent;
background-color: transparent;
}
.line input[type='checkbox'] {
accent-color: var(--btn-color);
}
.col {
display: flex;
flex-direction: column;
text-align: left;
}
.save {
border: none;
background-color: var(--btn-color);
padding: 0.5rem 2rem;
margin-top: 1rem;
cursor: pointer;
border-radius: 0.2rem;
font-size: 1.5rem;
margin-bottom: 0.75rem;
}
.mt {
margin-top: 1rem;
}
.not-selected {
opacity: 0.4;
}
#mode li {
list-style: none;
flex-grow: 1;
}
#mode {
flex-wrap: wrap;
}
#mode button {
background-color: var(--btn-color);
border: none;
text-align: center;
padding: 0.3rem 0.75rem;
cursor: pointer;
width: 100%;
border-radius: 0.5rem;
text-transform: uppercase;
}
#version {
font-size: 0.75rem;
}
#message {
display: none;
margin-top: 0.75rem;
margin-bottom: -0.25rem;
}
#reloadModel {
cursor: pointer;
}
#reloadModel[disabled] {
cursor: not-allowed;
opacity: 0.75;
}