|
| 1 | +import { ref, shallowRef } from 'vue'; |
| 2 | + |
| 3 | +interface SearchEngineItem { |
| 4 | + title: string; |
| 5 | + url: string; |
| 6 | +} |
| 7 | + |
| 8 | +export const useSearch = () => { |
| 9 | + const keyword = ref(''); |
| 10 | + const placeholder = ref('搜点什么呢'); |
| 11 | + const keywordHistory = ref(''); |
| 12 | + |
| 13 | + const engineList: SearchEngineItem[] = [ |
| 14 | + { title: '秘塔', url: 'https://metaso.cn/?q=%s' }, |
| 15 | + { title: 'Felo', url: 'https://felo.ai/search?q=%s' }, |
| 16 | + { title: '必应', url: 'https://www.bing.com/search?q=%s' }, |
| 17 | + { |
| 18 | + title: 'V2EX', |
| 19 | + url: `https://www.google.com/search?q=%s${encodeURIComponent(' site:v2ex.com')}`, |
| 20 | + }, |
| 21 | + { title: 'Luxirty', url: 'https://search.luxirty.com/search?q=%s' }, |
| 22 | + { title: 'Google', url: 'https://www.google.com/search?q=%s' }, |
| 23 | + { title: 'DuckDuckGo', url: 'https://duckduckgo.com/?q=%s' }, |
| 24 | + { |
| 25 | + title: 'GitHub', |
| 26 | + url: 'https://github.com/search?q=%s&type=repositories', |
| 27 | + }, |
| 28 | + { title: 'MDN', url: 'https://developer.mozilla.org/en-US/search?q=%s' }, |
| 29 | + { title: 'CanIUse', url: 'https://caniuse.com/?search=%s' }, |
| 30 | + { title: 'LONGMAN', url: 'https://www.ldoceonline.com/dictionary/%s' }, |
| 31 | + { |
| 32 | + title: 'DeepL', |
| 33 | + url: 'https://www.deepl.com/en/translator#en/zh-hans/%s', |
| 34 | + }, |
| 35 | + { |
| 36 | + title: 'GoogleTranslate', |
| 37 | + url: 'https://translate.google.com/?sl=auto&tl=zh-CN&text=%s&op=translate', |
| 38 | + }, |
| 39 | + { |
| 40 | + title: '百度翻译', |
| 41 | + url: 'https://fanyi.baidu.com/mtpe-individual/multimodal?query=%s', |
| 42 | + }, |
| 43 | + { title: '欧路', url: 'https://dict.eudic.net/dicts/en/%s' }, |
| 44 | + { title: '掘金', url: 'https://juejin.cn/search?query=%s' }, |
| 45 | + { title: '知乎', url: 'https://www.zhihu.com/search?type=content&q=%s' }, |
| 46 | + { title: '哔哩哔哩', url: 'https://search.bilibili.com/all?keyword=%s' }, |
| 47 | + { |
| 48 | + title: 'YouTube', |
| 49 | + url: 'https://www.youtube.com/results?search_query=%s', |
| 50 | + }, |
| 51 | + ]; |
| 52 | + |
| 53 | + const engine = shallowRef(engineList[0]); |
| 54 | + const useLastEngine = ref(false); |
| 55 | + const ENGINE_KEY = 'lb_search_engine'; |
| 56 | + const SEARCH_HISTORY_KEY = 'lb_search_history'; |
| 57 | + const USE_LAST_ENGINE_KEY = 'lb_search_engine_switch'; |
| 58 | + |
| 59 | + const useAfterHalfYear = ref(false); |
| 60 | + |
| 61 | + const updateEngine = (newEngine: SearchEngineItem) => { |
| 62 | + if (!useLastEngine.value) { |
| 63 | + return; |
| 64 | + } |
| 65 | + engine.value = newEngine; |
| 66 | + localStorage.setItem(ENGINE_KEY, newEngine.title); |
| 67 | + }; |
| 68 | + |
| 69 | + const loadEngine = () => { |
| 70 | + if (!useLastEngine.value) { |
| 71 | + return; |
| 72 | + } |
| 73 | + const engineTitle = localStorage.getItem(ENGINE_KEY) ?? ''; |
| 74 | + const lastEngine = engineList.find((item) => item.title === engineTitle); |
| 75 | + if (lastEngine) { |
| 76 | + engine.value = lastEngine; |
| 77 | + } |
| 78 | + }; |
| 79 | + |
| 80 | + const saveHistory = () => { |
| 81 | + const value = keyword.value.trim(); |
| 82 | + if (value) { |
| 83 | + keywordHistory.value = value; |
| 84 | + localStorage.setItem(SEARCH_HISTORY_KEY, value); |
| 85 | + } |
| 86 | + }; |
| 87 | + |
| 88 | + const loadHistory = () => { |
| 89 | + const value = localStorage.getItem(SEARCH_HISTORY_KEY); |
| 90 | + if (value) { |
| 91 | + keywordHistory.value = value; |
| 92 | + } |
| 93 | + }; |
| 94 | + |
| 95 | + const useHistory = () => { |
| 96 | + keyword.value = keywordHistory.value; |
| 97 | + }; |
| 98 | + |
| 99 | + const saveUseLastEngine = () => { |
| 100 | + localStorage.setItem(USE_LAST_ENGINE_KEY, String(useLastEngine.value)); |
| 101 | + engine.value = engineList[0]; |
| 102 | + }; |
| 103 | + |
| 104 | + const loadUseLastEngine = () => { |
| 105 | + const isLastOff = localStorage.getItem(USE_LAST_ENGINE_KEY) === 'false'; |
| 106 | + useLastEngine.value = !isLastOff; |
| 107 | + }; |
| 108 | + |
| 109 | + const search = (targetEngine = engine.value) => { |
| 110 | + updateEngine(targetEngine); |
| 111 | + |
| 112 | + if (!keyword.value) { |
| 113 | + placeholder.value = '输入关键词后才能搜索~'; |
| 114 | + return; |
| 115 | + } |
| 116 | + |
| 117 | + let text = keyword.value; |
| 118 | + if (useAfterHalfYear.value) { |
| 119 | + const date = new Date(); |
| 120 | + date.setMonth(date.getMonth() - 6); |
| 121 | + const y = date.getFullYear(); |
| 122 | + const m = date.getMonth(); |
| 123 | + const afterHalfYear = `after:${y}-${m + 1}-01`; |
| 124 | + text = `${text} ${afterHalfYear}`; |
| 125 | + } |
| 126 | + |
| 127 | + saveHistory(); |
| 128 | + const url = targetEngine.url.replace( |
| 129 | + '%s', |
| 130 | + encodeURIComponent(text), |
| 131 | + ); |
| 132 | + const w = window.open(url, '_self', 'noopener,noreferrer'); |
| 133 | + if (w) { |
| 134 | + w.opener = null; |
| 135 | + } |
| 136 | + }; |
| 137 | + |
| 138 | + loadUseLastEngine(); |
| 139 | + loadEngine(); |
| 140 | + loadHistory(); |
| 141 | + |
| 142 | + return { |
| 143 | + keyword, |
| 144 | + placeholder, |
| 145 | + keywordHistory, |
| 146 | + useHistory, |
| 147 | + engineList, |
| 148 | + engine, |
| 149 | + search, |
| 150 | + useLastEngine, |
| 151 | + useAfterHalfYear, |
| 152 | + saveUseLastEngine, |
| 153 | + }; |
| 154 | +}; |
0 commit comments