Browse Source

refactor: add home page

main
familyfriendlymikey 2 years ago
parent
commit
50c09e8468
  1. 28
      app/api.imba
  2. 7
      app/client.imba
  3. 109
      app/components/app-bang.imba
  4. 2
      app/components/app-community-links.imba
  5. 86
      app/components/app-home.imba
  6. 2
      app/components/app-link.imba
  7. 312
      app/components/app-links.imba
  8. 2
      app/styles.imba

28
app/api.imba

@ -8,6 +8,7 @@ import config from './config'
import { omit, orderBy } from 'lodash'
import { nanoid } from 'nanoid'
import fzi from 'fzi'
import { evaluate as eval_math } from 'mathjs'
export default new class api
@ -177,3 +178,30 @@ export default new class api
def navigate link
await increment_link_frequency link
window.location.href = link.url
get math_result
try
let result = Number(eval_math state.query)
throw _ if isNaN result
throw _ if result.toString! is state.query.trim!
result
catch
no
def handle_cut e
return unless e.target.selectionStart == e.target.selectionEnd
let s = math_result
s ||= state.query
await window.navigator.clipboard.writeText(s)
state.query = ''
sort_links!
def handle_add_link
state.loading = yes
try
await add_link state.query
state.query = ''
sort_links!
catch e
err "adding link", e
state.loading = no

7
app/client.imba

@ -15,6 +15,7 @@ let refs = {}
import api from './api'
import config from './config'
import './components/app-home'
import './components/app-community-links'
import './components/app-settings'
import './components/app-prompt'
@ -52,7 +53,7 @@ tag app
refs.settings = $as
refs.edit = $ae
refs.community-links = $acl
refs.links = $al
refs.links = $ah
unless global.localStorage.fuzzyhome_visited
await api.add_initial_links!
@ -69,7 +70,7 @@ tag app
def render
<self.disabled=state.loading>
css d:flex fld:column jc:flex-start ai:center
css d:flex fld:column jc:start ai:center
w:80vw max-width:700px max-height:80vh
bxs:0px 0px 10px rgba(0,0,0,0.35)
box-sizing:border-box p:30px rd:10px mt:10vh
@ -95,6 +96,6 @@ tag app
<app-edit$ae>
else
<app-links$al>
<app-home$ah>
imba.mount <app>

109
app/components/app-bang.imba

@ -1,5 +1,9 @@
tag app-bang
get bang
return active_bang if state.active_bang
config.data.default_bang
get encoded_bang_query
"{bang.url}{window.encodeURIComponent(state.query)}"
@ -9,27 +13,94 @@ tag app-bang
def render
<self
.selected
@click=handle_bang
>
css d:flex fld:row jc:space-between ai:center
px:16px py:11px rd:5px cursor:pointer c:#FAD4AB
<self>
css w:100% d:flex fld:column gap:10px
<app-tips>
<.tip-row>
<.tip
@click=(state.active_bang = no)
@hotkey('esc').capture.if(!state.loading)=(state.active_bang = no)
>
<.tip-hotkey> "Return"
<.tip-content> "Search"
<.tip
@click=api.handle_add_link
@hotkey('shift+return').capture.if(!state.loading)=api.handle_add_link
>
<.tip-hotkey> "Shift + Return"
<.tip-content.ellipsis>
<span[ws:pre]> "Create Link "
let sq = state.query.trim!.split /\s+/
if sq.length >= 2
let url = sq.pop!
<span> '"'
<span> sq.join " "
<span[c:blue3 ws:pre]> " {url}"
<span> '"'
else
<span> "\"{sq.join " "}\""
if state.active_bang
<.tip
@click=(state.active_bang = no)
@hotkey('esc').capture.if(!state.loading)=(state.active_bang = no)
>
<.tip-hotkey> "Esc"
<.tip-content> "Back"
else
<.tip
@click.if(!state.loading)=refs.settings.open
@hotkey('esc').capture.if(!state.loading)=refs.settings.open
>
<.tip-hotkey> "Esc"
<.tip-content> "Toggle Settings"
<app-tips-more$tips-more>
<.tip-row>
<.tip
@click.if(!state.loading)=api.toggle_effective_names
@hotkey('tab').capture.if(!state.loading)=api.toggle_effective_names
>
<.tip-hotkey> "Tab"
<.tip-content> "Toggle Effective Names"
<.tip
@click.if(!loading)=api.handle_cut
>
if math_result
<.tip-hotkey> "Cut (Math, If No Selection)"
<.tip-content> "Cut Math Result"
else
<.tip-hotkey> "Cut (If No Selection)"
<.tip-content> "Cut All Text"
<.tip.noclick>
<.tip-hotkey> "Paste (If Input Empty)"
<.tip-content> "Instant Search"
unless $tips-more.active
<.bang.selected@click=handle_bang>
css d:flex fld:row jc:space-between ai:center
px:16px py:11px rd:5px cursor:pointer c:blue3
<.link-left>
css d:flex fl:1
<.link-left>
css d:flex fl:1
<img.link-icon src=bang.icon>
css w:20px h:20px mr:10px rd:3px
<img.link-icon src=bang.icon>
css w:20px h:20px mr:10px rd:3px
<.display-name> encoded_bang_query
css tt:capitalize fs:20px overflow-wrap:anywhere
css tt:none word-break:break-all
<.display-name> encoded_bang_query
css c:#FAD4AB fs:20px word-break:break-all
<.link-right>
css d:flex fld:row jc:space-between ai:center
css .buttons-disabled .link-button visibility:hidden
css .selected .link-button visibility:visible
<.link-right>
css d:flex fld:row jc:space-between ai:center
<.frequency> bang.frequency
css fs:15px ml:7px
<.frequency> bang.frequency
css fs:15px ml:7px

