mirror of
https://github.com/michivonah/click-guide.git
synced 2025-12-22 22:16:28 +01:00
add meta data to guide & improve error handling
This commit is contained in:
parent
1fcbe7b968
commit
b574265e65
5 changed files with 108 additions and 36 deletions
|
|
@ -12,10 +12,11 @@ Similar to tango.us/dubble.so/folge.me/magichow.co but all local - no data leave
|
||||||
- [x] create basic popup UI
|
- [x] create basic popup UI
|
||||||
|
|
||||||
### Additional nice to have:
|
### Additional nice to have:
|
||||||
|
- [x] Meta data in guide (title, description, author, date)
|
||||||
- [ ] Viewer for Guide JSON
|
- [ ] Viewer for Guide JSON
|
||||||
- [ ] PDF export
|
- [ ] PDF export
|
||||||
- [ ] Editor for Guide
|
- [ ] Editor for Guide
|
||||||
- [ ] improve error handling
|
- [x] improve error handling
|
||||||
- [ ] Blur sensitive information
|
- [ ] Blur sensitive information
|
||||||
- [x] Pause/resume recording feature
|
- [x] Pause/resume recording feature
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,19 @@
|
||||||
// Background Worker
|
// Background Worker
|
||||||
|
|
||||||
|
const dateToday = new Date().toISOString().split('T')[0];
|
||||||
|
|
||||||
|
let guide = {
|
||||||
|
"title":"Guide",
|
||||||
|
"description":"",
|
||||||
|
"date":dateToday,
|
||||||
|
"author":"Me",
|
||||||
|
};
|
||||||
let steps = [];
|
let steps = [];
|
||||||
|
|
||||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
switch(message.action){
|
switch(message.action){
|
||||||
case "captureScreenshot":
|
case "captureScreenshot":
|
||||||
|
try{
|
||||||
chrome.tabs.captureVisibleTab(null, { format: "jpeg" }, (dataUrl) => {
|
chrome.tabs.captureVisibleTab(null, { format: "jpeg" }, (dataUrl) => {
|
||||||
if (chrome.runtime.lastError) {
|
if (chrome.runtime.lastError) {
|
||||||
console.error("Error capturing screenshot: ", chrome.runtime.lastError);
|
console.error("Error capturing screenshot: ", chrome.runtime.lastError);
|
||||||
|
|
@ -15,6 +24,10 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
sendResponse({ success: true, screenshot: dataUrl });
|
sendResponse({ success: true, screenshot: dataUrl });
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
catch(error){
|
||||||
|
return sendResponse({ success: false, message: error });
|
||||||
|
}
|
||||||
case "saveStep":
|
case "saveStep":
|
||||||
try{
|
try{
|
||||||
const step = {
|
const step = {
|
||||||
|
|
@ -31,14 +44,35 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
return sendResponse({ success: false, message: error });
|
return sendResponse({ success: false, message: error });
|
||||||
}
|
}
|
||||||
case "generateGuide":
|
case "generateGuide":
|
||||||
return sendResponse({ success: true, guide: steps });
|
try{
|
||||||
|
let filename = "guide.json";
|
||||||
|
chrome.storage.local.get(["guideTitle", "exportFilename"], (data) => {
|
||||||
|
if(data.guideTitle) guide.title = `Guide: ${data.guideTitle}`;
|
||||||
|
if(data.exportFilename) filename = `guide-${data.exportFilename}.json`;
|
||||||
|
guide.steps = steps;
|
||||||
|
return sendResponse({ success: true, guide: guide, filename: filename });
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(error){
|
||||||
|
return sendResponse({ success: false, message: error });
|
||||||
|
}
|
||||||
case "clearGuide":
|
case "clearGuide":
|
||||||
|
try{
|
||||||
steps = [];
|
steps = [];
|
||||||
return sendResponse({ success: true, message: "Cleared guide successfully" });
|
return sendResponse({ success: true, message: "Cleared guide successfully" });
|
||||||
|
}
|
||||||
|
catch(error){
|
||||||
|
return sendResponse({ success: false, message: error });
|
||||||
|
}
|
||||||
case "guideLenght":
|
case "guideLenght":
|
||||||
|
try{
|
||||||
count = steps.length;
|
count = steps.length;
|
||||||
return sendResponse({ success: true, stepCount: count });
|
return sendResponse({ success: true, stepCount: count });
|
||||||
case "debug":
|
}
|
||||||
|
catch(error){
|
||||||
|
return sendResponse({ success: false, message: error });
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
console.log(message.action);
|
console.log(message.action);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,22 @@
|
||||||
// Script which is executed on all web pages
|
// Script which is executed on all web pages
|
||||||
|
|
||||||
|
// Page meta data
|
||||||
|
const pageTitle = document.title;
|
||||||
|
const domainFormatted = window.location.host.replace(/\./g, "-");
|
||||||
|
|
||||||
|
// set guide title
|
||||||
|
chrome.storage.local.get("guideTitle", (data) => {
|
||||||
|
if(!data.guideTitle){
|
||||||
|
try{
|
||||||
|
chrome.storage.local.set({ guideTitle: pageTitle });
|
||||||
|
chrome.storage.local.set({ exportFilename: domainFormatted });
|
||||||
|
}
|
||||||
|
catch(error){
|
||||||
|
console.error(`Error while saving guide metadata: ${error}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// load recording status & react to updates
|
// load recording status & react to updates
|
||||||
let isRecording = false;
|
let isRecording = false;
|
||||||
chrome.storage.local.get("recording", (data) => {
|
chrome.storage.local.get("recording", (data) => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Cl1ck Gu1de",
|
"name": "Cl1ck Gu1de",
|
||||||
"version": "0.0.3",
|
"version": "0.0.4",
|
||||||
"description": "A browser add-on which records the steps clicked on a page and generates a easy to understand guide from it.",
|
"description": "A browser add-on which records the steps clicked on a page and generates a easy to understand guide from it.",
|
||||||
"permissions": ["scripting", "activeTab", "downloads", "tabs", "storage"],
|
"permissions": ["scripting", "activeTab", "downloads", "tabs", "storage"],
|
||||||
"host_permissions": ["<all_urls>"],
|
"host_permissions": ["<all_urls>"],
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
let isRecording = false;
|
let isRecording = false;
|
||||||
chrome.storage.local.get("recording", (data) => {
|
chrome.storage.local.get("recording", (data) => {
|
||||||
isRecording = data.recording || false;
|
isRecording = data.recording || false;
|
||||||
console.log(data);
|
|
||||||
updateRecordingLabel(isRecording);
|
updateRecordingLabel(isRecording);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -13,10 +12,14 @@ const toggleRecordingBtn = document.getElementById("toggleRecording");
|
||||||
const exportBtn = document.getElementById("exportBtn");
|
const exportBtn = document.getElementById("exportBtn");
|
||||||
|
|
||||||
toggleRecordingBtn.addEventListener('click', () => {
|
toggleRecordingBtn.addEventListener('click', () => {
|
||||||
//if(isRecording) chrome.runtime.sendMessage({action: "clearGuide"});
|
try{
|
||||||
isRecording = !isRecording; // toggle status
|
isRecording = !isRecording; // toggle status
|
||||||
updateRecordingLabel(isRecording); // update label
|
updateRecordingLabel(isRecording); // update label
|
||||||
chrome.storage.local.set({ recording: isRecording }); // save status
|
chrome.storage.local.set({ recording: isRecording }); // save status
|
||||||
|
}
|
||||||
|
catch(error){
|
||||||
|
console.error(`Got error on toggling recording: ${error}`)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
exportBtn.addEventListener('click', () => {
|
exportBtn.addEventListener('click', () => {
|
||||||
|
|
@ -24,8 +27,14 @@ exportBtn.addEventListener('click', () => {
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage({
|
||||||
action: "generateGuide"
|
action: "generateGuide"
|
||||||
}, (response) => {
|
}, (response) => {
|
||||||
|
if(response.success){
|
||||||
const guide = response.guide;
|
const guide = response.guide;
|
||||||
exportJSON(guide, "guide.json");
|
const filename = response.filename;
|
||||||
|
return exportJSON(guide, filename);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.error(`Failed to export guide: ${response.message} `);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -48,6 +57,7 @@ function updateRecordingLabel(bool){
|
||||||
|
|
||||||
// export guide as json
|
// export guide as json
|
||||||
function exportJSON(object, filename){
|
function exportJSON(object, filename){
|
||||||
|
try{
|
||||||
const json = JSON.stringify(object, null, 2);
|
const json = JSON.stringify(object, null, 2);
|
||||||
|
|
||||||
const blob = new Blob([json], { type: "application/json" });
|
const blob = new Blob([json], { type: "application/json" });
|
||||||
|
|
@ -59,7 +69,17 @@ function exportJSON(object, filename){
|
||||||
link.click();
|
link.click();
|
||||||
|
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
catch(error){
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try{
|
||||||
// clear guide
|
// clear guide
|
||||||
chrome.runtime.sendMessage({action: "clearGuide"});
|
return chrome.runtime.sendMessage({action: "clearGuide"});
|
||||||
|
}
|
||||||
|
catch(error){
|
||||||
|
return error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue