Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit

  • Loading branch information...
commit 8cdb77579bd23aa699c1ca06646307382fb23d1d 0 parents
@typester authored
35 README.md
@@ -0,0 +1,35 @@
+This script set is for adding local time tracking feature to [Hiveminder](http://hiveminder.com/).
+
+Yeah, I know Hiveminder supports time tracking. But it doesn't work at offline.
+I sometimes place myself at offline, because working at online has a number of temptations, twitter/irc/im and so on..
+
+
+## Features
+
+* Simple time tracking
+* Fluid app support (also include my userstyle for this)
+* Enable growl notification instead of jGrowl (Fluid only)
+* Notify current tasks every 10 minutes (it probably get you back to work ;)
+
+
+## Current issues
+
+* Currently it doesn't save elapsed time, so you lost it when reload page.
+
+
+## How to use
+
+### For fluid app users
+
+* Setup hiveminder fluid app
+* Open the app and go preferences panel -> Userstyles, and copy 'hiveminder-fluid.css' and paste it there.
+* Copy `jgrowll.user.js` and `hiveminder-local-time-track.user.js` into `~/Library/Application Support/Fluid/SSB/{Your App Name/Userscripts/` and enable these.
+
+### For firefox users
+
+* install `hiveminder-local-time-track.user.js` as Greasemonkey script and enable it.
+
+
+## Author
+
+Daisuke Murase <typester@cpan.org>
27 hiveminder-fluid.css
@@ -0,0 +1,27 @@
+div#info-wrapper {
+ display: none !important;
+}
+
+div#content-wrapper2 {
+ margin-left: 0px !important;
+}
+
+div#headers {
+ display: none !important;
+}
+
+.tasklist-fragment > .feed-list {
+ display: none !important;
+}
+
+div#footer {
+ display: none !important;
+}
+
+div#actions_container {
+ display: none !important;
+}
+
+h1.title {
+ display: none !important;
+}
143 hiveminder-local-time-track.user.js
@@ -0,0 +1,143 @@
+// ==UserScript==
+// @name hiveminder local time tracking
+// @namespace unknownplace.org
+// @description add time tracking feature on hiveminder
+// @include http://hiveminder.com/*
+// @include https://hiveminder.com/*
+// ==/UserScript==
+
+(function (d, w) {
+ var debug = false;
+ function log() { debug && w.console.log.apply(null, arguments) };
+
+ var $ = w.jQuery;
+ var tasks = [];
+
+ var start_button = $("<a>")
+ .text("Start!")
+ .addClass("track_start").css({
+ "display": "block",
+ "width": "50px",
+ "padding": "4px",
+ "-moz-border-radius-topleft": "5px",
+ "-moz-border-radius-bottomleft": "5px",
+ "-webkit-border-top-left-radius": "5px",
+ "-webkit-border-bottom-left-radius": "5px",
+ "background-color": "#00bb00",
+ "color": "#ffffff",
+ "text-align": "center",
+ "float": "left"
+ });
+
+ var stop_button = $("<a>")
+ .text("Stop!")
+ .addClass("track_stop").css({
+ "display": "block",
+ "width": "50px",
+ "padding": "4px",
+ "-moz-border-radius-topleft": "5px",
+ "-moz-border-radius-bottomleft": "5px",
+ "-webkit-border-top-left-radius": "5px",
+ "-webkit-border-bottom-left-radius": "5px",
+ "background-color": "#ff3344",
+ "color": "#ffffff",
+ "text-align": "center",
+ "float": "left"
+ }).hide();
+
+ var indicator = $("<div>")
+ .text("00:00:00")
+ .addClass("track_indicator").css({
+ "display": "block",
+ "width": "80px",
+ "padding": "4px",
+ "-moz-border-radius-topright": "5px",
+ "-moz-border-radius-bottomright": "5px",
+ "-webkit-border-top-right-radius": "5px",
+ "-webkit-border-bottom-right-radius": "5px",
+ "background-color": "#eee",
+ "color": "#333",
+ "text-align": "center",
+ "font-weight": "bold",
+ "float": "left"
+ });
+
+ var time_format = function (sec) {
+ var h = parseInt(sec / 60 / 60);
+ var m = parseInt((sec - h*60*60) / 60);
+ var s = parseInt(sec - h*60*60 - m*60);
+ if (h < 10) h = "0" + h;
+ if (m < 10) m = "0" + m;
+ if (s < 10) s = "0" + s;
+ return h + ":" + m + ":" + s;
+ }
+
+ var start = function (task) {
+ stop();
+
+ task.running = (new Date()).getTime() - task.time * 1000;
+ $(".track_start", task.obj).hide();
+ $(".track_stop", task.obj).show();
+
+ setTimeout(timer, 200, task);
+
+ $.jGrowl("Start \"" + task.name + "\"");
+ };
+
+ var stop = function () {
+ for (var i in tasks) {
+ var task = tasks[i];
+ if (task.running) {
+ task.running = false;
+ $(".track_stop", task.obj).hide();
+ $(".track_start", task.obj).show();
+
+ $.jGrowl("Stopped \"" + task.name + "\"");
+ }
+ }
+ };
+
+ var timer = function (task) {
+ if (task.running) {
+ var elapsed = ((new Date()).getTime() - task.running) / 1000;
+
+ if (parseInt(elapsed / 60) > parseInt(task.time / 60)) {
+ if ( (parseInt(elapsed / 60) % 10) == 0 ) {
+ $.jGrowl(task.name + " [" + time_format(elapsed) + "]", {
+ header: "You're doing now:"
+ });
+ }
+ }
+
+ task.time = elapsed;
+ task.indicator.text( time_format(task.time) );
+
+ setTimeout(arguments.callee, 200, task);
+ }
+ };
+
+ $(".todo .task").each(function (i) {
+ var task = {
+ obj : this,
+ id : $(".record_locator", this).text(),
+ name: $(".task_summary", this).text(),
+ time: 0,
+ running: false,
+ indicator: indicator.clone()
+ }
+ tasks.push(task);
+
+ var div = $("<div>").css({
+ "display": "block",
+ "overflow": "auto"
+ });
+
+ $(".edit_context_menu", this).after(div);
+ div
+ .append( start_button.clone().click(function () { start(task) }) )
+ .append( stop_button.clone().click(stop) )
+ .append( task.indicator );
+ });
+
+})(document, (typeof(unsafeWindow) != "undefined") ? unsafeWindow : window);
+
35 jgrowl.user.js
@@ -0,0 +1,35 @@
+// ==UserScript==
+// @name jgrowl
+// @namespace http://fluidapp.com
+// @description do growl notification instead of jgrowl
+// @include *
+// @author Daisuke Murase <typester@cpan.org>
+// ==/UserScript==
+
+(function (app) {
+ if (!app) return;
+
+ function strip_tags (str) {
+ str = str.replace(/<.*?>/g, "");
+ return str;
+ }
+
+ var jGrowl = jQuery.jGrowl;
+ jQuery.jGrowl = function (message, option) {
+ if (typeof(option) != "object") option = {};
+
+ // strip html tags
+ var header = strip_tags(option["header"] || "");
+ var description = strip_tags(message || "");
+
+ app.showGrowlNotification({
+ title: header,
+ description: description,
+ sticky: !!option["sticky"],
+ onclick: function () { app.activate() }
+ });
+
+ return true;
+ }
+
+})(window.fluid);
Please sign in to comment.
Something went wrong with that request. Please try again.