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');
|
||||
createTemplateBtn.className = 'template-create-btn';
|
||||
createTemplateBtn.innerHTML = `
|
||||
<svg width="16" height="16" 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"/>
|
||||
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<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>
|
||||
`;
|
||||
createTemplateBtn.addEventListener('click', () => {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
const aspectRatioInput = document.getElementById('aspect-ratio');
|
||||
const resolutionInput = document.getElementById('resolution');
|
||||
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 loadingState = document.getElementById('loading-state');
|
||||
|
|
@ -132,10 +139,58 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
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();
|
||||
slotManager.initialize(savedSettings.referenceImages || []);
|
||||
|
||||
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);
|
||||
aspectRatioInput.addEventListener('change', persistSettings);
|
||||
resolutionInput.addEventListener('change', persistSettings);
|
||||
|
|
@ -146,6 +201,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
const resolution = resolutionInput.value;
|
||||
const apiKey = apiKeyInput.value.trim();
|
||||
|
||||
if (!apiKey) {
|
||||
openApiSettings();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prompt) {
|
||||
showError('Please enter a prompt.');
|
||||
return;
|
||||
|
|
|
|||
171
static/style.css
171
static/style.css
|
|
@ -156,6 +156,15 @@ a:hover {
|
|||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
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 {
|
||||
|
|
@ -163,7 +172,7 @@ a:hover {
|
|||
height: 36px;
|
||||
padding: 0;
|
||||
min-width: 36px;
|
||||
border-radius: 0;
|
||||
border-radius: 50%;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
|
|
@ -207,6 +216,9 @@ a:hover {
|
|||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
margin-top: 1rem;
|
||||
padding-right: 10px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
.controls-footer {
|
||||
|
|
@ -231,12 +243,88 @@ a:hover {
|
|||
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 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
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 {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
|
|
@ -260,6 +348,8 @@ select {
|
|||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
input[type="password"], input[type="text"] {
|
||||
width: 100%;}
|
||||
select {
|
||||
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");
|
||||
|
|
@ -318,40 +408,52 @@ textarea {
|
|||
|
||||
.prompt-wrapper textarea {
|
||||
width: 100%;
|
||||
padding-bottom: 2.5rem; /* Make space for the button */
|
||||
}
|
||||
|
||||
.prompt-refine-btn {
|
||||
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);
|
||||
.prompt-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.prompt-action-btn {
|
||||
display: inline-flex;
|
||||
align-items: 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;
|
||||
transition: all 0.2s;
|
||||
z-index: 5;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.prompt-refine-btn:hover {
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
.prompt-action-btn:hover {
|
||||
background: rgba(251, 191, 36, 0.25);
|
||||
color: var(--accent-color);
|
||||
border-color: var(--accent-color);
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 10px rgba(251, 191, 36, 0.3);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.prompt-refine-btn svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
.prompt-action-btn svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
fill: currentColor;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.prompt-action-btn span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#confirm-refine-btn {
|
||||
|
|
@ -947,8 +1049,8 @@ button#generate-btn:disabled {
|
|||
/* Canvas Language Toggle (Top-Left Corner) */
|
||||
.canvas-lang-toggle {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
left: 1rem;
|
||||
top: 1.2rem;
|
||||
left: 2rem;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
|
|
@ -1493,6 +1595,29 @@ button#generate-btn:disabled {
|
|||
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 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
|
|
|||
|
|
@ -21,24 +21,40 @@
|
|||
<div class="brand">
|
||||
<h1>aPix <span class="badge">by SDVN</span></h1>
|
||||
</div>
|
||||
<button type="button" class="toolbar-info-btn info-icon-btn" data-popup-target="help"
|
||||
aria-label="Thông tin và hướng dẫn">
|
||||
<span aria-hidden="true">i</span>
|
||||
</button>
|
||||
<div class="sidebar-header-actions">
|
||||
<button type="button" class="toolbar-info-btn info-icon-btn" data-popup-target="help"
|
||||
aria-label="Thông tin và hướng dẫn">
|
||||
<span aria-hidden="true">i</span>
|
||||
</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 class="controls-section">
|
||||
<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">
|
||||
<label for="prompt">Prompt</label>
|
||||
<div class="prompt-wrapper">
|
||||
<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"
|
||||
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">
|
||||
|
|
@ -62,6 +78,7 @@
|
|||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<span>Refine Prompt</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -198,17 +215,17 @@
|
|||
<div id="refine-modal" class="popup-overlay hidden">
|
||||
<div class="popup-card">
|
||||
<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>
|
||||
</header>
|
||||
<div class="popup-body">
|
||||
<p style="color: var(--text-secondary); font-size: 0.9rem; margin-bottom: 0.5rem;">How would you like to
|
||||
change the current prompt?</p>
|
||||
<textarea id="refine-instruction" placeholder="e.g. Make it more realistic, add dramatic lighting..."
|
||||
<p style="color: var(--text-secondary); font-size: 0.9rem; margin-bottom: 0.5rem;">Bạn muốn điều chỉnh
|
||||
prompt hiện tại như thế nào?</p>
|
||||
<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>
|
||||
<div class="controls-footer" style="margin-top: 1rem; justify-content: flex-end; align-items: center;">
|
||||
<button id="confirm-refine-btn">
|
||||
<span>Refine</span>
|
||||
<span>Tinh chỉnh</span>
|
||||
<div class="btn-shine"></div>
|
||||
</button>
|
||||
<div id="refine-loading" class="hidden" style="color: var(--accent-color);">
|
||||
|
|
@ -310,6 +327,49 @@
|
|||
</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 class="popup-card">
|
||||
<header class="popup-header">
|
||||
|
|
@ -322,4 +382,4 @@
|
|||
<script type="module" src="{{ url_for('static', filename='script.js') }}"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
Loading…
Reference in a new issue