Skip to content

Commit fcf7103

Browse files
Evin JohnEvin John
authored andcommitted
update v3.5
1 parent d340bd5 commit fcf7103

File tree

7 files changed

+446
-85
lines changed

7 files changed

+446
-85
lines changed

chrome-extension/ai-studio-sparkle.js

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -662,14 +662,20 @@
662662
} catch (error) {
663663
console.error('Threadly: Error refining prompt:', error);
664664

665-
// Dispatch error event
666-
window.dispatchEvent(new CustomEvent('threadly-prompt-refine-error', {
667-
detail: {
668-
platform: 'ai-studio',
669-
error: error.message,
670-
originalText: currentText
671-
}
672-
}));
665+
// Handle extension context invalidation specifically
666+
if (error.message.includes('Extension context invalidated')) {
667+
// Show a user-friendly notification
668+
showContextInvalidatedNotification();
669+
} else {
670+
// Dispatch error event for other errors
671+
window.dispatchEvent(new CustomEvent('threadly-prompt-refine-error', {
672+
detail: {
673+
platform: 'ai-studio',
674+
error: error.message,
675+
originalText: currentText
676+
}
677+
}));
678+
}
673679

674680
} finally {
675681
// Stop animation and end at fade out state
@@ -1212,6 +1218,72 @@
12121218
});
12131219
}
12141220

1221+
// Function to show context invalidated notification
1222+
function showContextInvalidatedNotification() {
1223+
// Create notification element
1224+
const notification = document.createElement('div');
1225+
notification.style.cssText = `
1226+
position: fixed;
1227+
top: 20px;
1228+
right: 20px;
1229+
background: #ff6b6b;
1230+
color: white;
1231+
padding: 16px 20px;
1232+
border-radius: 8px;
1233+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
1234+
z-index: 10000;
1235+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1236+
font-size: 14px;
1237+
max-width: 300px;
1238+
cursor: pointer;
1239+
animation: slideInRight 0.3s ease-out;
1240+
`;
1241+
1242+
notification.innerHTML = `
1243+
<div style="font-weight: 600; margin-bottom: 4px;">🔄 Threadly Extension Updated</div>
1244+
<div style="font-size: 13px; opacity: 0.9;">Please refresh the page to continue using the refine feature.</div>
1245+
`;
1246+
1247+
// Add animation keyframes
1248+
if (!document.getElementById('threadly-notification-styles')) {
1249+
const style = document.createElement('style');
1250+
style.id = 'threadly-notification-styles';
1251+
style.textContent = `
1252+
@keyframes slideInRight {
1253+
from { transform: translateX(100%); opacity: 0; }
1254+
to { transform: translateX(0); opacity: 1; }
1255+
}
1256+
@keyframes slideOutRight {
1257+
from { transform: translateX(0); opacity: 1; }
1258+
to { transform: translateX(100%); opacity: 0; }
1259+
}
1260+
`;
1261+
document.head.appendChild(style);
1262+
}
1263+
1264+
// Add click handler to refresh page
1265+
notification.addEventListener('click', () => {
1266+
notification.style.animation = 'slideOutRight 0.3s ease-in forwards';
1267+
setTimeout(() => {
1268+
window.location.reload();
1269+
}, 300);
1270+
});
1271+
1272+
// Auto-remove after 10 seconds
1273+
setTimeout(() => {
1274+
if (notification.parentNode) {
1275+
notification.style.animation = 'slideOutRight 0.3s ease-in forwards';
1276+
setTimeout(() => {
1277+
if (notification.parentNode) {
1278+
notification.remove();
1279+
}
1280+
}, 300);
1281+
}
1282+
}, 10000);
1283+
1284+
document.body.appendChild(notification);
1285+
}
1286+
12151287
// Initialize only if on AI Studio's website
12161288
if (isAIStudioWebsite()) {
12171289
if (document.readyState === 'loading') {

chrome-extension/api-handler.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ class PromptRefiner {
8686

8787
async initialize() {
8888
try {
89+
// Check if chrome.storage is available (extension context not invalidated)
90+
if (!chrome || !chrome.storage || !chrome.storage.local) {
91+
console.error('Threadly: Extension context invalidated. Please refresh the page.');
92+
throw new Error('Extension context invalidated. Please refresh the page to continue using Threadly.');
93+
}
94+
8995
const result = await chrome.storage.local.get(['geminiApiKey']);
9096
this.apiKey = result.geminiApiKey;
9197

@@ -95,6 +101,12 @@ class PromptRefiner {
95101
return !!this.apiKey;
96102
} catch (error) {
97103
console.error('Failed to initialize PromptRefiner:', error);
104+
105+
// If it's a context invalidation error, provide a helpful message
106+
if (error.message.includes('Extension context invalidated')) {
107+
throw error; // Re-throw to be handled by the calling code
108+
}
109+
98110
return false;
99111
}
100112
}

chrome-extension/claude-icon.js

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,12 @@
516516
}
517517
} catch (error) {
518518
console.error('Threadly: Error processing prompt:', error);
519+
520+
// Handle extension context invalidation specifically
521+
if (error.message.includes('Extension context invalidated')) {
522+
// Show a user-friendly notification
523+
showContextInvalidatedNotification();
524+
}
519525
} finally {
520526
stopClickAnimationSequence(sparkleElement);
521527
}
@@ -614,14 +620,20 @@
614620
} catch (error) {
615621
console.error('Threadly: Error refining prompt:', error);
616622

617-
// Dispatch error event
618-
window.dispatchEvent(new CustomEvent('threadly-prompt-refine-error', {
619-
detail: {
620-
platform: 'claude',
621-
error: error.message,
622-
originalText: currentText
623-
}
624-
}));
623+
// Handle extension context invalidation specifically
624+
if (error.message.includes('Extension context invalidated')) {
625+
// Show a user-friendly notification
626+
showContextInvalidatedNotification();
627+
} else {
628+
// Dispatch error event for other errors
629+
window.dispatchEvent(new CustomEvent('threadly-prompt-refine-error', {
630+
detail: {
631+
platform: 'claude',
632+
error: error.message,
633+
originalText: currentText
634+
}
635+
}));
636+
}
625637

626638
} finally {
627639
// Stop animation and end at fade out state
@@ -961,6 +973,72 @@
961973
});
962974
}
963975

