[System Pop Up] Improve help center and what's new popup UI (#4395)

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
bmcomfy
2025-07-09 16:17:50 -07:00
committed by Terry Jia
parent 11b6677438
commit 5ced4eaf04
10 changed files with 125 additions and 95 deletions

View File

@@ -162,7 +162,7 @@ const TIME_UNITS = {
const SUBMENU_CONFIG = { const SUBMENU_CONFIG = {
DELAY_MS: 100, DELAY_MS: 100,
OFFSET_PX: 8, OFFSET_PX: 8,
Z_INDEX: 1002 Z_INDEX: 10001
} as const } as const
// Composables // Composables

View File

@@ -32,28 +32,32 @@
<div class="whats-new-popup" @click.stop> <div class="whats-new-popup" @click.stop>
<!-- Close Button --> <!-- Close Button -->
<button class="close-button" aria-label="Close" @click="closePopup"> <button
class="close-button"
:aria-label="$t('g.close')"
@click="closePopup"
>
<div class="close-icon"></div> <div class="close-icon"></div>
</button> </button>
<!-- Release Content --> <!-- Release Content -->
<div class="popup-content"> <div class="popup-content">
<div class="content-text" v-html="formattedContent"></div> <div class="content-text" v-html="formattedContent"></div>
</div>
<!-- Actions Section --> <!-- Actions Section -->
<div class="popup-actions"> <div class="popup-actions">
<a <a
class="learn-more-link" class="learn-more-link"
:href="changelogUrl" :href="changelogUrl"
target="_blank" target="_blank"
rel="noopener,noreferrer" rel="noopener,noreferrer"
@click="closePopup" @click="closePopup"
> >
{{ $t('whatsNewPopup.learnMore') }} {{ $t('whatsNewPopup.learnMore') }}
</a> </a>
<!-- TODO: CTA button --> <!-- TODO: CTA button -->
<!-- <button class="cta-button" @click="handleCTA">CTA</button> --> <!-- <button class="cta-button" @click="handleCTA">CTA</button> -->
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -68,7 +72,7 @@ import type { ReleaseNote } from '@/services/releaseService'
import { useReleaseStore } from '@/stores/releaseStore' import { useReleaseStore } from '@/stores/releaseStore'
import { formatVersionAnchor } from '@/utils/formatUtil' import { formatVersionAnchor } from '@/utils/formatUtil'
const { locale } = useI18n() const { locale, t } = useI18n()
const releaseStore = useReleaseStore() const releaseStore = useReleaseStore()
// Local state for dismissed status // Local state for dismissed status
@@ -101,13 +105,12 @@ const changelogUrl = computed(() => {
// Format release content for display using marked // Format release content for display using marked
const formattedContent = computed(() => { const formattedContent = computed(() => {
if (!latestRelease.value?.content) { if (!latestRelease.value?.content) {
return '<p>No release notes available.</p>' return `<p>${t('whatsNewPopup.noReleaseNotes')}</p>`
} }
try { try {
// Use marked to parse markdown to HTML // Use marked to parse markdown to HTML
return marked(latestRelease.value.content, { return marked(latestRelease.value.content, {
breaks: true, // Convert line breaks to <br>
gfm: true // Enable GitHub Flavored Markdown gfm: true // Enable GitHub Flavored Markdown
}) })
} catch (error) { } catch (error) {
@@ -199,14 +202,10 @@ defineExpose({
} }
.whats-new-popup { .whats-new-popup {
padding: 32px 32px 24px;
background: #353535; background: #353535;
border-radius: 12px; border-radius: 12px;
max-width: 400px; max-width: 400px;
width: 400px; width: 400px;
display: flex;
flex-direction: column;
gap: 32px;
outline: 1px solid #4e4e4e; outline: 1px solid #4e4e4e;
outline-offset: -1px; outline-offset: -1px;
box-shadow: 0px 8px 32px rgba(0, 0, 0, 0.3); box-shadow: 0px 8px 32px rgba(0, 0, 0, 0.3);
@@ -217,6 +216,10 @@ defineExpose({
.popup-content { .popup-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 24px;
overflow: hidden;
padding: 32px 32px 24px;
border-radius: 12px;
} }
/* Close button */ /* Close button */
@@ -224,17 +227,17 @@ defineExpose({
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
width: 31px; width: 32px;
height: 31px; height: 32px;
padding: 6px 7px; padding: 6px;
background: #7c7c7c; background: #7c7c7c;
border-radius: 15.5px; border-radius: 16px;
border: none; border: none;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
transform: translate(50%, -50%); transform: translate(30%, -30%);
transition: transition:
background-color 0.2s ease, background-color 0.2s ease,
transform 0.1s ease; transform 0.1s ease;
@@ -247,7 +250,7 @@ defineExpose({
.close-button:active { .close-button:active {
background: #6a6a6a; background: #6a6a6a;
transform: translate(50%, -50%) scale(0.95); transform: translate(30%, -30%) scale(0.95);
} }
.close-icon { .close-icon {
@@ -288,73 +291,45 @@ defineExpose({
.content-text { .content-text {
color: white; color: white;
font-size: 14px; font-size: 14px;
font-family: 'Inter', sans-serif;
font-weight: 400;
line-height: 1.5; line-height: 1.5;
word-wrap: break-word; word-wrap: break-word;
} }
/* Style the markdown content */ /* Style the markdown content */
/* Title */
.content-text :deep(*) {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.content-text :deep(h1) { .content-text :deep(h1) {
color: white;
font-size: 20px;
font-weight: 700;
margin: 0 0 16px 0;
line-height: 1.3;
}
.content-text :deep(h2) {
color: white;
font-size: 18px;
font-weight: 600;
margin: 16px 0 12px 0;
line-height: 1.3;
}
.content-text :deep(h2:first-child) {
margin-top: 0;
}
.content-text :deep(h3) {
color: white;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 700;
margin: 12px 0 8px 0; margin-bottom: 8px;
line-height: 1.3;
} }
.content-text :deep(h3:first-child) { /* Version subtitle - targets the first p tag after h1 */
margin-top: 0; .content-text :deep(h1 + p) {
} color: #c0c0c0;
font-size: 16px;
.content-text :deep(h4) { font-weight: 500;
color: white; margin-bottom: 16px;
font-size: 14px; opacity: 0.8;
font-weight: 600;
margin: 8px 0 6px 0;
}
.content-text :deep(h4:first-child) {
margin-top: 0;
} }
/* Regular paragraphs - short description */
.content-text :deep(p) { .content-text :deep(p) {
margin: 0 0 12px 0; margin-bottom: 16px;
line-height: 1.6; color: #e0e0e0;
}
.content-text :deep(p:first-child) {
margin-top: 0;
}
.content-text :deep(p:last-child) {
margin-bottom: 0;
} }
/* List */
.content-text :deep(ul), .content-text :deep(ul),
.content-text :deep(ol) { .content-text :deep(ol) {
margin: 0 0 12px 0; margin-bottom: 16px;
padding-left: 24px; padding-left: 0;
list-style: none;
} }
.content-text :deep(ul:first-child), .content-text :deep(ul:first-child),
@@ -367,12 +342,63 @@ defineExpose({
margin-bottom: 0; margin-bottom: 0;
} }
/* List items */
.content-text :deep(li) {
margin-bottom: 8px;
position: relative;
padding-left: 20px;
}
.content-text :deep(li:last-child) {
margin-bottom: 0;
}
/* Custom bullet points */
.content-text :deep(li::before) {
content: '';
position: absolute;
left: 0;
top: 10px;
display: flex;
width: 8px;
height: 8px;
justify-content: center;
align-items: center;
aspect-ratio: 1/1;
border-radius: 100px;
background: #60a5fa;
}
/* List item strong text */
.content-text :deep(li strong) {
color: #fff;
font-size: 14px;
display: block;
margin-bottom: 4px;
}
.content-text :deep(li p) {
font-size: 12px;
margin-bottom: 0;
line-height: 2;
}
/* Code styling */
.content-text :deep(code) {
background-color: #2a2a2a;
border: 1px solid #4a4a4a;
border-radius: 4px;
padding: 2px 6px;
color: #f8f8f2;
white-space: nowrap;
}
/* Remove top margin for first media element */ /* Remove top margin for first media element */
.content-text :deep(img:first-child), .content-text :deep(img:first-child),
.content-text :deep(video:first-child), .content-text :deep(video:first-child),
.content-text :deep(iframe:first-child) { .content-text :deep(iframe:first-child) {
margin-top: -32px; /* Align with the top edge of the popup content */ margin-top: -32px; /* Align with the top edge of the popup content */
margin-bottom: 12px; margin-bottom: 24px;
} }
/* Media elements */ /* Media elements */
@@ -381,8 +407,7 @@ defineExpose({
.content-text :deep(iframe) { .content-text :deep(iframe) {
width: calc(100% + 64px); width: calc(100% + 64px);
height: auto; height: auto;
border-radius: 6px; margin: 24px -32px;
margin: 12px -32px;
display: block; display: block;
} }
@@ -397,7 +422,6 @@ defineExpose({
.learn-more-link { .learn-more-link {
color: #60a5fa; color: #60a5fa;
font-size: 14px; font-size: 14px;
font-family: 'Inter', sans-serif;
font-weight: 500; font-weight: 500;
line-height: 18.2px; line-height: 18.2px;
text-decoration: none; text-decoration: none;
@@ -417,7 +441,6 @@ defineExpose({
border: none; border: none;
color: #121212; color: #121212;
font-size: 14px; font-size: 14px;
font-family: 'Inter', sans-serif;
font-weight: 500; font-weight: 500;
cursor: pointer; cursor: pointer;
} }

View File

@@ -46,7 +46,7 @@
</Teleport> </Teleport>
<!-- Backdrop to close popup when clicking outside --> <!-- Backdrop to close popup when clicking outside -->
<Teleport to="#graph-canvas-container"> <Teleport to="body">
<div <div
v-if="isHelpCenterVisible" v-if="isHelpCenterVisible"
class="help-center-backdrop" class="help-center-backdrop"
@@ -101,14 +101,14 @@ onMounted(async () => {
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: 999; z-index: 9999;
background: transparent; background: transparent;
} }
.help-center-popup { .help-center-popup {
position: absolute; position: absolute;
bottom: 1rem; bottom: 1rem;
z-index: 1000; z-index: 10000;
animation: slideInUp 0.2s ease-out; animation: slideInUp 0.2s ease-out;
pointer-events: auto; pointer-events: auto;
} }

View File

@@ -1489,6 +1489,7 @@
"loadError": "Failed to load help: {error}" "loadError": "Failed to load help: {error}"
}, },
"whatsNewPopup": { "whatsNewPopup": {
"learnMore": "Learn more" "learnMore": "Learn more",
"noReleaseNotes": "No release notes available."
} }
} }

View File

@@ -1484,7 +1484,8 @@
"title": "Bienvenido a ComfyUI" "title": "Bienvenido a ComfyUI"
}, },
"whatsNewPopup": { "whatsNewPopup": {
"learnMore": "Aprende más" "learnMore": "Aprende más",
"noReleaseNotes": "No hay notas de la versión disponibles."
}, },
"workflowService": { "workflowService": {
"enterFilename": "Introduzca el nombre del archivo", "enterFilename": "Introduzca el nombre del archivo",

View File

@@ -1484,7 +1484,8 @@
"title": "Bienvenue sur ComfyUI" "title": "Bienvenue sur ComfyUI"
}, },
"whatsNewPopup": { "whatsNewPopup": {
"learnMore": "En savoir plus" "learnMore": "En savoir plus",
"noReleaseNotes": "Aucune note de version disponible."
}, },
"workflowService": { "workflowService": {
"enterFilename": "Entrez le nom du fichier", "enterFilename": "Entrez le nom du fichier",

View File

@@ -1484,7 +1484,8 @@
"title": "ComfyUIへようこそ" "title": "ComfyUIへようこそ"
}, },
"whatsNewPopup": { "whatsNewPopup": {
"learnMore": "詳細はこちら" "learnMore": "詳細はこちら",
"noReleaseNotes": "リリースノートはありません。"
}, },
"workflowService": { "workflowService": {
"enterFilename": "ファイル名を入力", "enterFilename": "ファイル名を入力",

View File

@@ -1484,7 +1484,8 @@
"title": "ComfyUI에 오신 것을 환영합니다" "title": "ComfyUI에 오신 것을 환영합니다"
}, },
"whatsNewPopup": { "whatsNewPopup": {
"learnMore": "자세히 알아보기" "learnMore": "자세히 알아보기",
"noReleaseNotes": "릴리스 노트가 없습니다."
}, },
"workflowService": { "workflowService": {
"enterFilename": "파일 이름 입력", "enterFilename": "파일 이름 입력",

View File

@@ -1484,7 +1484,8 @@
"title": "Добро пожаловать в ComfyUI" "title": "Добро пожаловать в ComfyUI"
}, },
"whatsNewPopup": { "whatsNewPopup": {
"learnMore": "Узнать больше" "learnMore": "Узнать больше",
"noReleaseNotes": "Нет доступных примечаний к выпуску."
}, },
"workflowService": { "workflowService": {
"enterFilename": "Введите название файла", "enterFilename": "Введите название файла",

View File

@@ -1484,7 +1484,8 @@
"title": "欢迎使用 ComfyUI" "title": "欢迎使用 ComfyUI"
}, },
"whatsNewPopup": { "whatsNewPopup": {
"learnMore": "了解更多" "learnMore": "了解更多",
"noReleaseNotes": "暂无更新说明。"
}, },
"workflowService": { "workflowService": {
"enterFilename": "输入文件名", "enterFilename": "输入文件名",