Compare commits

..

1 Commits

Author SHA1 Message Date
Tim
2322b2da15 feat: remember selected tab 2025-08-16 16:10:37 +08:00
10 changed files with 18 additions and 116 deletions

View File

@@ -131,7 +131,7 @@ const goToNewPost = () => {
cursor: pointer;
z-index: 1000;
display: flex;
backdrop-filter: var(--blur-5);
backdrop-filter: blur(5px);
justify-content: center;
align-items: center;
}

View File

@@ -7,11 +7,6 @@
--header-background-color: white;
--header-border-color: lightgray;
--header-text-color: black;
--blur-1: blur(1px);
--blur-2: blur(2px);
--blur-4: blur(4px);
--blur-5: blur(5px);
--blur-10: blur(10px);
/* 加一个app前缀防止与firefox的userChrome.css中的--menu-background-color冲突 */
--app-menu-background-color: white;
--background-color: white;
@@ -64,14 +59,6 @@
--activity-card-background-color: #585858;
}
:root[data-frosted='off'] {
--blur-1: none;
--blur-2: none;
--blur-4: none;
--blur-5: none;
--blur-10: none;
}
body {
margin: 0;
padding: 0;

View File

@@ -41,8 +41,8 @@ export default {
left: 0;
right: 0;
bottom: 0;
backdrop-filter: var(--blur-2);
-webkit-backdrop-filter: var(--blur-2);
backdrop-filter: blur(2px);
-webkit-backdrop-filter: blur(2px);
}
.popup-content {
position: relative;

View File

@@ -188,7 +188,7 @@ onMounted(async () => {
justify-content: center;
height: var(--header-height);
background-color: var(--background-color-blur);
backdrop-filter: var(--blur-10);
backdrop-filter: blur(10px);
color: var(--header-text-color);
border-bottom: 1px solid var(--header-border-color);
}

View File

@@ -35,7 +35,7 @@ const goLogin = () => {
left: 0;
right: 0;
bottom: 0;
backdrop-filter: var(--blur-4);
backdrop-filter: blur(4px);
z-index: 1;
}

View File

@@ -150,6 +150,13 @@ const topics = ref(['最新回复', '最新', '排行榜' /*, '热门', '类别'
const selectedTopic = ref(
route.query.view === 'ranking' ? '排行榜' : route.query.view === 'latest' ? '最新' : '最新回复',
)
if (import.meta.client) {
const storedTopic = localStorage.getItem('home-selected-topic')
if (storedTopic && topics.value.includes(storedTopic)) {
selectedTopic.value = storedTopic
}
}
const articles = ref([])
const page = ref(0)
const pageSize = 10
@@ -340,7 +347,10 @@ watch(
watch([selectedCategory, selectedTags], () => {
loadOptions()
})
watch(selectedTopic, () => {
watch(selectedTopic, (topic) => {
if (import.meta.client) {
localStorage.setItem('home-selected-topic', topic)
}
// 仅当需要额外选项时加载
loadOptions()
})

View File

@@ -36,13 +36,6 @@
<BaseInput v-model="introduction" textarea rows="3" placeholder="说些什么..." />
<div class="setting-description">自我介绍会出现在你的个人主页可以简要介绍自己</div>
</div>
<div class="form-row switch-row">
<div class="setting-title">毛玻璃效果</div>
<label class="switch">
<input type="checkbox" v-model="frosted" />
<span class="slider"></span>
</label>
</div>
</div>
<div v-if="role === 'ADMIN'" class="admin-section">
<h3>管理员设置</h3>
@@ -72,13 +65,12 @@
</template>
<script setup>
import { ref, onMounted, watch } from 'vue'
import { ref, onMounted } from 'vue'
import AvatarCropper from '~/components/AvatarCropper.vue'
import BaseInput from '~/components/BaseInput.vue'
import Dropdown from '~/components/Dropdown.vue'
import { toast } from '~/main'
import { fetchCurrentUser, getToken, setToken } from '~/utils/auth'
import { frostedState, setFrosted } from '~/utils/frosted'
const config = useRuntimeConfig()
const API_BASE_URL = config.public.apiBaseUrl
const username = ref('')
@@ -95,7 +87,6 @@ const aiFormatLimit = ref(3)
const registerMode = ref('DIRECT')
const isLoadingPage = ref(false)
const isSaving = ref(false)
const frosted = ref(true)
onMounted(async () => {
isLoadingPage.value = true
@@ -114,7 +105,6 @@ onMounted(async () => {
navigateTo('/login', { replace: true })
}
isLoadingPage.value = false
frosted.value = frostedState.enabled
})
const onAvatarChange = (e) => {
@@ -128,7 +118,6 @@ const onAvatarChange = (e) => {
reader.readAsDataURL(file)
}
}
watch(frosted, (val) => setFrosted(val))
const onCropped = ({ file, url }) => {
avatarFile.value = file
avatar.value = url
@@ -311,58 +300,6 @@ const save = async () => {
max-width: 200px;
}
.switch-row {
flex-direction: row;
align-items: center;
justify-content: space-between;
max-width: 200px;
}
.switch {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: 0.2s;
border-radius: 20px;
}
.slider:before {
position: absolute;
content: '';
height: 16px;
width: 16px;
left: 2px;
bottom: 2px;
background-color: white;
transition: 0.2s;
border-radius: 50%;
}
input:checked + .slider {
background-color: var(--primary-color);
}
input:checked + .slider:before {
transform: translateX(20px);
}
.profile-section {
margin-bottom: 30px;
}

View File

@@ -1,6 +0,0 @@
import { defineNuxtPlugin } from 'nuxt/app'
import { initFrosted } from '~/utils/frosted'
export default defineNuxtPlugin(() => {
initFrosted()
})

View File

@@ -1,26 +0,0 @@
import { reactive } from 'vue'
const FROSTED_KEY = 'frosted-glass'
export const frostedState = reactive({
enabled: true,
})
function apply() {
if (!import.meta.client) return
document.documentElement.dataset.frosted = frostedState.enabled ? 'on' : 'off'
}
export function initFrosted() {
if (!import.meta.client) return
const saved = localStorage.getItem(FROSTED_KEY)
frostedState.enabled = saved !== 'false'
apply()
}
export function setFrosted(enabled) {
if (!import.meta.client) return
frostedState.enabled = enabled
localStorage.setItem(FROSTED_KEY, enabled ? 'true' : 'false')
apply()
}

View File

@@ -143,7 +143,7 @@ function fallbackThemeTransition(applyFn) {
background-color: ${currentBg};
z-index: 9999;
pointer-events: none;
backdrop-filter: var(--blur-1);
backdrop-filter: blur(1px);
`
document.body.appendChild(transitionElement)