mirror of
https://github.com/mue/mue.git
synced 2026-07-15 04:53:48 +02:00
150 lines
4.2 KiB
JavaScript
150 lines
4.2 KiB
JavaScript
/* global chrome */
|
|
import variables from 'config/variables';
|
|
import { memo, useRef, useEffect, useState, useCallback } from 'react';
|
|
import { MdSearch, MdMic } from 'react-icons/md';
|
|
import { Tooltip } from 'components/Elements';
|
|
import { useT } from 'contexts';
|
|
|
|
import EventBus from 'utils/eventbus';
|
|
|
|
import './search.scss';
|
|
|
|
function Search() {
|
|
const t = useT();
|
|
const [microphone, setMicrophone] = useState(null);
|
|
const [classList] = useState(
|
|
localStorage.getItem('widgetStyle') === 'legacy' ? 'searchIcons old' : 'searchIcons',
|
|
);
|
|
|
|
const micIcon = useRef(null);
|
|
|
|
const startSpeechRecognition = useCallback(() => {
|
|
const voiceSearch = new window.webkitSpeechRecognition();
|
|
voiceSearch.start();
|
|
|
|
micIcon.current.classList.add('micActive');
|
|
|
|
const searchText = document.getElementById('searchtext');
|
|
|
|
voiceSearch.onresult = (event) => {
|
|
searchText.value = event.results[0][0].transcript;
|
|
};
|
|
|
|
voiceSearch.onend = () => {
|
|
micIcon.current.classList.remove('micActive');
|
|
if (searchText.value === '') {
|
|
return;
|
|
}
|
|
|
|
setTimeout(() => {
|
|
variables.stats.postEvent('feature', 'Voice search');
|
|
if (chrome && chrome.search && chrome.search.query) {
|
|
chrome.search
|
|
.query({
|
|
text: searchText.value,
|
|
disposition: 'CURRENT_TAB',
|
|
})
|
|
.catch((error) => {
|
|
console.error('Search API error:', error);
|
|
window.location.href = `https://www.google.com/search?q=${encodeURIComponent(searchText.value)}`;
|
|
});
|
|
} else {
|
|
window.location.href = `https://www.google.com/search?q=${encodeURIComponent(searchText.value)}`;
|
|
}
|
|
}, 1000);
|
|
};
|
|
}, [micIcon]);
|
|
|
|
const init = useCallback(() => {
|
|
if (localStorage.getItem('voiceSearch') === 'true') {
|
|
setMicrophone(
|
|
<button
|
|
className="navbarButton"
|
|
onClick={startSpeechRecognition}
|
|
ref={micIcon}
|
|
aria-label={t('common.microphone_search')}
|
|
>
|
|
<MdMic className="micIcon" />
|
|
</button>,
|
|
);
|
|
} else {
|
|
setMicrophone(null);
|
|
}
|
|
}, [startSpeechRecognition]);
|
|
|
|
useEffect(() => {
|
|
init();
|
|
if (localStorage.getItem('searchFocus') === 'true') {
|
|
const element = document.getElementById('searchtext');
|
|
if (element) {
|
|
element.focus();
|
|
}
|
|
}
|
|
|
|
const handleRefresh = (data) => {
|
|
if (data === 'search') {
|
|
init();
|
|
}
|
|
};
|
|
|
|
EventBus.on('refresh', handleRefresh);
|
|
return () => {
|
|
EventBus.off('refresh', handleRefresh);
|
|
};
|
|
}, [init]);
|
|
|
|
function searchButton(e) {
|
|
e.preventDefault();
|
|
const value = e.target.value || document.getElementById('searchtext').value || 'mue fast';
|
|
variables.stats.postEvent('feature', 'Search');
|
|
|
|
if (chrome && chrome.search && chrome.search.query) {
|
|
chrome.search
|
|
.query({
|
|
text: value,
|
|
disposition: 'CURRENT_TAB',
|
|
})
|
|
.catch((error) => {
|
|
console.error('Search API error:', error);
|
|
window.location.href = `https://www.google.com/search?q=${encodeURIComponent(value)}`;
|
|
});
|
|
} else {
|
|
window.location.href = `https://www.google.com/search?q=${encodeURIComponent(value)}`;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="searchComponents">
|
|
<div className="searchMain">
|
|
<div className={classList}>
|
|
<Tooltip title={t('modals.main.settings.sections.search.voice_search')}>
|
|
{microphone}
|
|
</Tooltip>
|
|
</div>
|
|
<form onSubmit={searchButton} className="searchBar">
|
|
<div className={classList}>
|
|
<Tooltip title={t('widgets.search')}>
|
|
<button
|
|
className="navbarButton"
|
|
onClick={searchButton}
|
|
aria-label={t('common.search_label')}
|
|
>
|
|
<MdSearch />
|
|
</button>
|
|
</Tooltip>
|
|
</div>
|
|
<input
|
|
type="text"
|
|
placeholder={t('widgets.search')}
|
|
id="searchtext"
|
|
className="searchInput"
|
|
/>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const MemoizedSearch = memo(Search);
|
|
export { MemoizedSearch as default, MemoizedSearch as Search };
|