prompt guide
This commit is contained in:
parent
2a0d6c35ae
commit
0e12214f60
4 changed files with 289 additions and 41 deletions
|
|
@ -365,8 +365,11 @@ export function createTemplateGallery({ container, onSelectTemplate }) {
|
||||||
const createTemplateBtn = document.createElement('button');
|
const createTemplateBtn = document.createElement('button');
|
||||||
createTemplateBtn.className = 'template-create-btn';
|
createTemplateBtn.className = 'template-create-btn';
|
||||||
createTemplateBtn.innerHTML = `
|
createTemplateBtn.innerHTML = `
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M12 5V19M5 12H19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M10 14H12M12 14H14M12 14V16M12 14V12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||||
|
<path
|
||||||
|
d="M22 11.7979C22 9.16554 22 7.84935 21.2305 6.99383C21.1598 6.91514 21.0849 6.84024 21.0062 6.76946C20.1506 6 18.8345 6 16.2021 6H15.8284C14.6747 6 14.0979 6 13.5604 5.84678C13.2651 5.7626 12.9804 5.64471 12.7121 5.49543C12.2237 5.22367 11.8158 4.81578 11 4L10.4497 3.44975C10.1763 3.17633 10.0396 3.03961 9.89594 2.92051C9.27652 2.40704 8.51665 2.09229 7.71557 2.01738C7.52976 2 7.33642 2 6.94975 2C6.06722 2 5.62595 2 5.25839 2.06935C3.64031 2.37464 2.37464 3.64031 2.06935 5.25839C2 5.62595 2 6.06722 2 6.94975M21.9913 16C21.9554 18.4796 21.7715 19.8853 20.8284 20.8284C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2 19.6569 2 17.7712 2 14V11"
|
||||||
|
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
||||||
</svg>
|
</svg>
|
||||||
`;
|
`;
|
||||||
createTemplateBtn.addEventListener('click', () => {
|
createTemplateBtn.addEventListener('click', () => {
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
const aspectRatioInput = document.getElementById('aspect-ratio');
|
const aspectRatioInput = document.getElementById('aspect-ratio');
|
||||||
const resolutionInput = document.getElementById('resolution');
|
const resolutionInput = document.getElementById('resolution');
|
||||||
const apiKeyInput = document.getElementById('api-key');
|
const apiKeyInput = document.getElementById('api-key');
|
||||||
|
const openApiSettingsBtn = document.getElementById('open-api-settings-btn');
|
||||||
|
const apiSettingsOverlay = document.getElementById('api-settings-overlay');
|
||||||
|
const apiSettingsCloseBtn = document.getElementById('api-settings-close');
|
||||||
|
const saveApiSettingsBtn = document.getElementById('save-api-settings-btn');
|
||||||
|
const apiKeyToggleBtn = document.getElementById('toggle-api-key-visibility');
|
||||||
|
const apiKeyEyeIcon = apiKeyToggleBtn?.querySelector('.icon-eye');
|
||||||
|
const apiKeyEyeOffIcon = apiKeyToggleBtn?.querySelector('.icon-eye-off');
|
||||||
|
|
||||||
const placeholderState = document.getElementById('placeholder-state');
|
const placeholderState = document.getElementById('placeholder-state');
|
||||||
const loadingState = document.getElementById('loading-state');
|
const loadingState = document.getElementById('loading-state');
|
||||||
|
|
@ -132,10 +139,58 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
content: POPUP_CONTENT,
|
content: POPUP_CONTENT,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const openApiSettings = () => {
|
||||||
|
if (!apiSettingsOverlay) return;
|
||||||
|
apiSettingsOverlay.classList.remove('hidden');
|
||||||
|
apiKeyInput?.focus();
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeApiSettings = () => {
|
||||||
|
if (!apiSettingsOverlay) return;
|
||||||
|
apiSettingsOverlay.classList.add('hidden');
|
||||||
|
};
|
||||||
|
|
||||||
|
openApiSettingsBtn?.addEventListener('click', openApiSettings);
|
||||||
|
apiSettingsCloseBtn?.addEventListener('click', closeApiSettings);
|
||||||
|
saveApiSettingsBtn?.addEventListener('click', closeApiSettings);
|
||||||
|
|
||||||
|
apiSettingsOverlay?.addEventListener('click', (event) => {
|
||||||
|
if (event.target === apiSettingsOverlay) {
|
||||||
|
closeApiSettings();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('keydown', (event) => {
|
||||||
|
if (event.key === 'Escape' && apiSettingsOverlay && !apiSettingsOverlay.classList.contains('hidden')) {
|
||||||
|
event.preventDefault();
|
||||||
|
closeApiSettings();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const savedSettings = loadSettings();
|
const savedSettings = loadSettings();
|
||||||
slotManager.initialize(savedSettings.referenceImages || []);
|
slotManager.initialize(savedSettings.referenceImages || []);
|
||||||
|
|
||||||
apiKeyInput.addEventListener('input', persistSettings);
|
apiKeyInput.addEventListener('input', persistSettings);
|
||||||
|
let isApiKeyVisible = false;
|
||||||
|
|
||||||
|
const refreshApiKeyVisibility = () => {
|
||||||
|
if (!apiKeyInput) return;
|
||||||
|
apiKeyInput.type = isApiKeyVisible ? 'text' : 'password';
|
||||||
|
if (apiKeyToggleBtn) {
|
||||||
|
apiKeyToggleBtn.setAttribute('aria-pressed', String(isApiKeyVisible));
|
||||||
|
apiKeyToggleBtn.setAttribute('aria-label', isApiKeyVisible ? 'Ẩn API key' : 'Hiện API key');
|
||||||
|
}
|
||||||
|
apiKeyEyeIcon?.classList.toggle('hidden', isApiKeyVisible);
|
||||||
|
apiKeyEyeOffIcon?.classList.toggle('hidden', !isApiKeyVisible);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (apiKeyToggleBtn) {
|
||||||
|
apiKeyToggleBtn.addEventListener('click', () => {
|
||||||
|
isApiKeyVisible = !isApiKeyVisible;
|
||||||
|
refreshApiKeyVisibility();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
refreshApiKeyVisibility();
|
||||||
promptInput.addEventListener('input', persistSettings);
|
promptInput.addEventListener('input', persistSettings);
|
||||||
aspectRatioInput.addEventListener('change', persistSettings);
|
aspectRatioInput.addEventListener('change', persistSettings);
|
||||||
resolutionInput.addEventListener('change', persistSettings);
|
resolutionInput.addEventListener('change', persistSettings);
|
||||||
|
|
@ -146,6 +201,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
const resolution = resolutionInput.value;
|
const resolution = resolutionInput.value;
|
||||||
const apiKey = apiKeyInput.value.trim();
|
const apiKey = apiKeyInput.value.trim();
|
||||||
|
|
||||||
|
if (!apiKey) {
|
||||||
|
openApiSettings();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!prompt) {
|
if (!prompt) {
|
||||||
showError('Please enter a prompt.');
|
showError('Please enter a prompt.');
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
171
static/style.css
171
static/style.css
|
|
@ -156,6 +156,15 @@ a:hover {
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
padding-bottom: 32px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-icon-btn {
|
.info-icon-btn {
|
||||||
|
|
@ -163,7 +172,7 @@ a:hover {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
min-width: 36px;
|
min-width: 36px;
|
||||||
border-radius: 0;
|
border-radius: 50%;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
@ -207,6 +216,9 @@ a:hover {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding-right: 10px;
|
||||||
|
margin-right: -10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls-footer {
|
.controls-footer {
|
||||||
|
|
@ -231,12 +243,88 @@ a:hover {
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.api-settings-note {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||||
|
border-radius: 0.65rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
background: rgba(255, 255, 255, 0.02);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-settings-note-icon {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
.input-group {
|
.input-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.api-settings-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-settings-warning {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #ffd166;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
border: 1px solid rgba(255, 209, 102, 0.4);
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
background: rgba(255, 209, 102, 0.08);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-settings-input-group {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-key-field {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-key-toggle-btn {
|
||||||
|
width: 43.5px;
|
||||||
|
height: 43.5px;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.2s, background 0.2s, color 0.2s;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-key-toggle-btn:hover {
|
||||||
|
border-color: var(--accent-color);
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-key-toggle-btn svg {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-key-hint {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-key-hint a {
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
@ -260,6 +348,8 @@ select {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type="password"], input[type="text"] {
|
||||||
|
width: 100%;}
|
||||||
select {
|
select {
|
||||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(15, 15, 25, 0.3)),
|
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(15, 15, 25, 0.3)),
|
||||||
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8'%3E%3Cpath fill='rgba(249, 203, 42, 0.85)' d='M7 8L0.928 0.5h12.144L7 8z'/%3E%3C/svg%3E");
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8'%3E%3Cpath fill='rgba(249, 203, 42, 0.85)' d='M7 8L0.928 0.5h12.144L7 8z'/%3E%3C/svg%3E");
|
||||||
|
|
@ -318,40 +408,52 @@ textarea {
|
||||||
|
|
||||||
.prompt-wrapper textarea {
|
.prompt-wrapper textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-bottom: 2.5rem; /* Make space for the button */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt-refine-btn {
|
.prompt-actions {
|
||||||
position: absolute;
|
|
||||||
bottom: 0.5rem;
|
|
||||||
right: 0.5rem;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: rgba(255, 255, 255, 0.08);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
color: var(--text-secondary);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-action-btn {
|
||||||
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
gap: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
|
border-radius: 50%;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
z-index: 5;
|
text-decoration: none;
|
||||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt-refine-btn:hover {
|
.prompt-action-btn:hover {
|
||||||
background: rgba(251, 191, 36, 0.15);
|
background: rgba(251, 191, 36, 0.25);
|
||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
border-color: var(--accent-color);
|
border-color: var(--accent-color);
|
||||||
transform: scale(1.05);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 4px 10px rgba(251, 191, 36, 0.3);
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt-refine-btn svg {
|
.prompt-action-btn svg {
|
||||||
width: 16px;
|
width: 18px;
|
||||||
height: 16px;
|
height: 18px;
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-action-btn span {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#confirm-refine-btn {
|
#confirm-refine-btn {
|
||||||
|
|
@ -947,8 +1049,8 @@ button#generate-btn:disabled {
|
||||||
/* Canvas Language Toggle (Top-Left Corner) */
|
/* Canvas Language Toggle (Top-Left Corner) */
|
||||||
.canvas-lang-toggle {
|
.canvas-lang-toggle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 1rem;
|
top: 1.2rem;
|
||||||
left: 1rem;
|
left: 2rem;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1493,6 +1595,29 @@ button#generate-btn:disabled {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#save-api-settings-btn {
|
||||||
|
padding: 0.6rem 1.25rem;
|
||||||
|
background: linear-gradient(135deg, var(--accent-color), var(--accent-hover));
|
||||||
|
color: #000;
|
||||||
|
font-weight: 600;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.1s, box-shadow 0.2s;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#save-api-settings-btn:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 5px 15px rgba(251, 191, 36, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#save-api-settings-btn:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
.template-preview-url-input {
|
.template-preview-url-input {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|
|
||||||
|
|
@ -21,24 +21,40 @@
|
||||||
<div class="brand">
|
<div class="brand">
|
||||||
<h1>aPix <span class="badge">by SDVN</span></h1>
|
<h1>aPix <span class="badge">by SDVN</span></h1>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sidebar-header-actions">
|
||||||
<button type="button" class="toolbar-info-btn info-icon-btn" data-popup-target="help"
|
<button type="button" class="toolbar-info-btn info-icon-btn" data-popup-target="help"
|
||||||
aria-label="Thông tin và hướng dẫn">
|
aria-label="Thông tin và hướng dẫn">
|
||||||
<span aria-hidden="true">i</span>
|
<span aria-hidden="true">i</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" id="open-api-settings-btn" class="toolbar-info-btn info-icon-btn"
|
||||||
|
aria-label="Thiết lập API key" aria-haspopup="dialog">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M20.1 9.2214C18.29 9.2214 17.55 7.9414 18.45 6.3714C18.97 5.4614 18.66 4.3014 17.75 3.7814L16.02 2.7914C15.23 2.3214 14.21 2.6014 13.74 3.3914L13.63 3.5814C12.73 5.1514 11.25 5.1514 10.34 3.5814L10.23 3.3914C9.78 2.6014 8.76 2.3214 7.97 2.7914L6.24 3.7814C5.33 4.3014 5.02 5.4714 5.54 6.3814C6.45 7.9414 5.71 9.2214 3.9 9.2214C2.86 9.2214 2 10.0714 2 11.1214V12.8814C2 13.9214 2.85 14.7814 3.9 14.7814C5.71 14.7814 6.45 16.0614 5.54 17.6314C5.02 18.5414 5.33 19.7014 6.24 20.2214L7.97 21.2114C8.76 21.6814 9.78 21.4014 10.25 20.6114L10.36 20.4214C11.26 18.8514 12.74 18.8514 13.65 20.4214L13.76 20.6114C14.23 21.4014 15.25 21.6814 16.04 21.2114L17.77 20.2214C18.68 19.7014 18.99 18.5314 18.47 17.6314C17.56 16.0614 18.3 14.7814 20.11 14.7814C21.15 14.7814 22.01 13.9314 22.01 12.8814V11.1214C22 10.0814 21.15 9.2214 20.1 9.2214ZM12 15.2514C10.21 15.2514 8.75 13.7914 8.75 12.0014C8.75 10.2114 10.21 8.7514 12 8.7514C13.79 8.7514 15.25 10.2114 15.25 12.0014C15.25 13.7914 13.79 15.2514 12 15.2514Z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="controls-section">
|
<div class="controls-section">
|
||||||
<div class="controls-content">
|
<div class="controls-content">
|
||||||
<div class="input-group">
|
|
||||||
<label for="api-key">API Key</label>
|
|
||||||
<input type="password" id="api-key" placeholder="Google Cloud API Key">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="prompt">Prompt</label>
|
<label for="prompt">Prompt</label>
|
||||||
<div class="prompt-wrapper">
|
<div class="prompt-wrapper">
|
||||||
<textarea id="prompt" placeholder="Describe your imagination..." rows="6"></textarea>
|
<textarea id="prompt" placeholder="Describe your imagination..." rows="6"></textarea>
|
||||||
<button id="refine-prompt-btn" class="prompt-refine-btn" title="Refine with AI">
|
</div>
|
||||||
|
<div class="prompt-actions">
|
||||||
|
<a href="https://chatgpt.com/g/g-6923d39c8efc8191be0bc3089bebc441-banana-prompt-guide"
|
||||||
|
target="_blank" rel="noopener noreferrer" class="prompt-action-btn"
|
||||||
|
title="Prompt Guide">
|
||||||
|
<svg fill="currentColor" height="16px" width="16px" viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" />
|
||||||
|
</svg>
|
||||||
|
<span>Prompt Guide</span>
|
||||||
|
</a>
|
||||||
|
<button id="refine-prompt-btn" class="prompt-action-btn" title="Refine with AI">
|
||||||
<svg fill="currentColor" height="16px" width="16px" version="1.1" id="Layer_1"
|
<svg fill="currentColor" height="16px" width="16px" version="1.1" id="Layer_1"
|
||||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
viewBox="0 0 512.422 512.422" xml:space="preserve">
|
viewBox="0 0 512.422 512.422" xml:space="preserve">
|
||||||
|
|
@ -62,6 +78,7 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
<span>Refine Prompt</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -198,17 +215,17 @@
|
||||||
<div id="refine-modal" class="popup-overlay hidden">
|
<div id="refine-modal" class="popup-overlay hidden">
|
||||||
<div class="popup-card">
|
<div class="popup-card">
|
||||||
<header class="popup-header">
|
<header class="popup-header">
|
||||||
<h2>Refine Prompt</h2>
|
<h2>Tinh chỉnh Prompt</h2>
|
||||||
<button id="close-refine-modal" type="button" class="popup-close" aria-label="Close">×</button>
|
<button id="close-refine-modal" type="button" class="popup-close" aria-label="Close">×</button>
|
||||||
</header>
|
</header>
|
||||||
<div class="popup-body">
|
<div class="popup-body">
|
||||||
<p style="color: var(--text-secondary); font-size: 0.9rem; margin-bottom: 0.5rem;">How would you like to
|
<p style="color: var(--text-secondary); font-size: 0.9rem; margin-bottom: 0.5rem;">Bạn muốn điều chỉnh
|
||||||
change the current prompt?</p>
|
prompt hiện tại như thế nào?</p>
|
||||||
<textarea id="refine-instruction" placeholder="e.g. Make it more realistic, add dramatic lighting..."
|
<textarea id="refine-instruction" placeholder="Ví dụ: Làm cho thật thực tế, thêm ánh sáng điện ảnh..."
|
||||||
rows="3"></textarea>
|
rows="3"></textarea>
|
||||||
<div class="controls-footer" style="margin-top: 1rem; justify-content: flex-end; align-items: center;">
|
<div class="controls-footer" style="margin-top: 1rem; justify-content: flex-end; align-items: center;">
|
||||||
<button id="confirm-refine-btn">
|
<button id="confirm-refine-btn">
|
||||||
<span>Refine</span>
|
<span>Tinh chỉnh</span>
|
||||||
<div class="btn-shine"></div>
|
<div class="btn-shine"></div>
|
||||||
</button>
|
</button>
|
||||||
<div id="refine-loading" class="hidden" style="color: var(--accent-color);">
|
<div id="refine-loading" class="hidden" style="color: var(--accent-color);">
|
||||||
|
|
@ -310,6 +327,49 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="api-settings-overlay" class="popup-overlay hidden" role="dialog" aria-modal="true"
|
||||||
|
aria-labelledby="api-settings-title">
|
||||||
|
<div class="popup-card" style="max-width: 480px;">
|
||||||
|
<header class="popup-header">
|
||||||
|
<h2 id="api-settings-title">Thiết lập API Key</h2>
|
||||||
|
<button id="api-settings-close" type="button" class="popup-close" aria-label="Close">×</button>
|
||||||
|
</header>
|
||||||
|
<div class="popup-body api-settings-body">
|
||||||
|
<p class="api-settings-warning">
|
||||||
|
API cần thiết lập thanh toán với Google để sử dụng. Sau khi có key, lưu vào đây để ứng dụng hoạt
|
||||||
|
động.
|
||||||
|
</p>
|
||||||
|
<div class="input-group api-settings-input-group">
|
||||||
|
<label for="api-key">Google Cloud API Key</label>
|
||||||
|
<div class="api-key-field">
|
||||||
|
<input type="password" id="api-key" placeholder="Google Cloud API Key">
|
||||||
|
<button type="button" id="toggle-api-key-visibility" class="api-key-toggle-btn"
|
||||||
|
aria-label="Hiện API key" aria-pressed="false">
|
||||||
|
<svg class="icon-eye" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M12 4.5c-4.97 0-9.27 3.11-11 7.5 1.73 4.39 6.03 7.5 11 7.5s9.27-3.11 11-7.5C21.27 7.61 16.97 4.5 12 4.5zm0 12a4.5 4.5 0 110-9 4.5 4.5 0 010 9zm0-7a2.5 2.5 0 100 5 2.5 2.5 0 000-5z" />
|
||||||
|
</svg>
|
||||||
|
<svg class="icon-eye-off hidden" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M2 12c2.5-4.5 6.5-7 11-7 1.72 0 3.38.4 4.95 1.16l1.68-1.68L21.5 3 3 21.5l1.48-1.48 1.93-1.93C7.72 20.28 9.83 21 12 21c4.97 0 9.27-3.11 11-7.5-.56-1.43-1.46-2.73-2.55-3.84L20.84 7.8C20.95 8.03 21 8.26 21 8.5c0 3.59-3.39 6.5-9 6.5a8.9 8.9 0 01-4.72-1.27l1.45-1.45c.46.23.95.37 1.46.37 2.76 0 5-2.24 5-5 0-.5-.08-.98-.24-1.43l1.58-1.58C19.12 11.25 20 11.61 21 12c-1.73 4.39-6.03 7.5-11 7.5-1.72 0-3.38-.4-4.95-1.16L2 19.5 3.5 21l18.5-18.5L19.5 0 18 1.5l-1.63 1.63A10.95 10.95 0 0012 1c-4.97 0-9.27 3.11-11 7.5z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p class="input-hint api-key-hint">
|
||||||
|
Lấy API key tại
|
||||||
|
<a href="https://aistudio.google.com/api-keys" target="_blank"
|
||||||
|
rel="noreferrer">aistudio.google.com/api-keys</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="controls-footer" style="justify-content: flex-end; margin-top: 0.5rem;">
|
||||||
|
<button id="save-api-settings-btn">
|
||||||
|
<span>Đóng</span>
|
||||||
|
<div class="btn-shine"></div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="popup-overlay" class="popup-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="popup-title">
|
<div id="popup-overlay" class="popup-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="popup-title">
|
||||||
<div class="popup-card">
|
<div class="popup-card">
|
||||||
<header class="popup-header">
|
<header class="popup-header">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue