添加背景页面右边栏Pexels图片api每次获取80张每页,默认显示12张,点击更多继续加载12张

This commit is contained in:
jingrow 2026-01-21 23:06:04 +08:00
parent c777398bdc
commit fa9bde2d89

View File

@ -408,6 +408,23 @@ favorite-colors-grid<template>
<div class="pexels-images-section">
<h4 class="section-title">{{ t('Pexels Backgrounds') }}</h4>
<div class="pexels-search-box">
<input
v-model="pexelsSearchInput"
type="text"
class="pexels-search-input"
:placeholder="t('Search backgrounds...')"
@keyup.enter="searchPexelsImages"
/>
<button
type="button"
class="pexels-search-btn"
@click="searchPexelsImages"
:disabled="pexelsLoading"
>
<i class="fa fa-search"></i>
</button>
</div>
<n-spin :show="pexelsLoading">
<div v-if="pexelsImages.length > 0" class="background-images-grid">
<div
@ -562,6 +579,23 @@ favorite-colors-grid<template>
<div class="pexels-images-section">
<h4 class="section-title">{{ t('Pexels Backgrounds') }}</h4>
<div class="pexels-search-box">
<input
v-model="pexelsSearchInput"
type="text"
class="pexels-search-input"
:placeholder="t('Search backgrounds...')"
@keyup.enter="searchPexelsImages"
/>
<button
type="button"
class="pexels-search-btn"
@click="searchPexelsImages"
:disabled="pexelsLoading"
>
<i class="fa fa-search"></i>
</button>
</div>
<n-spin :show="pexelsLoading">
<div v-if="pexelsImages.length > 0" class="background-images-grid">
<div
@ -746,6 +780,7 @@ const fetchPexelsImages = async () => {
console.warn('Pexels API key not configured. Skipping image fetch.')
pexelsImages.value = []
pexelsLoading.value = false
pexelsHasMore.value = false
return
}
@ -771,9 +806,11 @@ const fetchPexelsImages = async () => {
pexelsImages.value = [...pexelsImages.value, ...newPhotos]
}
PEXELS_TOTAL_FETCHED.value = pexelsImages.value.length
// If we got fewer images than requested, there are no more images
pexelsHasMore.value = newPhotos.length >= PEXELS_PER_PAGE
} catch (error: any) {
console.error('Failed to fetch Pexels images:', error)
pexelsHasMore.value = false
// Don't show error message if API key is not configured
if (PEXELS_API_KEY) {
message.error(t('Failed to load background images'))
@ -1114,10 +1151,12 @@ const pexelsImages = ref<any[]>([])
const pexelsLoading = ref(false)
const pexelsPage = ref(1)
const pexelsQuery = ref('nature background')
const pexelsSearchInput = ref('nature background')
const PEXELS_API_KEY = __PEXELS_API_KEY__ || ''
const pexelsDisplayCount = ref(12)
const PEXELS_PER_PAGE = 12
const PEXELS_TOTAL_FETCHED = ref(0)
const PEXELS_PER_PAGE = 80 // Fetch 80 images per API call
const PEXELS_DISPLAY_INCREMENT = 12 // Display 12 more images each time
const pexelsHasMore = ref(true) // Track if there are more images to fetch
// Custom background images
const customBackgrounds = ref<string[]>([])
@ -1129,21 +1168,69 @@ const displayedPexelsImages = computed(() => {
// Show "Load More" button condition
const showLoadMoreButton = computed(() => {
return pexelsImages.value.length > pexelsDisplayCount.value
// Show button if:
// 1. There are more images in cache to display, OR
// 2. There might be more images to fetch from API
return pexelsImages.value.length > pexelsDisplayCount.value ||
(pexelsImages.value.length > 0 && pexelsHasMore.value && pexelsImages.value.length >= pexelsDisplayCount.value)
})
// Load more Pexels images
const loadMorePexelsImages = async () => {
// Increase display count by 12
pexelsDisplayCount.value += PEXELS_PER_PAGE
// First, try to display more from cached images
const remainingCached = pexelsImages.value.length - pexelsDisplayCount.value
// If we need to fetch more images from API
if (pexelsDisplayCount.value > pexelsImages.value.length) {
pexelsPage.value++
await fetchPexelsImages()
if (remainingCached >= PEXELS_DISPLAY_INCREMENT) {
// Enough cached images, just increase display count
pexelsDisplayCount.value += PEXELS_DISPLAY_INCREMENT
} else if (remainingCached > 0) {
// Some cached images left, display them first
pexelsDisplayCount.value = pexelsImages.value.length
// Then fetch more if available
if (pexelsHasMore.value) {
pexelsPage.value++
await fetchPexelsImages()
// Display up to 12 more from the newly fetched images
const needed = PEXELS_DISPLAY_INCREMENT - remainingCached
pexelsDisplayCount.value = Math.min(
pexelsImages.value.length,
pexelsDisplayCount.value + needed
)
}
} else {
// No cached images left, fetch more from API
if (pexelsHasMore.value) {
pexelsPage.value++
await fetchPexelsImages()
// Display 12 more images
pexelsDisplayCount.value = Math.min(
pexelsImages.value.length,
pexelsDisplayCount.value + PEXELS_DISPLAY_INCREMENT
)
}
}
}
// Search Pexels images with new query
const searchPexelsImages = async () => {
const searchTerm = pexelsSearchInput.value.trim()
if (!searchTerm) {
message.warning(t('Please enter search keywords'))
return
}
// Reset state for new search
pexelsQuery.value = searchTerm
pexelsPage.value = 1
pexelsImages.value = []
pexelsDisplayCount.value = 12
pexelsHasMore.value = true
// Fetch new results
await fetchPexelsImages()
}
// Load custom backgrounds from localStorage
const loadCustomBackgrounds = () => {
try {
@ -3155,6 +3242,67 @@ const removeHistoryItem = (index: number) => {
gap: 16px;
}
/* Pexels Search Box */
.pexels-search-box {
display: flex;
gap: 8px;
margin-bottom: 4px;
}
.pexels-search-input {
flex: 1;
padding: 10px 14px;
border: 1px solid #e5e7eb;
border-radius: 8px;
font-size: 14px;
color: #1f2937;
background: white;
transition: all 0.2s ease;
outline: none;
&::placeholder {
color: #9ca3af;
}
&:focus {
border-color: #1fc76f;
box-shadow: 0 0 0 3px rgba(31, 199, 111, 0.1);
}
}
.pexels-search-btn {
padding: 10px 16px;
background: #1fc76f;
border: none;
border-radius: 8px;
color: white;
font-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
min-width: 44px;
i {
font-size: 16px;
}
&:hover:not(:disabled) {
background: #1ab866;
box-shadow: 0 2px 8px rgba(31, 199, 111, 0.3);
}
&:active:not(:disabled) {
transform: scale(0.98);
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
.upload-dragger-content {
padding: 20px;
display: flex;