You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

179 lines
4.9 KiB

let p = console.log
import { err } from './utils'
import db from './db'
import state from './state'
import config from './config'
import { omit, orderBy } from 'lodash'
import { nanoid } from 'nanoid'
import fzi from 'fzi'
export default new class api
def add_link text
let link = await create_link_from_text text
link.id = nanoid!
await db.links.add link
await reload_db!
imba.commit!
p omit(link, "icon")
return link
def update_link old_link, new_link_text
let new_link = await create_link_from_text new_link_text
new_link.frequency = old_link.frequency
let result = await db.links.update old_link.id, new_link
throw "Link id not found." if result is 0
await reload_db!
imba.commit!
p omit(old_link, "icon")
p omit(new_link, "icon")
return new_link
def delete_link link
def go
try
await db.links.delete(link.id)
catch e
return err "deleting link", e
try
await reload_db!
catch e
return err "reloading db after successful delete", e
state.loading = yes
await go!
state.link_selection_index = Math.min state.link_selection_index, state.sorted_links.length - 1
state.loading = no
def pin_link link
link.is_pinned = !link.is_pinned
try
let result = await db.links.update link.id, link
throw "Link id not found." if result is 0
catch e
return err "pinning link", e
await reload_db!
imba.commit!
def reload_db
state.links = await db.links.toArray()
sort_links!
def increment_link_frequency link
try
await db.links.update link.id, { frequency: link.frequency + 1 }
catch e
err "putting link", e
def sort_links
if state.query.trim!.length <= 0
return state.sorted_links = orderBy(state.links, ['is_pinned', 'frequency'], ['desc', 'desc'])
if config.data.enable_effective_names
return state.sorted_links = fzi state.links, state.query
state.sorted_links = fzi state.links, state.query, "display_name"
def add_initial_links
let initial_links = [
"tutorial github.com/familyfriendlymikey/fuzzyhome"
"!brave search `b search.brave.com/search?q="
"!youtube youtube.com/results?search_query="
"photopea photopea.com"
"twitch twitch.tv"
"messenger `me messenger.com"
"instagram `in instagram.com"
"localhost `3000 http://localhost:3000"
]
for link_text in initial_links
try
add_link link_text
catch e
err "adding link", e
def create_link_from_text text
text = text.trim!
throw "Text is empty." if text is ''
let split_text = text.split(/\s+/)
throw "No url provided." if split_text.length < 2
let url = split_text.pop!
let host
{ href:url, host } = parse_url url
let icon = await fetch_image_as_base_64 host
let name
if split_text[-1].startsWith "`"
name = split_text.pop!.slice(1)
let display_name = split_text.join(" ")
let is_bang = no
let is_pinned = no
if display_name.startsWith "!"
is_bang = yes
display_name = display_name.slice(1)
name ||= display_name
{ name, display_name, is_bang, is_pinned, url, frequency:0, icon }
def fetch_image_as_base_64 host
let fallback = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAH0lEQVR42mO8seXffwYqAsZRA0cNHDVw1MBRA0eqgQCDRkbJSQHxEQAAAABJRU5ErkJggg=='
return new Promise! do |resolve|
let res
try
res = await global.fetch("https://icon.horse/icon/{host}")
catch
p "Failed to get icon from icon horse."
return resolve fallback
# todo: can i use .text() on this or something
let blob = await res.blob!
let reader = new FileReader!
reader.onload = do
resolve this.result
reader.onerror = do
p "Failed to get data from reader."
resolve fallback
return
reader.readAsDataURL(blob)
def toggle_effective_names
config.data.enable_effective_names = !config.data.enable_effective_names
config.save!
sort_links!
def construct_link_text link
link.display_name = link.display_name.trim!
link.name = link.name.trim!
link.url = link.url.trim!
let link_text = ""
link_text += "!" if link.is_bang
link_text += link.display_name
link_text += " `{link.name}" if link.name isnt link.display_name
link_text += " {link.url}"
link_text
def parse_url url
throw "invalid url" if url === null
let get_url = do |s|
let url = new URL s
throw _ unless (url.host and url.href)
url
try
return get_url url
try
return get_url "https://{url}"
throw "invalid url"
def get_pretty_date
Date!.toString!.split(" ").slice(0, 4).join(" ")
get selected_link
state.sorted_links[state.link_selection_index]
def set_link_selection_index index
state.link_selection_index = index
def increment_link_selection_index
set_link_selection_index Math.min(state.sorted_links.length - 1, state.link_selection_index + 1)
def decrement_link_selection_index
set_link_selection_index Math.max(0, state.link_selection_index - 1)
def navigate link
await increment_link_frequency link
window.location.href = link.url