[enh] simple theme: image detail
When an image is selected, the detail with the full size image is displayed on the right side of the screen (or full screen on tablet and phone). When Javascript is disabled, the thumbnail is a linked to the full size image, as it was before. When the image proxy is enabled, the full size image is also proxied, in consequence this commit increases the bandwidth usage of instances. The detail can be closed by the close button or the Esc key. It is possible to go to the next and previous images using the j and k keys or the button on the top right of the screen.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
searxng.ready(function() {
|
||||
|
||||
searxng.on('.result', 'click', function() {
|
||||
highlightResult(this)(true);
|
||||
highlightResult(this)(true);
|
||||
});
|
||||
|
||||
searxng.on('.result a', 'focus', function(e) {
|
||||
@@ -124,9 +124,7 @@ searxng.ready(function() {
|
||||
if (Object.prototype.hasOwnProperty.call(vimKeys, e.keyCode) && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
|
||||
var tagName = e.target.tagName.toLowerCase();
|
||||
if (e.keyCode === 27) {
|
||||
if (tagName === 'input' || tagName === 'select' || tagName === 'textarea') {
|
||||
vimKeys[e.keyCode].fun();
|
||||
}
|
||||
vimKeys[e.keyCode].fun(e);
|
||||
} else {
|
||||
if (e.target === document.body || tagName === 'a' || tagName === 'button') {
|
||||
e.preventDefault();
|
||||
@@ -213,9 +211,12 @@ searxng.ready(function() {
|
||||
document.location.reload(true);
|
||||
}
|
||||
|
||||
function removeFocus() {
|
||||
if (document.activeElement) {
|
||||
function removeFocus(e) {
|
||||
const tagName = e.target.tagName.toLowerCase();
|
||||
if (document.activeElement && (tagName === 'input' || tagName === 'select' || tagName === 'textarea')) {
|
||||
document.activeElement.blur();
|
||||
} else {
|
||||
searxng.closeDetail();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,6 +286,9 @@ searxng.ready(function() {
|
||||
function openResult(newTab) {
|
||||
return function() {
|
||||
var link = document.querySelector('.result[data-vim-selected] h3 a');
|
||||
if (link === null) {
|
||||
link = document.querySelector('.result[data-vim-selected] > a');
|
||||
}
|
||||
if (link !== null) {
|
||||
var url = link.getAttribute('href');
|
||||
if (newTab) {
|
||||
@@ -368,4 +372,8 @@ searxng.ready(function() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
searxng.scrollPageToSelected = scrollPageToSelected;
|
||||
searxng.selectNext = highlightResult('down');
|
||||
searxng.selectPrevious = highlightResult('up');
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
'use strict';
|
||||
|
||||
searxng.ready(function() {
|
||||
searxng.image_thumbnail_layout = new searxng.ImageLayout('#urls', '#urls .result-images', 'img.image_thumbnail', 10, 200);
|
||||
searxng.image_thumbnail_layout = new searxng.ImageLayout('#urls', '#urls .result-images', 'img.image_thumbnail', 14, 6, 200);
|
||||
searxng.image_thumbnail_layout.watch();
|
||||
|
||||
searxng.on('.btn-collapse', 'click', function() {
|
||||
@@ -31,17 +31,74 @@
|
||||
}
|
||||
});
|
||||
|
||||
w.addEventListener('scroll', function() {
|
||||
var e = d.getElementById('backToTop'),
|
||||
scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
if (e !== null) {
|
||||
if (scrollTop >= 200) {
|
||||
e.style.opacity = 1;
|
||||
} else {
|
||||
e.style.opacity = 0;
|
||||
function selectImage(e) {
|
||||
/*eslint no-unused-vars: 0*/
|
||||
let t = e.target;
|
||||
while (t && t.nodeName != 'ARTICLE') {
|
||||
t = t.parentNode;
|
||||
}
|
||||
if (t) {
|
||||
// load full size image in background
|
||||
const imgElement = t.querySelector('.result-images-source img');
|
||||
const thumbnailElement = t.querySelector('.image_thumbnail');
|
||||
const detailElement = t.querySelector('.detail');
|
||||
if (imgElement) {
|
||||
const imgSrc = imgElement.getAttribute('data-src');
|
||||
if (imgSrc) {
|
||||
const loader = d.createElement('div');
|
||||
const imgLoader = new Image();
|
||||
|
||||
loader.classList.add('loader');
|
||||
detailElement.appendChild(loader);
|
||||
|
||||
imgLoader.onload = e => {
|
||||
imgElement.src = imgSrc;
|
||||
loader.remove();
|
||||
};
|
||||
imgLoader.onerror = e => {
|
||||
loader.remove();
|
||||
};
|
||||
imgLoader.src = imgSrc;
|
||||
imgElement.src = thumbnailElement.src;
|
||||
imgElement.removeAttribute('data-src');
|
||||
}
|
||||
}
|
||||
}
|
||||
d.getElementById('results').classList.add('image-detail-open');
|
||||
searxng.image_thumbnail_layout.align();
|
||||
searxng.scrollPageToSelected();
|
||||
}
|
||||
|
||||
searxng.closeDetail = function(e) {
|
||||
d.getElementById('results').classList.remove('image-detail-open');
|
||||
searxng.image_thumbnail_layout.align();
|
||||
searxng.scrollPageToSelected();
|
||||
}
|
||||
|
||||
searxng.on('.result-images', 'click', e => {
|
||||
e.preventDefault();
|
||||
selectImage(e);
|
||||
});
|
||||
searxng.on('.result-images a', 'focus', selectImage, true);
|
||||
searxng.on('.result-detail-close', 'click', e => {
|
||||
e.preventDefault();
|
||||
searxng.closeDetail();
|
||||
});
|
||||
searxng.on('.result-detail-previous', 'click', e => searxng.selectPrevious(false));
|
||||
searxng.on('.result-detail-next', 'click', e => searxng.selectNext(false));
|
||||
|
||||
w.addEventListener('scroll', function() {
|
||||
var e = d.getElementById('backToTop'),
|
||||
scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
|
||||
results = d.getElementById('results');
|
||||
if (e !== null) {
|
||||
if (scrollTop >= 100) {
|
||||
results.classList.add('scrolling');
|
||||
} else {
|
||||
results.classList.remove('scrolling');
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -71,6 +71,14 @@ html {
|
||||
/// Settings Colors
|
||||
--color-settings-tr-hover: #f7f7f7;
|
||||
--color-settings-engine-description-font: darken(#dcdcdc, 30%);
|
||||
/// Detail modal
|
||||
--color-result-detail-font: #fff;
|
||||
--color-result-detail-label-font: lightgray;
|
||||
--color-result-detail-background: #000;
|
||||
--color-result-detail-hr: #333;
|
||||
--color-result-detail-link: #8af;
|
||||
--color-result-detail-loader-border: rgba(255, 255, 255, 0.2);
|
||||
--color-result-detail-loader-borderleft: rgba(0, 0, 0, 0);
|
||||
/// Toolkit Colors
|
||||
--color-toolkit-badge-font: #fff;
|
||||
--color-toolkit-badge-background: #777;
|
||||
@@ -156,6 +164,14 @@ html {
|
||||
--color-result-engines-font: #777;
|
||||
--color-result-search-url-border: #333;
|
||||
--color-result-search-url-font: #fff;
|
||||
/// Detail modal : same as the light version
|
||||
--color-result-detail-font: #fff;
|
||||
--color-result-detail-label-font: lightgray;
|
||||
--color-result-detail-background: #000;
|
||||
--color-result-detail-hr: #333;
|
||||
--color-result-detail-link: #8af;
|
||||
--color-result-detail-loader-border: rgba(255, 255, 255, 0.2);
|
||||
--color-result-detail-loader-borderleft: rgba(0, 0, 0, 0);
|
||||
// Images Colors
|
||||
--color-result-image-span-background-hover: rgba(0, 0, 0, 0.6);
|
||||
--color-result-image-span-font: #fff;
|
||||
@@ -183,8 +199,8 @@ html {
|
||||
--color-toolkit-engine-tooltip-border: #333;
|
||||
--color-toolkit-engine-tooltip-shadow: #444;
|
||||
--color-toolkit-engine-tooltip-background: #222;
|
||||
--color-toolkit-loader-border: rgba(0, 0, 0, 0.2);
|
||||
--color-toolkit-loader-borderleft: rgba(255, 255, 255, 0);
|
||||
--color-toolkit-loader-border: rgba(255, 255, 255, 0.2);
|
||||
--color-toolkit-loader-borderleft: rgba(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
243
searx/static/themes/simple/src/less/detail.less
Normal file
243
searx/static/themes/simple/src/less/detail.less
Normal file
@@ -0,0 +1,243 @@
|
||||
#main_results #results.image-detail-open.only_template_images {
|
||||
width: 59.25rem !important;
|
||||
}
|
||||
|
||||
#main_results #results.only_template_images.image-detail-open #backToTop {
|
||||
left: 56.75rem !important;
|
||||
right: inherit;
|
||||
}
|
||||
|
||||
article.result-images .detail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#results.image-detail-open article.result-images[data-vim-selected] .detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
left: 60rem;
|
||||
right: 0;
|
||||
top: 7rem;
|
||||
bottom: 0;
|
||||
background: var(--color-result-detail-background);
|
||||
border: 1px solid var(--color-result-detail-background);
|
||||
z-index: 10000;
|
||||
padding: 4rem 3rem 3rem 3rem;
|
||||
|
||||
a.result-images-source {
|
||||
display: block;
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
|
||||
img {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
object-fit: contain;
|
||||
width: inherit;
|
||||
max-width: 100%;
|
||||
min-height: inherit;
|
||||
max-height: calc(100vh - 25rem - 7rem);
|
||||
background: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.result-images-labels {
|
||||
color: var(--color-result-detail-font);
|
||||
max-height: 16rem;
|
||||
min-height: 16rem;
|
||||
|
||||
hr {
|
||||
border-top: 1px solid var(--color-result-detail-hr);
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
h4 {
|
||||
height: 2rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
p {
|
||||
color: var(--color-result-detail-label-font);
|
||||
font-size: 0.9rem;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 12rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4,
|
||||
p,
|
||||
a {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
p.result-content {
|
||||
height: 2rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
p.result-url {
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
p.result-content:hover,
|
||||
p.result-url:hover {
|
||||
position: relative;
|
||||
overflow: inherit !important;
|
||||
background: var(--color-result-detail-background);
|
||||
text-overflow: inherit !important;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited,
|
||||
a:hover,
|
||||
a:active {
|
||||
color: var(--color-result-detail-link);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
a.result-detail-close {
|
||||
top: 1rem;
|
||||
left: 1rem;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
a.result-detail-previous {
|
||||
top: 1rem;
|
||||
right: 6rem;
|
||||
// center the icon by moving it slightly on the left
|
||||
padding: 0.4rem 0.5rem 0.4rem 0.3rem;
|
||||
}
|
||||
|
||||
a.result-detail-next {
|
||||
top: 1rem;
|
||||
right: 2rem;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
a.result-detail-close,
|
||||
a.result-detail-next,
|
||||
a.result-detail-previous {
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
position: absolute;
|
||||
filter: opacity(40%);
|
||||
z-index: 2000002;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
a.result-detail-next,
|
||||
a.result-detail-previous {
|
||||
span::before {
|
||||
// vertical center small icons
|
||||
vertical-align: sub;
|
||||
}
|
||||
}
|
||||
|
||||
a.result-detail-close,
|
||||
a.result-detail-close:visited,
|
||||
a.result-detail-close:hover,
|
||||
a.result-detail-close:active,
|
||||
a.result-detail-previous,
|
||||
a.result-detail-previous:visited,
|
||||
a.result-detail-previous:hover,
|
||||
a.result-detail-previous:active,
|
||||
a.result-detail-next,
|
||||
a.result-detail-next:visited,
|
||||
a.result-detail-next:hover,
|
||||
a.result-detail-next:active {
|
||||
color: var(--color-result-detail-font);
|
||||
background: var(--color-result-detail-background);
|
||||
border: 1px solid var(--color-result-detail-font);
|
||||
}
|
||||
|
||||
a.result-detail-close:focus,
|
||||
a.result-detail-close:hover,
|
||||
a.result-detail-previous:focus,
|
||||
a.result-detail-previous:hover,
|
||||
a.result-detail-next:focus,
|
||||
a.result-detail-next:hover {
|
||||
filter: opacity(80%);
|
||||
}
|
||||
|
||||
.loader {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 50%;
|
||||
border-top: 0.5em solid var(--color-result-detail-loader-border);
|
||||
border-right: 0.5em solid var(--color-result-detail-loader-border);
|
||||
border-bottom: 0.5em solid var(--color-result-detail-loader-border);
|
||||
border-left: 0.5em solid var(--color-result-detail-loader-borderleft);
|
||||
}
|
||||
}
|
||||
|
||||
#results.image-detail-open.scrolling article.result-images[data-vim-selected] .detail {
|
||||
top: 0;
|
||||
|
||||
a.result-images-source img {
|
||||
max-height: calc(100vh - 25rem);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @tablet) {
|
||||
#results.image-detail-open article.result-images[data-vim-selected] .detail {
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
a.result-images-source {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
max-height: calc(100vh - 24rem);
|
||||
}
|
||||
}
|
||||
|
||||
a.result-detail-next {
|
||||
right: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @phone) {
|
||||
#results.image-detail-open article.result-images[data-vim-selected] .detail {
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 1rem;
|
||||
|
||||
a.result-images-source img {
|
||||
width: 100%;
|
||||
max-height: calc(100vh - 20rem);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.result-images-labels p span {
|
||||
width: inherit;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
@import "code.less";
|
||||
@import "toolkit.less";
|
||||
@import "autocomplete.less";
|
||||
@import "detail.less";
|
||||
|
||||
// for index.html template
|
||||
@import "index.less";
|
||||
@@ -138,6 +139,10 @@ article[data-vim-selected]::before {
|
||||
|
||||
article.result-images[data-vim-selected] {
|
||||
background: var(--color-result-vim-arrow);
|
||||
|
||||
.image_thumbnail {
|
||||
filter: opacity(60%);
|
||||
}
|
||||
}
|
||||
|
||||
article.result-images[data-vim-selected]::before {
|
||||
@@ -283,25 +288,26 @@ article.result-images[data-vim-selected]::before {
|
||||
|
||||
img {
|
||||
float: inherit;
|
||||
margin: 0;
|
||||
margin: 0.125rem;
|
||||
padding: 0;
|
||||
border: none;
|
||||
max-height: 200px;
|
||||
background: var(--color-result-image-background);
|
||||
}
|
||||
|
||||
span a {
|
||||
span.title {
|
||||
display: none;
|
||||
color: var(--color-result-image-span-font);
|
||||
}
|
||||
|
||||
&:hover span a {
|
||||
&:hover span.title {
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 4px;
|
||||
margin: 0 0 4px 4px;
|
||||
// color: @color-result-image-span-font;
|
||||
background-color: var(--color-result-image-span-background-hover);
|
||||
font-size: 0.7em;
|
||||
}
|
||||
@@ -569,6 +575,10 @@ article.result-images[data-vim-selected]::before {
|
||||
}
|
||||
}
|
||||
|
||||
#results.scrolling #backToTop {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media screen and (max-width: @tablet) {
|
||||
#main_preferences,
|
||||
#main_about,
|
||||
|
||||
Reference in New Issue
Block a user