|
|
@ -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> |
|
|
|