Feature(custom): release not now use markdown render, also optimize UI dispaly of update page

This commit is contained in:
Kuingsmile
2026-01-12 11:51:27 +08:00
parent 9accc4e4da
commit 2443f56562
4 changed files with 3242 additions and 3199 deletions

View File

@@ -99,6 +99,7 @@ const buildMainPageMenu = (win: BrowserWindow) => {
label: $t('ABOUT'), label: $t('ABOUT'),
click() { click() {
dialog.showMessageBox({ dialog.showMessageBox({
type: 'info',
title: 'PicList', title: 'PicList',
message: 'PicList', message: 'PicList',
detail: `Version: ${pkg.version}\nAuthor: Kuingsmile\nGithub: https://github.com/Kuingsmile/PicList`, detail: `Version: ${pkg.version}\nAuthor: Kuingsmile\nGithub: https://github.com/Kuingsmile/PicList`,

View File

@@ -12,7 +12,7 @@
class="collapse-button" class="collapse-button"
@click="isCollapsed = !isCollapsed" @click="isCollapsed = !isCollapsed"
> >
<component :is="isCollapsed ? ChevronRightIcon : ChevronLeftIcon" :size="20" /> <component :is="isCollapsed ? ChevronRightIcon : ChevronLeftIcon" :size="16" />
</button> </button>
</div> </div>

View File

@@ -846,15 +846,6 @@
<!-- Update Preferences --> <!-- Update Preferences -->
<div class="settings-section update-preferences-section"> <div class="settings-section update-preferences-section">
<div class="section-header-with-icon">
<div class="section-icon-wrapper update small-icon">
<Settings :size="15" />
</div>
<div>
<h2>{{ t('pages.settings.update.updatePreferences') }}</h2>
</div>
</div>
<div class="update-preference-card"> <div class="update-preference-card">
<label class="switch-label"> <label class="switch-label">
<input v-model="formOfSetting.showUpdateTip" type="checkbox" class="switch-input" /> <input v-model="formOfSetting.showUpdateTip" type="checkbox" class="switch-input" />
@@ -871,15 +862,6 @@
<!-- Release Notes Section --> <!-- Release Notes Section -->
<div class="settings-section release-notes-section"> <div class="settings-section release-notes-section">
<div class="section-header-with-icon">
<div class="section-icon-wrapper notes small-icon">
<FileText :size="15" />
</div>
<div>
<h2>{{ t('pages.settings.update.releaseNotes') }}</h2>
</div>
</div>
<div class="release-notes-card enhanced"> <div class="release-notes-card enhanced">
<div class="release-notes-header"> <div class="release-notes-header">
<div class="release-notes-title"> <div class="release-notes-title">
@@ -905,9 +887,7 @@
</div> </div>
<span>{{ t('pages.settings.update.loadingReleaseNotes') }}</span> <span>{{ t('pages.settings.update.loadingReleaseNotes') }}</span>
</div> </div>
<div v-else-if="releaseNotes" class="release-notes-text"> <div v-else-if="releaseNotes" class="notes-body" v-html="renderedReleaseNotes"></div>
<pre class="release-notes-pre">{{ releaseNotes }}</pre>
</div>
<div v-else-if="releaseNotesError" class="release-notes-error"> <div v-else-if="releaseNotesError" class="release-notes-error">
<div class="error-icon"></div> <div class="error-icon"></div>
<span>{{ releaseNotesError }}</span> <span>{{ releaseNotesError }}</span>
@@ -1779,6 +1759,7 @@ import {
Settings, Settings,
Store, Store,
} from 'lucide-vue-next' } from 'lucide-vue-next'
import { marked } from 'marked'
import type { IConfig } from 'piclist' import type { IConfig } from 'piclist'
import pkg from 'root/package.json' import pkg from 'root/package.json'
import { computed, onBeforeMount, reactive, ref, toRaw, watch } from 'vue' import { computed, onBeforeMount, reactive, ref, toRaw, watch } from 'vue'
@@ -2267,6 +2248,10 @@ function formatLastFetchTime(date: Date): string {
} }
} }
const renderedReleaseNotes = computed(() => {
return marked(releaseNotes.value, { breaks: true, gfm: true })
})
async function fetchReleaseNotes(forceRefresh = false): Promise<void> { async function fetchReleaseNotes(forceRefresh = false): Promise<void> {
if (!forceRefresh && releaseNotesLastFetch.value) { if (!forceRefresh && releaseNotesLastFetch.value) {
const timeSinceLastFetch = Date.now() - releaseNotesLastFetch.value.getTime() const timeSinceLastFetch = Date.now() - releaseNotesLastFetch.value.getTime()

View File

@@ -1,3 +1,4 @@
/* stylelint-disable selector-pseudo-class-no-unknown */
.piclist-settings { .piclist-settings {
overflow-y: auto; overflow-y: auto;
padding: 1.5rem; padding: 1.5rem;
@@ -876,7 +877,6 @@ small {
max-height: 400px; max-height: 400px;
background: var(--color-background); background: var(--color-background);
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: var(--color-accent) transparent;
} }
.release-notes-content::-webkit-scrollbar { .release-notes-content::-webkit-scrollbar {
@@ -919,10 +919,6 @@ small {
gap: 0.75rem; gap: 0.75rem;
} }
.release-notes-text {
padding: 0;
}
.release-notes-pre { .release-notes-pre {
margin: 0; margin: 0;
border: none; border: none;
@@ -3175,3 +3171,64 @@ small {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
} }
.notes-body {
overflow-y: auto;
border-radius: 12px;
padding: 1.25rem;
max-height: 195px;
font-size: 0.9375rem;
line-height: 1.5;
background: #f8fafc;
color: #475569;
}
.notes-body :deep(h1),
.notes-body :deep(h2),
.notes-body :deep(h3) {
margin-top: 1.25rem;
margin-bottom: 0.5rem;
font-weight: 700;
color: #1e293b;
}
.notes-body :deep(h1:first-child),
.notes-body :deep(h2:first-child),
.notes-body :deep(h3:first-child) {
margin-top: 0;
}
.notes-body :deep(p) {
margin-bottom: 0.875rem;
}
.notes-body :deep(ul),
.notes-body :deep(ol) {
padding-left: 1.5rem;
margin: 0.875rem 0;
}
.notes-body :deep(li) {
margin-bottom: 0.375rem;
}
.notes-body :deep(code) {
border-radius: 4px;
padding: 0.125rem 0.375rem;
font-size: 0.875em;
background: #e2e8f0;
color: #334155;
}
.notes-body :deep(pre) {
overflow-x: auto;
border-radius: 8px;
padding: 1rem;
margin: 0.875rem 0;
background: #e2e8f0;
}
.notes-body :deep(pre code) {
padding: 0;
background: transparent;
}