1.0.2
Cette révision appartient à :
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
.idea
|
.idea
|
||||||
src/src.zip
|
ytptube-extension.zip
|
||||||
@@ -1,5 +1,15 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 1.0.2 - 2025-08-12
|
||||||
|
|
||||||
|
- **Fixed**: Selected preset was not being sent to YTPTube API - now properly includes preset in requests
|
||||||
|
- **Fixed**: Output template and download folder were not being sent - now automatically includes configured template and folder options
|
||||||
|
- **Added**: Loading indicator with Bulma's built-in spinner for better user feedback during requests
|
||||||
|
- **Added**: Status messages in popup showing success/error feedback after sending URLs
|
||||||
|
- **Added**: Button disabling during request processing to prevent multiple submissions
|
||||||
|
- **Improved**: Enhanced error handling and user feedback throughout the extension
|
||||||
|
|
||||||
|
|
||||||
## 1.0.1 - 2025-05-28
|
## 1.0.1 - 2025-05-28
|
||||||
|
|
||||||
- Fix issue prevent adding urls via Chromium browsers.
|
- Fix issue prevent adding urls via Chromium browsers.
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
zip_file="ytptube-extension.zip"
|
||||||
|
extension_dir="./src"
|
||||||
|
if [ -f "$zip_file" ]; then
|
||||||
|
echo "Removing existing zip file: $zip_file"
|
||||||
|
rm "$zip_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
IGNORE_FILES=(
|
||||||
|
"*.git*"
|
||||||
|
"*.vscode*"
|
||||||
|
"*.idea*"
|
||||||
|
"*.DS_Store"
|
||||||
|
"node_modules/*"
|
||||||
|
"dist/*"
|
||||||
|
"build/*"
|
||||||
|
"screenshots/*"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "Creating zip file: $zip_file"
|
||||||
|
|
||||||
|
# The zip file should contain the contents of the src directory not the directory itself
|
||||||
|
(
|
||||||
|
cd "$extension_dir" || exit 1
|
||||||
|
zip -r "../$zip_file" . -x "${IGNORE_FILES[@]}"
|
||||||
|
)
|
||||||
|
|
||||||
+48
-13
@@ -83,17 +83,39 @@ const sendRequest = async (path, data) => {
|
|||||||
return {status: req.status, statusText: req.statusText, data: req};
|
return {status: req.status, statusText: req.statusText, data: req};
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendUrl = async user_url => {
|
const sendUrl = async (user_url, preset = null) => {
|
||||||
try {
|
try {
|
||||||
const data = await sendRequest('/api/history', {url: user_url});
|
const requestData = {url: user_url};
|
||||||
|
if (preset) {
|
||||||
|
requestData.preset = preset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add template and folder if configured
|
||||||
|
const template = await getOption("template");
|
||||||
|
if (template) {
|
||||||
|
requestData.template = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
const folder = await getOption("folder");
|
||||||
|
if (folder) {
|
||||||
|
requestData.folder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug('Sending request data:', requestData);
|
||||||
|
|
||||||
|
const data = await sendRequest('/api/history', requestData);
|
||||||
if (200 === data.status) {
|
if (200 === data.status) {
|
||||||
notify('Request sent successfully.');
|
notify('Request sent successfully.');
|
||||||
return
|
return { success: true, message: 'Request sent successfully.' };
|
||||||
}
|
}
|
||||||
notify(`Failed to send request. '${data.status}: ${data.statusText}'.`);
|
const errorMessage = `Failed to send request. '${data.status}: ${data.statusText}'.`;
|
||||||
|
notify(errorMessage);
|
||||||
|
return { success: false, message: errorMessage };
|
||||||
}catch (e) {
|
}catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
notify(`Failed to send request. '${e.message}'.`);
|
const errorMessage = `Failed to send request. '${e.message}'.`;
|
||||||
|
notify(errorMessage);
|
||||||
|
return { success: false, message: errorMessage };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,22 +128,35 @@ chrome.contextMenus.onClicked.addListener(async (info, _) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendUrl(info.linkUrl);
|
// Get the default preset for context menu actions
|
||||||
|
const defaultPreset = await getOption("preset");
|
||||||
|
await sendUrl(info.linkUrl, defaultPreset);
|
||||||
});
|
});
|
||||||
|
|
||||||
chrome.runtime.onMessage.addListener(async (message) => {
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
if (message.command !== "send-to-ytptube") {
|
if (message.command !== "send-to-ytptube") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = message.url || await getCurrentUrl();
|
(async () => {
|
||||||
|
try {
|
||||||
|
let url = message.url || await getCurrentUrl();
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
await notify('No url found');
|
await notify('No url found');
|
||||||
return;
|
sendResponse({ success: false, message: 'No url found' });
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await sendUrl(url);
|
const result = await sendUrl(url, message.preset);
|
||||||
|
sendResponse(result);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error in message handler:', error);
|
||||||
|
sendResponse({ success: false, message: error.message });
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
return true; // Keep the messaging channel open for async response
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"name": "YTPTube Extension",
|
"name": "YTPTube Extension",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"description": "Add URLs to YTPTube instance",
|
"description": "Add URLs to YTPTube instance",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"activeTab",
|
"activeTab",
|
||||||
|
|||||||
@@ -28,7 +28,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="field is-grouped">
|
<div class="field is-grouped">
|
||||||
<div class="control is-expanded">
|
<div class="control is-expanded">
|
||||||
<button class="button is-primary is-fullwidth" type="submit">Send to YTPTube</button>
|
<button id="submit-btn" class="button is-primary is-fullwidth" type="submit">
|
||||||
|
Send to YTPTube
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="control is-expanded">
|
<div class="control is-expanded">
|
||||||
<button class="button is-info is-fullwidth" type="button" id="go-to-options">
|
<button class="button is-info is-fullwidth" type="button" id="go-to-options">
|
||||||
@@ -36,6 +38,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="status-message" class="notification is-hidden" style="margin-top: 10px;"></div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+44
-4
@@ -3,12 +3,12 @@
|
|||||||
const $ = s => document.querySelector(s)
|
const $ = s => document.querySelector(s)
|
||||||
|
|
||||||
if (typeof chrome === 'undefined') {
|
if (typeof chrome === 'undefined') {
|
||||||
let chrome = browser
|
let chrome = browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOption = async (key, default_data) => {
|
const getOption = async (key, default_data) => {
|
||||||
let item = await chrome.storage.sync.get(key);
|
let item = await chrome.storage.sync.get(key);
|
||||||
return item[key] ?? default_data;
|
return item[key] || default_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const notify = message => chrome.notifications.create({
|
const notify = message => chrome.notifications.create({
|
||||||
@@ -18,15 +18,55 @@ const notify = message => chrome.notifications.create({
|
|||||||
"message": message
|
"message": message
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const showLoading = (isLoading) => {
|
||||||
|
const submitBtn = $('#submit-btn')
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
submitBtn.disabled = true
|
||||||
|
submitBtn.classList.add('is-loading')
|
||||||
|
} else {
|
||||||
|
submitBtn.disabled = false
|
||||||
|
submitBtn.classList.remove('is-loading')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const showStatusMessage = (message, isSuccess = true) => {
|
||||||
|
const statusDiv = $('#status-message')
|
||||||
|
statusDiv.textContent = message
|
||||||
|
statusDiv.className = `notification ${isSuccess ? 'is-success' : 'is-danger'}`
|
||||||
|
statusDiv.classList.remove('is-hidden')
|
||||||
|
|
||||||
|
// Hide the message after 3 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
statusDiv.classList.add('is-hidden')
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
|
||||||
$("#ytptube_popup").addEventListener("submit", async (e) => {
|
$("#ytptube_popup").addEventListener("submit", async (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const url = $('#user_url').value
|
const url = $('#user_url').value
|
||||||
|
const preset = $('#preset').value
|
||||||
if (!url) {
|
if (!url) {
|
||||||
notify('URL is required.')
|
showStatusMessage('URL is required.', false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await chrome.runtime.sendMessage({command: 'send-to-ytptube', url: url})
|
showLoading(true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await chrome.runtime.sendMessage({command: 'send-to-ytptube', url: url, preset: preset})
|
||||||
|
|
||||||
|
if (response && response.success) {
|
||||||
|
showStatusMessage('Request sent successfully!', true)
|
||||||
|
} else {
|
||||||
|
showStatusMessage(response?.message || 'Failed to send request.', false)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
showStatusMessage('Error sending request.', false)
|
||||||
|
console.error('Error:', error)
|
||||||
|
} finally {
|
||||||
|
showLoading(false)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const getCurrentUrl = async () => (await chrome.tabs.query({currentWindow: true, active: true}))[0].url
|
const getCurrentUrl = async () => (await chrome.tabs.query({currentWindow: true, active: true}))[0].url
|
||||||
|
|||||||
Référencer dans un nouveau ticket
Bloquer un utilisateur