添加背景页面右边栏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"> <div class="pexels-images-section">
<h4 class="section-title">{{ t('Pexels Backgrounds') }}</h4> <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"> <n-spin :show="pexelsLoading">
<div v-if="pexelsImages.length > 0" class="background-images-grid"> <div v-if="pexelsImages.length > 0" class="background-images-grid">
<div <div
@ -562,6 +579,23 @@ favorite-colors-grid<template>
<div class="pexels-images-section"> <div class="pexels-images-section">
<h4 class="section-title">{{ t('Pexels Backgrounds') }}</h4> <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"> <n-spin :show="pexelsLoading">
<div v-if="pexelsImages.length > 0" class="background-images-grid"> <div v-if="pexelsImages.length > 0" class="background-images-grid">
<div <div
@ -746,6 +780,7 @@ const fetchPexelsImages = async () => {
console.warn('Pexels API key not configured. Skipping image fetch.') console.warn('Pexels API key not configured. Skipping image fetch.')
pexelsImages.value = [] pexelsImages.value = []
pexelsLoading.value = false pexelsLoading.value = false
pexelsHasMore.value = false
return return
} }
@ -771,9 +806,11 @@ const fetchPexelsImages = async () => {
pexelsImages.value = [...pexelsImages.value, ...newPhotos] 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) { } catch (error: any) {
console.error('Failed to fetch Pexels images:', error) console.error('Failed to fetch Pexels images:', error)
pexelsHasMore.value = false
// Don't show error message if API key is not configured // Don't show error message if API key is not configured
if (PEXELS_API_KEY) { if (PEXELS_API_KEY) {
message.error(t('Failed to load background images')) message.error(t('Failed to load background images'))
@ -1114,10 +1151,12 @@ const pexelsImages = ref<any[]>([])
const pexelsLoading = ref(false) const pexelsLoading = ref(false)
const pexelsPage = ref(1) const pexelsPage = ref(1)
const pexelsQuery = ref('nature background') const pexelsQuery = ref('nature background')
const pexelsSearchInput = ref('nature background')
const PEXELS_API_KEY = __PEXELS_API_KEY__ || '' const PEXELS_API_KEY = __PEXELS_API_KEY__ || ''
const pexelsDisplayCount = ref(12) const pexelsDisplayCount = ref(12)
const PEXELS_PER_PAGE = 12 const PEXELS_PER_PAGE = 80 // Fetch 80 images per API call
const PEXELS_TOTAL_FETCHED = ref(0) 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 // Custom background images
const customBackgrounds = ref<string[]>([]) const customBackgrounds = ref<string[]>([])
@ -1129,21 +1168,69 @@ const displayedPexelsImages = computed(() => {
// Show "Load More" button condition // Show "Load More" button condition
const showLoadMoreButton = computed(() => { 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 // Load more Pexels images
const loadMorePexelsImages = async () => { const loadMorePexelsImages = async () => {
// Increase display count by 12 // First, try to display more from cached images
pexelsDisplayCount.value += PEXELS_PER_PAGE const remainingCached = pexelsImages.value.length - pexelsDisplayCount.value
// If we need to fetch more images from API if (remainingCached >= PEXELS_DISPLAY_INCREMENT) {
if (pexelsDisplayCount.value > pexelsImages.value.length) { // Enough cached images, just increase display count
pexelsPage.value++ pexelsDisplayCount.value += PEXELS_DISPLAY_INCREMENT
await fetchPexelsImages() } 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 // Load custom backgrounds from localStorage
const loadCustomBackgrounds = () => { const loadCustomBackgrounds = () => {
try { try {
@ -3155,6 +3242,67 @@ const removeHistoryItem = (index: number) => {
gap: 16px; 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 { .upload-dragger-content {
padding: 20px; padding: 20px;
display: flex; display: flex;