fix: improve email content readability in dark mode (#855)

This commit is contained in:
Bowl42
2026-03-04 20:52:19 +08:00
committed by GitHub
parent 928a35b7cb
commit abad88b986
4 changed files with 28 additions and 8 deletions

View File

@@ -18,6 +18,7 @@
- fix: |Admin API| 修复 `/admin/account_settings` 在未配置 KV 且 `fromBlockList` 为空时触发 `Cannot read properties of undefined (reading 'put')` 的问题
- fix: |数据库| 修复 `DB_INIT_QUERIES` 缺少 `idx_raw_mails_message_id` 索引导致 `UPDATE raw_mails ... WHERE message_id = ?` 全表扫描的问题,同步 `schema.sql` 与初始化代码,新增 v0.0.6 迁移逻辑
- fix: |文档| 修复 User Mail API 文档中错误使用 `x-admin-auth` 的问题,改为正确的 `x-user-token`
- fix: |前端| 修复暗色主题下邮件内容文字看不清的问题,优化纯文本邮件和 Shadow DOM 渲染的暗色模式样式
- docs: |文档| 新增 Admin 删除邮件、删除邮箱地址、清空收件箱、清空发件箱 API 文档
### Improvements

View File

@@ -18,6 +18,7 @@
- fix: |Admin API| Fix `/admin/account_settings` throwing `Cannot read properties of undefined (reading 'put')` when KV is not configured and `fromBlockList` is empty
- fix: |Database| Fix missing `idx_raw_mails_message_id` index in `DB_INIT_QUERIES` causing full table scan on `UPDATE raw_mails ... WHERE message_id = ?`, sync `schema.sql` with init code, add v0.0.6 migration
- fix: |Docs| Fix User Mail API documentation incorrectly using `x-admin-auth`, changed to correct `x-user-token`
- fix: |Frontend| Fix email content text being unreadable in dark theme, improve dark mode styles for plain text mail and Shadow DOM rendering
- docs: |Docs| Add Admin API documentation for delete mail, delete address, clear inbox, and clear sent items
### Improvements

View File

@@ -8,7 +8,7 @@ import { getDownloadEmlUrl } from '../utils/email-parser';
import { utcToLocalDate } from '../utils';
import { useGlobalState } from '../store';
const { preferShowTextMail, useIframeShowMail, useUTCDate } = useGlobalState();
const { preferShowTextMail, useIframeShowMail, useUTCDate, isDark } = useGlobalState();
const { t } = useI18n({
messages: {
@@ -184,22 +184,22 @@ const handleSaveToS3 = async (filename, blob) => {
<AiExtractInfo :metadata="mail.metadata" />
<!-- 邮件内容 -->
<div class="mail-content">
<div class="mail-content" :class="{ 'dark-mode': isDark }">
<pre v-if="showTextMail" class="mail-text">{{ mail.text }}</pre>
<iframe v-else-if="useIframeShowMail" :srcdoc="mail.message" class="mail-iframe">
</iframe>
<ShadowHtmlComponent v-else :key="mail.id" :htmlContent="mail.message" class="mail-html" />
<ShadowHtmlComponent v-else :key="mail.id" :htmlContent="mail.message" :isDark="isDark" class="mail-html" />
</div>
</div>
<n-drawer v-model:show="showFullscreen" width="100%" placement="bottom" :trap-focus="false" :block-scroll="false"
style="height: 100vh;">
<n-drawer-content :title="mail.subject" closable>
<div class="fullscreen-mail-content">
<div class="fullscreen-mail-content" :class="{ 'dark-mode': isDark }">
<pre v-if="showTextMail" class="mail-text">{{ mail.text }}</pre>
<iframe v-else-if="useIframeShowMail" :srcdoc="mail.message" class="mail-iframe">
</iframe>
<ShadowHtmlComponent v-else :key="mail.id" :htmlContent="mail.message" class="mail-html" />
<ShadowHtmlComponent v-else :key="mail.id" :htmlContent="mail.message" :isDark="isDark" class="mail-html" />
</div>
</n-drawer-content>
</n-drawer>
@@ -259,6 +259,10 @@ const handleSaveToS3 = async (filename, blob) => {
line-height: inherit;
}
.dark-mode .mail-text {
color: #e0e0e0;
}
.mail-iframe {
width: 100%;
height: 100%;
@@ -266,6 +270,10 @@ const handleSaveToS3 = async (filename, blob) => {
min-height: 400px;
}
.dark-mode .mail-iframe {
background-color: #fff;
}
.mail-html {
width: 100%;
height: 100%;

View File

@@ -11,6 +11,10 @@ const props = defineProps({
type: String,
required: true,
},
isDark: {
type: Boolean,
default: false,
},
});
const shadowHost = ref(null);
@@ -40,7 +44,13 @@ const renderShadowDom = () => {
// Update content if Shadow DOM exists
if (shadowRoot) {
shadowRoot.innerHTML = props.htmlContent;
const darkModeStyle = props.isDark
? `<style>
:host { color: #e0e0e0; }
a { color: #A8C7FA; }
</style>`
: '';
shadowRoot.innerHTML = darkModeStyle + props.htmlContent;
}
} catch (error) {
console.error('Failed to render Shadow DOM, falling back to v-html:', error);
@@ -68,8 +78,8 @@ onBeforeUnmount(() => {
shadowRoot = null;
});
// Update Shadow DOM when htmlContent changes
watch(() => props.htmlContent, () => {
// Update Shadow DOM when htmlContent or dark mode changes
watch(() => [props.htmlContent, props.isDark], () => {
renderShadowDom();
}, { flush: 'post' });
</script>