2
app/components/app-community-links.imba

@ -38,7 +38,7 @@ tag app-community-links
>
css self
d:flex fld:column jc:flex-start fl:1
d:flex fld:column jc:start fl:1
w:100% ofy:auto pt:15px
css .link

86
app/components/app-home.imba

@ -0,0 +1,86 @@
tag app-home
def mount
$links-input.focus!
def handle_paste e
return unless config.data.enable_search_on_paste
return if state.query.length > 0
global.setTimeout(&, 0) do
return if api.math_result isnt no
bang ||= config.data.default_bang
handle_bang!
def handle_click_copy s
try
await window.navigator.clipboard.writeText(s)
state.query = ''
api.sort_links!
def handle_input
api.set_link_selection_index 0
api.sort_links!
def handle_click_link
if state.active_bang or state.sorted_links.length < 1
return handle_bang!
let link = api.selected_link
if link.is_bang
state.query = ''
state.active_bang = link
else
api.navigate link
def handle_click_delete link
return unless window.confirm "Do you really want to delete {link..display_name}?"
handle_delete link
def handle_click_pin link
api.pin_link link
def handle_shift_backspace
return unless state.sorted_links.length > 0
refs.edit.open api.selected_link
def render
<self>
css w:100% d:flex fld:column gap:10px ofy:hidden
<.header>
css d:flex fld:row w:100%
css .side c:purple3/90 fs:15px d:flex ja:center w:30px cursor:pointer
css .side svg w:15px d:flex
css .left jc:left
css .right jc:right
<.side.left@click=api.toggle_effective_names>
if config.data.enable_effective_names
<svg src="../assets/eye.svg">
else
<svg src="../assets/eye-off.svg">
<input$links-input
bind=state.query
@input.if(!state.loading)=handle_input
@paste.if(!state.loading)=handle_paste
@cut=api.handle_cut
disabled=state.loading
>
if (let m = api.math_result) isnt no
<.side.right@click=handle_click_copy(m)>
"= {Math.round(m * 100)/100}"
css c:blue3 fs:20px ml:10px w:unset
else
<.side.right @click.if(!state.loading)=refs.settings.open>
<svg src="../assets/settings.svg">
if state.active_bang or state.sorted_links.length < 1
<app-bang>
else
<app-links>

2
app/components/app-link.imba

@ -33,7 +33,7 @@ tag app-link
css .selected .link-button visibility:visible
<.link-buttons .buttons-disabled=!config.data.enable_buttons>
css d:flex fld:row jc:flex-start ai:center pr:25px gap:5px
css d:flex fld:row jc:start ai:center pr:25px gap:5px
css .link-button visibility:hidden rd:3px c:purple4 fs:15px cursor:pointer px:3px
css .link-button svg w:15px

312
app/components/app-links.imba

