|
178 | 178 | @change="changeLayoutColumns" |
179 | 179 | size="small" |
180 | 180 | class="layout-select" |
181 | | - :style="{ width: '110px' }" |
| 181 | + :style="{ width: '120px' }" |
182 | 182 | position="bl" |
183 | 183 | :popup-container="'body'" |
184 | 184 | > |
185 | 185 | <template #prefix> |
186 | 186 | <icon-menu /> |
187 | 187 | </template> |
188 | | - <a-option :value="12">12列</a-option> |
189 | | - <a-option :value="6">6列</a-option> |
190 | | - <a-option :value="3">3列</a-option> |
| 188 | + <a-option value="smart">智能</a-option> |
| 189 | + <a-option value="12">12列</a-option> |
| 190 | + <a-option value="9">9列</a-option> |
| 191 | + <a-option value="6">6列</a-option> |
| 192 | + <a-option value="3">3列</a-option> |
191 | 193 | </a-select> |
192 | 194 | </div> |
193 | 195 | </div> |
194 | | - <div class="episodes-grid" :style="{ '--episodes-columns': episodeLayoutColumns }"> |
| 196 | + <div class="episodes-grid" :style="{ '--episodes-columns': actualLayoutColumns }"> |
195 | 197 | <a-button |
196 | 198 | v-for="(episode, index) in currentRouteEpisodes" |
197 | 199 | :key="index" |
@@ -281,7 +283,7 @@ const favoriteLoading = ref(false) |
281 | 283 | // 选集排序和显示策略 |
282 | 284 | const episodeSortOrder = ref('asc') // 'asc' 正序, 'desc' 倒序 |
283 | 285 | const episodeDisplayStrategy = ref(localStorage.getItem('episodeDisplayStrategy') || 'full') // 'full' 完整显示, 'smart' 智能去重, 'simple' 精简显示 |
284 | | -const episodeLayoutColumns = ref(parseInt(localStorage.getItem('episodeLayoutColumns')) || 12) // 每行显示的按钮数量 |
| 286 | +const episodeLayoutColumns = ref(localStorage.getItem('episodeLayoutColumns') || 'smart') // 每行显示的按钮数量,支持智能布局 |
285 | 287 | // 当前使用的站源信息(可能是全局站源或临时站源) |
286 | 288 | const currentSiteInfo = ref({ |
287 | 289 | name: '', |
@@ -370,6 +372,38 @@ const isCurrentFavorited = computed(() => { |
370 | 372 | return favoriteStore.isFavorited(originalVideoInfo.value.id, currentSiteInfo.value.api) |
371 | 373 | }) |
372 | 374 |
|
| 375 | +// 智能布局计算属性 |
| 376 | +const smartLayoutColumns = computed(() => { |
| 377 | + if (!currentRouteEpisodes.value.length) return 12 |
| 378 | + |
| 379 | + // 计算最长的选集名称长度 |
| 380 | + const maxNameLength = Math.max(...currentRouteEpisodes.value.map(episode => |
| 381 | + (episode.displayName || episode.name || '').length |
| 382 | + )) |
| 383 | + |
| 384 | + // 以总宽度60为基础,每个字符大约占用1个单位宽度 |
| 385 | + // 考虑按钮的padding、margin等额外空间,每个按钮需要额外2-3个单位 |
| 386 | + const buttonWidth = maxNameLength + 1 // 文字宽度 + 按钮内边距等 |
| 387 | + |
| 388 | + // 计算能容纳的列数,范围在1-12之间 |
| 389 | + let columns = Math.floor(60 / buttonWidth) |
| 390 | + |
| 391 | + // 确保列数在1-12范围内 |
| 392 | + columns = Math.max(1, Math.min(12, columns)) |
| 393 | + |
| 394 | + console.log('智能布局计算:', { maxNameLength, buttonWidth, columns }) |
| 395 | + |
| 396 | + return columns |
| 397 | +}) |
| 398 | +
|
| 399 | +// 实际使用的列数 |
| 400 | +const actualLayoutColumns = computed(() => { |
| 401 | + if (episodeLayoutColumns.value === 'smart') { |
| 402 | + return smartLayoutColumns.value |
| 403 | + } |
| 404 | + return parseInt(episodeLayoutColumns.value) || 12 |
| 405 | +}) |
| 406 | +
|
373 | 407 | // 方法 |
374 | 408 | const parseEpisodes = (urlString) => { |
375 | 409 | if (!urlString) return [] |
@@ -791,7 +825,7 @@ const changeDisplayStrategy = (strategy) => { |
791 | 825 |
|
792 | 826 | // 布局列数切换 |
793 | 827 | const changeLayoutColumns = (columns) => { |
794 | | - episodeLayoutColumns.value = parseInt(columns) |
| 828 | + episodeLayoutColumns.value = columns |
795 | 829 | localStorage.setItem('episodeLayoutColumns', columns) |
796 | 830 | } |
797 | 831 |
|
|
0 commit comments