Browse Source

use localStorage instead of Chrome bookmarks; possibility to add and remove link

main
Marek Piasecki 1 year ago
parent
commit
5722deeb01
  1. 13
      chrome/manifest.json
  2. 20
      package-lock.json
  3. 7
      package.json
  4. 24
      src/api.imba
  5. 61
      src/components/app-home.imba
  6. 9
      src/components/app-links.imba
  7. 5
      src/config.imba
  8. 25
      src/main.imba
  9. 7
      src/state.imba
  10. 3
      vite.config.js

13
chrome/manifest.json

@ -1,13 +0,0 @@
{
"name": "fuzzyhome",
"description": "A power user oriented new-tab page that enables lightning speed navigation through the dark magic of fuzzy finding.",
"version": "2.2.0",
"manifest_version": 3,
"permissions": [
"bookmarks",
"storage"
],
"chrome_url_overrides": {
"newtab": "dist/index.html"
}
}

20
package-lock.json

@ -14,6 +14,9 @@
"math-expression-evaluator": "^2.0.0", "math-expression-evaluator": "^2.0.0",
"vite": "^3.2.5", "vite": "^3.2.5",
"vite-plugin-imba": "^0.10.1" "vite-plugin-imba": "^0.10.1"
},
"devDependencies": {
"vite-plugin-singlefile": "^0.13.2"
} }
}, },
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {
@ -2030,7 +2033,6 @@
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"peer": true,
"dependencies": { "dependencies": {
"braces": "^3.0.2", "braces": "^3.0.2",
"picomatch": "^2.3.1" "picomatch": "^2.3.1"
@ -2750,6 +2752,22 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/vite-plugin-singlefile": {
"version": "0.13.2",
"resolved": "https://registry.npmjs.org/vite-plugin-singlefile/-/vite-plugin-singlefile-0.13.2.tgz",
"integrity": "sha512-HAvrU9mxasNMn/YF0Hb9NjsWDstCWe4iLQ6IR5ppOiNMvXjcyqU3C9SDQ32xnonx3Y04JUGjD2bGiT6q0S9T8w==",
"dev": true,
"dependencies": {
"micromatch": "^4.0.5"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"peerDependencies": {
"rollup": ">=2.79.0",
"vite": ">=3.2.0"
}
},
"node_modules/vitest": { "node_modules/vitest": {
"version": "0.27.1", "version": "0.27.1",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.27.1.tgz", "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.27.1.tgz",

7
package.json

@ -5,8 +5,8 @@
"homepage": "https://fuzzyho.me/", "homepage": "https://fuzzyho.me/",
"author": "Mikey Oz (https://github.com/familyfriendlymikey)", "author": "Mikey Oz (https://github.com/familyfriendlymikey)",
"scripts": { "scripts": {
"dev": "vite build -w --outDir chrome/dist --minify false", "dev": "vite",
"build": "vite build --outDir chrome/dist" "build": "vite build"
}, },
"dependencies": { "dependencies": {
"fzi": "^1.5.0", "fzi": "^1.5.0",
@ -15,5 +15,8 @@
"math-expression-evaluator": "^2.0.0", "math-expression-evaluator": "^2.0.0",
"vite": "^3.2.5", "vite": "^3.2.5",
"vite-plugin-imba": "^0.10.1" "vite-plugin-imba": "^0.10.1"
},
"devDependencies": {
"vite-plugin-singlefile": "^0.13.2"
} }
} }

24
src/api.imba

@ -1,4 +1,4 @@
import state from './state.imba' import state, { storage } from './state.imba'
import config from './config.imba' import config from './config.imba'
import { find, omit, orderBy } from 'lodash' import { find, omit, orderBy } from 'lodash'
@ -8,17 +8,24 @@ import Mexp from 'math-expression-evaluator'
let mexp = new Mexp let mexp = new Mexp
export default new class api export default new class api
#home_input = #link_input = null
def pin_link link def pin_link link
Pins[link.url] ^= 1 Pins[link.url] ^= 1
sort_links! sort_links!
global.chrome.storage.sync.set {pins:Pins} storage.set 'pins', Pins
imba.commit! imba.commit!
def increment_link_frequency link def increment_link_frequency link
Frequencies[link.url] ??= 0 Frequencies[link.url] ??= 0
Frequencies[link.url] += 1 Frequencies[link.url] += 1
global.chrome.storage.sync.set {frequencies:Frequencies} storage.set 'frequencies', Frequencies
def refresh_links
let links = []
links.push(title: k, url: v) for own k,v of Links
state.links = self.traverse(links)
self.sort_links!
def get-link-from-node node def get-link-from-node node
return unless let url = node..url return unless let url = node..url
@ -74,16 +81,23 @@ export default new class api
Date!.toString!.split(" ").slice(0, 4).join(" ") Date!.toString!.split(" ").slice(0, 4).join(" ")
get selected_link get selected_link
state.sorted_links[state.link_selection_index] state.sorted_links[state.link_selection_index] || { name: "", alias: "", is_bang:no, url: "" }
def select_name(name)
set_link_selection_index(0)
while selected_link.name != name
increment_link_selection_index!
def set_link_selection_index index def set_link_selection_index index
state.link_selection_index = index state.link_selection_index = index
def increment_link_selection_index def increment_link_selection_index
set_link_selection_index Math.min(state.sorted_links.length - 1, state.link_selection_index + 1) set_link_selection_index Math.min(state.sorted_links.length - 1, state.link_selection_index + 1)
#home_input.focus!
def decrement_link_selection_index def decrement_link_selection_index
set_link_selection_index Math.max(0, state.link_selection_index - 1) let i = set_link_selection_index Math.max(-1, state.link_selection_index - 1)
#link_input.focus! if i == -1
def navigate link def navigate link
await increment_link_frequency link await increment_link_frequency link

61
src/components/app-home.imba

@ -2,9 +2,38 @@ tag app-home
def mount def mount
$home-input.focus! $home-input.focus!
api.#home_input = $home-input
api.#link_input = $link-input-url
def blur def blur
setTimeout(&, 100) do $home-input.focus! setTimeout(&, 100) do
if document.activeElement != $link-input-url and document.activeElement != $link-input-title
$home-input.focus!
def edd_link
let title = $link-input-title.value
let url = $link-input-url.value
if !title
$link-input-title.focus!
elif !url
$link-input-url.focus!
else
if api.selected_link.name != title
delete Links[api.selected_link.name]
Links[title] =? url
storage.set 'links', Links
api.refresh_links!
api.select_name(title)
$home-input.focus!
def delete_link
delete Links[$link-input-title.value]
storage.set 'links', Links
$link-input-title.value = ""
$link-input-url.value = ""
api.refresh_links!
$home-input.focus!
def handle_click_copy s def handle_click_copy s
try try
@ -18,6 +47,31 @@ tag app-home
<self> <self>
css w:100% d:flex fld:column ofy:hidden gap:20px css w:100% d:flex fld:column ofy:hidden gap:20px
<.header>
css
d:hcl filter:grayscale(80%)
> input
h:34px px:20px
fs:14px
bd:1px solid $input-bc
outline:none rd:5px
bg:$input-bg c:$text-c
caret-color:$input-caret-c
<[c:$button-c] @click=delete_link!> "⨯"
<input$link-input-title[ml:17px bdr:0 rdr:0]
disabled=state.loading
@blur=blur
placeholder="title"
@keydown.enter.stop=edd_link!
value=api.selected_link.name
>
<input$link-input-url[bdl:0 rdl:0 w:380px]
disabled=state.loading
@blur=blur
placeholder="url"
@keydown.enter.stop=edd_link!
value=api.selected_link.url
>
<.header> <.header>
css css
@ -69,9 +123,10 @@ tag app-home
css e:400ms of:hidden css e:400ms of:hidden
@off o:0 @off o:0
if state.active_bang or state.sorted_links.length < 1 if state.active_bang or (state.sorted_links.length < 1 and state.links.length)
<app-bang> <app-bang>
else else
<app-links> <app-links>
if !state.links.length
<h3[ta:center c:$button-c] @click=$link-input-url.focus!> "Add first link"

9
src/components/app-links.imba

@ -38,7 +38,14 @@ tag app-links
hotkey_handler: api.decrement_link_selection_index.bind(api) hotkey_handler: api.decrement_link_selection_index.bind(api)
hotkey: 'up' hotkey: 'up'
hotkey_display_name: "Up Arrow" hotkey_display_name: "Up Arrow"
content: "Move Selection Up" content: state.link_selection_index > 0 ? "Move Selection Up" : "Add New Link"
}
result.push temp
temp = {
click_handler: do api.#link_input.focus!
hotkey_display_name: "Shift+Tab"
content: "Edit Link"
} }
result.push temp result.push temp

5
src/config.imba

@ -1,13 +1,14 @@
import {storage} from './state.imba'
export default new class config export default new class config
def save def save
global.localStorage.fuzzyhome_config = JSON.stringify(data) storage.set 'fuzzyhome_config', data
def constructor def constructor
data = {} data = {}
try try
data = JSON.parse(global.localStorage.fuzzyhome_config) data = storage.get 'fuzzyhome_config'
data.focus ??= yes data.focus ??= yes

25
src/main.imba

@ -4,7 +4,7 @@ import pkg from '../package.json'
let version = pkg.version let version = pkg.version
L "fuzzyhome version {version}" L "fuzzyhome version {version}"
import state from './state.imba' import state, { storage } from './state.imba'
import api from './api.imba' import api from './api.imba'
import config from './config.imba' import config from './config.imba'
@ -23,26 +23,23 @@ extend tag element
api api
get config get config
config config
get storage
storage
if config.data.focus and location.search =? "?x" if config.data.focus and location.search =? "?x"
throw new Error throw new Error
global.Pins = {} global.Pins = {}
global.Frequencies = {} global.Frequencies = {}
global.Links = {}
def init def init
let { pins } = await global.chrome.storage.sync.get 'pins' Pins = storage.get('pins') || {}
Pins = pins or {} Frequencies = storage.get('frequencies') || {}
Links = storage.get('links') || {}
let { frequencies } = await global.chrome.storage.sync.get 'frequencies' api.refresh_links!
Frequencies = frequencies or {} state.loaded = yes
imba.commit!
global.chrome.bookmarks.getTree! do(bookmarks)
const bookmarks-bar = bookmarks[0].children[0].children
state.links = api.traverse bookmarks-bar
api.sort_links!
state.loaded = yes
imba.commit!
init! init!
@ -66,7 +63,7 @@ tag app
bg:$appbg bg:$appbg
w:80vw max-width:700px max-height:80vh w:80vw max-width:700px max-height:80vh
bxs:0px 0px 10px rgba(0,0,0,0.35) bxs:0px 0px 10px rgba(0,0,0,0.35)
box-sizing:border-box p:30px rd:10px mt:10vh box-sizing:border-box p:30px rd:10px mt:7vh
if state.view is 'settings' if state.view is 'settings'
<app-settings> <app-settings>

7
src/state.imba

@ -1,3 +1,8 @@
export const storage = {
set: do |k, v| global.localStorage.setItem(k, JSON.stringify(v))
get: do |k| JSON.parse global.localStorage.getItem(k)
}
export default { export default {
view: 'home' view: 'home'
query: '' query: ''
@ -7,4 +12,4 @@ export default {
link_selection_index: 0 link_selection_index: 0
active_bang: no active_bang: no
loaded:no loaded:no
} }

3
vite.config.js

@ -1,7 +1,8 @@
import { imba } from 'vite-plugin-imba'; import { imba } from 'vite-plugin-imba';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import { viteSingleFile } from "vite-plugin-singlefile"
export default defineConfig({ export default defineConfig({
base: '', base: '',
plugins: [imba()], plugins: [imba(), viteSingleFile({removeViteModuleLoader: true})],
}); });

Loading…
Cancel
Save