Skip to content

Commit

Permalink
Add select dom feature
Browse files Browse the repository at this point in the history
  • Loading branch information
philffm committed Jul 7, 2024
1 parent 1cf508f commit 228fe09
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 35 deletions.
6 changes: 4 additions & 2 deletions bookmarklet-generator/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
</head>
<body>
<div class="container">
<h1>Bookmarklet Generator</h1>
<label for="apiKey">API Key:</label>
<h1>AI Summary Helper</h1>
<h2>Bookmarklet Generator</h2>
<label for="apiKey">API Key: </label>
<input type="text" id="apiKey" placeholder="Enter your OpenAI API Key">
<label class="light" for="apiKey">Disclaimer: We are not saving your token. The token is stored locally on your device.</label>
<label for="prompt">Prompt:</label>
<textarea id="prompt">
<h3> Article summary section with creative title explaining the article in simple terms.
Expand Down
117 changes: 84 additions & 33 deletions bookmarklet-generator/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,91 @@ document.addEventListener('DOMContentLoaded', () => {
const apiKey = '${apiKey}';
const prompt = \`${prompt}\`;
const content = document.body.innerText;
fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Summarize in valid HTML format with sections:' + prompt },
{ role: 'user', content: content }
]
})
})
.then(response => response.json())
.then(result => {
const summary = result.choices[0].message.content;
const summaryContainer = document.createElement('blockquote');
summaryContainer.innerHTML = '<div><h2>AI Summary 🧙</h2>' + summary.replace(/\\n\\n/g, '<br>') + '</div>';
// Find the main content block and the last <h1> element
const mainContentBlock = document.querySelector('main') || document.body;
const lastH1 = mainContentBlock.querySelectorAll('h1');
if (lastH1.length > 0) {
lastH1[lastH1.length - 1].insertAdjacentElement('afterend', summaryContainer);
} else {
mainContentBlock.prepend(summaryContainer);
// Inject styles
const style = document.createElement('style');
style.innerHTML = \`
#ai-summary-message {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #007bff;
color: white;
text-align: center;
padding: 10px 0;
z-index: 10000;
font-size: 18px;
font-weight: bold;
animation: pulsate 1s infinite;
}
@keyframes pulsate {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.hover-effect {
outline: 2px dashed #007bff;
}
})
.catch(error => {
console.error('Error:', error);
alert('Error fetching summary. Check the console for details.');
});
\`;
document.head.appendChild(style);
const messageDiv = document.createElement('div');
messageDiv.id = 'ai-summary-message';
messageDiv.textContent = 'Click on the element where you want to insert the summary.';
document.body.prepend(messageDiv);
document.body.style.cursor = 'crosshair';
function hoverHandler(event) {
event.target.classList.toggle('hover-effect');
}
document.addEventListener('mouseover', hoverHandler);
document.addEventListener('mouseout', hoverHandler);
document.addEventListener('click', function handler(event) {
event.preventDefault();
event.stopPropagation();
document.body.style.cursor = 'default';
const targetElement = event.target;
document.removeEventListener('click', handler);
document.removeEventListener('mouseover', hoverHandler);
document.removeEventListener('mouseout', hoverHandler);
messageDiv.textContent = 'Retrieving summary...';
fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Summarize in valid HTML format with sections:' + prompt },
{ role: 'user', content: content }
]
})
})
.then(response => response.json())
.then(result => {
const summary = result.choices[0].message.content;
const summaryContainer = document.createElement('blockquote');
summaryContainer.innerHTML = '<div><h2>AI Summary 🧙</h2>' + summary.replace(/\\n\\n/g, '<br>') + '</div>';
targetElement.insertAdjacentElement('afterend', summaryContainer);
messageDiv.remove();
})
.catch(error => {
console.error('Error:', error);
alert('Error fetching summary. Check the console for details.');
messageDiv.remove();
});
}, { once: true });
})();
`;

Expand Down
4 changes: 4 additions & 0 deletions bookmarklet-generator/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ body {
margin: 15px 0 5px;
color: #007bff;
}
.light{
color: #333;
}
input, textarea {
width: 100%;
padding: 10px;
Expand Down Expand Up @@ -58,4 +61,5 @@ body {
border-radius: 4px;
border: 1px solid #ccc;
}


22 changes: 22 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# AI Summary Helper
![Icon](chrome-extension/icons/icon128.png)

I often stumble over articles online I might want to read later. Before I used to open the tab "for later" up until a point when I had 100 tabs open and eventually lost track of them all at a certain point.

With the summary helper I created a tool that allows to summarize articles with a custom prompt - so it can be as tailored to your language and profession or interested as you define it. The summary gets inserted in the content area itself. This was important to me since that way I can easily forward the artice including the generated summary to my Kindle device using Reabbles Send-to-Kindle tool.

<On the go I am way more likely to engage with the content I intentionally selected earlier.

## Overview

This project includes two components:
Expand All @@ -22,3 +28,19 @@ This project includes two components:
### Bookmarklet Generator

1. Navigate to the `bookmarklet-generator` directory and follow the instructions in the `readme.md`.


## Feature Agenda 🚀

### Browser Plugin

### Bookmarklet Generator
[x] Save API Key in Browser
[] iOS compatibility (press to add?)
[] Select dom element by clicking
- "Where sould summary be insertd
[] Add status state
- pulsating "Talking to god"
- Spinner
- Blurred

0 comments on commit 228fe09

Please sign in to comment.