Skip to content

Commit 88069e4

Browse files
committed
Improve fetching from wallhaven
1 parent 7e5e216 commit 88069e4

4 files changed

Lines changed: 65 additions & 2 deletions

File tree

app.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ func (a *App) SaveWallhavenConfig(config map[string]interface{}) error {
521521

522522
// SearchWallhaven searches wallhaven.cc for wallpapers.
523523
func (a *App) SearchWallhaven(params wallhaven.SearchParams) (*wallhaven.SearchResult, error) {
524-
return a.wallhaven.Search(params)
524+
return a.wallhaven.SearchMultiPage(params, 2)
525525
}
526526

527527
// DownloadWallpaper downloads a wallpaper from a URL. Returns local path.

frontend/src/lib/components/wallhaven/WallhavenBrowser.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
getResults,
77
getIsSearching,
88
search,
9+
searchPage,
910
getTotalPages,
1011
getTotalResults,
1112
getPage,
@@ -45,7 +46,7 @@
4546
totalPages={getTotalPages()}
4647
onPageChange={p => {
4748
setPage(p);
48-
search();
49+
searchPage();
4950
}}
5051
/>
5152
{/if}

frontend/src/lib/stores/wallhaven.svelte.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,15 @@ export function togglePurity(index: number): void {
154154

155155
// --- Actions ---
156156
export async function search(): Promise<void> {
157+
page = 1;
158+
await doSearch();
159+
}
160+
161+
export async function searchPage(): Promise<void> {
162+
await doSearch();
163+
}
164+
165+
async function doSearch(): Promise<void> {
157166
isSearching = true;
158167
try {
159168
const {SearchWallhaven} = await import('../../../wailsjs/go/main/App');

internal/wallhaven/client.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,59 @@ func (c *Client) Search(params SearchParams) (*SearchResult, error) {
102102
return &result, nil
103103
}
104104

105+
// SearchMultiPage fetches numPages consecutive pages concurrently and merges
106+
// the results. Metadata is normalized so the caller sees logical pagination
107+
// (e.g. last_page is adjusted for the multi-page fetch).
108+
func (c *Client) SearchMultiPage(params SearchParams, numPages int) (*SearchResult, error) {
109+
if numPages <= 1 {
110+
return c.Search(params)
111+
}
112+
113+
type pageResult struct {
114+
index int
115+
result *SearchResult
116+
err error
117+
}
118+
119+
ch := make(chan pageResult, numPages)
120+
for i := 0; i < numPages; i++ {
121+
go func(idx int) {
122+
p := params
123+
p.Page = params.Page + idx
124+
res, err := c.Search(p)
125+
ch <- pageResult{index: idx, result: res, err: err}
126+
}(i)
127+
}
128+
129+
results := make([]*SearchResult, numPages)
130+
for i := 0; i < numPages; i++ {
131+
pr := <-ch
132+
if pr.err != nil {
133+
if pr.index == 0 {
134+
return nil, pr.err
135+
}
136+
continue
137+
}
138+
results[pr.index] = pr.result
139+
}
140+
141+
merged := results[0]
142+
if merged == nil {
143+
return nil, fmt.Errorf("wallhaven search failed for first page")
144+
}
145+
for i := 1; i < numPages; i++ {
146+
if results[i] != nil {
147+
merged.Data = append(merged.Data, results[i].Data...)
148+
}
149+
}
150+
151+
// Normalize pagination metadata so the caller sees logical pages
152+
merged.Meta.CurrentPage = (params.Page-1)/numPages + 1
153+
merged.Meta.LastPage = (merged.Meta.LastPage + numPages - 1) / numPages
154+
155+
return merged, nil
156+
}
157+
105158
// wallhavenPagePattern matches wallhaven.cc page URLs and extracts the ID.
106159
var wallhavenPagePattern = regexp.MustCompile(`wallhaven\.cc/w/([a-zA-Z0-9]+)`)
107160

0 commit comments

Comments
 (0)