mirror of
https://github.com/karl0ss/homepage.git
synced 2025-05-27 16:11:59 +01:00
Merge pull request #897 from avdept/add_search_to_quicklaunch
Add internet search to quicklaunch
This commit is contained in:
commit
adce18d023
@ -282,7 +282,8 @@
|
|||||||
},
|
},
|
||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service",
|
||||||
|
"search": "Search"
|
||||||
},
|
},
|
||||||
"wmo": {
|
"wmo": {
|
||||||
"0-day": "Sunny",
|
"0-day": "Sunny",
|
||||||
@ -432,7 +433,7 @@
|
|||||||
},
|
},
|
||||||
"cloudflared": {
|
"cloudflared": {
|
||||||
"origin_ip": "Origin IP",
|
"origin_ip": "Origin IP",
|
||||||
"status": "Status"
|
"status": "Status"
|
||||||
},
|
},
|
||||||
"proxmoxbackupserver": {
|
"proxmoxbackupserver": {
|
||||||
"datastore_usage": "Datastore",
|
"datastore_usage": "Datastore",
|
||||||
@ -446,4 +447,4 @@
|
|||||||
"videos": "Videos",
|
"videos": "Videos",
|
||||||
"storage": "Storage"
|
"storage": "Storage"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import ResolvedIcon from "./resolvedicon";
|
|||||||
|
|
||||||
import { SettingsContext } from "utils/contexts/settings";
|
import { SettingsContext } from "utils/contexts/settings";
|
||||||
|
|
||||||
export default function QuickLaunch({servicesAndBookmarks, searchString, setSearchString, isOpen, close, searchDescriptions}) {
|
export default function QuickLaunch({servicesAndBookmarks, searchString, setSearchString, isOpen, close, searchDescriptions, searchProvider}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { settings } = useContext(SettingsContext);
|
const { settings } = useContext(SettingsContext);
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
|
|||||||
|
|
||||||
function handleSearchKeyDown(event) {
|
function handleSearchKeyDown(event) {
|
||||||
if (!isOpen) return;
|
if (!isOpen) return;
|
||||||
|
|
||||||
if (event.key === "Escape") {
|
if (event.key === "Escape") {
|
||||||
closeAndReset();
|
closeAndReset();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -50,6 +50,7 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleItemHover(event) {
|
function handleItemHover(event) {
|
||||||
setCurrentItemIndex(parseInt(event.target?.dataset?.index, 10));
|
setCurrentItemIndex(parseInt(event.target?.dataset?.index, 10));
|
||||||
}
|
}
|
||||||
@ -75,6 +76,15 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
|
|||||||
if (searchDescriptions) {
|
if (searchDescriptions) {
|
||||||
newResults = newResults.sort((a, b) => b.priority - a.priority);
|
newResults = newResults.sort((a, b) => b.priority - a.priority);
|
||||||
}
|
}
|
||||||
|
if (searchProvider) {
|
||||||
|
newResults.push(
|
||||||
|
{
|
||||||
|
href: searchProvider.url + encodeURIComponent(searchString),
|
||||||
|
name: `${searchProvider.name} ${t("quicklaunch.search")} `,
|
||||||
|
type: 'search',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
setResults(newResults);
|
setResults(newResults);
|
||||||
|
|
||||||
@ -82,7 +92,7 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
|
|||||||
setCurrentItemIndex(0);
|
setCurrentItemIndex(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [searchString, servicesAndBookmarks, searchDescriptions]);
|
}, [searchString, servicesAndBookmarks, searchDescriptions, searchProvider, t]);
|
||||||
|
|
||||||
|
|
||||||
const [hidden, setHidden] = useState(true);
|
const [hidden, setHidden] = useState(true);
|
||||||
@ -90,7 +100,7 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
|
|||||||
function handleBackdropClick(event) {
|
function handleBackdropClick(event) {
|
||||||
if (event.target?.tagName === "DIV") closeAndReset();
|
if (event.target?.tagName === "DIV") closeAndReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
searchField.current.focus();
|
searchField.current.focus();
|
||||||
document.body.addEventListener('click', handleBackdropClick);
|
document.body.addEventListener('click', handleBackdropClick);
|
||||||
@ -135,20 +145,20 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
|
|||||||
i === currentItemIndex && "bg-theme-300/50 dark:bg-theme-700/50",
|
i === currentItemIndex && "bg-theme-300/50 dark:bg-theme-700/50",
|
||||||
)} onClick={handleItemClick}>
|
)} onClick={handleItemClick}>
|
||||||
<div className="flex flex-row items-center mr-4 pointer-events-none">
|
<div className="flex flex-row items-center mr-4 pointer-events-none">
|
||||||
<div className="w-5 text-xs mr-4">
|
{(r.icon || r.abbr) && <div className="w-5 text-xs mr-4">
|
||||||
{r.icon && <ResolvedIcon icon={r.icon} />}
|
{r.icon && <ResolvedIcon icon={r.icon} />}
|
||||||
{r.abbr && r.abbr}
|
{r.abbr && r.abbr}
|
||||||
</div>
|
</div>}
|
||||||
<div className="flex flex-col md:flex-row text-left items-baseline mr-4 pointer-events-none">
|
<div className="flex flex-col md:flex-row text-left items-baseline mr-4 pointer-events-none">
|
||||||
<span className="mr-4">{r.name}</span>
|
<span className="mr-4">{r.name}</span>
|
||||||
{r.description &&
|
{r.description &&
|
||||||
<span className="text-xs text-theme-600 text-light">
|
<span className="text-xs text-theme-600 text-light">
|
||||||
{searchDescriptions && r.priority < 2 ? highlightText(r.description) : r.description}
|
{searchDescriptions && r.priority < 2 ? highlightText(r.description) : r.description}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-theme-600 font-bold pointer-events-none">{r.type === 'service' ? t("quicklaunch.service") : t("quicklaunch.bookmark")}</div>
|
<div className="text-xs text-theme-600 font-bold pointer-events-none">{t(`quicklaunch.${r.type ? r.type.toLowerCase() : 'bookmark'}`)}</div>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
@ -3,7 +3,7 @@ import { useTranslation } from "next-i18next";
|
|||||||
import { FiSearch } from "react-icons/fi";
|
import { FiSearch } from "react-icons/fi";
|
||||||
import { SiDuckduckgo, SiMicrosoftbing, SiGoogle, SiBaidu, SiBrave } from "react-icons/si";
|
import { SiDuckduckgo, SiMicrosoftbing, SiGoogle, SiBaidu, SiBrave } from "react-icons/si";
|
||||||
|
|
||||||
const providers = {
|
export const searchProviders = {
|
||||||
google: {
|
google: {
|
||||||
name: "Google",
|
name: "Google",
|
||||||
url: "https://www.google.com/search?q=",
|
url: "https://www.google.com/search?q=",
|
||||||
@ -39,7 +39,7 @@ const providers = {
|
|||||||
export default function Search({ options }) {
|
export default function Search({ options }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const provider = providers[options.provider];
|
const provider = searchProviders[options.provider];
|
||||||
const [query, setQuery] = useState("");
|
const [query, setQuery] = useState("");
|
||||||
|
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
|
@ -22,6 +22,7 @@ import { bookmarksResponse, servicesResponse, widgetsResponse } from "utils/conf
|
|||||||
import ErrorBoundary from "components/errorboundry";
|
import ErrorBoundary from "components/errorboundry";
|
||||||
import themes from "utils/styles/themes";
|
import themes from "utils/styles/themes";
|
||||||
import QuickLaunch from "components/quicklaunch";
|
import QuickLaunch from "components/quicklaunch";
|
||||||
|
import { searchProviders } from "components/widgets/search/search";
|
||||||
|
|
||||||
const ThemeToggle = dynamic(() => import("components/toggles/theme"), {
|
const ThemeToggle = dynamic(() => import("components/toggles/theme"), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
@ -193,6 +194,11 @@ function Home({ initialSettings }) {
|
|||||||
|
|
||||||
const [searching, setSearching] = useState(false);
|
const [searching, setSearching] = useState(false);
|
||||||
const [searchString, setSearchString] = useState("");
|
const [searchString, setSearchString] = useState("");
|
||||||
|
let searchProvider = null;
|
||||||
|
const searchWidget = Object.values(widgets).find(w => w.type === "search");
|
||||||
|
if (searchWidget) {
|
||||||
|
searchProvider = searchProviders[searchWidget.options?.provider];
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function handleKeyDown(e) {
|
function handleKeyDown(e) {
|
||||||
@ -251,6 +257,7 @@ function Home({ initialSettings }) {
|
|||||||
isOpen={searching}
|
isOpen={searching}
|
||||||
close={setSearching}
|
close={setSearching}
|
||||||
searchDescriptions={settings.quicklaunch?.searchDescriptions}
|
searchDescriptions={settings.quicklaunch?.searchDescriptions}
|
||||||
|
searchProvider={settings.quicklaunch?.hideInternetSearch ? null : searchProvider}
|
||||||
/>
|
/>
|
||||||
{widgets && (
|
{widgets && (
|
||||||
<>
|
<>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user