feat: Wikidata engine and Wikipedia knowledge infobox
- Add wikidata engine (wbsearchentities), tests, factory/planner/config - Wikipedia REST summary: infobox from extract, thumbnail, article URL - InfoboxView URL; render infobox list in results_inner + base styles - Preferences Wikidata toggle; engine badge color for wikidata Made-with: Cursor
This commit is contained in:
parent
6e45abb150
commit
24577b27be
13 changed files with 344 additions and 34 deletions
|
|
@ -528,6 +528,7 @@
|
|||
.result[data-engine="braveapi"], .engine-badge[data-engine="braveapi"] { --engine-accent: #ff6600; }
|
||||
.result[data-engine="qwant"], .engine-badge[data-engine="qwant"] { --engine-accent: #5c97ff; }
|
||||
.result[data-engine="wikipedia"], .engine-badge[data-engine="wikipedia"] { --engine-accent: #a3a3a3; }
|
||||
.result[data-engine="wikidata"], .engine-badge[data-engine="wikidata"] { --engine-accent: #339966; }
|
||||
.result[data-engine="github"], .engine-badge[data-engine="github"] { --engine-accent: #8b5cf6; }
|
||||
.result[data-engine="reddit"], .engine-badge[data-engine="reddit"] { --engine-accent: #ff4500; }
|
||||
.result[data-engine="youtube"], .engine-badge[data-engine="youtube"] { --engine-accent: #ff0000; }
|
||||
|
|
@ -538,6 +539,73 @@
|
|||
.result[data-engine="ddg_images"], .engine-badge[data-engine="ddg_images"] { --engine-accent: #de5833; }
|
||||
.result[data-engine="qwant_images"], .engine-badge[data-engine="qwant_images"] { --engine-accent: #5c97ff; }
|
||||
|
||||
/* Wikipedia / knowledge infobox */
|
||||
.infobox-list {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.infobox-card {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
align-items: flex-start;
|
||||
padding: 1rem 1.15rem;
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.infobox-image-wrap {
|
||||
flex-shrink: 0;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: var(--radius-sm);
|
||||
overflow: hidden;
|
||||
background: var(--bg-tertiary);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.infobox-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.infobox-main {
|
||||
flex: 1;
|
||||
min-width: min(100%, 220px);
|
||||
}
|
||||
|
||||
.infobox-title {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.infobox-content {
|
||||
font-size: 0.9rem;
|
||||
color: var(--desc-color);
|
||||
line-height: 1.55;
|
||||
margin-bottom: 0.65rem;
|
||||
}
|
||||
|
||||
.infobox-link {
|
||||
display: inline-block;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
color: var(--title-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.infobox-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.dialog-error {
|
||||
padding: 0.65rem 0.85rem;
|
||||
margin-bottom: 0.75rem;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@
|
|||
<input type="checkbox" name="engine" value="wikipedia" checked>
|
||||
<span>Wikipedia</span>
|
||||
</label>
|
||||
<label class="engine-toggle">
|
||||
<input type="checkbox" name="engine" value="wikidata" checked>
|
||||
<span>Wikidata</span>
|
||||
</label>
|
||||
<label class="engine-toggle">
|
||||
<input type="checkbox" name="engine" value="github">
|
||||
<span>GitHub</span>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,26 @@
|
|||
<div id="corrections" class="correction">{{range .Corrections}}{{.}} {{end}}</div>
|
||||
{{end}}
|
||||
|
||||
{{if or .Answers .Infoboxes}}
|
||||
{{if .Infoboxes}}
|
||||
<div class="infobox-list" role="region" aria-label="Summary">
|
||||
{{range .Infoboxes}}
|
||||
<aside class="infobox-card">
|
||||
{{if .ImgSrc}}
|
||||
<div class="infobox-image-wrap">
|
||||
<img src="{{.ImgSrc}}" alt="" class="infobox-img" loading="lazy" width="120" height="120">
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="infobox-main">
|
||||
{{if .Title}}<h2 class="infobox-title">{{.Title}}</h2>{{end}}
|
||||
{{if .Content}}<p class="infobox-content">{{.Content}}</p>{{end}}
|
||||
{{if .URL}}<a href="{{.URL}}" class="infobox-link" target="_blank" rel="noopener noreferrer">Read article on Wikipedia</a>{{end}}
|
||||
</div>
|
||||
</aside>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if .Answers}}
|
||||
<div id="answers">
|
||||
{{range .Answers}}
|
||||
<div class="dialog-error">{{.}}</div>
|
||||
|
|
@ -38,7 +57,7 @@
|
|||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{else if not .Answers}}
|
||||
{{else if and (not .Answers) (not .Infoboxes)}}
|
||||
<div class="no-results">
|
||||
<div class="no-results-icon" aria-hidden="true">🔍</div>
|
||||
<h2>No results found</h2>
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ type InfoboxView struct {
|
|||
Title string
|
||||
Content string
|
||||
ImgSrc string
|
||||
URL string
|
||||
}
|
||||
|
||||
// FilterOption represents a filter radio option for the sidebar.
|
||||
|
|
@ -273,7 +274,10 @@ func FromResponse(resp contracts.SearchResponse, query string, pageno int, activ
|
|||
if v, ok := ib["img_src"].(string); ok {
|
||||
iv.ImgSrc = util.SanitizeResultURL(v)
|
||||
}
|
||||
if iv.Title != "" || iv.Content != "" {
|
||||
if v, ok := ib["url"].(string); ok {
|
||||
iv.URL = util.SanitizeResultURL(v)
|
||||
}
|
||||
if iv.Title != "" || iv.Content != "" || iv.ImgSrc != "" {
|
||||
pd.Infoboxes = append(pd.Infoboxes, iv)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue