Merge pull request #584 from CH-122/fix/mobile-theme-mode

fix: 手机状态栏暗黑模式背景颜色显示不正确
This commit is contained in:
Tim
2025-08-15 15:48:09 +08:00
committed by GitHub
5 changed files with 75 additions and 6 deletions

View File

@@ -16,7 +16,7 @@
<NuxtPage keepalive />
</div>
<div v-if="showNewPostIcon && isMobile" class="new-post-icon" @click="goToNewPost">
<div v-if="showNewPostIcon && isMobile" class="app-new-post-icon" @click="goToNewPost">
<i class="fas fa-edit"></i>
</div>
</div>
@@ -74,7 +74,7 @@ const goToNewPost = () => {
</script>
<style src="~/assets/global.css"></style>
<style scoped>
<style>
.header-container {
position: fixed;
top: 0;
@@ -107,7 +107,7 @@ const goToNewPost = () => {
margin: 0 auto;
}
.new-post-icon {
.app-new-post-icon {
background-color: var(--new-post-icon-color);
color: white;
width: 60px;

View File

@@ -25,6 +25,10 @@
<i class="fas fa-search"></i>
</div>
<div v-if="isMobile" class="theme-icon" @click="cycleTheme">
<i :class="iconClass"></i>
</div>
<ToolTip v-if="!isMobile" content="发帖" placement="bottom">
<div class="new-post-icon" @click="goToNewPost">
<i class="fas fa-edit"></i>
@@ -64,6 +68,8 @@ import SearchDropdown from '~/components/SearchDropdown.vue'
import { authState, clearToken, loadCurrentUser } from '~/utils/auth'
import { fetchUnreadCount, notificationState } from '~/utils/notification'
import { useIsMobile } from '~/utils/screen'
import { themeState, cycleTheme, ThemeMode } from '~/utils/theme'
const props = defineProps({
showMenuBtn: {
type: Boolean,
@@ -136,6 +142,18 @@ const headerMenuItems = computed(() => [
{ text: '退出', onClick: goToLogout },
])
/** 其余逻辑保持不变 */
const iconClass = computed(() => {
switch (themeState.mode) {
case ThemeMode.DARK:
return 'fas fa-moon'
case ThemeMode.LIGHT:
return 'fas fa-sun'
default:
return 'fas fa-desktop'
}
})
onMounted(async () => {
const updateAvatar = async () => {
if (authState.loggedIn) {
@@ -287,7 +305,7 @@ onMounted(async () => {
background-color: var(--menu-selected-background-color);
}
.search-icon {
.search-icon, .theme-icon {
font-size: 18px;
cursor: pointer;
}

View File

@@ -117,7 +117,7 @@
</div>
<!-- 解决动态样式的水合错误 -->
<ClientOnly>
<ClientOnly v-if='!isMobile'>
<div class="menu-footer">
<div class="menu-footer-btn" @click="cycleTheme">
<i :class="iconClass"></i>
@@ -133,6 +133,9 @@ import { ref, computed, watch, onMounted } from 'vue'
import { themeState, cycleTheme, ThemeMode } from '~/utils/theme'
import { authState } from '~/utils/auth'
import { fetchUnreadCount, notificationState } from '~/utils/notification'
import { useIsMobile } from '~/utils/screen'
const isMobile = useIsMobile()
const config = useRuntimeConfig()
const API_BASE_URL = config.public.apiBaseUrl

View File

@@ -26,7 +26,31 @@ export default defineNuxtConfig({
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = mode === 'dark' || mode === 'light' ? mode : (prefersDark ? 'dark' : 'light');
document.documentElement.dataset.theme = theme;
} catch (e) {}
let themeColor = '#fff';
let themeStatus = 'default';
if (theme === 'dark') {
themeColor = '#333';
themeStatus = 'black-translucent';
} else {
themeColor = '#ffffff';
themeStatus = 'default';
}
const androidMeta = document.createElement('meta');
androidMeta.name = 'theme-color';
androidMeta.content = themeColor;
const iosMeta = document.createElement('meta');
iosMeta.name = 'apple-mobile-web-app-status-bar-style';
iosMeta.content = themeStatus;
document.head.appendChild(androidMeta);
document.head.appendChild(iosMeta);
} catch (e) {
console.warn('Theme initialization failed:', e);
}
})();
`,
},

View File

@@ -24,6 +24,30 @@ function apply(mode) {
: mode
if (root.dataset.theme === newMode) return
root.dataset.theme = newMode
// 更新 meta 标签
const androidMeta = document.querySelector('meta[name="theme-color"]')
const iosMeta = document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]')
const themeColor = getComputedStyle(document.documentElement).getPropertyValue('--background-color').trim();
const themeStatus = newMode === 'dark' ? 'black-translucent' : 'default'
if (androidMeta) {
androidMeta.content = themeColor
} else {
const newAndroidMeta = document.createElement('meta')
newAndroidMeta.name = 'theme-color'
newAndroidMeta.content = themeColor
document.head.appendChild(newAndroidMeta)
}
if (iosMeta) {
iosMeta.content = themeStatus
} else {
const newIosMeta = document.createElement('meta')
newIosMeta.name = 'apple-mobile-web-app-status-bar-style'
newIosMeta.content = themeStatus
document.head.appendChild(newIosMeta)
}
}
export function initTheme() {