Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

test ready notification revision

  • Loading branch information...
commit 6dcf70553fa1549619aa4f8b53fec599b1fc4060 1 parent b4d2a6f
@gregory80 gregory80 authored
View
61 notes.txt
@@ -1,6 +1,6 @@
-
+## Current Status
1.2.1
- Display currently watched linkes, ability to modify and remove 'watched' links
+ Display currently watched links, ability to modify and remove 'watched' links
1.2
Watch Button, Trending, character counter
@@ -12,21 +12,35 @@
----- Bug
-to fix the open issue with calls to all_domains that aren't logged in, required a restructuring of the startup process
- .. set from cache should do only that...
- ... I need some methods to manage this
- ... then if I am get signed in, it should call all_domains then....
+## Future Rev
+
+vr2 plan
+ Move to clicks per min api.
-===========
-Consider moving 'watch and alert' into a worker, where the timer and processing is done via the worker, which 'reaches' out/up to the background to get 'data' as it needs it.
+ Change trending api usage (only targets your links, this will be used for graphing your impact against a click per min score)
+
+ Canvas Charting
+
+ Attempt to integrate goog analytics (believe to be resolved, check bug status)
+
+ Speed Shortens
+ skips shorten and share, copy link directly to clipbord
+ (notifications -- > see have-a-cookie project for examples of this)
+
+ Translate HTML into JSON for fastFrag deployment
+
+ All tasks moved to BG progrecces
+
+ Disable emile.js in favor of CSS transitions.
+ Transitions are hardware accelerated. JS 'tweening' is not via CSS step algo is not.
-With this adjustment, allow for display of 'watch list' and un-watching links via the UI
-This UI change could also add 'timeout' value, which would be the amount of time to stop looking for this link. 2 hours 1 day, 5 days etc
+ Attempt to support local(e) via fastFrag seperation of 'language' and structure on render
+
+## Notes / Paste Ground
==== Manifest.json ====
@@ -38,24 +52,21 @@ The version number is automatically incremented by build.sh
*/
---- as noted, comments moved
-Support local in future rev
-
-
-=== Error Handling / Post Share Experience ====
-Currently, raw, returns success or failure. Does not check for minor errors, like not sending to one account if multiple accounts are specified
-
-Improvement Ideas:
- 1. Replace textarea with links and account used, make area scrollable to it over fits box exactly (no-redrawn)
- Add a close button, returns to text area with original 'shared' message
+(resolved?)
+---- Bug
+to fix the open issue with calls to all_domains that aren't logged in, required a restructuring of the startup process
+ .. set from cache should do only that...
+ ... I need some methods to manage this
+ ... then if I am get signed in, it should call all_domains then....
- 2. display a series of 'messages' to user, in order of response (ticker-like style. Similar to bit.ly error handling)
+===========
+Consider moving 'watch and alert' into a worker, where the timer and processing is done via the worker, which 'reaches' out/up to the background to get 'data' as it needs it.
- **3. Add link to 'share history', takes user to page of history of all shares, message and result.
- Adjust current message to include a # of #.
- ex: Successfully shared to # of # accounts. more >>
- (1 vote gregory80)
+With this adjustment, allow for display of 'watch list' and un-watching links via the UI
+
+This UI change could also add 'timeout' value, which would be the amount of time to stop looking for this link. 2 hours 1 day, 5 days etc
View
3  scripts/ping.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+for i in {1..15}; do curl -A 'chromer' http://bit.ly/dhWTKm 2&> /dev/null; done;
View
259 src/background.html
@@ -24,11 +24,12 @@
<script type="text/javascript" src="js/bitlyapi-v3.0.js"></script>
<script type="text/javascript" src="js/sqldb-v1.0.js"></script>
<script type="text/javascript" src="js/libs/md5.js"></script>
- <script type="text/javascript" src="js/libs/bg_common.js"></script>
- <script type="text/javascript" src="js/libs/common.js"></script>
+ <script type="text/javascript" src="js/libs/bg_common.js"></script>
+ <script type="text/javascript" src="js/libs/common.js"></script>
+ <script type="text/javascript" src="js/libs/bitNote.js"></script>
<script type="text/javascript" charset="utf-8">
-
+
// for use with expand_and_meta
function process_domains( url_list ) {
var i=0, j=0, domain, possible,
@@ -73,7 +74,7 @@
return final_list;
}
-
+
function sign_in(username, password, callback) {
logger("auth attempt for", username)
bitly.auth(username, password, function(response) {
@@ -92,6 +93,7 @@
});
chrome.browserAction.setPopup({ "popup" : "popup.html"});
fetch_all_domains();
+ watch_and_alert();
}
if(callback) callback(response)
@@ -102,11 +104,10 @@
bitly.remove_credentials();
auto_expand_urls = true;
- if(bit_interval) { clearInterval( bit_interval ); }
+ if(bit_interval) { clearInterval( bit_interval ); }
- localdelete("trends");
localdelete("realtime");
- localdelete("watch_list");
+ localdelete("note_blacklist");
localdelete("notifications");
localdelete("stash");
@@ -117,89 +118,110 @@
localdelete("user_data");
localdelete("share_accounts"); // we don't store share accounts in SQL
localdelete("no_expand_domains");
-
- bit_db.remove("watch_list", delete_sql_handler );
+
bit_db.remove("notifications", delete_sql_handler );
-
+
bit_db.remove("no_expand_domains", delete_sql_handler );
bit_db.remove("user_data", delete_sql_handler );
bit_db.remove("domain", delete_sql_handler );
bit_db.remove("auto_expand_urls", delete_sql_handler );
bitly.set_domain("bit.ly");
-
+
chrome.browserAction.setPopup({ "popup" : ""});
return;
}
function delete_sql_handler() {
// this is just a callback for deletes, check for success / failure, todo
- }
+ }
+
+
+ function notification_close_action( evt ){
+ console.log("close the", evt, arguments)
+ }
function display_notification() {
- if( get_latest_notifications().length <=0 ) return;
- // Or create an HTML notification:
- // check the viewm, make sure I don't have one open
- var notification = webkitNotifications.createHTMLNotification(
- 'notification.html' // html url - can be relative
- );
-
-
- // wait to show these, prevents possible race condition with 'set_notifications'
- setTimeout(function() {
- notification.show();
- }, 1000 );
-
- return true;
+ bitNote.show();
}
-
+
function watch_and_alert() {
console.log("trending interval check started");
- logger("Watch and Alert for a link has been enabled, notifications");
-
- get_realtime_metrics(function(jo) {
- jo.watch_list = get_watch_list();
- trends_worker.postMessage( jo );
- });
-
+ //logger("Watch and Alert for a link has been enabled, notifications");
+ if(!bitly.bit_request.access_token) {
+ console.log("no token to poll with");
+ }
+ var black_list=[], note_blacklist = localfetch("note_blacklist") || [];
+
+ console.log("starts with", note_blacklist)
+ var params = {
+ oauth_key : bitly.bit_request.access_token,
+ 'black_list' : note_blacklist,
+ 'action' : 'start'
+ }
+ trends_worker.postMessage( params );
}
function process_realtime_post_notification( short_urls ) {
- var r_time = localfetch("realtime"), bit_result, i=0,
- notes_list = [], l_notes = get_latest_notifications(), r_watch_list=[];
-
+ var r_time = localfetch("realtime"), bit_result, i=0, black_list=[], active_links = [],
+ notes_list = [], l_notes = get_latest_notifications(),
+ prefs = get_note_preferences();
+
if(short_urls.length <= 0 ) { return; }
r_time = r_time && r_time.realtime_links || [];
+
bitly.expand_and_meta( short_urls, function(jo) {
// add to the notifications, remove from the list...
for(var k in jo.expand_and_meta) {
bit_result = jo.expand_and_meta[k];
- for(i=0;i<r_time.length;i++) {
+
+ for(i=0;i<r_time.length;i++) {
if(r_time[i].user_hash === bit_result.user_hash) {
bit_result.trend_clicks = r_time[i].clicks;
- notes_list.push( bit_result );
- r_watch_list.push( bit_result.short_url );
- break;
}
}
- //remove_watch_item( bit_result.short_url );
+ if(bit_result.trend_clicks > prefs.threshold) {
+ black_list.push( bit_result.short_url );
+ notes_list.push( bit_result );
+ }
}
-
- remove_watch_items_list( r_watch_list );
l_notes = l_notes.concat(notes_list);
- set_notification_list( l_notes );
+ console.log("l_notes", l_notes)
+ console.log("black list", black_list)
+ set_notification_list( l_notes );
- display_notification();
- });
- }
+ if(l_notes.length > 0 ) {
+
+ display_notification();
+ }
+ if(black_list.length > 0) {
+ ///////////// //
+ var note_b_list = localfetch("note_blacklist") || [];
+ var params = {
+ oauth_key : bitly.bit_request.access_token,
+ 'black_list' : note_b_list.concat( black_list ),
+ 'action' : 'update'
+ }
+
+ // I can trim out stuff from note_blacklist
+
+ console.log("Updating the worker", black_list, params)
+ trends_worker.postMessage( params );
+ }
+
+ expire_old_blacklist();
+
+ });
+ }
+
function share_message( message, callback) {
var a = localfetch("share_accounts"),
accounts = a && a.share_accounts || [],
@@ -214,7 +236,7 @@
callback({'error' : 'no active accounts'})
return;
}
-
+
params.account_id = share_ids;
params.share_text = message;
bitly.share( params, function(jo) {
@@ -224,16 +246,16 @@
jo.error = true;
}
callback(jo);
- } );
- }
-
+ } );
+ }
+
function clear_domain_list() {
domains_list = [];
bit_db.remove( "domains_list" , function() {
console.log("success deleting domains list", arguments)
})
}
-
+
function set_api_domain( api_domain ) {
var api_change = bitly.set_domain( api_domain );
if(api_change) {
@@ -246,25 +268,10 @@
function get_realtime_metrics( callback ) {
- var minues=1, realtime = localfetch("realtime"), now = _now(),
- then = now - (1000*60*minues), trends;
- if(realtime && realtime.timestamp > then) {
-
- callback( realtime ); // use cache results when we can
- } else {
- bitly.realtime( function(jo) {
- jo.timestamp = now;
-
- localstore("realtime", jo);
- if(jo && jo.realtime_links && jo.realtime_links.length > 0 ) {
- trends = localfetch("trends") || [];
- trends.unshift( jo );
- localstore("trends", trends);
- }
-
- callback( jo )
- });
- }
+ var minues=1, realtime = localfetch("realtime"), now = _now(),
+ then = now - (1000*30), trends;
+
+ callback( realtime );
}
function get_api_domain() {
@@ -284,7 +291,7 @@
//anything here
})
}
-
+
function resync_linked_account( callback ) {
// get fresh from sever
var account, accounts, i=0;
@@ -297,7 +304,7 @@
response.error = true;
callback(response)
return;
- }
+ }
accounts = response && response.share_accounts;
if(accounts) {
@@ -322,10 +329,10 @@
bit_db.save( "domains_list", params, function() {
console.log("storing domains to sql", bit_domains.length)
})
- domains_list = bit_domains;
+ domains_list = bit_domains;
}
- });
- }
+ });
+ }
/*
Methods to fetch from 'cache'
@@ -343,8 +350,9 @@
if(user_data && user_data.x_login && user_data.x_apiKey) {
logger("User credentials found in cache");
bitly.set_credentials( user_data.x_login, user_data.x_apiKey, user_data.access_token );
+ watch_and_alert();
chrome.browserAction.setPopup({ "popup" : "popup.html"});
-
+
} else {
bit_db.find("user_data", function( sql_user_data ) {
@@ -352,6 +360,7 @@
localstore("user_data", sql_user_data);
// stash credentials into bitly API
bitly.set_credentials( sql_user_data.x_login, sql_user_data.x_apiKey, sql_user_data.access_token );
+ watch_and_alert();
chrome.browserAction.setPopup({ "popup" : "popup.html"});
});
}
@@ -362,7 +371,7 @@
if(!no_expand_domains || no_expand_domains.length <= 0) {
bit_db.find("no_expand_domains", function( domains_list ) {
-
+
if(!domains_list) {
no_expand_domains = ["bit.ly", "j.mp"];
bit_db.save("no_expand_domains", no_expand_domains, function() {
@@ -379,31 +388,22 @@
// bit_db.save("auto_copy", {'copy' : copy_bool }, function(){
// // save was successful
// localstore("auto_copy", copy_bool);
- // });
+ // });
bit_db.find("auto_copy", function(jo) {
if(jo === undefined) return;
localstore("auto_copy", jo.copy );
})
}
-
- function set_watch_list_from_cache() {
- bit_db.find("watch_list", function(jo) {
- if(jo === undefined) return;
- set_watch_list(jo);
- if(jo.length > 0) {
- watch_and_alert();
- }
- })
- }
-
+
+
function set_notifications_from_cache() {
bit_db.find("notifications", function(jo) {
if(jo === undefined) return;
localstore("notifications", jo );
})
}
-
+
function set_auto_expand_from_cache() {
bit_db.find("auto_expand_urls", function(jo) {
@@ -430,7 +430,7 @@
bit_db.find("domains_list", function(jo) {
var now = _now(), then = now - (24*60*60*1000)*5, curr_user;
if(jo && jo.timestamp > then && jo.domains.length > 10) {
-
+
domains_list = jo.domains || jo;
} else {
curr_user = localfetch("user_data") || {};
@@ -443,9 +443,9 @@
});
}
-
-// Start the App controls
+
+// Start the App controls
function init_api() {
// get from local storage?
// pull this value from a settings file
@@ -471,17 +471,47 @@
bitly.metrics("referrers", function(jo) {
console.log("referrers", jo)
- });
+ });
+ }
+
+ function trends_worker_message_event( evt ) {
+ // console.log(evt, "the worker says?")
+ console.log(evt.data, "trend data")
+
+
+ if(!evt.data.trending_links) {
+ return;
+ }
+
+
+ localstore("realtime", evt.data.trending_links );
+
+ var lists = evt.data.remove_list || [], black_list=[];
+ for( var i=0,item; item = lists[i]; i++ ) {
+ black_list.push( item.short_url );
+ }
+
+
+ var prefs = get_note_preferences();
+
+ if(prefs.enabled) {
+ process_realtime_post_notification( evt.data.notifications );
+ }
}
// the bit.ly API connector
logger("Initialize bit.ly extension");
- var bitly=init_api(), bit_db=init_db(), trends_worker,
+ var bitly=init_api(), bit_db=init_db(), trends_worker, click_by_min_worker,
domains_list, auto_expand_urls = true, bit_interval, // bit_interval is the timer for watch list
// for google tracking, when that's ready
_gaq = _gaq || [];
// Initialize Cache Items
+ expire_old_blacklist();
+ trends_worker = new Worker("js/workers/realtime_data.js");
+ trends_worker.onmessage = trends_worker_message_event;
+
+
set_current_bitly_user_from_cache();
set_domain_list_from_cache();
set_auto_expand_from_cache();
@@ -489,30 +519,19 @@
set_no_expand_domains_from_cache();
set_auto_copy_from_cache();
set_notifications_from_cache();
- set_watch_list_from_cache();
-
- trends_worker = new Worker("js/workers/realtime_data.js");
- trends_worker.onmessage = function(evt) {
- var i=0, dead_links=[];
- switch( evt.data.action) {
- case "analyzed_links":
- dead_links = evt.data.results && evt.data.results.dead_links || [];
- //for(i=0;i<dead_links.length;i++){ remove_watch_item( dead_links[i] ); }
- remove_watch_items_list( dead_links );
- setTimeout(function() {
- process_realtime_post_notification( evt.data.results.short_urls );
- }, 40);
-
- break;
+
+
+
+ // click_by_min_worker = new Worker("js/workers/clicks_per_minute.js");
+ // click_by_min_worker.postMessage({'shortUrl' : []});
+ //
+ // click_by_min_worker.onmessage = function(evt) {
+ // console.log(evt, "that worker works")
+ // }
- case "realtime":
- watch_and_alert();
- break;
- }
-
- }
+
/*
Listen for requests from content scripts, popups and other pages etc
@@ -547,7 +566,7 @@
*/
case "share":
//share_text
- share_message( (request.share_text || ""), sendResponse );
+ share_message( (request.share_text || ""), sendResponse );
break;
case "share_accounts":
@@ -621,7 +640,7 @@
case "page_select":
if(request.long_url.indexOf("http") === 0) {
chrome.tabs.executeScript(request.tab_id, {file: "js/content_plugins/getSelected.js"});
- }
+ }
break;
View
14 src/css/common.css
@@ -140,17 +140,23 @@
padding-left:10px;
}
-
+body.page_loaded #blueBanner {
+ height:45px;
+}
#blueBanner {
- height:45px;
+ height:0px;
background:#6BAFF0;
- -webkit-box-shadow:0 4px 4px #D9D9D9;
+ position:fixed;
+ top:0;
+ width:100%;
+ -webkit-box-shadow:0 4px 4px #D9D9D9;
+ -webkit-transition: height .5s ease-in-out;
}
#logo {
/* margin:18px 30px 0;*/
width:800px;
- margin:30px auto 0;
+ margin:75px auto 0;
}
#middle {
View
15 src/css/notifications.css
@@ -1,6 +1,6 @@
#container {
- width:290px;
- height:110px;
+ width:280px;
+ height:100px;
position:relative;
overflow:hidden;
color:#888;
@@ -13,6 +13,11 @@
}
+
+.more_trending_link_box {
+ padding-top:3px;
+}
+
#bit_fish {
position:absolute;
bottom:5px;
@@ -24,13 +29,13 @@
/*so so so bad... whatver*/
h4 {
font-weight:normal;
- font-size:13px;
+ font-size:18px;
}
-#footer h1 {
+/*#footer h1 {
font-size:18px;
color:#888;
font-weight:normal;
-}
+}*/
.note_headline {
overflow: hidden;
View
12 src/css/trending.css
@@ -29,7 +29,7 @@
height:20px;
}
.bit_trend_title h3 {
- font-size:15px;
+ font-size:18px;
font-weight:normal;
overflow: hidden;
text-overflow: ellipsis;
@@ -70,16 +70,22 @@
}
.longlink {
padding:2px 0 5px;
-
+
+}
+.changed_trend {
+ font-size:11px;
}
.longlink a {
color:#999;
- font-size:11px;
+ font-size:13px;
display:block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
+.changed_trend {
+
+}
.changed_trend img {
}
View
18 src/js/bitlyapi-v3.0.js
@@ -21,6 +21,7 @@ var host = "http://api.bit.ly",
'share' : '/v3/user/share',
'clicks' : '/v3/clicks',
'lookup' : '/v3/lookup',
+ 'clicks_by_minute' : '/v3/clicks_by_minute',
'realtime' : '/v3/user/realtime_links',
'metrics_base' : '/v3/user/'
}, errors = [];
@@ -176,10 +177,24 @@ BitApi.prototype = {
internal_multiget( host + urls.lookup, 'url', params, callback );
},
+ realtime_clicks_by_minutes : function( shortUrls, callback ) {
+ // http://api.bitly.net/v3/clicks_by_minute?
+ //login=XXXXXXX&apiKey=XXXXXXXXXXXXXXXXXXXXXXX&shortUrl=http://stk.ly/b45q7L
+ var params = {}
+
+ this.count+=1;
+ var params = { 'login' : this.bit_request.login,
+ 'apiKey' : this.bit_request.apiKey,
+ 'shortUrl' : shortUrls };
+ internal_multiget( host + urls.clicks_by_minute, 'url', params, callback );
+ },
+
/*
- SSL Hosts
+ SSL Hosts (HTTPS)
*/
+
+
realtime : function( callback ) {
var params = { 'access_token' : this.bit_request.access_token }
bitlyRequest( ssl_host + urls.realtime, params, callback );
@@ -208,7 +223,6 @@ BitApi.prototype = {
bitly_domains : function( callback ) {
//
var params = { 'access_token' : this.bit_request.access_token }
- //http://api.bit.ly/v3/all_domains
bitlyRequest( ssl_host + urls.domains, params, callback);
},
View
100 src/js/libs/bg_common.js
@@ -123,6 +123,7 @@ function get_no_expand_domains() {
/* Notification Preferences: enabled, threshold etc */
function get_note_preferences() {
+ // 20 days later, this was kinda genius - good job me. the only thing that doesn't suck
var default_pref = { 'enabled' : true, 'threshold' : 20, "interval" : 1, "interval_type" : 'hour' };
return localfetch("note_preferences") || default_pref;
}
@@ -155,13 +156,16 @@ function remove_notification() {
var notes = get_latest_notifications();
notes.shift();
- __process_notification_for_db( notes );
+ // console.log("old_note", old_note.short_url)
+ // //localstore.push()
+ //__process_notification_for_db( notes );
}
function set_notification_list( notes_list ) {
- __process_notification_for_db( notes_list );
+ localstore("notifications", notes_list);
+ //__process_notification_for_db( notes_list );
}
function __process_notification_for_db( notes ) {
@@ -177,78 +181,60 @@ function __process_notification_for_db( notes ) {
function set_notification( note ) {
var notes = localfetch("notifications") || [];
- notes.push( note );
- __process_notification_for_db( notes );
+ for(var i=0, notice; notice=notes[i]; i++) {
+ if(note.short_url === notice.short_url) {
+ return;
+ }
+ }
+ notes.push( note );
+
+ //__process_notification_for_db( notes );
}
////////////////***********************////////////////////////
-/* Watch List */
-function get_watch_list() {
- return localfetch("watch_list") || [];
-}
-function update_watch_item( watch_obj ) {
- var i=0, watch, w_list = get_watch_list();
- for( ; watch=w_list[i]; i++) {
- if( watch.short_url === watch_obj.short_url ) {
- watch.threshold = watch_obj.threshold;
- //watch.timestamp = watch_obj.timestamp;
+function add_to_notes_blacklist( new_notes ) {
+ // these are just items we don't want to see again
+ var notes = localfetch("note_blacklist") || [];
+
+ for(var i=0,note;note=new_notes[i]; i++) {
+ if(notes.indexOf( note ) > -1) {
+ continue;
}
+ notes.push( note );
}
- console.log(w_list)
- set_watch_list( w_list );
-}
-
-function set_watch_item( short_url, threshold ) {
- var list = localfetch("watch_list") || [];
- list.push( {'short_url': short_url, 'threshold': threshold, 'timestamp' : _now() } );
- set_watch_list( list );
-
- // set timeout or set interval?????
- // I can send the entire watch list, the callback should just loop over the results....
+ console.log( notes, "add these to temp blacklist" );
+ localstore("note_blacklist", notes);
}
-function set_watch_list( watch_list ) {
- // careful, overwrites, doesn't append
- localstore("watch_list", watch_list)
+
+function expire_old_blacklist() {
+ /*
+ Any url that's not in the in 'alive_list' take out of the expiration list.
+ */
+ var notes = localfetch("note_blacklist") || [], new_notes=[], r_time = localfetch("realtime");
+ r_time = r_time && r_time.realtime_links || [];
- if(watch_list.length > 0) {
- bit_db.save("watch_list", watch_list, function(tx, sql_result) {
- // something
- });
- } else {
- // drop it
- bit_db.remove("watch_list", function(){} );
- }
-
-
-}
-
-function remove_watch_items_list( short_urls ) {
-
- var l_watch = get_watch_list(), i=0, watched, f_wach_list=[];
- for(i=0; i<l_watch.length; i++) {
- watched = l_watch[i];
- if(short_urls.indexOf( watched.short_url ) === -1 ) {
- f_wach_list.push( watched );
+ outerLoop_expire:
+ for(var i=0, note; note=notes[i]; i++) {
+ for(var j=0; j<r_time.length; j++) {
+
+ if( note.indexOf( r_time[j].user_hash ) > -1 ) {
+ new_notes.push( note );
+ continue outerLoop_expire;
+ }
}
+
}
+ localstore("note_blacklist", new_notes);
+
- set_watch_list( f_wach_list );
}
-function remove_watch_item( short_url ) {
- var latest_watch_list = get_watch_list(), i=0, watch_item, clean_list=[];
- for( var i=0, watch_item; watch_item=latest_watch_list[i]; i++) {
- if(watch_item.short_url !== short_url) {
- clean_list.push( watch_item );
- }
- }
- set_watch_list( clean_list );
-}
+
////////////////***********************////////////////////////
View
37 src/js/libs/bitNote.js
@@ -0,0 +1,37 @@
+/*
+ filename : bitNote
+ http://unlicense.org/
+ author: gregory tomlinson
+ Sat Sep 11 21:48:26 EDT 2010
+*/
+
+(function() {
+
+ var notification;
+ function notification_close_action( evt ){
+ console.log("close the", evt, arguments)
+ }
+ function notification_display_action(evt) {
+ console.log("note is diplayed", evt)
+ }
+
+
+ var bitNote = {
+
+ html : "notification.html",
+
+ show : function( on_note_display, callback ) {
+ notification = webkitNotifications.createHTMLNotification( 'notification.html' );
+ // html url - can be relative
+
+ notification.ondisplay = on_note_display || notification_display_action;
+ notification.onerror = callback || function() { console.log( "error" ); }
+ notification.onclose = callback || notification_close_action;
+ notification.show();
+ return notification;
+ }
+ }
+
+ window.bitNote = bitNote;
+
+})();
View
247 src/js/libs/bitTrends.js
@@ -1,6 +1,6 @@
/*
- Dependency: common.js, timeFormat.js
+ Dependency: common.js, timeFormat.js, fastFrag.js
This 'script' is really just an interface to the trends DOM structure
@@ -19,7 +19,7 @@
return new bTrend( el, realtime_bits );
}
window.bitTrends = bitTrends;
- var trend_heigt = 75;
+ var trend_height = 75;
// all the real work, this was all a $.fn.whatever really is anyway, except it inherited the jQuery info
function bTrend( el, realtime_bits ) {
@@ -45,13 +45,15 @@
var current_trend = dataStich( this.realtime_bits.realtime_links, this.cache.meta ),
- trends = this.trends_list.slice(0), html;
+ trends = _copy( this.trends_list ), html, results;
trends.shift();
current_trend = addTrendingData( current_trend, trends );
//
html = drawTrendElements( current_trend );
- this.el.innerHTML = html;
+ results = fastFrag.create( html )
+ this.el.innerHTML = "";
+ this.el.appendChild( results );
},
@@ -74,7 +76,7 @@
var current_trend = dataStich( new_bits, this.cache.meta ),
- trends = this.trends_list.slice(0), html, trend_change_elem;
+ trends = _copy(this.trends_list), html, trend_change_elem;
current_trend = addTrendingData( current_trend, trends );
for(i=0; i<old_bits.length; i++) { old_bit_hash_keys.push( (old_bits[i]).user_hash ) }
@@ -87,9 +89,9 @@
}
}
- for(i=0; i<old_bits.length; i++) {
-
- }
+ // for(i=0; i<old_bits.length; i++) {
+ //
+ // }
@@ -107,10 +109,14 @@
// hash match
// J is where the element needs to go...
- trend_change_elem = item.getElementsByClassName("changed_trend")[0]
+ trend_change_elem = _q(".changed_trend", item);
var t_elem = _q(".bit_trend_clicks", item);
- t_elem.innerHTML = _drawClicks( new_bit );
- trend_change_elem.innerHTML = _drawChanged( new_bit );
+ t_elem.innerHTML = "";
+ t_elem.appendChild( fastFrag.create( _drawClicks( new_bit ) ) )
+ //t_elem.innerHTML = ;
+ trend_change_elem.innerHTML = "";
+ trend_change_elem.appendChild( fastFrag.create( _drawChanged( new_bit ) ) )
+
break;
}
}
@@ -137,26 +143,22 @@
}
var counter = 0;
- console.log("The missing elements are", missing_elements_list);
+ //console.log("The missing elements are", missing_elements_list);
for(var k in missing_elements_list) {
var bit_trend_item = missing_elements_list[k],
- clone = _q("item").cloneNode(true), el_position,
- t_elem = _q(".bit_trend_clicks", clone),
- t_elem_1 = _q(".changed_trend", clone),
- t_elem_2 = _q(".bit_trend_title", clone),
- t_elem_3 = _q(".bit_hash_value", clone);
-
+ el_position = (el_items.length+counter)*trend_height,
+ results = fastFrag.create({
+ type : "item",
+ css : "bit_trend_item",
+ attributes : {
+ bit_position : el_position,
+ bit_hash : bit_trend_item.user_hash,
+ style : 'top:' + el_position +'px;',
- t_elem.innerHTML = _drawClicks( bit_trend_item );
- t_elem_1.innerHTML = _drawChanged( bit_trend_item );
- t_elem_2.innerHTML = _drawHead( bit_trend_item );
- t_elem_3.innerHTML = bit_trend_item.user_hash;
- // addend the element now to end of container...
- el_position = (el_items.length+counter)*trend_heigt;
- clone.setAttribute("bit_hash", bit_trend_item.user_hash );
- clone.setAttribute("style", "top:"+el_position+"px")
- clone.setAttribute("bit_position", el_position)
- bitTrendsBox.appendChild( clone )
+ },
+ content : _drawItem( bit_trend_item )
+ });
+ bitTrendsBox.appendChild( results );
counter+=1;
}
@@ -165,26 +167,21 @@
// now let's move / animate the elements
// so if I loop over the el_items, I should be able to move to their location in the new_bits array
-
+ var trend_el, b_pos;
for(i=0; i<current_trend.length; i++) {
// alright, now find this elements position...
- var trend_el, b_pos;
- //console.log(bitTrendsBox.getElementsByTagName("item"))
+
try{
trend_el= _q("[bit_hash~='"+ current_trend[i].user_hash +"']", bitTrendsBox);
} catch(e){
// take this node out??
}
b_pos = trend_el.getAttribute("bit_position")*1
- if( i*trend_heigt === b_pos ) {
+ if( i*trend_height === b_pos ) {
//console.log("position is the same")
} else {
- //console.log("move this element from", b_pos, "to", i*trend_heigt, "px")
- trend_el.setAttribute("bit_position", (i*trend_heigt) )
- //trend_el.setAttribute("style", "top:"+ (i*trend_heigt) +"px")
-
-
- emile(trend_el, "top:"+ (i*trend_heigt) +"px;", {
+ trend_el.setAttribute("bit_position", (i*trend_height) )
+ emile(trend_el, "top:"+ (i*trend_height) +"px;", {
duration: 1700
});
@@ -208,13 +205,10 @@
}
- // find percent change formular
- // ((current_value/old_value) - 1)*100 ... if oldvalue is 0, it's gonna throw an error
- // Take the new, "current value" and divide it by the old, obsolete value. Subtract 1.00 (or 100%) from the result.
+
function addTrendingData( current_trend, trends ) {
- //console.log(arguments)
- //trends = trends.slice(0,10)
+
var i=0, trend, key, j=0, past_trend, past_realtime, past_realtimes, ii=0;
outerLoop:
@@ -226,7 +220,7 @@
for(ii=0; past_realtime=past_realtimes[ii]; ii++) {
//console.log(past_realtime)
if(key === past_realtime.user_hash && trend.clicks !== past_realtime.clicks) {
- console.log(trend.user_hash, trend.clicks, past_realtime.clicks, past_trend.timestamp )
+ //console.log(trend.user_hash, trend.clicks, past_realtime.clicks, past_trend.timestamp )
trend.past_timestamp = past_trend.timestamp;
trend.past_clicks = past_realtime.clicks;
@@ -277,78 +271,135 @@
function drawTrendElements( current_trend_list ) {
var i=0, urls = current_trend_list, url,
- item, html = "", height=trend_heigt;
- //html += timeFormat( realtimes_from_cache.timestamp );
- console.log(realtimes_from_cache.timestamp)
- html += '<div class="bitTrendsOuterContainer" id="bitTrendsBox">';
+ item, html = "", height=trend_height, structure, structure_items = [];
+
for( ; url=urls[i]; i++) {
- html += '<item bit_position="'+i*height+'" style="top:'+ i*height +'px;" class="bit_trend_item" bit_hash="'+url.user_hash+'">';
- html += _drawItem( url );
- html += '</item>';
+ structure_items.push({
+ type : "item",
+ css : "bit_trend_item",
+ attributes : {
+ bit_position : (i*height),
+ bit_hash : url.user_hash,
+ style : 'top:' + i*height +'px;',
+
+ },
+ content : _drawItem( url )
+ })
+
+
}
- html += '</div>';
- return html;
+ structure = {
+ css : "bitTrendsOuterContainer",
+ id : "bitTrendsBox",
+ content : structure_items
+ }
+
+ return structure;
}
- function _drawItem( url, pos ) {
- var html = "";
-
- html += '<div class="bit_trend_clicks">';
- html += _drawClicks( url );
- html += '</div>'
-
+ function _drawItem( url ) {
+
+ var structure = [{
+ css : "bit_trend_clicks",
+ content : _drawClicks( url )
+ },{
+ css : "bit_trends_meta",
+ content : [ _drawHead( url ), {
+ css : "changed_trend",
+ content : _drawChanged( url )
+ }, {
+ css : "bit_hash_value",
+ attributes : {
+ style : "display:none;"
+ },
+ content : url.user_hash
+ }]
+ },{
+ css : "hr",
+ content : {
+ type : "hr"
+ }
+ }];
+
+ return structure;
- html += '<div class="bit_trends_meta">'
- html += _drawHead( url );
- html += '<div class="changed_trend">';
- html += _drawChanged( url );
- html += '</div>';
- html += '<div class="bit_hash_value" style="display:none;">'+ url.user_hash +'</div>'
- html += '</div>'
- html += '<div class="hr"><hr /></div>'
- //html += '<div>Total: ' + commify( url.user_clicks ) + " of " + commify( url.global_clicks ) + '</div>';
- return html;
}
function _drawClicks( url ) {
- var html = "";
- html += '<div class="click_number">' + commify( url.clicks ) + '</div>';
- html += '<div class="smallText">clicks</div>'
- return html;
+ var structure = [{
+ css : "click_number",
+ content : commify( url.clicks )
+ }, {
+ css : "smallText",
+ content : "clicks"
+ }]
+ return structure;
}
function _drawHead( url ) {
- var html = "";
- html += '<div class="bit_trend_title">'
- html += '<div class="treadHeader">'
- html += '<h3>'
- html += '<a href="'+escaper(url.long_url)+'" target="new">' + escaper( url.title || url.long_url ) + '</a>';
- html += '</h3>'
- html += '</div>';
- html += '<div class="longlink"><a href="'+escaper(url.long_url)+'">'+escaper(url.long_url)+'</a></div>'
- html += '</div>'
- return html;
+ return {
+ css : "bit_trend_title",
+ content : [{
+ css : "treadHeader",
+ content : {
+ type : "h3",
+ content : {
+ type : "a",
+ content : url.title || url.long_url,
+ attributes : {
+ href : url.long_url
+ }
+ }
+ }
+ },{
+ css : "longlink",
+ content : {
+ type : "a",
+ content : url.long_url,
+ attributes : {
+ href : url.long_url
+ }
+ }
+ }]
+ }
+
}
function _drawChanged(url) {
- var html = "", dir = "up";
+ var diff = [], structure, dir = "up";
+ // if(url.time_diff) {
+ // dir = (url.percent_change > 0) ? "up" : "down";
+ // diff = [{
+ // type : "img",
+ // attributes : {
+ // src : 's/graphics/'+dir+'_arrow.png',
+ // height : 9,
+ // width : 9,
+ // border : 0,
+ // alt : ""
+ // }
+ // }, {
+ // text : ' ' + Math.ceil( url.percent_change ) + '%' + url.time_diff.toLowerCase() + ' from ' + url.past_clicks + ' clicks'
+ // }]
+ // } else {
+ // diff = [{
+ // text : "No change 1 min ago "
+ // }]
+ // }
+ diff.push({
+ type : "a",
+ attributes : {
+ href : 'http://bit.ly/'+url.user_hash+'+',
+ target : "new"
+ },
+ content : ' more info +'
+ })
+ structure = diff
- if(url.time_diff) {
- dir = (url.percent_change > 0) ? "up" : "down";
- html += '<img src="s/graphics/'+dir+'_arrow.png" alt="0" border="0" width="9" height="9" />'
- html += ' ' + Math.ceil( url.percent_change ) +"%";
- html += url.time_diff.toLowerCase();
- html += ' from ' + url.past_clicks + ' clicks';
+ return structure;
- } else {
- html += "No change 1 min ago ";
- }
-
- html += ' <a href="http://bit.ly/'+url.user_hash+'+" target="new">more info +</a>';
- return html;
-
}
function extend() {
View
37 src/js/libs/common.js
@@ -29,4 +29,41 @@ function _qAll( query, context ) {
// returns list, not a live collection..., context is optional
context = context || document;
return context.querySelectorAll( query );
+}
+
+
+/*
+ curtousey of digiwhack.me project with http://unlicense.org
+*/
+function _pClass( elem, css_class_name ) {
+ // do, probably need a flag
+ var regex = new RegExp( css_class_name ), obj = elem, p;
+ do {
+ if( regex.test( obj.className ) ) {
+ p = obj;
+ }
+ } while( !p && (obj = obj.parentNode));
+ return p;
+}
+function hasClass(ele,cls) {
+ return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
+}
+function addClass(ele,cls) {
+ if (!hasClass(ele,cls)) ele.className += " "+cls;
+}
+function removeClass(ele,cls) {
+ if (hasClass(ele,cls)) {
+ var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
+ ele.className=ele.className.replace(reg,' ');
+ }
+}
+function _copy( obj1 ) {
+ // http://my.opera.com/GreyWyvern/blog/show.dml/1725165
+ // derivative of prototype method, don't want to mess with native types (object, boolean, string etc)
+ var i, newObj = (obj1 instanceof Array) ? [] : {};
+ for (i in obj1) {
+ if (obj1[i] && typeof obj1[i] == "object") {
+ newObj[i] = _copy( obj1[i] );
+ } else { newObj[i] = obj1[i]; }
+ } return newObj;
}
View
76 src/js/libs/fastFrag.js
@@ -0,0 +1,76 @@
+(function(){
+ /*
+ fastFrag
+ Turn JSON into HTML, http://github.com/gregory80/fastFrag
+ */
+
+ var fastFrag = {
+ create : function( params ) {
+ return drawHTML(params);
+ },
+ version : "1.0.1"
+
+ };
+ window.fastFrag = fastFrag;
+
+ var d = document;
+
+ function drawHTML( params ) {
+ var frag = d.createDocumentFragment(), k, el;
+ if(params && params.length === undefined) {
+ el = _singleNode( params );
+ frag.appendChild( el );
+ } else {
+ for(k in params) {
+ el = _singleNode( params[k] );
+ frag.appendChild( el );
+ }
+ }
+ return frag;
+ }
+
+ function _mke(elem) {
+ return document.createElement( elem );
+ }
+ function _mke_attribute( el, attrs ) {
+ var safe_value;
+ for(var k in attrs) {
+ // yuck
+ if(k === "disabled" && !attrs[k]) { continue; }
+ el.setAttribute(k, _safe( attrs[k] ) );
+ }
+ return el;
+ }
+ function _make_element( o ) {
+ var el_name, el;
+ el_name = o.type || "div";
+ el = _mke( el_name );
+ if(o.attributes) { _mke_attribute(el, o.attributes); }
+ el.id = (o.id) ? o.id : null; el.className = (o.css) ? o.css : null;
+ return el;
+ }
+ function _safe( string ) {
+ return (d.createTextNode(string).nodeValue).toString(); // put in a text node, then grab it
+ }
+ function _singleNode( o ) {
+ var frag = d.createDocumentFragment(), el, content_type = typeof o.content, txt, txt_value;
+ if( o.text !== undefined ) {
+ el = d.createTextNode( o.text || "" );
+ } else {
+ el = _make_element( o );
+ txt=null;
+ if( content_type === "object") {
+ txt = drawHTML( o.content );
+ } else if(content_type === "string") {
+ txt = d.createTextNode( o.content );
+ } else {
+ txt_value = (o.content !== undefined) ? (o.content.toString() || "") : "";
+ txt = d.createTextNode( txt_value );
+ }
+ el.appendChild( txt );
+ }
+
+ frag.appendChild(el);
+ return frag;
+ }
+})();
View
34 src/js/libs/fastGrid.js
@@ -0,0 +1,34 @@
+/*
+ filename : fastGrid
+ http://unlicense.org/
+ author: gregory tomlinson
+ Wed Sep 8 21:09:30 EDT 2010
+*/
+
+(function() {
+
+ // the fastFrag components
+ /*
+ Move away from static HTML and into JSON format
+ Allows for finer grained control of display content with minimal DOM access
+ (aka faster)
+ */
+
+ var fastGrid = {
+
+ popup : function() {
+ return {}
+ },
+
+ options_page : function() {
+ return {}
+ },
+
+ trending_page : function() {
+ return {}
+ }
+ }
+
+ window.fastGrid = fastGrid;
+
+})();
View
75 src/js/workers/clicks_per_minute.js
@@ -0,0 +1,75 @@
+
+/*
+ We *hopefully* have access to the XMLHTTPRequest Object from here, nothing else unless we load it.
+*/
+
+onmessage = init
+
+
+var timer, polling_urls, current_request;
+
+function init( evt ) {
+ /*
+ init the API key and login values
+
+ evt.data.login
+ evt.data.apiKey
+ // short urls to start
+ ;
+ */
+ //polling_urls = evt.data.shortUrl;
+ onmessage = dataHandler;
+ //start_poll();
+ makeRemoteCall();
+}
+
+function start_poll() {
+ if(timer){ clearTimeout(timer); }
+ timer = setTimeout(makeRemoteCall, 20000)
+}
+
+function makeRemoteCall() {
+
+ if(current_request) {
+ current_request.abort();
+ }
+
+ // todo pull this value from the init values!!!
+ current_request = ajaxRequest({
+ url : 'http://api.bit.ly/v3/clicks_by_minute?login=j3h14h&apiKey=R_ea5a37f5757cf2ef91b514b66d6d8fcc&shortUrl=http://nyti.ms/cjdehk',
+ success : function(jo) {
+ postMessage(jo)
+ }
+ })
+
+}
+
+function dataHandler(evt) {
+ // listen for changes to shortURLs
+ //polling_urls = evt.data.shortUrl;
+ start_poll();
+}
+
+
+function ajaxRequest( obj ) {
+ var xhr = new XMLHttpRequest(), message, post_data;
+
+ xhr.open(obj.type || "GET", obj.url, true);
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ // do success
+ if(xhr.status!=200) {
+ if(obj.error) obj.error({'error' : true }, obj.url, xhr.status);
+ return;
+ }
+ try {
+ message = JSON.parse(xhr.responseText)
+ } catch(e) {
+ message = xhr.responseXML || xhr.responseText
+ }
+ obj.success( message, obj.url, xhr.status )
+ }
+ }
+ xhr.send( null );
+ return xhr;
+}
View
155 src/js/workers/realtime_data.js
@@ -1,58 +1,137 @@
/*
html5 workers
- http://robertnyman.com/2010/03/25/using-html5-web-workers-to-have-background-computational-power/
+
*/
-var timer;
+
+
+
+var ssl_key, black_list=[], ajax_in_action, timer;
onmessage = function(evt) {
- //evt.data
- if(!evt.data || !evt.data.realtime_links) { return; }
+ if( evt.data.action === "start") {
+
+ if(!evt.data.oauth_key ) { return; }
+ ssl_key = evt.data.oauth_key;
+ black_list = evt.data.black_list || [];
+
+ callRemote();
+
+ } else {
+
+
+ if(evt.data.oauth_key) {
+ ssl_key = evt.data.oauth_key;
+ }
+
+
+ if(evt.data.black_list ) {
+ black_list = evt.data.black_list || [];
+ }
+
+ callRemote();
+
+ }
+
+}
+
+function handle_api_repsonses(jo) {
+
+ if(jo && jo.data && jo.status_code===200) {
+
+ var params = process_realtime( jo.data );
+ postMessage( params );
+
+ } else {
+ postMessage(jo);
+ }
+ timer = setTimeout(callRemote, 20000);
+
+}
+
+function callRemote(){
+ if(ajax_in_action) {
+ ajax_in_action.abort();
+ }
- var results = processRealtimeResultsResponse( evt.data );
- postMessage({'action' : 'analyzed_links', 'results' : results });
- if(results.watch_list.length > 0 ) {
- startTimer();
+ if(timer) {
+ clearTimeout(timer);
}
+
+ setTimeout(function() {
+ ajax_in_action = ajaxRequest( ssl_key, handle_api_repsonses );
+ }, 20000);
+
}
-function processRealtimeResultsResponse(jo) {
- var link, links = jo && jo.realtime_links, curr_time = (new Date()).getTime(),
- w_list = jo.watch_list || [], final_watch_links = [],
- old_time=curr_time - (1000*60*60*24), dead_links=[], short_urls;
- short_urls=[];
- for(i=0; link=links[i]; i++) {
- for(j=0; item=w_list[j]; j++) {
- hash = (item.short_url.split("/")).reverse().shift();
- // todo
- // drop out links after 1 day
-
- if(item.timestamp < old_time) {
- dead_links.push(short_url);
- } else if( hash === link.user_hash && item.threshold <= link.clicks ) {
- short_urls.push( item.short_url );
- break;
+function process_realtime( data ) {
+ var links = data.realtime_links, notifications=[], remove_list=[];
+ outerLoop:
+ for(var i=0,link; link=links[i]; i++) {
+
+
+ for(var j=0,short_url; short_url=black_list[i]; i++) {
+ var pieces = short_url.split("/"), hash = pieces.pop();
+ if( hash === link.user_hash ) {
+ continue outerLoop;
}
- }
- }
+ // if( short_url.indexOf( link.user_hash ) > -1 ) {
+ // continue outerLoop;
+ // }
+ }
+
+
+ var shorty = "http://bit.ly/" + link.user_hash;
+ notifications.push( shorty );
+
+
+ }
- // strip the dead
- for(i=0; i<w_list.length; i++) {
- if( dead_links.indexOf( w_list[i] ) === -1 ) { final_watch_links.push( w_list[i]); }
+ return {
+ 'notifications' : notifications,
+ 'trending_links' : data,
+ 'current_blacklist' : black_list
}
- // leave 'dead_links' in so the background page can strip fron localstorage and localsql
- // we are trimming here to avoid
- return { 'dead_links' : dead_links, 'short_urls' : short_urls, 'watch_list' : final_watch_links }
}
-function startTimer() {
- if(timer) clearTimeout(timer);
- setTimeout(timerComplete, 30000);
+
+
+function ajaxRequest( oauth_key, callback ) {
+ var xhr = new XMLHttpRequest(), message,
+ post_data, url="https://api-ssl.bit.ly/v3/user/realtime_links";
+
+ if(!oauth_key || oauth_key === "") {
+ postMessage({'error' : 'no auth key'})
+ return;
+ }
+ url += '?access_token=' + encodeURIComponent( oauth_key );
+ xhr.open("GET", url, true);
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ // do success
+ // if(xhr.status!=200) {
+ // if(callback) callback({'error' : true}, xhr.status);
+ // return;
+ // }
+ try {
+ message = JSON.parse(xhr.responseText)
+ } catch(e) {
+ message = xhr.responseXML || xhr.responseText
+ }
+ callback( message, xhr.status );
+ }
+ }
+ xhr.send();
+ return xhr;
}
-function timerComplete() {
- postMessage({ 'action' : 'realtime'});
-}
+
+
+
+
+
+
+
View
2  src/js/workers/screen_resizer.js
@@ -1,4 +1,4 @@
-/*
+note_prefs/*
Worker Script
screen_resizer
View
150 src/notification.html
@@ -1,5 +1,5 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" manifest="cache-manifest">
+<!DOCTYPE HTML>
+<html>
<!-- MIME TYPE Guidlines and references: http://hixie.ch/advocacy/xhtml -->
<head>
@@ -14,48 +14,134 @@
<body>
<div id="container">
<div id="containerInner">
- <div id="footer">
- <h1><a class="trendsPage" href="#">Trending: </a></h1>
- </div>
- <div id="note_contents_box">
-
- </div>
- <div id="bit_fish">
- <img src="s/graphics/bitly_fish_48.png" border="0" height="48" width="48" alt="" />
- </div>
+ <div id="note_contents_box"></div>
</div>
- </div> <!-- end #container -->
+ </div>
+
+ <script type="text/javascript" src="js/libs/fastFrag.js" charset="utf-8"></script>
<script type="text/javascript" src="js/libs/common.js" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
+ (function(){
+
+
+ console.log("working?")
var bg = chrome.extension.getBackgroundPage(),
notification_data = bg.get_latest_notifications(),
- latest = notification_data && notification_data.shift(), html = "";
- if(!latest) {
- note_contents_box.innerHTML = "Oops, Sorry but an error happened"
+ latest = notification_data, display_urls=[];
+ // if(!latest) {
+ // // note_contents_box.innerHTML = "Oops, Sorry but an error happened"
+ // return;
+ // }
+ // okay, let's trash the stuff in memory
+
+ bg.set_notification_list( [] );
+
+ latest_display = latest.slice(0,3);
+ var params = {}, items = [];
+ for(var j=0, bl_item; bl_item=latest[j]; j++) {
+ display_urls.push( bl_item.short_url );
+ }
+ for(var i=0,note; note=latest_display[i]; i++) {
+ params={
+ type : "li",
+ content : note.short_url
+ }
+
+ items.push( params );
+ }
+
+
+ items.push({
+ type : "li",
+ css : "more_trending_link_box",
+ content : {
+ type : "a",
+ css : "",
+ content : "more",
+ attributes : {
+ href : "#"
+ }
+ }
+ })
+
+ bg.add_to_notes_blacklist( display_urls );
+
+
+ var ending = (latest.length>1) ? "s" : "";
+
+
+ // todo error handle for zero
+
+ var strucuture = {
+
+ content : [{
+ ///css : "note_headline",
+ type : "h4",
+ content : {
+ type : "a",
+ css : "",
+ content : latest.length + " New Trending Bit" + ending,
+ attributes : {
+ href : "#"
+ }
+ }
+ },{
+ content : {
+ type : "ul",
+ content : items
+ }
+ },{
+ id : "bit_fish",
+ content : {
+ type : "img",
+ attributes : {
+ src : "s/graphics/bitly_fish_48.png",
+ width : 48,
+ height : 48,
+ border : 0,
+ alt : ""
+ }
+ }
+ }]
+
}
- console.log(notification_data);
- html += "<div class='note_headline'>";
- html += escaper(latest.title || latest.long_url)
- html += "</div>";
- // html += "<div>"
- // html += latest.long_url
- // html += "</div>"
- //html += "Past Hour: " + latest.trend_clicks;
- html += '<h4>Total clicks</h4>';
- html += commify( latest.user_clicks );
- html += "<div>of</div>";
- html += commify( latest.global_clicks );
- var trend_link = document.querySelector(".trendsPage");
+ var results = fastFrag.create( strucuture );
+ note_contents_box.appendChild( results );
+
+ var trend_link = _q("#containerInner");
trend_link.addEventListener('click', function(e) {
e.preventDefault();
bg.get_chrome_page("trending.html");
- });
- trend_link.innerHTML = "Trending Bit: " + commify(latest.trend_clicks) + " clicks";
- note_contents_box.innerHTML = html;
- bg.remove_notification();
+ });
+
+ }());
+
+
+
+ // console.log(notification_data);
+ // html += "<div class='note_headline'>";
+ // html += escaper(latest.title || latest.long_url)
+ // html += "</div>";
+ // // html += "<div>"
+ // // html += latest.long_url
+ // // html += "</div>"
+ // //html += "Past Hour: " + latest.trend_clicks;
+ // html += '<h4>Total clicks</h4>';
+ // html += commify( latest.user_clicks );
+ // html += "<div>of</div>";
+ // html += commify( latest.global_clicks );
+ //
+ // var trend_link = document.querySelector(".trendsPage");
+ // trend_link.addEventListener('click', function(e) {
+ // e.preventDefault();
+ // bg.get_chrome_page("trending.html");
+ // });
+ // trend_link.innerHTML = "Trending Bit: " + commify(latest.trend_clicks) + " clicks";
+ // note_contents_box.innerHTML = html;
+ // bg.remove_notification();
// now remove it from list...
</script>
View
497 src/options.html
@@ -46,31 +46,7 @@ <h1 id="bitly_options">Settings</h1>
<div id="share_accounts"></div>
- <div id="api_domains">
-
- <div class="api_type_selector options_container">
- <h3>API Domains</h3>
-
- <p>You can choose either the bit.ly API or the j.mp API. Both work just the same way, but j.mp is just a little shorter. This change only applies to new shortens.</p>
-
- <form id="api_choice_form" action="#" method="get" accept-charset="utf-8">
-
- <div class="bentoOptions">
-
- <input type="radio" name="api_choice" checked value="bit.ly" id="jmp">
- <label for="jmp">Use bit.ly API</label>
- </div>
-
- <div class="bentoOptions">
- <input type="radio" name="api_choice" value="j.mp" id="bitly">
- <label for="bitly">Use j.mp API</label>
-
- </div>
-
- </form>
- </div>
- </div>
<div class="options_container">
<h3>Auto Copy Short Urls</h3>
@@ -84,9 +60,9 @@ <h1 id="bitly_options">Settings</h1>
<div class="options_container">
<h3>Trend Notifications</h3>
- <p>Automatically notify me when a link starts to become popular, or trend. Notifications will be shown when a link reaches the threshold specified below during the past hour.</p>
+ <p>Automatically notify me when my link starts to become popular, or trend. Notifications will be shown when a link reaches the threshold specified below during the past hour.</p>
<div>
- <input type="checkbox" name="auto_copy_short_urls" checked value="" id="watch_urls">
+ <input type="checkbox" name="auto_copy_short_urls" value="" id="watch_urls">
<label for="watch_urls">Allow link watching</label>
<div class="smallInputContainer notificationInnerContainer" style="display:none;">
@@ -99,7 +75,7 @@ <h1 id="bitly_options">Settings</h1>
</form>
- <p class="no_domains_note">Note: Changes to threshold only apply to newly watched links. Threshold can be any integer from 10-400</p>
+ <p class="no_domains_note">Note: Threshold can be any integer from 5-5,000</p>
</div>
<div id="watching_links_box">
@@ -122,7 +98,31 @@ <h1 id="bitly_options">Settings</h1>
</div>
-
+ <div id="api_domains">
+
+ <div class="api_type_selector options_container">
+ <h3>API Domains</h3>
+
+ <p>You can choose either the bit.ly API or the j.mp API. Both work just the same way, but j.mp is just a little shorter. This change only applies to new shortens.</p>
+
+ <form id="api_choice_form" action="#" method="get" accept-charset="utf-8">
+
+ <div class="bentoOptions">
+
+ <input type="radio" name="api_choice" checked value="bit.ly" id="jmp">
+ <label for="jmp">Use bit.ly API</label>
+ </div>
+
+ <div class="bentoOptions">
+ <input type="radio" name="api_choice" value="j.mp" id="bitly">
+ <label for="bitly">Use j.mp API</label>
+
+ </div>
+
+
+ </form>
+ </div>
+ </div>
@@ -176,6 +176,7 @@ <h1 id="bitly_options">Settings</h1>
<!-- <script type="text/javascript" src=""></script> -->
<script type="text/javascript" src="js/libs/common.js"></script>
+ <script type="text/javascript" src="js/libs/fastFrag.js"></script>
<script type="text/javascript" src="js/libs/logFormat.js"></script>
<script type="text/javascript" src="js/libs/timeFormat.js"></script>
<script type="text/javascript" charset="utf-8">
@@ -200,8 +201,8 @@ <h1 id="bitly_options">Settings</h1>
function get_safe_threshold( num_value ) {
- var safe_value = Math.max(num_value, 10);
- safe_value = Math.ceil( Math.min(safe_value, 500) );
+ var safe_value = Math.max(num_value, 5);
+ safe_value = Math.ceil( Math.min(safe_value, 5000) );
return safe_value;
}
@@ -224,109 +225,221 @@ <h1 id="bitly_options">Settings</h1>
}
function display_add_domain_no_expand_input( parent_elem ) {
- var html = "", div = document.createElement("div");
- html += '<div class="domains_host_container">'
- html += '<input type="text" name="no_expand_domain_new_domain" value="" id="no_expand_domain_new_domain" class="" />';
- html += '<input type="submit" value="Add" name="add_new_no_expand_domain" id="add_new_no_expand_domain" class="activeButtons" />'
- html += '</div>'
- div.innerHTML = html;
- parent_elem.appendChild( div );
+ var results, structure = {
+ css : "domains_host_container",
+ content : [{
+ type : "input",
+ id : "no_expand_domain_new_domain",
+ attributes : {
+ name : "no_expand_domain_new_domain",
+ type : "text"
+ }
+ },{
+ type : "input",
+ css : "activeButtons",
+ id : "add_new_no_expand_domain",
+ attributes : {
+ name : "add_new_no_expand_domain",
+ type : "submit",
+ value : "Add"
+ }
+ }]
+ }
+
+ results = fastFrag.create( structure );
+ parent_elem.appendChild( results );
}
function display_no_expand_domains() {
var d_list = bg.get_no_expand_domains(), i=0,
- domain, html="", disble_box="disabled";
- html += '<h4>Except These Domains:</h4>'
- html += '<ul class="no_expand_domains_list">';
+ domain, disble_box="disabled", structured_items = [];
for( ; domain=d_list[i]; i++) {
// note
// if bit.ly / j.mp ever support hover card, change to checked, to encourage removal
- if(domain === "bit.ly" || domain === 'j.mp') disble_box = "disabled"
- else disble_box = ""
- html += '<li>'
- html += '<input class="no_expand_check" type="checkbox" value="'+domain+'" '+disble_box;
- html += ' name="no_expand_domain" id="no_expand_d_'+i+'" />';
- html += '<label for="no_expand_d_'+i+'">' + domain + '</label>';
- html += '<div class="hr"><hr /></div>'
- html += '</li>'
+ if(domain === "bit.ly" || domain === 'j.mp') { disble_box = true; }
+ else { disble_box = false; }
+
+ structured_items.push({
+ type : "li",
+ content : [{
+ type : "input",
+ id : 'no_expand_d_'+i,
+ css : "no_expand_check",
+ attributes: {
+ type : "checkbox",
+ value : domain,
+ name : "no_expand_domain",
+ disabled : disble_box
+ }
+ },{
+ type : "label",
+ content : domain,
+ attributes : {
+ 'for' : 'no_expand_d_'+i
+ }
+ },{
+ css : "hr",
+ content : {
+ type : "hr"
+ }
+ }]
+ });
+
}
- html += '</ul>';
- html += '<div id="new_no_expand_domain"></div>'
- html += '<div>'
- html += '<a class="" id="add_no_expand_domain_form" href="#">Add domain host</a>'
- html += ' | <a class="" id="remove_no_expand_domains" href="#">Remove selected</a>'
- html += '<p class="no_domains_note">'
- html += 'Note: subdomains must be specified, facebook.com will not match www.facebook.com'
- html += '</p>'
- html += '</div>'
+
+
+ var structure = [{
+ type : "h4",
+ content : 'Except These Domains:'
+ },{
+ type : "ul",
+ css : "no_expand_domains_list",
+ content : structured_items
+ },{
+ id : "new_no_expand_domain"
+ },{
+ content : [{
+ type : "a",
+ id : "add_no_expand_domain_form",
+ content : "Add domain host",
+ attributes : {
+ href : "#"
+ }
+ },{
+ text : " | "
+ },{
+ type : "a",
+ content : "Remove selected",
+ id : "remove_no_expand_domains",
+ attributes : {
+ href : "#"
+ }
+ },{
+ type : "p",
+ css : "no_domains_note",
+ content : "Note: subdomains must be specified, facebook.com will not match www.facebook.com"
+ }]
+ }]
//div.innerHTML = html;
- no_expand_domains_box_elem.innerHTML = html;
+ no_expand_domains_box_elem.innerHTML = "";
+ no_expand_domains_box_elem.appendChild( fastFrag.create( structure ) )
}
- function display_user_watched_links() {
- var w_list = bg.get_watch_list(), i=0, html="", w;
- if(w_list.length>0) {
- html += '<h4>Watching:</h4>';
- html += '<ul>'
- for( ; w=w_list[i]; i++) {
- html += '<li>'
- html += '<input type="checkbox" name="" value="'+ w.short_url +'" id="watch_item_'+i+'">'
- html += '<a href="'+w.short_url+'">' + w.short_url + "</a> since "
- html += timeFormat( w.timestamp ).toLowerCase();
- html += '<label for="threshold">Threshold</label>';
- html += '<input type="hidden" name="timestamp" value="'+w.timestamp+'" id="some_name">'
- html += '<input type="text" name="threshold" value="'+ w.threshold +'" id="w_threshold_'+i+'" />';
- html += '<input type="submit" name="some_name" value="Update" class="activeButtons" id="">';
- html += '</li>'
- }
+ // function display_user_watched_links() {
+ // if(w_list.length>0) {
+ //
+ // for( ; w=w_list[i]; i++) {
+ //
+ // struture_items.push({
+ // type : "li",
+ // content : [{
+ // type : "input",
+ // id : 'watch_item_'+i,
+ // attributes : {
+ // type : "checkbox",
+ // value : w.short_url
+ // }
+ // },{
+ // type : "a",
+ // content : w.short_url,
+ // attributes : {
+ // href : w.short_url,
+ // target : "new"
+ // }
+ // },{
+ // text : " since " + timeFormat( w.timestamp ).toLowerCase()
+ // },{
+ // type : "label",
+ // content : "Threshold"
+ // }, {
+ // type : "input",
+ // attributes : {
+ // type : 'hidden',
+ // name : 'timestamp',
+ // value : w.timestamp
+ // }
+ // }, {
+ // type : "input",
+ // id : 'w_threshold_'+i,
+ // attributes : {
+ // type : "text",
+ // name : "threshold",
+ // value : w.threshold
+ // }
+ // }, {
+ // type : "input",
+ // css : "activeButtons",
+ // attributes : {
+ // type : "submit",
+ // value : "Update"
+ // }
+ // }]
+ // })
+ // }
+ //
+ //
+ // structure = [{
+ // type : "h4",
+ // content : "Watching:"
+ // }, {
+ // type : "ul",
+ // content : struture_items
+ // }, {
+ // css : "watch_controls_box",
+ // content : {
+ // type : "a",
+ // css : "removeWatchButton",
+ // content : "Remove selected",
+ // attributes : {
+ // href : "#"
+ // }
+ // }
+ // }]
+ //
+ // }
+ //
+ // watching_links_box.innerHTML = "";
+ // watching_links_box.appendChild( fastFrag.create( structure) );
+ // if(w_list.length<=0) { return; }
+ // _q(".removeWatchButton", watching_links_box).addEventListener('click', function(e) {
+ // e.preventDefault();
+ // var i=0, url_list=[], watch_selected = _qAll("input[type=checkbox]:checked", watching_links_box);
+ // console.log(watch_selected);
+ // for(i=0; i<watch_selected.length; i++) {
+ // url_list.push( watch_selected[i].value );
+ // }
+ // if(watch_selected.length>0) {
+ // setTimeout(function() {
+ // display_user_watched_links();
+ // }, 100)
+ //
+ // }
+ //
+ //
+ // });
+ // watching_links_box.addEventListener('click', function(e) {
+ // console.log(e.target.type)
+ // var el = e.target, threshold, safe_value, sUrl, p, timestamp=0;
+ // if(el.type && el.type==="submit") {
+ // e.preventDefault();
+ // p = el.parentNode;
+ // threshold = _q("input[type=text]", p);
+ // sUrl = _q("input[type=checkbox]", p).value;
+ // timestamp = (_q("input[type=hidden]", p).value)*1;
+ // safe_value = get_safe_threshold( threshold.value );
+ // // method for updating a short url here...
- html += '</ul>'
- html += '<div class="watch_controls_box"><a class="removeWatchButton" href="#">Remove selected</a></div>';
- }
-
- watching_links_box.innerHTML = html;
- if(w_list.length<=0) { return; }
- _q(".removeWatchButton", watching_links_box).addEventListener('click', function(e) {
- e.preventDefault();
- var i=0, url_list=[], watch_selected = _qAll("input[type=checkbox]:checked", watching_links_box);
- console.log(watch_selected);
- for(i=0; i<watch_selected.length; i++) {
- url_list.push( watch_selected[i].value );
- }
- bg.remove_watch_items_list( url_list );
- if(watch_selected.length>0) {
- setTimeout(function() {
- display_user_watched_links();
- }, 100)
-
- }
-
-
- });
- watching_links_box.addEventListener('click', function(e) {
- console.log(e.target.type)
- var el = e.target, threshold, safe_value, sUrl, p, timestamp=0;
- if(el.type && el.type==="submit") {
- e.preventDefault();
- p = el.parentNode;
- threshold = _q("input[type=text]", p);
- sUrl = _q("input[type=checkbox]", p).value;
- timestamp = (_q("input[type=hidden]", p).value)*1;
- safe_value = get_safe_threshold( threshold.value );
- // method for updating a short url here...
- bg.update_watch_item( {'short_url' : sUrl, 'threshold' : safe_value,
- 'timestamp':timestamp } );
- }