976+
// Function to show context invalidated notification
977+
function showContextInvalidatedNotification() {
978+
// Create notification element
979+
const notification = document.createElement('div');
980+
notification.style.cssText = `
981+
position: fixed;
982+
top: 20px;
983+
right: 20px;
984+
background: #ff6b6b;
985+
color: white;
986+
padding: 16px 20px;
987+
border-radius: 8px;
988+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
989+
z-index: 10000;
990+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
991+
font-size: 14px;
992+
max-width: 300px;
993+
cursor: pointer;
994+
animation: slideInRight 0.3s ease-out;
995+
`;
996+
997+
notification.innerHTML = `
998+
<div style="font-weight: 600; margin-bottom: 4px;">🔄 Threadly Extension Updated</div>
999+
<div style="font-size: 13px; opacity: 0.9;">Please refresh the page to continue using the refine feature.</div>
1000+
`;
1001+
1002+
// Add animation keyframes
1003+
if (!document.getElementById('threadly-notification-styles')) {
1004+
const style = document.createElement('style');
1005+
style.id = 'threadly-notification-styles';
1006+
style.textContent = `
1007+
@keyframes slideInRight {
1008+
from { transform: translateX(100%); opacity: 0; }
1009+
to { transform: translateX(0); opacity: 1; }
1010+
}
1011+
@keyframes slideOutRight {
1012+
from { transform: translateX(0); opacity: 1; }
1013+
to { transform: translateX(100%); opacity: 0; }
1014+
}
1015+
`;
1016+
document.head.appendChild(style);
1017+
}
1018+
1019+
// Add click handler to refresh page
1020+
notification.addEventListener('click', () => {
1021+
notification.style.animation = 'slideOutRight 0.3s ease-in forwards';
1022+
setTimeout(() => {
1023+
window.location.reload();
1024+
}, 300);
1025+
});
1026+
1027+
// Auto-remove after 10 seconds
1028+
setTimeout(() => {
1029+
if (notification.parentNode) {
1030+
notification.style.animation = 'slideOutRight 0.3s ease-in forwards';
1031+
setTimeout(() => {
1032+
if (notification.parentNode) {
1033+
notification.remove();
1034+
}
1035+
}, 300);
1036+
}
1037+
}, 10000);
1038+
1039+
document.body.appendChild(notification);
1040+
}
1041+
9641042
// Initialize only if on Claude's website
9651043
if (isClaudeWebsite()) {
9661044
if (document.readyState === 'loading') {

0 commit comments

Comments
 (0)