@ -1,263 +1,91 @@
import { evaluate as eval_math } from 'mathjs'
tag app-links
def mount
$links-input.focus!
def handle_paste e
return unless config.data.enable_search_on_paste
return if state.query.length > 0
global.setTimeout(&, 0) do
return if math_result isnt no
bang ||= config.data.default_bang
handle_bang!
def handle_click_copy s
try
await window.navigator.clipboard.writeText(s)
state.query = ''
api.sort_links!
def handle_cut e
return unless e.target.selectionStart == e.target.selectionEnd
let s = math_result
s ||= state.query
await window.navigator.clipboard.writeText(s)
state.query = ''
api.sort_links!
def handle_add
state.loading = yes
try
await api.add_link state.query
state.query = ''
api.sort_links!
catch e
err "adding link", e
state.loading = no
get math_result
try
let result = Number(eval_math state.query)
throw _ if isNaN result
throw _ if result.toString! is state.query.trim!
result
catch
no
def handle_input
api.set_link_selection_index 0
api.sort_links!
def handle_click_link
if state.active_bang or state.sorted_links.length < 1
return handle_bang!
let link = api.selected_link
if link.is_bang
state.query = ''
state.active_bang = link
else
api.navigate link
def handle_click_delete link
return unless window.confirm "Do you really want to delete {link..display_name}?"
handle_delete link
def handle_click_pin link
api.pin_link link
def handle_shift_backspace
return unless state.sorted_links.length > 0
refs.edit.open api.selected_link
def handle_shift_return
def go
if viewing_community_links
try
await add_community_link api.selected_link
catch e
err "adding community link", e
else
handle_add!
state.loading = yes
await go!
editing_link = no
state.query = ''
api.sort_links!
state.loading = no
def toggle_settings
refs.settings.open!
def render
<self>
css w:100% d:flex fld:column gap:10px
if $as.active
<app-settings$as>
css w:100% d:flex fld:column gap:10px ofy:hidden
else
<app-tips>
<.header>
css d:flex fld:row w:100%
css .side c:purple3/90 fs:15px d:flex ja:center w:30px cursor:pointer
css .side svg w:15px d:flex
css .left jc:left
css .right jc:right
<.tip-row>
<.side.left@click=api.toggle_effective_names>
if config.data.enable_effective_names
<svg src="../assets/eye.svg">
else
<svg src="../assets/eye-off.svg">
<input$links-input
bind=state.query
@input.if(!state.loading)=handle_input
@paste.if(!state.loading)=handle_paste
@cut=handle_cut
disabled=state.loading
<.tip
@click=handle_click_link
@hotkey('return').force.if(!loading)=handle_click_link
>
<.tip-hotkey> "Return"
<.tip-content> "Navigate To Link"
if (let m = math_result) isnt no
<.side.right@click=handle_click_copy(m)>
"= {Math.round(m * 100)/100}"
css c:blue3 fs:20px ml:10px w:unset
else
<.side.right @click.if(!state.loading)=toggle_settings>
<svg src="../assets/settings.svg">
if state.active_bang or state.sorted_links.length < 1
<app-tips>
<.tip-row>
<.tip
@click=(state.active_bang = no)
@hotkey('esc').capture.if(!state.loading)=(state.active_bang = no)
>
<.tip-hotkey> "Esc"
<.tip-content> "Back"
<.tip
@click=handle_shift_return
@hotkey('shift+return').capture.if(!state.loading)=handle_shift_return
>
<.tip-hotkey> "Shift + Return"
<.tip-content.ellipsis>
<span[ws:pre]> "Create Link "
let sq = state.query.trim!.split /\s+/
if sq.length >= 2
let url = sq.pop!
<span> '"'
<span> sq.join " "
<span[c:blue3 ws:pre]> " {url}"
<span> '"'
else
<span> "\"{sq.join " "}\""
<.tip
@click=(state.active_bang = no)
@hotkey('esc').capture.if(!state.loading)=(state.active_bang = no)
>
<.tip-hotkey> "Return"
<.tip-content> "Search"
else
<app-tips>
<.tip-row>
<.tip
@click=handle_click_link
@hotkey('return').force.if(!loading)=handle_click_link
>
<.tip-hotkey> "Return"
<.tip-content> "Navigate To Link"
<.tip
@click=handle_shift_return
@hotkey('shift+return').capture.if(!state.loading)=handle_shift_return
>
<.tip-hotkey> "Shift + Return"
<.tip-content.ellipsis>
<span[ws:pre]> "Create Link "
let sq = state.query.trim!.split /\s+/
if sq.length >= 2
let url = sq.pop!
<span> '"'
<span> sq.join " "
<span[c:blue3 ws:pre]> " {url}"
<span> '"'
else
<span> "\"{sq.join " "}\""
<.tip
@click=handle_shift_backspace
@hotkey('shift+backspace').capture.if(!state.loading)=handle_shift_backspace
>
<.tip-hotkey> "Shift + Backspace"
<.tip-content> "Edit Link"
<.tip
@click=handle_shift_return
@hotkey('shift+return').capture.if(!state.loading)=handle_shift_return
>
<.tip-hotkey> "Shift + Return"
<.tip-content.ellipsis>
<span[ws:pre]> "Create Link "
let sq = state.query.trim!.split /\s+/
if sq.length >= 2
let url = sq.pop!
<span> '"'
<span> sq.join " "
<span[c:blue3 ws:pre]> " {url}"
<span> '"'
else
<span> "\"{sq.join " "}\""
<.tip
@click=handle_shift_backspace
@hotkey('shift+backspace').capture.if(!state.loading)=handle_shift_backspace
>
<.tip-hotkey> "Shift + Backspace"
<.tip-content> "Edit Link"
<app-tips-more$tips-more>
<app-tips-more$tips-more>
<.tip-row>
<.tip-row>
<.tip
@click.if(!state.loading)=api.toggle_effective_names
@hotkey('tab').capture.if(!state.loading)=api.toggle_effective_names
>
<.tip-hotkey> "Tab"
<.tip-content> "Toggle Effective Names"
<.tip
@click.if(!state.loading)=api.toggle_effective_names
@hotkey('tab').capture.if(!state.loading)=api.toggle_effective_names
>
<.tip-hotkey> "Tab"
<.tip-content> "Toggle Effective Names"
<.tip
@click.if(!state.loading)=api.toggle_settings
@hotkey('esc').capture.if(!state.loading)=toggle_settings
>
<.tip-hotkey> "Esc"
<.tip-content> "Toggle Settings"
<.tip
@click.if(!state.loading)=refs.settings.open
@hotkey('esc').capture.if(!state.loading)=refs.settings.open
>
<.tip-hotkey> "Esc"
<.tip-content> "Toggle Settings"
<.tip.noclick
@hotkey('down').capture.if(!state.loading)=api.increment_link_selection_index
@hotkey('up').capture.if(!state.loading)=api.decrement_link_selection_index
>
<.tip-hotkey> "Up/Down Arrow"
<.tip-content> "Move Selection"
<.tip.noclick
@hotkey('down').capture.if(!state.loading)=api.increment_link_selection_index
@hotkey('up').capture.if(!state.loading)=api.decrement_link_selection_index
>
<.tip-hotkey> "Up/Down Arrow"
<.tip-content> "Move Selection"
<.tip-row>
<.tip-row>
<.tip
@click.if(!loading)=handle_cut
>
if math_result
<.tip-hotkey> "Cut (Math, If No Selection)"
<.tip-content> "Cut Math Result"
else
<.tip-hotkey> "Cut (If No Selection)"
<.tip-content> "Cut All Text"
<.tip
@click.if(!loading)=api.handle_cut
>
if api.math_result
<.tip-hotkey> "Cut (Math, If No Selection)"
<.tip-content> "Cut Math Result"
else
<.tip-hotkey> "Cut (If No Selection)"
<.tip-content> "Cut All Text"
<.tip.noclick>
<.tip-hotkey> "Paste (If Input Empty)"
<.tip-content> "Instant Search"
<.tip.noclick>
<.tip-hotkey> "Paste (If Input Empty)"
<.tip-content> "Instant Search"
<.tip.placeholder>
<.tip.placeholder>
unless $tips-more.active
<.links>
css d:flex fld:column jc:flex-start
fl:1 w:100% ofy:auto
unless $tips-more.active
<.links>
css ofy:scroll
for link, index in state.sorted_links
<app-link link=link index=index>
if state.active_bang
<app-bang bang=state.active_bang>
elif state.sorted_links.length < 1
<app-bang bang=config.data.default_bang>
else
for link, index in state.sorted_links
<app-link link=link index=index>

2
app/styles.imba

@ -1,5 +1,5 @@
global css body
d:flex fld:column jc:flex-start ai:center
d:flex fld:column jc:start ai:center
m:0 w:100% h:100% bg:#20222f
ff:sans-serif fw:1
user-select:none

Loading…
Cancel
Save