diff --git a/app/client.imba b/app/client.imba index 17ac9f3..9a85083 100644 --- a/app/client.imba +++ b/app/client.imba @@ -7,6 +7,7 @@ import fzi from 'fzi' import download from 'downloadjs' import { nanoid } from 'nanoid' import { parse_url } from './utils' +import initial_config from './config' let state = { query: '' @@ -14,10 +15,6 @@ let state = { scored_links: [] } -let config = { - search_engine: {} -} - global._fuzzyhome_delete_everything = do return unless window.confirm "This will delete everything. Are you sure?" indexedDB.deleteDatabase("fuzzyhome") @@ -45,15 +42,15 @@ tag app fatal_error = yes return unless global.localStorage.fuzzyhome_visited - add_initial_links! + await add_initial_links! global.localStorage.fuzzyhome_visited = yes await load_config! def add_initial_links let initial_links = [ - "click here to learn how to use this tool effectively github.com/familyfriendlymikey/fuzzyhome" - "google google.com" - "youtube youtube.com" + "tutorial github.com/familyfriendlymikey/fuzzyhome" + "!brave search search.brave.com/search?q=" + "!youtube search youtube.com/results?search_query=" "photopea photopea.com" "twitch twitch.tv" "messenger messenger.com" @@ -67,16 +64,15 @@ tag app err "adding link", e def validate_config - throw 'config error' unless config..search_engine.hasOwnProperty 'url' - throw 'config error' unless config..search_engine.hasOwnProperty 'icon' - throw 'config error' unless config..search_engine.hasOwnProperty 'frequency' + throw _ if config.default_bang.id === null + throw _ if config.default_bang.url === null + throw _ if config.default_bang.img === null + throw _ if config.default_bang.name === null + throw _ if config.default_bang.frequency === null def reset_config p "resetting config" - let url = 'https://www.google.com/search?q=' - let frequency = 0 - let icon = await fetch_image_as_base_64 'google.com' - config.search_engine = { url, icon, frequency } + config = initial_config save_config! def save_config @@ -87,7 +83,7 @@ tag app config = JSON.parse(global.localStorage.fuzzyhome_config) validate_config! catch - await reset_config! + reset_config! def err s, e p e @@ -118,19 +114,11 @@ tag app def decrement_selection_index selection_index = Math.max(0, selection_index - 1) - def increment_search_engine_frequency - config.search_engine.frequency += 1 - save_config! - - get encoded_search_query - "{config.search_engine.url}{window.encodeURIComponent(state.query)}" + get active_bang + return bang or config.default_bang get encoded_bang_query - "{bang.url}{window.encodeURIComponent(state.query)}" - - def use_search_engine - increment_search_engine_frequency! - window.location.href = encoded_search_query + "{active_bang.url}{window.encodeURIComponent(state.query)}" def fetch_image_as_base_64 host let fallback = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAH0lEQVR42mO8seXffwYqAsZRA0cNHDVw1MBRA0eqgQCDRkbJSQHxEQAAAABJRU5ErkJggg==' @@ -189,10 +177,11 @@ tag app await db.links.add link await reload_db! imba.commit! + return link def handle_edit link def edit_link - let input = window.prompt "Enter the new link name and url:" + let input = window.prompt "Enter the new link name and url:", "{link.name} {link.url}" return if input === null try await update_link link, input @@ -209,38 +198,37 @@ tag app throw "link id not found" if result === 0 await reload_db! imba.commit! + return new_link def handle_click_link link await increment_link_frequency link window.location.href = link.url - def handle_click_search - increment_search_engine_frequency! - def handle_bang - return unless bang - let url = encoded_bang_query - await increment_link_frequency bang - window.location.href = url + await increment_link_frequency active_bang + window.location.href = encoded_bang_query def handle_click_bang handle_bang! + def navigate link + await increment_link_frequency link + window.location.href = link.url + def handle_return - if bang - handle_bang! - elif state.scored_links.length < 1 - use_search_engine! + if bang or state.scored_links.length < 1 + return handle_bang! + let link = state.scored_links[selection_index] + if link.name.startsWith '!' + state.query = '' + bang = link else - let link = state.scored_links[selection_index] - await increment_link_frequency link - window.location.href = link.url + navigate link - def handle_tab - return bang = no if bang - return unless state.scored_links.length > 0 - state.query = '' - bang = state.scored_links[selection_index] + def handle_del + if state.query.length < 1 + bang = no + sort_links! def handle_click_delete link handle_delete link @@ -306,31 +294,14 @@ tag app settings_active = no loading = no - def handle_click_config - - def edit_config - let input = window.prompt "Please enter the URL of your search engine." - return if input === null - try - var { href: url, host } = parse_url input - catch e - return err "changing search engine", e - let icon = await fetch_image_as_base_64 host - Object.assign config.search_engine, { url, icon } - save_config! - - loading = yes - await edit_config! - settings_active = no - loading = no - def handle_click_github global.location.href = "https://github.com/familyfriendlymikey/fuzzyhome" def handle_paste e return if state.query.length > 0 global.setTimeout(&, 0) do - use_search_engine! + bang = config.default_bang + handle_bang! get pretty_date Date!.toString!.split(" ").slice(0, 4).join(" ") @@ -407,7 +378,7 @@ tag app tt:capitalize fs:20px overflow-wrap:anywhere - css .search + css .bang-text tt:none word-break:break-all css .link-right @@ -451,10 +422,6 @@ tag app .disabled=loading @click.if(!loading)=handle_click_export > "EXPORT" - <.settings-button - .disabled=loading - @click.if(!loading)=handle_click_config - > "CONFIG" <.settings-button .disabled=loading @click.if(!loading)=handle_click_github @@ -468,7 +435,7 @@ tag app @hotkey('shift+backspace').capture=handle_shift_backspace @hotkey('down').capture=increment_selection_index @hotkey('up').capture=decrement_selection_index - @hotkey('tab').capture=handle_tab + @keydown.del=handle_del @input=handle_input @paste=handle_paste @blur=this.focus @@ -488,17 +455,17 @@ tag app <.middle-button.disabled> "+" <.links> - if bang + if bang or state.scored_links.length < 1 <.link-left> - - <.name.search> encoded_bang_query + + <.name.bang-text> encoded_bang_query <.link-right[jc:flex-end]> - <.frequency> bang.frequency - elif state.scored_links.length > 0 + <.frequency> active_bang.frequency + else for link, index in state.scored_links "✎" <.link-button@click.prevent.stop=handle_click_delete(link)> "x" <.frequency> link.frequency - else - - <.link-left> - - <.name.search> encoded_search_query - <.link-right[jc:flex-end]> - <.frequency> config.search_engine.frequency $main-input.focus! imba.mount diff --git a/app/config.imba b/app/config.imba new file mode 100644 index 0000000..5bc7017 --- /dev/null +++ b/app/config.imba @@ -0,0 +1,9 @@ +let config = {} +config.default_bang = { + "name": "!google", + "url": "https://www.google.com/search?q=", + "frequency": 0, + "img": "data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///zD9/f2W/f392P39/fn9/f35/f391/39/ZT+/v4uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Cf39/Zn///////////////////////////////////////////39/ZX///8IAAAAAAAAAAAAAAAA/v7+Cf39/cH/////+v35/7TZp/92ul3/WKs6/1iqOv9yuFn/rNWd//j79v///////f39v////wgAAAAAAAAAAP39/Zn/////7PXp/3G3WP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP+Or1j//vDo///////9/f2VAAAAAP///zD/////+vz5/3G3V/9TqDT/WKo6/6LQkf/U6cz/1urO/6rUm/+Zo0r/8IZB//adZ////v7///////7+/i79/f2Y/////4nWzf9Lqkj/Vqo4/9Xqzv///////////////////////ebY//SHRv/0hUL//NjD///////9/f2U/f392v////8sxPH/Ebzt/43RsP/////////////////////////////////4roL/9IVC//i1jf///////f391/39/fr/////Cr37/wW8+/+16/7/////////////////9IVC//SFQv/0hUL/9IVC//SFQv/3pnX///////39/fn9/f36/////wu++/8FvPv/tuz+//////////////////SFQv/0hUL/9IVC//SFQv/0hUL/96p7///////9/f35/f392/////81yfz/CrL5/2uk9v///////////////////////////////////////////////////////f392P39/Zn/////ks/7/zdS7P84Rur/0NT6///////////////////////9/f////////////////////////39/Zb+/v4y//////n5/v9WYu3/NUPq/ztJ6/+VnPT/z9L6/9HU+v+WnfT/Ul7t/+Hj/P////////////////////8wAAAAAP39/Z3/////6Or9/1hj7v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9sdvD////////////9/f2YAAAAAAAAAAD///8K/f39w//////5+f7/paz2/11p7v88Suv/Okfq/1pm7v+iqfX/+fn+///////9/f3B/v7+CQAAAAAAAAAAAAAAAP///wr9/f2d///////////////////////////////////////////9/f2Z/v7+CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f2Z/f392/39/fr9/f36/f392v39/Zj///8wAAAAAAAAAAAAAAAAAAAAAPAPAADAAwAAgAEAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/g3+/v5X/f39mf39/cj9/f3q/f39+f39/fn9/f3q/f39yP39/Zn+/v5W////DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f2c/f399f/////////////////////////////////////////////////////9/f31/f39mv7+/iMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/gn9/f2K/f39+////////////////////////////////////////////////////////////////////////////f39+v39/Yf///8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4k/f390v////////////////////////////////////////////////////////////////////////////////////////////////39/dD///8iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////MP39/er//////////////////////////+r05v+v16H/gsBs/2WxSf9Wqjj/Vqk3/2OwRv99vWX/pdKV/97u2P////////////////////////////39/ej+/v4vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f3q/////////////////////+v15/+Pxnv/VKk2/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/36+Z//d7tf///////////////////////39/ej///8iAAAAAAAAAAAAAAAAAAAAAAAAAAD///8K/f390//////////////////////E4bn/XKw+/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1apN/+x0pv///////////////////////39/dD///8IAAAAAAAAAAAAAAAAAAAAAP39/Yv/////////////////////sdij/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/YKU1/8qOPv/5wZ////////////////////////39/YcAAAAAAAAAAAAAAAD+/v4l/f39+////////////////8Lgt/9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9utlT/n86N/7faqv+426v/pdKV/3u8ZP9UqDX/U6g0/3egN//jiUH/9IVC//SFQv/82MP//////////////////f39+v7+/iMAAAAAAAAAAP39/Z3////////////////q9Ob/W6w+/1OoNP9TqDT/U6g0/1OoNP9nskz/zOXC/////////////////////////////////+Dv2v+osWP/8YVC//SFQv/0hUL/9IVC//WQVP/++fb//////////////////f39mgAAAAD+/v4O/f399v///////////////4LHj/9TqDT/U6g0/1OoNP9TqDT/dblc//L58P/////////////////////////////////////////////8+v/3p3f/9IVC//SFQv/0hUL/9IVC//rIqf/////////////////9/f31////DP7+/ln////////////////f9v7/Cbz2/zOwhv9TqDT/U6g0/2KwRv/v9+z///////////////////////////////////////////////////////738//1kFT/9IVC//SFQv/0hUL/9plg///////////////////////+/v5W/f39nP///////////////4jf/f8FvPv/Bbz7/yG1s/9QqDz/vN2w//////////////////////////////////////////////////////////////////rHqP/0hUL/9IVC//SFQv/0hUL//vDn//////////////////39/Zn9/f3L////////////////R878/wW8+/8FvPv/Bbz7/y7C5P/7/fr//////////////////////////////////////////////////////////////////ere//SFQv/0hUL/9IVC//SFQv/718H//////////////////f39yP39/ez///////////////8cwvv/Bbz7/wW8+/8FvPv/WNL8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rIqv/////////////////9/f3q/f39+v///////////////we9+/8FvPv/Bbz7/wW8+/993P3///////////////////////////////////////SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+cGf//////////////////39/fn9/f36////////////////B737/wW8+/8FvPv/Bbz7/33c/f//////////////////////////////////////9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6xaX//////////////////f39+f39/e3///////////////8cwvv/Bbz7/wW8+/8FvPv/WdP8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vVv//////////////////9/f3q/f39y////////////////0bN/P8FvPv/Bbz7/wW8+/8hrvn/+/v///////////////////////////////////////////////////////////////////////////////////////////////////////////////////39/cj9/f2c////////////////ht/9/wW8+/8FvPv/FZP1/zRJ6/+zuPf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////f39mf7+/lr////////////////d9v7/B7n7/yB38f81Q+r/NUPq/0hV7P/u8P3////////////////////////////////////////////////////////////////////////////////////////////////////////////+/v5X////D/39/ff///////////////9tkPT/NUPq/zVD6v81Q+r/NUPq/2Fs7//y8v7////////////////////////////////////////////09f7//////////////////////////////////////////////////f399f7+/g0AAAAA/f39n////////////////+Tm/P89Suv/NUPq/zVD6v81Q+r/NUPq/1Bc7f/IzPn/////////////////////////////////x8v5/0xY7P+MlPP////////////////////////////////////////////9/f2cAAAAAAAAAAD+/v4n/f39/P///////////////7W69/81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9ZZe7/k5v0/6609/+vtff/lJv0/1pm7v81Q+r/NUPq/zVD6v+GjvL//v7//////////////////////////////f39+/7+/iQAAAAAAAAAAAAAAAD9/f2N/////////////////////6Cn9f81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v+BivL////////////////////////////9/f2KAAAAAAAAAAAAAAAAAAAAAP7+/gv9/f3V/////////////////////7W69/8+S+v/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/P0zr/7q/+P///////////////////////f390v7+/gkAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3r/////////////////////+Xn/P94gfH/NkTq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NkTq/3Z/8f/l5/z///////////////////////39/er+/v4kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f3r///////////////////////////k5vz/nqX1/2p08P9IVez/OEbq/zdF6v9GU+z/aHLv/5qh9f/i5Pz////////////////////////////9/f3q////MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3V/////////////////////////////////////////////////////////////////////////////////////////////////f390v7+/iQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wr9/f2N/f39/P///////////////////////////////////////////////////////////////////////////f39+/39/Yv+/v4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4n/f39n/39/ff//////////////////////////////////////////////////////f399v39/Z3+/v4lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Dv7+/lr9/f2c/f39y/39/e39/f36/f39+v39/ez9/f3L/f39nP7+/ln+/v4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPAAAAD4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/", + "id": "FEJbsKLUMwHbazbqW3c4i" +} +export default config