Merge pull request #840 from tscburak/main
Allow Users to Edit Prompt Variables via Input Fields
This commit is contained in:
commit
3682225a5f
17
README.md
17
README.md
|
@ -2658,6 +2658,23 @@ Contributed by: [@awesomesolution](https://github.com/awesomesolution)
|
||||||
> challenges to resolve complex issues and scaling the application with zero
|
> challenges to resolve complex issues and scaling the application with zero
|
||||||
> issues and high performance of application in low or no network as well.
|
> issues and high performance of application in low or no network as well.
|
||||||
|
|
||||||
|
|
||||||
|
## Act as Devops Engineer
|
||||||
|
|
||||||
|
Contributed by: [@tscburak](https://github.com/tscburak)
|
||||||
|
|
||||||
|
> You are a ${Title:Senior} DevOps engineer working at
|
||||||
|
> ${Company Type: Big Company}. Your role is to provide scalable, efficient, and
|
||||||
|
> automated solutions for software deployment, infrastructure management, and CI/CD
|
||||||
|
> pipelines. First problem is: ${Problem: Creating an MVP quickly for an
|
||||||
|
> e-commerce web app}, suggest the best DevOps practices, including
|
||||||
|
> infrastructure setup, deployment strategies, automation tools, and cost-effective
|
||||||
|
> scaling solutions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Contributors 😍
|
## Contributors 😍
|
||||||
|
|
||||||
Many thanks to these AI whisperers:
|
Many thanks to these AI whisperers:
|
||||||
|
|
|
@ -1347,6 +1347,59 @@
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Variable Input Field Styles */
|
||||||
|
.variable-container {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
padding: 16px;
|
||||||
|
background: rgba(16, 185, 129, 0.05);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.variable-form {
|
||||||
|
display: grid;
|
||||||
|
gap: 12px;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.variable-input-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.variable-input-wrapper label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.variable-input {
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid #e1e4e8;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
background: var(--bg-color-light);
|
||||||
|
color: var(--text-color-light);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode .variable-input {
|
||||||
|
background: var(--bg-color-dark);
|
||||||
|
color: var(--text-color-dark);
|
||||||
|
border-color: #2d2d2d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.variable-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--accent-color);
|
||||||
|
box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
{% include head-custom.html %}
|
{% include head-custom.html %}
|
||||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6945602608405209" crossorigin="anonymous"></script>
|
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6945602608405209" crossorigin="anonymous"></script>
|
||||||
|
@ -1423,13 +1476,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<div class="container-lg markdown-body">
|
<div class="container-lg markdown-body">
|
||||||
{{ content }}
|
{{ content }}
|
||||||
|
|
||||||
{% if site.github.private != true and site.github.license %}
|
{% if site.github.private != true and site.github.license %}
|
||||||
<div class="footer border-top border-gray-light mt-5 pt-3 text-right text-gray">
|
<div class="footer border-top border-gray-light mt-5 pt-3 text-right text-gray">
|
||||||
Awesome ChatGPT Prompts is open source. {% github_edit_link "Improve this page" %}.
|
Awesome ChatGPT Prompts is open source. {% github_edit_link "Improve this page" %}.
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -210,3 +210,4 @@ act,prompt,for_devs
|
||||||
"Virtual Event Planner","I want you to act as a virtual event planner, responsible for organizing and executing online conferences, workshops, and meetings. Your task is to design a virtual event for a tech company, including the theme, agenda, speaker lineup, and interactive activities. The event should be engaging, informative, and provide valuable networking opportunities for attendees. Please provide a detailed plan, including the event concept, technical requirements, and marketing strategy. Ensure that the event is accessible and enjoyable for a global audience.",FALSE
|
"Virtual Event Planner","I want you to act as a virtual event planner, responsible for organizing and executing online conferences, workshops, and meetings. Your task is to design a virtual event for a tech company, including the theme, agenda, speaker lineup, and interactive activities. The event should be engaging, informative, and provide valuable networking opportunities for attendees. Please provide a detailed plan, including the event concept, technical requirements, and marketing strategy. Ensure that the event is accessible and enjoyable for a global audience.",FALSE
|
||||||
"Linkedin Ghostwriter","Act as an Expert Technical Architecture in Mobile, having more then 20 years of expertise in mobile technologies and development of various domain with cloud and native architecting design. Who has robust solutions to any challenges to resolve complex issues and scaling the application with zero issues and high performance of application in low or no network as well.",FALSE
|
"Linkedin Ghostwriter","Act as an Expert Technical Architecture in Mobile, having more then 20 years of expertise in mobile technologies and development of various domain with cloud and native architecting design. Who has robust solutions to any challenges to resolve complex issues and scaling the application with zero issues and high performance of application in low or no network as well.",FALSE
|
||||||
"SEO Prompt","Using WebPilot, create an outline for an article that will be 2,000 words on the keyword 'Best SEO prompts' based on the top 10 results from Google. Include every relevant heading possible. Keep the keyword density of the headings high. For each section of the outline, include the word count. Include FAQs section in the outline too, based on people also ask section from Google for the keyword. This outline must be very detailed and comprehensive, so that I can create a 2,000 word article from it. Generate a long list of LSI and NLP keywords related to my keyword. Also include any other words related to the keyword. Give me a list of 3 relevant external links to include and the recommended anchor text. Make sure they're not competing articles. Split the outline into part 1 and part 2.",TRUE
|
"SEO Prompt","Using WebPilot, create an outline for an article that will be 2,000 words on the keyword 'Best SEO prompts' based on the top 10 results from Google. Include every relevant heading possible. Keep the keyword density of the headings high. For each section of the outline, include the word count. Include FAQs section in the outline too, based on people also ask section from Google for the keyword. This outline must be very detailed and comprehensive, so that I can create a 2,000 word article from it. Generate a long list of LSI and NLP keywords related to my keyword. Also include any other words related to the keyword. Give me a list of 3 relevant external links to include and the recommended anchor text. Make sure they're not competing articles. Split the outline into part 1 and part 2.",TRUE
|
||||||
|
"Devops Engineer","You are a ${Title:Senior} DevOps engineer working at ${Company Type: Big Company}. Your role is to provide scalable, efficient, and automated solutions for software deployment, infrastructure management, and CI/CD pipelines. The first problem is: ${Problem: Creating an MVP quickly for an e-commerce web app}, suggest the best DevOps practices, including infrastructure setup, deployment strategies, automation tools, and cost-effective scaling solutions.",TRUE
|
|
330
script.js
330
script.js
|
@ -13,6 +13,95 @@ function toggleDarkMode() {
|
||||||
moonIcon.style.display = isDarkMode ? "block" : "none";
|
moonIcon.style.display = isDarkMode ? "block" : "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add these new functions at the top
|
||||||
|
function extractVariables(text) {
|
||||||
|
const regex = /\${([^}]+)}/g;
|
||||||
|
const variables = [];
|
||||||
|
let match;
|
||||||
|
|
||||||
|
while ((match = regex.exec(text)) !== null) {
|
||||||
|
const [variable, defaultValue] = match[1].split(":").map((s) => s.trim());
|
||||||
|
variables.push({ name: variable, default: defaultValue || "" });
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...new Set(variables.map((v) => JSON.stringify(v)))].map((v) =>
|
||||||
|
JSON.parse(v)
|
||||||
|
); // Remove duplicates
|
||||||
|
}
|
||||||
|
|
||||||
|
function createVariableInputs(variables, container) {
|
||||||
|
const form = document.createElement("div");
|
||||||
|
form.className = "variable-form";
|
||||||
|
|
||||||
|
variables.forEach((variable) => {
|
||||||
|
const wrapper = document.createElement("div");
|
||||||
|
wrapper.className = "variable-input-wrapper";
|
||||||
|
|
||||||
|
const label = document.createElement("label");
|
||||||
|
label.textContent = variable.name;
|
||||||
|
label.style.fontWeight = "600";
|
||||||
|
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.type = "text";
|
||||||
|
input.className = "variable-input";
|
||||||
|
input.placeholder = variable.default || `Enter ${variable.name}`;
|
||||||
|
input.dataset.variable = variable.name;
|
||||||
|
input.dataset.default = variable.default || "";
|
||||||
|
|
||||||
|
wrapper.appendChild(label);
|
||||||
|
wrapper.appendChild(input);
|
||||||
|
form.appendChild(wrapper);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(form);
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update the prompt preview with user input or default values
|
||||||
|
function updatePromptPreview(promptText, form) {
|
||||||
|
const variables = extractVariables(promptText);
|
||||||
|
|
||||||
|
if (variables.length === 0) {
|
||||||
|
return promptText; // Return original text if no variables found
|
||||||
|
}
|
||||||
|
|
||||||
|
let previewText = promptText;
|
||||||
|
// Replace variables with their default values without editting (for prompt cards, copy buttons, chat)
|
||||||
|
if (!form) {
|
||||||
|
variables.forEach(variable => {
|
||||||
|
const pattern = new RegExp(`\\$\{${variable.name}[^}]*\}`, 'g');
|
||||||
|
const replacement = variable.default || `<b>${variable.name}</b>`;
|
||||||
|
previewText = previewText.replace(pattern, replacement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Replace variables according to the user inputs.
|
||||||
|
else {
|
||||||
|
const inputs = form.querySelectorAll(".variable-input");
|
||||||
|
|
||||||
|
inputs.forEach((input) => {
|
||||||
|
const value = input.value.trim();
|
||||||
|
const variable = input.dataset.variable;
|
||||||
|
const defaultValue = input.dataset.default;
|
||||||
|
const pattern = new RegExp(`\\$\{${variable}[^}]*\}`, 'g');
|
||||||
|
let replacement;
|
||||||
|
if (value) {
|
||||||
|
// User entered value
|
||||||
|
replacement = value;
|
||||||
|
} else if (defaultValue) {
|
||||||
|
// Show default value with highlight
|
||||||
|
replacement = defaultValue;
|
||||||
|
} else {
|
||||||
|
// No value or default, show variable name
|
||||||
|
replacement = variable;
|
||||||
|
}
|
||||||
|
replacement = `<b>${replacement}</b>`;
|
||||||
|
|
||||||
|
previewText = previewText.replace(pattern, replacement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return previewText;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize everything after DOM loads
|
// Initialize everything after DOM loads
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
// Initialize dev mode
|
// Initialize dev mode
|
||||||
|
@ -127,11 +216,12 @@ async function initializeSearch() {
|
||||||
const searchTerm = e.target.value.toLowerCase();
|
const searchTerm = e.target.value.toLowerCase();
|
||||||
|
|
||||||
const filteredPrompts = prompts.filter((prompt) => {
|
const filteredPrompts = prompts.filter((prompt) => {
|
||||||
const matchesSearch = prompt.act.toLowerCase().includes(searchTerm) ||
|
const matchesSearch =
|
||||||
|
prompt.act.toLowerCase().includes(searchTerm) ||
|
||||||
prompt.prompt.toLowerCase().includes(searchTerm);
|
prompt.prompt.toLowerCase().includes(searchTerm);
|
||||||
|
|
||||||
return isDevMode
|
return isDevMode
|
||||||
? (matchesSearch && prompt.for_devs === true)
|
? matchesSearch && prompt.for_devs === true
|
||||||
: matchesSearch;
|
: matchesSearch;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -165,29 +255,32 @@ function updatePromptCount(filteredCount, totalCount) {
|
||||||
|
|
||||||
function parseCSV(csv) {
|
function parseCSV(csv) {
|
||||||
const lines = csv.split("\n");
|
const lines = csv.split("\n");
|
||||||
const headers = lines[0].split(",").map((header) =>
|
const headers = lines[0]
|
||||||
header.replace(/"/g, "").trim()
|
.split(",")
|
||||||
);
|
.map((header) => header.replace(/"/g, "").trim());
|
||||||
|
|
||||||
return lines.slice(1).map((line) => {
|
return lines
|
||||||
const values = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || [];
|
.slice(1)
|
||||||
const entry = {};
|
.map((line) => {
|
||||||
|
const values = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || [];
|
||||||
|
const entry = {};
|
||||||
|
|
||||||
headers.forEach((header, index) => {
|
headers.forEach((header, index) => {
|
||||||
let value = values[index] ? values[index].replace(/"/g, "").trim() : "";
|
let value = values[index] ? values[index].replace(/"/g, "").trim() : "";
|
||||||
// Remove backticks from the act/title
|
// Remove backticks from the act/title
|
||||||
if (header === "act") {
|
if (header === "act") {
|
||||||
value = value.replace(/`/g, "");
|
value = value.replace(/`/g, "");
|
||||||
}
|
}
|
||||||
// Convert 'TRUE'/'FALSE' strings to boolean for for_devs
|
// Convert 'TRUE'/'FALSE' strings to boolean for for_devs
|
||||||
if (header === "for_devs") {
|
if (header === "for_devs") {
|
||||||
value = value.toUpperCase() === "TRUE";
|
value = value.toUpperCase() === "TRUE";
|
||||||
}
|
}
|
||||||
entry[header] = value;
|
entry[header] = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}).filter((entry) => entry.act && entry.prompt);
|
})
|
||||||
|
.filter((entry) => entry.act && entry.prompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
function displaySearchResults(results) {
|
function displaySearchResults(results) {
|
||||||
|
@ -231,8 +324,9 @@ function displaySearchResults(results) {
|
||||||
// Find the prompt card with matching title
|
// Find the prompt card with matching title
|
||||||
const cards = document.querySelectorAll(".prompt-card");
|
const cards = document.querySelectorAll(".prompt-card");
|
||||||
const targetCard = Array.from(cards).find((card) => {
|
const targetCard = Array.from(cards).find((card) => {
|
||||||
const cardTitle = card.querySelector(".prompt-title").textContent
|
const cardTitle = card
|
||||||
.replace(/\s+/g, " ") // Normalize whitespace
|
.querySelector(".prompt-title")
|
||||||
|
.textContent.replace(/\s+/g, " ") // Normalize whitespace
|
||||||
.replace(/[\n\r]/g, "") // Remove newlines
|
.replace(/[\n\r]/g, "") // Remove newlines
|
||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
|
@ -241,8 +335,10 @@ function displaySearchResults(results) {
|
||||||
.replace(/[\n\r]/g, "") // Remove newlines
|
.replace(/[\n\r]/g, "") // Remove newlines
|
||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
return cardTitle.toLowerCase().includes(searchTitle.toLowerCase()) ||
|
return (
|
||||||
searchTitle.toLowerCase().includes(cardTitle.toLowerCase());
|
cardTitle.toLowerCase().includes(searchTitle.toLowerCase()) ||
|
||||||
|
searchTitle.toLowerCase().includes(cardTitle.toLowerCase())
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (targetCard) {
|
if (targetCard) {
|
||||||
|
@ -262,8 +358,8 @@ function displaySearchResults(results) {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
// On mobile, scroll the window
|
// On mobile, scroll the window
|
||||||
const cardRect = targetCard.getBoundingClientRect();
|
const cardRect = targetCard.getBoundingClientRect();
|
||||||
const scrollTop = window.pageYOffset + cardRect.top - headerHeight -
|
const scrollTop =
|
||||||
20;
|
window.pageYOffset + cardRect.top - headerHeight - 20;
|
||||||
|
|
||||||
window.scrollTo({
|
window.scrollTo({
|
||||||
top: scrollTop,
|
top: scrollTop,
|
||||||
|
@ -273,8 +369,8 @@ function displaySearchResults(results) {
|
||||||
// On desktop, scroll the main-content container
|
// On desktop, scroll the main-content container
|
||||||
const mainContent = document.querySelector(".main-content");
|
const mainContent = document.querySelector(".main-content");
|
||||||
const cardRect = targetCard.getBoundingClientRect();
|
const cardRect = targetCard.getBoundingClientRect();
|
||||||
const scrollTop = mainContent.scrollTop + cardRect.top -
|
const scrollTop =
|
||||||
headerHeight - 20;
|
mainContent.scrollTop + cardRect.top - headerHeight - 20;
|
||||||
|
|
||||||
mainContent.scrollTo({
|
mainContent.scrollTo({
|
||||||
top: scrollTop,
|
top: scrollTop,
|
||||||
|
@ -315,12 +411,13 @@ function filterPrompts() {
|
||||||
.then((csvText) => {
|
.then((csvText) => {
|
||||||
const prompts = parseCSV(csvText);
|
const prompts = parseCSV(csvText);
|
||||||
const filteredPrompts = prompts.filter((prompt) => {
|
const filteredPrompts = prompts.filter((prompt) => {
|
||||||
const matchesSearch = !searchTerm ||
|
const matchesSearch =
|
||||||
|
!searchTerm ||
|
||||||
prompt.act.toLowerCase().includes(searchTerm) ||
|
prompt.act.toLowerCase().includes(searchTerm) ||
|
||||||
prompt.prompt.toLowerCase().includes(searchTerm);
|
prompt.prompt.toLowerCase().includes(searchTerm);
|
||||||
|
|
||||||
return isDevMode
|
return isDevMode
|
||||||
? (matchesSearch && prompt.for_devs === true)
|
? matchesSearch && prompt.for_devs === true
|
||||||
: matchesSearch;
|
: matchesSearch;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -329,7 +426,7 @@ function filterPrompts() {
|
||||||
filteredPrompts.length,
|
filteredPrompts.length,
|
||||||
isDevMode
|
isDevMode
|
||||||
? prompts.filter((p) => p.for_devs === true).length
|
? prompts.filter((p) => p.for_devs === true).length
|
||||||
: prompts.length,
|
: prompts.length
|
||||||
);
|
);
|
||||||
displaySearchResults(filteredPrompts);
|
displaySearchResults(filteredPrompts);
|
||||||
|
|
||||||
|
@ -337,23 +434,29 @@ function filterPrompts() {
|
||||||
const promptsGrid = document.querySelector(".prompts-grid");
|
const promptsGrid = document.querySelector(".prompts-grid");
|
||||||
if (promptsGrid) {
|
if (promptsGrid) {
|
||||||
const cards = promptsGrid.querySelectorAll(
|
const cards = promptsGrid.querySelectorAll(
|
||||||
".prompt-card:not(.contribute-card)",
|
".prompt-card:not(.contribute-card)"
|
||||||
);
|
);
|
||||||
cards.forEach((card) => {
|
cards.forEach((card) => {
|
||||||
const title = card.querySelector(".prompt-title").textContent.trim();
|
const title = card.querySelector(".prompt-title").textContent.trim();
|
||||||
const matchingPrompt = prompts.find((p) => {
|
const matchingPrompt = prompts.find((p) => {
|
||||||
const pTitle = p.act.replace(/\s+/g, " ").replace(/[\n\r]/g, "")
|
const pTitle = p.act
|
||||||
|
.replace(/\s+/g, " ")
|
||||||
|
.replace(/[\n\r]/g, "")
|
||||||
.trim();
|
.trim();
|
||||||
const cardTitle = title.replace(/\s+/g, " ").replace(/[\n\r]/g, "")
|
const cardTitle = title
|
||||||
|
.replace(/\s+/g, " ")
|
||||||
|
.replace(/[\n\r]/g, "")
|
||||||
.trim();
|
.trim();
|
||||||
return pTitle.toLowerCase() === cardTitle.toLowerCase() ||
|
return (
|
||||||
|
pTitle.toLowerCase() === cardTitle.toLowerCase() ||
|
||||||
pTitle.toLowerCase().includes(cardTitle.toLowerCase()) ||
|
pTitle.toLowerCase().includes(cardTitle.toLowerCase()) ||
|
||||||
cardTitle.toLowerCase().includes(pTitle.toLowerCase());
|
cardTitle.toLowerCase().includes(pTitle.toLowerCase())
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show card if not in dev mode or if it's a dev prompt in dev mode
|
// Show card if not in dev mode or if it's a dev prompt in dev mode
|
||||||
card.style.display =
|
card.style.display =
|
||||||
(!isDevMode || (matchingPrompt && matchingPrompt.for_devs === true))
|
!isDevMode || (matchingPrompt && matchingPrompt.for_devs === true)
|
||||||
? ""
|
? ""
|
||||||
: "none";
|
: "none";
|
||||||
});
|
});
|
||||||
|
@ -396,23 +499,29 @@ function createPromptCards() {
|
||||||
const isDevMode = document.getElementById("devModeToggle").checked;
|
const isDevMode = document.getElementById("devModeToggle").checked;
|
||||||
|
|
||||||
const promptElements = document.querySelectorAll(
|
const promptElements = document.querySelectorAll(
|
||||||
"h2[id^=act] + p + blockquote",
|
"h2[id^=act] + p + blockquote"
|
||||||
);
|
);
|
||||||
|
|
||||||
promptElements.forEach((blockquote) => {
|
promptElements.forEach((blockquote) => {
|
||||||
const title = blockquote.previousElementSibling.previousElementSibling
|
const title =
|
||||||
.textContent.trim();
|
blockquote.previousElementSibling.previousElementSibling.textContent.trim();
|
||||||
const content = blockquote.textContent.trim();
|
const content = blockquote.textContent.trim();
|
||||||
|
|
||||||
// Find matching prompt in CSV
|
// Find matching prompt in CSV
|
||||||
const matchingPrompt = prompts.find((p) => {
|
const matchingPrompt = prompts.find((p) => {
|
||||||
const csvTitle = p.act.replace(/\s+/g, " ").replace(/[\n\r]/g, "")
|
const csvTitle = p.act
|
||||||
|
.replace(/\s+/g, " ")
|
||||||
|
.replace(/[\n\r]/g, "")
|
||||||
.trim();
|
.trim();
|
||||||
const elementTitle = title.replace(/\s+/g, " ").replace(/[\n\r]/g, "")
|
const elementTitle = title
|
||||||
|
.replace(/\s+/g, " ")
|
||||||
|
.replace(/[\n\r]/g, "")
|
||||||
.trim();
|
.trim();
|
||||||
return csvTitle.toLowerCase() === elementTitle.toLowerCase() ||
|
return (
|
||||||
|
csvTitle.toLowerCase() === elementTitle.toLowerCase() ||
|
||||||
csvTitle.toLowerCase().includes(elementTitle.toLowerCase()) ||
|
csvTitle.toLowerCase().includes(elementTitle.toLowerCase()) ||
|
||||||
elementTitle.toLowerCase().includes(csvTitle.toLowerCase());
|
elementTitle.toLowerCase().includes(csvTitle.toLowerCase())
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Extract contributor from the paragraph element
|
// Extract contributor from the paragraph element
|
||||||
|
@ -457,9 +566,9 @@ function createPromptCards() {
|
||||||
<div class="prompt-title">
|
<div class="prompt-title">
|
||||||
${title}
|
${title}
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<button class="chat-button" title="Open in AI Chat" onclick="openInChat(this, '${
|
<button class="chat-button" title="Open in AI Chat" onclick="openInChat(this, '${encodeURIComponent(
|
||||||
encodeURIComponent(content.trim())
|
updatePromptPreview(content.trim())
|
||||||
}')">
|
)}')">
|
||||||
<svg class="chat-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg class="chat-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -468,9 +577,9 @@ function createPromptCards() {
|
||||||
<line x1="12" y1="19" x2="20" y2="19"></line>
|
<line x1="12" y1="19" x2="20" y2="19"></line>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button class="copy-button" title="Copy prompt" onclick="copyPrompt(this, '${
|
<button class="copy-button" title="Copy prompt" onclick="copyPrompt(this, '${encodeURIComponent(
|
||||||
encodeURIComponent(content.trim())
|
updatePromptPreview(content.trim())
|
||||||
}')">
|
)}')">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path>
|
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path>
|
||||||
<rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect>
|
<rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect>
|
||||||
|
@ -478,7 +587,7 @@ function createPromptCards() {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="prompt-content">${content}</p>
|
<p class="prompt-content">${updatePromptPreview(content)}</p>
|
||||||
<a href="https://github.com/${contributor}" class="contributor-badge" target="_blank" rel="noopener">@${contributor}</a>
|
<a href="https://github.com/${contributor}" class="contributor-badge" target="_blank" rel="noopener">@${contributor}</a>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -496,7 +605,7 @@ function createPromptCards() {
|
||||||
copyButton.addEventListener("click", async (e) => {
|
copyButton.addEventListener("click", async (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(content);
|
await navigator.clipboard.writeText(updatePromptPreview(content));
|
||||||
copyButton.innerHTML = `
|
copyButton.innerHTML = `
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<polyline points="20 6 9 17 4 12"></polyline>
|
<polyline points="20 6 9 17 4 12"></polyline>
|
||||||
|
@ -596,6 +705,7 @@ function createModal() {
|
||||||
initializeModalListeners();
|
initializeModalListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Modify the existing showModal function
|
||||||
function showModal(title, content) {
|
function showModal(title, content) {
|
||||||
let modalOverlay = document.getElementById("modalOverlay");
|
let modalOverlay = document.getElementById("modalOverlay");
|
||||||
if (!modalOverlay) {
|
if (!modalOverlay) {
|
||||||
|
@ -605,22 +715,53 @@ function showModal(title, content) {
|
||||||
|
|
||||||
const modalTitle = modalOverlay.querySelector(".modal-title");
|
const modalTitle = modalOverlay.querySelector(".modal-title");
|
||||||
const modalContent = modalOverlay.querySelector(".modal-content");
|
const modalContent = modalOverlay.querySelector(".modal-content");
|
||||||
|
|
||||||
|
// Extract variables from content
|
||||||
|
const variables = extractVariables(content);
|
||||||
|
|
||||||
|
// Create variable inputs container if variables exist
|
||||||
|
if (variables.length > 0) {
|
||||||
|
const variableContainer = document.createElement("div");
|
||||||
|
variableContainer.className = "variable-container";
|
||||||
|
|
||||||
|
const form = createVariableInputs(variables, variableContainer);
|
||||||
|
|
||||||
|
// Initialize the modal content with updated prompt preview if variables exist
|
||||||
|
const previewText = updatePromptPreview(content, form);
|
||||||
|
modalContent.innerHTML = previewText;
|
||||||
|
|
||||||
|
// Add event listeners for real-time updates
|
||||||
|
form.addEventListener("input", () => {
|
||||||
|
const previewText = updatePromptPreview(content, form);
|
||||||
|
modalContent.innerHTML = previewText;
|
||||||
|
|
||||||
|
// Update chat button data
|
||||||
|
const modalChatButton = modalOverlay.querySelector(".modal-chat-button");
|
||||||
|
if (modalChatButton) {
|
||||||
|
modalChatButton.dataset.content = previewText;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Insert variable container before content
|
||||||
|
modalContent.parentElement.insertBefore(variableContainer, modalContent);
|
||||||
|
} else {
|
||||||
|
modalTitle.textContent = title;
|
||||||
|
modalContent.textContent = content;
|
||||||
|
}
|
||||||
|
|
||||||
const modalCopyButton = modalOverlay.querySelector(".modal-copy-button");
|
const modalCopyButton = modalOverlay.querySelector(".modal-copy-button");
|
||||||
const modalContributor = modalOverlay.querySelector(".modal-contributor");
|
const modalContributor = modalOverlay.querySelector(".modal-contributor");
|
||||||
const modalChatButton = modalOverlay.querySelector(".modal-chat-button");
|
const modalChatButton = modalOverlay.querySelector(".modal-chat-button");
|
||||||
|
|
||||||
if (!modalTitle || !modalContent) return;
|
if (!modalTitle || !modalContent) return;
|
||||||
|
|
||||||
modalTitle.textContent = title;
|
|
||||||
modalContent.textContent = content;
|
|
||||||
|
|
||||||
// Update chat button text with platform name and handle visibility
|
// Update chat button text with platform name and handle visibility
|
||||||
const platform = document.querySelector(".platform-tag.active");
|
const platform = document.querySelector(".platform-tag.active");
|
||||||
const isDevMode = document.getElementById("devModeToggle").checked;
|
const isDevMode = document.getElementById("devModeToggle").checked;
|
||||||
|
|
||||||
if (platform) {
|
if (platform) {
|
||||||
const shouldHideChat = ["gemini", "llama"].includes(
|
const shouldHideChat = ["gemini", "llama"].includes(
|
||||||
platform.dataset.platform,
|
platform.dataset.platform
|
||||||
);
|
);
|
||||||
modalChatButton.style.display = shouldHideChat ? "none" : "flex";
|
modalChatButton.style.display = shouldHideChat ? "none" : "flex";
|
||||||
|
|
||||||
|
@ -635,13 +776,13 @@ function showModal(title, content) {
|
||||||
|
|
||||||
modalChatButton.innerHTML = `
|
modalChatButton.innerHTML = `
|
||||||
<svg class="chat-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: ${
|
<svg class="chat-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: ${
|
||||||
isDevMode ? "none" : "block"
|
isDevMode ? "none" : "block"
|
||||||
}">
|
}">
|
||||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
<svg class="terminal-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: ${
|
<svg class="terminal-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: ${
|
||||||
isDevMode ? "block" : "none"
|
isDevMode ? "block" : "none"
|
||||||
}">
|
}">
|
||||||
<polyline points="4 17 10 11 4 5"></polyline>
|
<polyline points="4 17 10 11 4 5"></polyline>
|
||||||
<line x1="12" y1="19" x2="20" y2="19"></line>
|
<line x1="12" y1="19" x2="20" y2="19"></line>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -651,27 +792,26 @@ function showModal(title, content) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store content for chat button
|
// Store content for chat button
|
||||||
modalChatButton.dataset.content = content;
|
modalChatButton.dataset.content = modalContent.textContent;
|
||||||
|
|
||||||
// Find the contributor for this prompt
|
// Find the contributor for this prompt
|
||||||
const promptCard = Array.from(document.querySelectorAll(".prompt-card")).find(
|
const promptCard = Array.from(document.querySelectorAll(".prompt-card")).find(
|
||||||
(card) =>
|
(card) =>
|
||||||
card.querySelector(".prompt-title").textContent.trim() === title.trim(),
|
card.querySelector(".prompt-title").textContent.trim() === title.trim()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (promptCard) {
|
if (promptCard) {
|
||||||
const contributorBadge = promptCard.querySelector(".contributor-badge");
|
const contributorBadge = promptCard.querySelector(".contributor-badge");
|
||||||
if (contributorBadge) {
|
if (contributorBadge) {
|
||||||
modalContributor.href = contributorBadge.href;
|
modalContributor.href = contributorBadge.href;
|
||||||
modalContributor.textContent =
|
modalContributor.textContent = `Contributed by ${contributorBadge.textContent}`;
|
||||||
`Contributed by ${contributorBadge.textContent}`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add copy functionality
|
// Add copy functionality
|
||||||
modalCopyButton.addEventListener("click", async () => {
|
modalCopyButton.addEventListener("click", async () => {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(content);
|
await navigator.clipboard.writeText(modalContent.textContent);
|
||||||
modalCopyButton.innerHTML = `
|
modalCopyButton.innerHTML = `
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<polyline points="20 6 9 17 4 12"></polyline>
|
<polyline points="20 6 9 17 4 12"></polyline>
|
||||||
|
@ -705,22 +845,22 @@ function hideModal() {
|
||||||
modalOverlay.remove();
|
modalOverlay.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
let selectedPlatform = localStorage.getItem("selected-platform") ||
|
let selectedPlatform =
|
||||||
"github-copilot"; // Get from localStorage or default to github
|
localStorage.getItem("selected-platform") || "github-copilot"; // Get from localStorage or default to github
|
||||||
|
|
||||||
// Platform toggle functionality
|
// Platform toggle functionality
|
||||||
document.querySelectorAll(".platform-tag").forEach((button) => {
|
document.querySelectorAll(".platform-tag").forEach((button) => {
|
||||||
button.addEventListener("click", () => {
|
button.addEventListener("click", () => {
|
||||||
document.querySelectorAll(".platform-tag").forEach((btn) =>
|
document
|
||||||
btn.classList.remove("active")
|
.querySelectorAll(".platform-tag")
|
||||||
);
|
.forEach((btn) => btn.classList.remove("active"));
|
||||||
button.classList.add("active");
|
button.classList.add("active");
|
||||||
selectedPlatform = button.dataset.platform;
|
selectedPlatform = button.dataset.platform;
|
||||||
localStorage.setItem("selected-platform", selectedPlatform);
|
localStorage.setItem("selected-platform", selectedPlatform);
|
||||||
|
|
||||||
// Hide/show chat buttons based on platform
|
// Hide/show chat buttons based on platform
|
||||||
const chatButtons = document.querySelectorAll(
|
const chatButtons = document.querySelectorAll(
|
||||||
".chat-button, .modal-chat-button",
|
".chat-button, .modal-chat-button"
|
||||||
);
|
);
|
||||||
const shouldHideChat = ["gemini", "llama"].includes(selectedPlatform);
|
const shouldHideChat = ["gemini", "llama"].includes(selectedPlatform);
|
||||||
chatButtons.forEach((btn) => {
|
chatButtons.forEach((btn) => {
|
||||||
|
@ -776,15 +916,39 @@ function openInChat(button, encodedPrompt) {
|
||||||
|
|
||||||
// Existing copy function
|
// Existing copy function
|
||||||
async function copyPrompt(button, encodedPrompt) {
|
async function copyPrompt(button, encodedPrompt) {
|
||||||
const promptText = decodeURIComponent(encodedPrompt);
|
let promptText = decodeURIComponent(encodedPrompt);
|
||||||
|
|
||||||
|
// If there's a modal open, use the current state of variables
|
||||||
|
const modalContent = document.querySelector(".modal-content");
|
||||||
|
if (modalContent) {
|
||||||
|
// Get all variable inputs
|
||||||
|
const form = document.querySelector(".variable-form");
|
||||||
|
if (form) {
|
||||||
|
const inputs = form.querySelectorAll(".variable-input");
|
||||||
|
inputs.forEach((input) => {
|
||||||
|
const value = input.value.trim();
|
||||||
|
const variable = input.dataset.variable;
|
||||||
|
const defaultValue = input.dataset.default;
|
||||||
|
const pattern = new RegExp(`\\$\{${variable}[^}]*\}`, "g");
|
||||||
|
|
||||||
|
// Use value or default value
|
||||||
|
const replacement = value || defaultValue || variable;
|
||||||
|
promptText = promptText.replace(pattern, replacement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(promptText);
|
await navigator.clipboard.writeText(updatePromptPreview(promptText));
|
||||||
const originalHTML = button.innerHTML;
|
const originalHTML = button.innerHTML;
|
||||||
button.innerHTML =
|
button.innerHTML = `
|
||||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17 4 12"/></svg>';
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<polyline points="20 6 9 17 4 12"></polyline>
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
button.innerHTML = originalHTML;
|
button.innerHTML = originalHTML;
|
||||||
}, 1000);
|
}, 2000);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to copy text: ", err);
|
console.error("Failed to copy text: ", err);
|
||||||
}
|
}
|
||||||
|
@ -826,7 +990,7 @@ function hideCopilotSuggestion(switchToCopilot) {
|
||||||
|
|
||||||
if (switchToCopilot) {
|
if (switchToCopilot) {
|
||||||
const copilotButton = document.querySelector(
|
const copilotButton = document.querySelector(
|
||||||
'[data-platform="github-copilot"]',
|
'[data-platform="github-copilot"]'
|
||||||
);
|
);
|
||||||
if (copilotButton) {
|
if (copilotButton) {
|
||||||
copilotButton.click();
|
copilotButton.click();
|
||||||
|
@ -844,14 +1008,14 @@ function hideCopilotSuggestion(switchToCopilot) {
|
||||||
|
|
||||||
// Function to update chat button icons based on dev mode
|
// Function to update chat button icons based on dev mode
|
||||||
function updateChatButtonIcons(isDevMode) {
|
function updateChatButtonIcons(isDevMode) {
|
||||||
document.querySelectorAll(".chat-button, .modal-chat-button").forEach(
|
document
|
||||||
(button) => {
|
.querySelectorAll(".chat-button, .modal-chat-button")
|
||||||
|
.forEach((button) => {
|
||||||
const chatIcon = button.querySelector(".chat-icon");
|
const chatIcon = button.querySelector(".chat-icon");
|
||||||
const terminalIcon = button.querySelector(".terminal-icon");
|
const terminalIcon = button.querySelector(".terminal-icon");
|
||||||
if (chatIcon && terminalIcon) {
|
if (chatIcon && terminalIcon) {
|
||||||
chatIcon.style.display = isDevMode ? "none" : "block";
|
chatIcon.style.display = isDevMode ? "none" : "block";
|
||||||
terminalIcon.style.display = isDevMode ? "block" : "none";
|
terminalIcon.style.display = isDevMode ? "block" : "none";
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue