feature(copy-code): can copy code

This commit is contained in:
Christopher 2023-06-25 20:43:26 -04:00
parent 1d3bcb2078
commit 77769738c7

View File

@ -184,302 +184,352 @@ function getWebviewContent(apiResponse = '', question = '') {
.join(''); .join('');
return ` return `
<html> <html>
<head>
<style>
.panel {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 50%;
height: 100%;
margin: 0 auto;
background-color: #1e1e1e;
color: #d4d4d4;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.textbox {
width: 100%;
height: 200px;
resize: both;
padding: 10px;
}
.buttons {
display: flex;
justify-content: space-between;
width: 50%;
}
.button {
flex-grow: 1;
background-color: #007acc;
color: #fff;
padding: 10px;
text-align: center;
cursor: pointer;
border: none;
outline: none;
font-size: 14px;
}
#response { <head>
white-space: pre-wrap; <style>
} .panel {
display: flex;
#file-list { flex-direction: column;
margin-top: 20px; align-items: center;
border justify-content: center;
} width: 50%;
height: 100%;
.form-group { margin: 0 auto;
display: flex; background-color: #1e1e1e;
flex-direction: column; color: #d4d4d4;
margin-bottom: 20px; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
width: 100%; }
}
.textbox {
.form-group label { width: 100%;
margin-bottom: 5px; height: 200px;
font-size: 14px; resize: both;
} padding: 10px;
}
.form-group input[type="text"] {
padding: 10px; .buttons {
font-size: 14px; display: flex;
border: none; justify-content: space-between;
outline: none; width: 50%;
background-color: #2d2d2d; }
color: #d4d4d4;
} .button {
flex-grow: 1;
.form-group input[type="text"]::placeholder { background-color: #007acc;
color: #d4d4d4; color: #fff;
} padding: 10px;
text-align: center;
.form-group .button-options { cursor: pointer;
display: flex; border: none;
justify-content: space-between; outline: none;
margin-top: 10px; font-size: 14px;
} }
.form-group .button-options button { #response {
padding: 10px; white-space: pre-wrap;
font-size: 14px; }
border: none;
outline: none; #file-list {
cursor: pointer; margin-top: 20px;
background-color: #007acc; border
color: #fff; }
}
.form-group {
.form-group .button-options button:hover { display: flex;
background-color: #005f8c; flex-direction: column;
} margin-bottom: 20px;
width: 100%;
.form-group .button-options button:active { }
background-color: #004d73;
} .form-group label {
margin-bottom: 5px;
.form-group .button-options button:focus { font-size: 14px;
box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.5); }
}
.form-group input[type="text"] {
.file-list { padding: 10px;
margin-top: 20px; font-size: 14px;
width: 100%; border: none;
} outline: none;
background-color: #2d2d2d;
.file-list h2 { color: #d4d4d4;
margin-bottom: 10px; }
font-size: 14px;
} .form-group input[type="text"]::placeholder {
color: #d4d4d4;
.file-list .file-item { }
display: flex;
align-items: center; .form-group .button-options {
margin-bottom: 5px; display: flex;
font-size: 14px; justify-content: space-between;
} margin-top: 10px;
}
.file-list .file-item input[type="checkbox"] {
margin-right: 5px; .form-group .button-options button {
} padding: 10px;
font-size: 14px;
.file-list .file-item label { border: none;
margin-bottom: 0; outline: none;
} cursor: pointer;
background-color: #007acc;
.file-list .file-item .file-path { color: #fff;
overflow-wrap: break-word; }
}
.form-group .button-options button:hover {
.file-list .file-item .file-path:hover { background-color: #005f8c;
text-decoration: underline; }
cursor: pointer;
} .form-group .button-options button:active {
background-color: #004d73;
.file-list .file-item .file-path:active { }
color: #007acc;
} .form-group .button-options button:focus {
box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.5);
.file-list .file-item .file-path:focus { }
box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.5);
} .file-list {
margin-top: 20px;
.collapsible { width: 100%;
background-color: #2d2d2d; }
color: #d4d4d4;
cursor: pointer; .file-list h2 {
padding: 10px; margin-bottom: 10px;
width: 100%; font-size: 14px;
border: none; }
outline: none;
text-align: left; .file-list .file-item {
font-size: 14px; display: flex;
} align-items: center;
margin-bottom: 5px;
.collapsible:hover { font-size: 14px;
background-color: #3c3c3c; }
}
.file-list .file-item input[type="checkbox"] {
.collapsible:active { margin-right: 5px;
background-color: #4c4c4c; }
}
.file-list .file-item label {
.collapsible:focus { margin-bottom: 0;
box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.5); }
}
.file-list .file-item .file-path {
.content { overflow-wrap: break-word;
padding: 0 10px; }
display: none;
overflow: hidden; .file-list .file-item .file-path:hover {
background-color: #f1f1f1; text-decoration: underline;
width:100%; cursor: pointer;
} }
.content p { .file-list .file-item .file-path:active {
margin-top: 0; color: #007acc;
font-size: 14px; }
}
.file-list .file-item .file-path:focus {
.active, .collapsible:hover { box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.5);
background-color: #555; }
}
.collapsible {
.active:after { background-color: #2d2d2d;
content: "\\2212"; color: #d4d4d4;
} cursor: pointer;
padding: 10px;
.collapsible:after { width: 100%;
content: "\\002B"; border: none;
color: #d4d4d4; outline: none;
font-weight: bold; text-align: left;
float: right; font-size: 14px;
margin-left: 5px; }
}
.collapsible:hover {
.active:after { background-color: #3c3c3c;
content: "\\2212"; }
}
.collapsible:active {
.collapsible:after { background-color: #4c4c4c;
content: "\\002B"; }
color: #d4d4d4;
font-weight: bold; .collapsible:focus {
float: right; box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.5);
margin-left: 5px; }
}
.content {
#rendered { padding: 0 10px;
background-color: #2d2d2d; display: none;
word-wrap: wrap; overflow: hidden;
margin-top: 20px; background-color: #f1f1f1;
border: 1px solid white; width: 100%;
border-radius: 5px; }
padding: 10px;
} .content p {
margin-top: 0;
#question-rep { font-size: 14px;
font-weight: bold; }
background-color: #2d2d2d;
word-wrap: wrap; .active,
border: 1px solid white; .collapsible:hover {
border-radius: 5px; background-color: #555;
} }
div#api-response.content.active { .active:after {
background-color: #313131; content: "\\2212";
} }
</style> .collapsible:after {
</head> content: "\\002B";
<body class="panel"> color: #d4d4d4;
<h1>GPT Context</h1> font-weight: bold;
<form id="questionForm"> float: right;
<div class="form-group"> margin-left: 5px;
<label for="question">Enter your question:</label> }
<input type="text" id="question" name="question" placeholder="Enter your question" required>
<div class="button-options"> .active:after {
<button type="submit">Submit</button> content: "\\2212";
}
.collapsible:after {
content: "\\002B";
color: #d4d4d4;
font-weight: bold;
float: right;
margin-left: 5px;
}
#rendered {
background-color: #2d2d2d;
word-wrap: wrap;
margin-top: 20px;
border: 1px solid white;
border-radius: 5px;
padding: 10px;
}
#question-rep {
font-weight: bold;
background-color: #2d2d2d;
word-wrap: wrap;
border: 1px solid white;
border-radius: 5px;
}
div#api-response.content.active {
background-color: #313131;
}
#code-block {
padding: 0;
background: none;
border: none;
font: inherit;
color: inherit;
cursor: pointer;
outline: inherit;
margin: 0;
width: 100%;
text-align: left;
}
</style>
</head>
<body class="panel">
<h1>GPT Context</h1>
<form id="questionForm">
<div class="form-group">
<input type="text" id="question" name="question" placeholder="Enter your question:">
<div class="button-options">
<button type="submit" onclick="submitQuestionApi()">Submit</button>
<button type="button" onclick="clearSelectedFiles()">Clear</button> <button type="button" onclick="clearSelectedFiles()">Clear</button>
<button type="button" onclick="refreshSelectedFiles()">Refresh</button> <button type="button" onclick="refreshSelectedFiles()">Refresh</button>
</div> </div>
</div>
<div class="form-group">
<div class="collapsible" onclick="toggleApiResponse()">
API Response
</div>
<div class="content" id="api-response">
<div id="question-rep">
<p>${question ? '> ' + question : null}</p>
</div>
${
apiResponse ? `
<div id="rendered">
<p id="responses">
<pre id="response">${apiResponse.replace(/```([^```]+)```/g, '<code>$1</code>')}</pre>
</p>
</div>
` : null
}
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="collapsible" onclick="toggleApiResponse()" id="alert-response">
API Response
</div>
<div class="content" id="api-response">
<div id="question-rep">
<p>${question ? '> ' + question : null}</p>
</div>
${
apiResponse ? `
<div id="rendered">
<p id="responses">
<pre id="response">${apiResponse.replace(/```([^```]+)```/g, '<button onclick="copyCode()" id="code-block"><code>$1</code></button>')}</pre>
</p>
</div>
` : null
}
</div>
</div>
<div class="form-group">
<label for="selected-files">Selected Files:</label> <label for="selected-files">Selected Files:</label>
<div class="file-list"> <div class="file-list">
${fileList ? fileList : '<p class="no-files">No files selected</p>'} ${fileList ? fileList : '<p class="no-files">No files selected</p>'}
</div> </div>
</div> </div>
<script> <script>
const vscode = acquireVsCodeApi(); const vscode = acquireVsCodeApi();
function toggleFileSelection(uri) { function copyCode() {
vscode.postMessage({ event.preventDefault();
command: 'toggleFileSelection', const codeBlocks = document.getElementsByTagName('code');
uri: uri const selectedCodeBlock = event.target.closest('code');
});
} if (selectedCodeBlock) {
const codeText = selectedCodeBlock.innerText;
function clearSelectedFiles() { const dummyTextArea = document.createElement('textarea');
vscode.postMessage({ dummyTextArea.value = codeText;
command: 'clearSelectedFiles' document.body.appendChild(dummyTextArea);
}); dummyTextArea.select();
} document.execCommand('copy');
document.body.removeChild(dummyTextArea);
function refreshSelectedFiles() {
vscode.postMessage({ vscode.postMessage({
command: 'refreshFiles' command: 'codeCopied'
}); });
} }
}
function toggleApiResponse() {
// Add an event listener to detect changes in apiResponse
window.addEventListener('DOMContentLoaded', () => {
const observer = new MutationObserver(() => {
if (apiResponse !== null) {
const alert = document.getElementById('alert-response');
alert.style.backgroundColor = '#4CAF50';
}
});
observer.observe(document, {
childList: true,
subtree: true
});
});
function toggleFileSelection(uri) {
vscode.postMessage({
command: 'toggleFileSelection',
uri: uri
});
}
function clearSelectedFiles() {
vscode.postMessage({
command: 'clearSelectedFiles'
});
}
function refreshSelectedFiles() {
vscode.postMessage({
command: 'refreshFiles'
});
}
function toggleApiResponse() {
const apiResponse = document.getElementById('api-response'); const apiResponse = document.getElementById('api-response');
var response = document.getElementById('responses'); var response = document.getElementById('responses');
if(response === null) { if (response === null) {
return; return;
} }
apiResponse.classList.toggle('active'); apiResponse.classList.toggle('active');
@ -493,30 +543,34 @@ function getWebviewContent(apiResponse = '', question = '') {
collapsible.classList.add('active'); collapsible.classList.add('active');
} }
} }
const form = document.getElementById('questionForm'); const form = document.getElementById('questionForm');
form.addEventListener('submit', event => { function submitQuestionApi() {
event.preventDefault(); event.preventDefault();
const question = document.getElementById('question').value; if (document.getElementById('question').value === '' || document.getElementById('question').value === null) {
const checkboxes = document.querySelectorAll('input[type="checkbox"]'); return;
const selectedUris = []; }
checkboxes.forEach(checkbox => { const question = document.getElementById('question').value;
if (checkbox.checked) { const checkboxes = document.querySelectorAll('input[type="checkbox"]');
const uri = checkbox.getAttribute('data-uri'); const selectedUris = [];
selectedUris.push(uri); checkboxes.forEach(checkbox => {
} if (checkbox.checked) {
}); const uri = checkbox.getAttribute('data-uri');
vscode.postMessage({ selectedUris.push(uri);
command: 'submitQuestion', }
text: question, });
selectedUris: selectedUris vscode.postMessage({
}); command: 'submitQuestion',
}); text: question,
</script> selectedUris: selectedUris
</body> });
</html> }
`; </script>
</body>
</html>
`;
} }
@ -556,6 +610,8 @@ function activate(context) {
webviewView.webview.html = getWebviewContent(); webviewView.webview.html = getWebviewContent();
} else if (message.command === 'submitQuestion') { } else if (message.command === 'submitQuestion') {
await handleQuestionSubmission(webviewView, message.text, message.selectedUris); await handleQuestionSubmission(webviewView, message.text, message.selectedUris);
} else if (message.command === 'codeCopied') {
vscode.window.showInformationMessage('Code copied to clipboard');
} }
}); });
} }