Move all logic to background script
This commit is contained in:
parent
e46d295346
commit
12e9d50a45
@ -9,25 +9,16 @@
|
||||
"96": "icons/icon96.png",
|
||||
"128": "icons/icon128.png"
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": [
|
||||
"js/browser-polyfill.min.js",
|
||||
"js/generated/out/cljs_base.js",
|
||||
"js/generated/content.js"
|
||||
]
|
||||
}
|
||||
],
|
||||
"background": {
|
||||
"scripts": ["js/browser-polyfill.min.js",
|
||||
"js/generated/out/cljs_base.js",
|
||||
"js/generated/background.js"]
|
||||
"js/generated/main.js"]
|
||||
},
|
||||
"browser_action": {
|
||||
"default_icon": "icons/icon48.png",
|
||||
"default_title": "Looped In"
|
||||
},
|
||||
"permissions": ["tabs"],
|
||||
"content_security_policy": "script-src 'self'; object-src 'self'; connect-src 'self' https://hn.algolia.com",
|
||||
"web_accessible_resources": ["js/*.map", "js/generated/*.map"]
|
||||
}
|
||||
|
10
project.clj
10
project.clj
@ -14,11 +14,7 @@
|
||||
:source-map true
|
||||
:pretty-print true
|
||||
:output-dir "ext/js/generated/out"
|
||||
:language-in :es6
|
||||
:modules
|
||||
{:content
|
||||
{:output-to "ext/js/generated/content.js"
|
||||
:entries #{"looped-in.content"}}
|
||||
:background
|
||||
{:output-to "ext/js/generated/background.js"
|
||||
:entries #{"looped-in.background"}}}}}]})
|
||||
{:background
|
||||
{:output-to "ext/js/generated/main.js"
|
||||
:entries #{"looped-in.main"}}}}}]})
|
||||
|
@ -1,40 +0,0 @@
|
||||
(ns looped-in.background
|
||||
(:require [clojure.core.match :refer [match]]
|
||||
[cljs.core.async :refer [go chan >! <!]]
|
||||
[ajax.core :refer [GET]]
|
||||
[looped-in.logging :as log]
|
||||
[looped-in.promises :refer [channel->promise]]))
|
||||
|
||||
(enable-console-print!)
|
||||
|
||||
(def browser-action (.-browserAction js/browser))
|
||||
|
||||
(defn fetch-submission
|
||||
"Fetches submissions from Hacker News by `url`"
|
||||
[url]
|
||||
(let [response-chan (chan)]
|
||||
(GET "https://hn.algolia.com/api/v1/search"
|
||||
{:params {"query" url
|
||||
"hitsPerPage" 1000
|
||||
"restrictSearchableAttributes" "url"}
|
||||
:handler (fn [res] (go (>! response-chan res)))
|
||||
:error-handler (fn [err] (log/error "Error fetching HN stories:"
|
||||
(clj->js err)))})
|
||||
response-chan))
|
||||
|
||||
(defn handle-message
|
||||
"Handles messages from the content script"
|
||||
[msg]
|
||||
(match (.-type msg)
|
||||
"urlVisited" (channel->promise (fetch-submission (.-url msg)))
|
||||
x (log/warn "Ignoring unknown message type" x)))
|
||||
|
||||
(-> js/browser
|
||||
(.-runtime)
|
||||
(.-onMessage)
|
||||
(.addListener handle-message
|
||||
#_(fn [msg]
|
||||
(prn msg)
|
||||
(.setBadgeBackgroundColor browser-action #js {:color "#232323"})
|
||||
(.setBadgeText browser-action
|
||||
#js {:text (str (.-numComments msg))}))))
|
@ -1,50 +0,0 @@
|
||||
(ns looped-in.content
|
||||
(:require-macros [cljs.core.async.macros :refer [go]])
|
||||
(:require [ajax.core :refer [GET]]
|
||||
[cljs.core.async :as async :refer [go <!]]
|
||||
[looped-in.logging :as log]
|
||||
[looped-in.promises :refer [promise->channel]]))
|
||||
|
||||
(enable-console-print!)
|
||||
|
||||
(defn filter-response
|
||||
"Filters a response from hn.algolia.com to give just the relevant results"
|
||||
;; TODO implement a cache by URL and timestamp that caches the results of the
|
||||
;; request and this method for 5 minutes using localStorage
|
||||
[url response]
|
||||
(let [{:strs [hits]} response]
|
||||
(log/debug "response" response)
|
||||
(filter #(= (get % "url") url) hits)))
|
||||
|
||||
(defn sort-hits
|
||||
"Sorts hits from hn.algolia.com by post date descending"
|
||||
[hits]
|
||||
(sort-by #(get % "created_at_i") #(compare %2 %1) hits))
|
||||
|
||||
(defn total-num-comments
|
||||
"Returns the total number of comments from some hits"
|
||||
[hits]
|
||||
(reduce (fn [acc {:strs [num_comments]}] (+ acc num_comments)) 0 hits))
|
||||
|
||||
(defn handle-hits
|
||||
"Handles a filtered response"
|
||||
[hits]
|
||||
(log/debug (clj->js hits))
|
||||
(let [num-comments (total-num-comments hits)]
|
||||
(-> js/browser
|
||||
(.-runtime)
|
||||
(.sendMessage #js {:numComments num-comments}))))
|
||||
|
||||
#_(let [current-url (-> js/window (.-location) (.-href))
|
||||
sub-chan (fetch-submission current-url)]
|
||||
(go (->> (<! sub-chan)
|
||||
(filter-response current-url)
|
||||
(sort-hits)
|
||||
(handle-hits))))
|
||||
|
||||
(let [current-url (-> js/window (.-location) (.-href))
|
||||
results-chan (-> js/browser
|
||||
(.-runtime)
|
||||
(.sendMessage #js {:type "urlVisited" :url current-url})
|
||||
(promise->channel))]
|
||||
(go (log/debug "results:" (<! results-chan))))
|
@ -1,13 +1,13 @@
|
||||
(ns looped-in.logging)
|
||||
|
||||
(defn info [& args]
|
||||
(apply js/console.info "[Looped In]" args))
|
||||
(apply js/console.info "[Looped In]" (map clj->js args)))
|
||||
|
||||
(defn error [& args]
|
||||
(apply js/console.error "[Looped In]" args))
|
||||
(apply js/console.error "[Looped In]" (map clj->js args)))
|
||||
|
||||
(defn debug [& args]
|
||||
(apply js/console.debug "[Looped In]" args))
|
||||
(apply js/console.debug "[Looped In]" (map clj->js args)))
|
||||
|
||||
(defn warn [& args]
|
||||
(apply js/console.warn "[Looped In]" args))
|
||||
(apply js/console.warn "[Looped In]" (map clj->js args)))
|
||||
|
79
src/looped_in/main.cljs
Normal file
79
src/looped_in/main.cljs
Normal file
@ -0,0 +1,79 @@
|
||||
(ns looped-in.main
|
||||
(:require [clojure.core.match :refer [match]]
|
||||
[cljs.core.async :refer [go chan >! <!]]
|
||||
[ajax.core :refer [GET]]
|
||||
[looped-in.logging :as log]
|
||||
[looped-in.promises :refer [channel->promise promise->channel]]))
|
||||
|
||||
(enable-console-print!)
|
||||
|
||||
(defn fetch-submission
|
||||
"Fetches submissions from Hacker News by `url`"
|
||||
[url]
|
||||
(let [response-chan (chan)]
|
||||
(GET "https://hn.algolia.com/api/v1/search"
|
||||
{:params {"query" url
|
||||
"hitsPerPage" 1000
|
||||
"restrictSearchableAttributes" "url"}
|
||||
:handler (fn [res] (go (>! response-chan res)))
|
||||
:error-handler (fn [err] (log/error "Error fetching HN stories:"
|
||||
(clj->js err)))})
|
||||
response-chan))
|
||||
|
||||
(defn url-path [url]
|
||||
(when (not (nil? url))
|
||||
(second (re-matches #"http.*://(.*)" url))))
|
||||
|
||||
(defn filter-response
|
||||
"Filters a response from hn.algolia.com to give just the relevant results"
|
||||
[url response]
|
||||
(let [{:strs [hits]} response]
|
||||
(filter #(= (url-path (get % "url")) (url-path url)) hits)))
|
||||
|
||||
(defn sort-hits
|
||||
"Sorts hits from hn.algolia.com by post date descending"
|
||||
[hits]
|
||||
(sort-by #(get % "created_at_i") #(compare %2 %1) hits))
|
||||
|
||||
(defn total-num-comments
|
||||
"Returns the total number of comments from some hits"
|
||||
[hits]
|
||||
(reduce (fn [acc {:strs [num_comments]}] (+ acc num_comments)) 0 hits))
|
||||
|
||||
(defn set-badge-text! [text]
|
||||
(.setBadgeBackgroundColor (.-browserAction js/browser) #js {:color "#232323"})
|
||||
(.setBadgeText (.-browserAction js/browser) #js {:text text}))
|
||||
|
||||
;; TODO implement a cache on the result of the urlVisited message
|
||||
|
||||
(defn handle-update [tab-id]
|
||||
(go (let [query-p (-> js/browser (.-tabs) (.query #js {:active true
|
||||
:currentWindow true}))
|
||||
query-chan (promise->channel query-p)
|
||||
tab (first (<! query-chan))
|
||||
url (.-url tab)
|
||||
fetch-chan (fetch-submission url)
|
||||
response (<! fetch-chan)
|
||||
hits (->> response
|
||||
(filter-response url)
|
||||
(sort-hits))
|
||||
num-comments (total-num-comments hits)]
|
||||
(set-badge-text! (str num-comments)))))
|
||||
|
||||
(-> js/browser
|
||||
(.-tabs)
|
||||
(.-onActivated)
|
||||
(.addListener handle-update))
|
||||
|
||||
(-> js/browser
|
||||
(.-tabs)
|
||||
(.-onUpdated)
|
||||
(.addListener handle-update))
|
||||
|
||||
;; Application logic:
|
||||
;; 1. Event comes in (new url)
|
||||
;; 2. Fetch HN hits
|
||||
;; 3. Filter and sort hits
|
||||
;; 4. Count comments, update badge
|
||||
;; 5. Fetch item details
|
||||
;; 6. Construct popup (or sidebar?) html
|
Loading…
Reference in New Issue
Block a user