switch to bulma and remove pure css, improve the messaging

Cette révision appartient à :
arabcoders
2025-05-23 01:45:24 +03:00
Parent 7d32fd8340
révision bf8c0f3d44
7 fichiers modifiés avec 25031 ajouts et 173 suppressions
+29 -36
Voir le fichier
@@ -49,17 +49,17 @@ const getOption = async key => {
}
}
const sendRequest = async user_url => {
const instanceUrl = await getOption("instance_url");
const sendRequest = async (path, data) => {
let instanceUrl = await getOption("instance_url");
if (!instanceUrl) {
notify('YTPTube instance url not configured.');
return;
throw new Error('YTPTube instance url not configured.');
}
if (instanceUrl.endsWith('/')) {
instanceUrl = instanceUrl.slice(0, -1);
}
let headers = {};
let data = {
url: user_url,
}
const auth_username = await getOption("username");
const auth_password = await getOption("password");
@@ -67,41 +67,34 @@ const sendRequest = async user_url => {
headers['Authorization'] = 'Basic ' + btoa(`${auth_username}:${auth_password}`);
}
const preset = await getOption("preset");
if (preset) {
data['preset'] = preset;
}
const template = await getOption("template");
if (template) {
data['template'] = template;
}
const folder = await getOption("folder");
if (folder) {
data['folder'] = folder;
}
const url = new URL(instanceUrl);
url.pathname = path;
console.debug(`Sending to '${instanceUrl}'.`, data, headers.length > 0 ? 'with auth header' : 'without auth header');
const url = new URL(instanceUrl);
url.pathname = '/api/history';
let opts = {method: data.length > 0 ? 'POST' : 'GET', headers: headers};
const req = await fetch(url, {
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
if (data) {
opts.headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(data);
}
if (200 === req.status) {
const req = await fetch(url, opts);
return {status: req.status, statusText: req.statusText, data: req};
};
const sendUrl = async user_url => {
try {
const data = await sendRequest('/api/history', {url: user_url});
if (200 === data.status) {
notify('Request sent successfully.');
return
}
notify(`Failed to send request. '${req.status}: ${req.statusText}'.`);
notify(`Failed to send request. '${data.status}: ${data.statusText}'.`);
}catch (e) {
console.error(e);
notify(`Failed to send request. '${e.message}'.`);
}
};
chrome.contextMenus.onClicked.addListener(async (info, _) => {
@@ -113,7 +106,7 @@ chrome.contextMenus.onClicked.addListener(async (info, _) => {
return;
}
await sendRequest(info.linkUrl);
await sendUrl(info.linkUrl);
});
chrome.runtime.onMessage.addListener(async (message) => {
@@ -128,7 +121,7 @@ chrome.runtime.onMessage.addListener(async (message) => {
return;
}
await sendRequest(url);
await sendUrl(url);
});
+24826
Voir le fichier
Fichier diff supprimé car celui-ci est trop grand Voir la Diff
-11
Voir le fichier
Diff de fichier supprimé car une ou plusieurs lignes sont trop longues
+4 -1
Voir le fichier
@@ -7,7 +7,7 @@
]
},
"name": "YTPTube Extension",
"version": "0.0.3",
"version": "1.0.0",
"description": "Add URLs to YTPTube instance",
"permissions": [
"activeTab",
@@ -41,5 +41,8 @@
"id": "ytptube@arabcoders.org",
"strict_min_version": "113.0"
}
},
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self';"
}
}
+58 -51
Voir le fichier
@@ -4,75 +4,82 @@
<head>
<meta charset="utf-8">
<title>Options menu for YTPTube Extension</title>
<link rel="stylesheet" href="css/pure.css"/>
<style>
@media (prefers-color-scheme: dark) {
body {
color: white;
background-color: #19191c;
}
input {
background-color: #19191c;
color: white;
}
fieldset > legend {
color: white !important;
}
}
</style>
<link rel="stylesheet" href="css/bulma.css"/>
</head>
<body>
<form id="ytptube_options" class="pure-form pure-form-stacked">
<fieldset style="padding:1em">
<legend>Settings</legend>
<div class="pure-control-group">
<label for="instance_url">YTPTube URL</label>
<input type="text" class="pure-input-1" id="instance_url" placeholder="https://ytptube.example.org">
<span class="pure-form-message">URL to your YTPTube instance</span><br>
<body class="container">
<div class="columns is-multiline">
<div class="column is-12">
<form id="ytptube_options" class="content m-1">
<div class="field">
<label class="label" for="instance_url">YTPTube URL</label>
<div class="control">
<input type="text" class="input" id="instance_url" placeholder="https://ytptube.example.org">
</div>
<span class="help">URL to your YTPTube instance</span>
</div>
<div class="pure-control-group">
<label for="preset">Preset</label>
<input type="text" class="pure-input-1" id="preset" placeholder="Leave empty to use default preset.">
<span class="pure-form-message">Preset to use for the URL</span><br>
<div class="field">
<label class="label" for="preset">Preset</label>
<div class="control">
<input type="text" class="input" id="preset" placeholder="Leave empty to use default preset.">
</div>
<span class="help">Preset to use for the URL</span>
</div>
<div class="pure-control-group">
<label for="template">Output Template</label>
<input type="text" class="pure-input-1" id="template"
<div class="field">
<label class="label" for="template">Output Template</label>
<div class="control">
<input type="text" class="input" id="template"
placeholder="Leave empty to use default output template.">
<span class="pure-form-message">Filename template to use for the output file.</span><br>
</div>
<span class="help">Filename template to use for the output file.</span>
</div>
<div class="pure-control-group">
<label for="folder">Download Folder</label>
<input type="text" class="pure-input-1" id="folder" placeholder="Leave empty to use default download path.">
<span class="pure-form-message">Where to save downloaded files.</span><br>
<div class="field">
<label class="label" for="folder">Download Folder</label>
<div class="control">
<input type="text" class="input" id="folder"
placeholder="Leave empty to use default download path.">
</div>
<span class="help">Where to save downloaded files.</span>
</div>
<div class="pure-control-group">
<label for="username">Auth Username</label>
<input type="text" class="pure-input-1" id="username"
placeholder="Leave empty if you have not configured a authentication.">
<span class="pure-form-message">Username to use for authentication.</span><br>
<div class="field">
<label class="label" for="username">Auth Username</label>
<div class="control">
<input type="text" class="input" id="username" placeholder="Auth username">
</div>
<span class="help">Leave empty if you have not configured a authentication.</span>
</div>
<div class="pure-control-group">
<label for="password">Auth Password</label>
<input type="password" class="pure-input-1" id="password"
placeholder="Leave empty if you have not configured a authentication.">
<span class="pure-form-message">Password to use for authentication.</span><br>
<div class="field">
<label class="label" for="password">Auth Password</label>
<div class="control">
<input type="password" class="input" id="password" placeholder="Auth Password">
</div>
<span class="help">Leave empty if you have not configured a authentication.</span>
</div>
<label for="showContextMenu">
<label class="checkbox mb-1" for="showContextMenu">
<input type="checkbox" id="showContextMenu"/> Show context menu in supported sites
</label><br>
</label>
<button class="pure-button pure-input-1 pure-button-primary" type="submit">Save</button>
</fieldset>
<div class="field has-text-danger">
<p id="error_msg"></p>
</div>
<div class="field is-grouped">
<div class="control is-expanded">
<button class="button is-primary is-fullwidth" type="submit">Save</button>
</div>
<div class="control is-expanded">
<button class="button is-info is-fullwidth" type="button" id="test_config">Test</button>
</div>
</div>
</form>
</div>
</div>
<script src="options.js"></script>
</body>
+70 -8
Voir le fichier
@@ -3,10 +3,63 @@
const str_keys = ["instance_url", "preset", "template", "folder", "username", "password"]
if (typeof chrome === 'undefined') {
// noinspection JSUnusedLocalSymbols
let chrome = browser
}
const notify = (message, no_inline) => {
if (!no_inline) {
document.querySelector('#error_msg').innerText = message;
}
chrome.notifications.create({
"type": "basic",
"iconUrl": chrome.runtime.getURL("icons/icon-128.png"),
"title": 'YTPTube Extension',
"message": message,
});
}
const testConfig = async () => {
document.querySelector('#error_msg').innerText = "";
let instance_url = document.querySelector("#instance_url").value;
if (!instance_url) {
notify("Please enter a valid YTPTube instance URL.");
return false;
}
if (instance_url.endsWith('/')) {
instance_url = instance_url.slice(0, -1);
}
let username = document.querySelector("#username").value;
let password = document.querySelector("#password").value;
let headers = {}
if (username && password) {
headers['Authorization'] = 'Basic ' + btoa(username + ':' + password);
}
try {
const req = await fetch(`${instance_url}/api/ping`, {
method: 'GET',
headers: headers
});
if (200 === req.status) {
notify("Connection successful.", true);
return true;
}
const json = await req.json();
notify(json.error ?? "Unknown error.");
} catch (e) {
notify("Error: " + e);
}
return false;
}
document.addEventListener("DOMContentLoaded", () => {
function onError(error) {
console.log(`Error: ${error}`);
@@ -19,9 +72,13 @@ document.addEventListener("DOMContentLoaded", () => {
chrome.storage.sync.get("showContextMenu").then(r => document.querySelector("#showContextMenu").checked = r.showContextMenu || false);
});
document.getElementById("ytptube_options").addEventListener("submit", (e) => {
document.getElementById("ytptube_options").addEventListener("submit", async e => {
e.preventDefault();
if (false === (await testConfig())) {
return false;
}
let showContextMenu = document.querySelector("#showContextMenu").checked;
let data = {presets: {presets: ['default'], last_updated: 0}}
@@ -31,12 +88,17 @@ document.getElementById("ytptube_options").addEventListener("submit", (e) => {
chrome.storage.sync.set(data);
chrome.contextMenus.update("send-to-ytptube", {visible: showContextMenu});
chrome.notifications.create({
"type": "basic",
"iconUrl": chrome.runtime.getURL("icons/icon-128.png"),
"title": 'YTPTube Extension',
"message": "Options saved."
notify("Options saved.", true);
setTimeout(() => {
try {
window.close()
} catch (e) {
}
}, 1000);
});
setTimeout(() => window.close(), 1000);
document.getElementById("test_config").addEventListener("click", async e => {
e.preventDefault();
await testConfig();
});
+25 -47
Voir le fichier
@@ -3,64 +3,42 @@
<head>
<meta charset="UTF-8">
<title>YTPTube Extension</title>
<link rel="stylesheet" href="css/pure.css"/>
<style>
#ytptube_popup {
min-width: 250px;
min-height: 120px;
margin: 1em;
}
body {
font-size: 100%;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background-color: #19191c;
}
input {
background-color: #19191c;
color: white;
}
fieldset > legend {
color: white !important;
}
}
.button-secondary {
background: rgb(66, 184, 221);
}
</style>
<link rel="stylesheet" href="css/bulma.css"/>
</head>
<body>
<body class="container">
<form id="ytptube_popup" class="pure-form pure-form-stacked">
<div class="pure-control-group">
<label for="preset">Preset</label>
<select id="preset" class="pure-input-1" style="padding-top:0;padding-bottom:0">
<div class="columns is-multiline">
<div class="column is-12">
<form id="ytptube_popup" class="pl-2 pr-2 pt-2">
<div class="field">
<label class="label" for="preset">Preset</label>
<div class="select is-fullwidth">
<select id="preset" class="is-fullwidth">
<option value="default">default</option>
</select>
<span class="pure-form-message">Select preset to use with the URL.</span>
</div>
<div class="pure-control-group">
<label for="user_url">URL:</label>
<input id="user_url" class="pure-input-1" type="text" placeholder="https://..">
<span class="pure-form-message">The URL to send to YTPTube instance</span>
<span class="help">Select preset to use with the URL.</span>
</div>
<div class="pure-control-group">
<button class="pure-button pure-input-1 pure-button-primary" type="submit">Send to YTPTube</button>
<div class="field">
<label class="label" for="user_url">URL:</label>
<div class="control">
<input id="user_url" class="input" type="text" placeholder="https://..">
</div>
<br>
<div class="pure-control-group">
<button class="pure-button pure-input-1 button-secondary" type="button" id="go-to-options">
<span class="help">The URL to send.</span>
</div>
<div class="field is-grouped">
<div class="control is-expanded">
<button class="button is-primary is-fullwidth" type="submit">Send to YTPTube</button>
</div>
<div class="control is-expanded">
<button class="button is-info is-fullwidth" type="button" id="go-to-options">
Open options page
</button>
</div>
</div>
</form>
</div>
</div>
<script src="popup.js"></script>