diff --git a/README.md b/README.md index 7597263..8a13b13 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,23 @@ Track Your Time Spent On Coding and Make Coding a Habit ## Features -Track Your Coding Time by Programming language and files +Track Your Coding Time Offline tracking time Earn points from your coding time +Exclude project from being tracked (Beta) + +We don't share your data with any third party + +Share your goals using the web app with others developers to stay accountable + + ## Requirements -You need API Key and you can get it from [HabitScript Setttings](https://habit-script.herokuapp.com/signup) +You need API Key and you can get it from [HabitScript Setttings](https://habit-script.herokuapp.com/signup) (If you want to visualize your data in the web app) ## Release Notes diff --git a/package.json b/package.json index cfcee15..14d44ef 100644 --- a/package.json +++ b/package.json @@ -48,11 +48,9 @@ "webpack-cli": "^3.3.5" }, "dependencies": { - "cowsay": "^1.4.0", - "express": "^4.17.1", - "fs-extra": "^8.1.0", - "lowdb": "^1.0.0", - "mkdirp": "^0.5.1", + "moment": "^2.24.0", + "moment-duration-format": "^2.3.2", + "moment-timezone": "^0.5.26", "node-fetch": "^2.6.0", "os": "^0.1.1" }, diff --git a/src/client.js b/src/client.js index 287d583..c74c563 100644 --- a/src/client.js +++ b/src/client.js @@ -1,113 +1,91 @@ - -const fetch = require('node-fetch'); -const apiEndpoint = require('./config'); -const vscode = require('vscode'); -const fs = require('fs') +const fetch = require("node-fetch"); +const apiEndpoint = require("./config"); +const vscode = require("vscode"); +const fs = require("fs"); import { statusBar, apiKey, fileDuration } from "./extension"; -import { serverIsDown } from "./offline" -import { getJSONFile } from "./dashboard" -import {getApikey} from "./login" +import { serverIsDown } from "./offline"; +import { getJSONFile } from "./dashboard"; +import { getApikey } from "./login"; let lastSendingData = 0; - export function sendData() { - let file = getJSONFile(); - let fileDuration = []; - let data = fs.readFileSync(file); - - // @ts-ignore - fileDuration = JSON.parse(data) - - let url = `${apiEndpoint}duration`; - const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; - - - console.log(url) - - let body = { - fileDuration, - apiKey - } - async function sendPost() { - - // @ts-ignore - let response = await fetch(url, { - method: 'POST', - // @ts-ignore - body: JSON.stringify(body), - headers: { 'Content-Type': 'application/json' } - - }); - let data = await response.json() - return data; - } - - - sendPost() - - - .then(data => { - console.log(data); - - }) - .catch(err => { - console.log(err) - // serverIsDown(); - }) - - + let file = getJSONFile(); + let fileDuration = []; + let data = fs.readFileSync(file); + + // @ts-ignore + fileDuration = JSON.parse(data); + + let url = `${apiEndpoint}duration`; + const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; + + console.log(url); + + let body = { + fileDuration, + apiKey + }; + async function sendPost() { + // @ts-ignore + let response = await fetch(url, { + method: "POST", + // @ts-ignore + body: JSON.stringify(body), + headers: { "Content-Type": "application/json" } + }); + let data = await response.json(); + return data; + } + + sendPost() + .then(data => { + console.log(data); + }) + .catch(err => { + console.log(err); + // serverIsDown(); + }); } - - - - - - - - - -// Check API Is Valid +// Check API Is Valid export function checkApi() { - console.log('CHeck Api') - - let url = `${apiEndpoint}duration/u/${apiKey}` - console.log(url) - - let editors = { - name: "vs_code", - connected_at: new Date().toISOString() - } - let isValid; - // @ts-ignore - fetch(url, { - - method: 'POST', - body: JSON.stringify(editors), - headers: { 'Content-Type': 'application/json' } - }) - .then(response => { - - return response.json() - }) - .then(resData => { - console.log(resData) - if (resData !== undefined) { - - vscode.window.showInformationMessage('Congratulations, Codabits is now active!'); - } - else { - vscode.window.showInformationMessage('Oops, API Key is not valid!'); - - getApikey() - } - }) - - .catch((err) => { - getApikey() - console.log(err) - }) - - return isValid; -} \ No newline at end of file + console.log("CHeck Api"); + + let url = `${apiEndpoint}duration/u/${apiKey}`; + console.log(url); + + let editors = { + name: "vs_code", + connected_at: new Date().toISOString() + }; + let isValid; + // @ts-ignore + fetch(url, { + method: "POST", + body: JSON.stringify(editors), + headers: { "Content-Type": "application/json" } + }) + .then(response => { + return response.json(); + }) + .then(resData => { + console.log(resData); + if (resData !== undefined) { + vscode.window.showInformationMessage( + "Congratulations, Codabits is now active!" + ); + } else { + vscode.window.showInformationMessage("Oops, API Key is not valid!"); + + getApikey(); + } + }) + + .catch(err => { + getApikey(); + console.log(err); + }); + + return isValid; +} diff --git a/src/dashboard.js b/src/dashboard.js index b9c4787..26d918b 100644 --- a/src/dashboard.js +++ b/src/dashboard.js @@ -1,7 +1,8 @@ const os = require("os"); +var moment = require("moment"); const { workspace, window, ViewColumn } = require("vscode"); - +import { humanizeMinutes } from "./data"; const fs = require("fs"); let fileDuration = []; @@ -53,10 +54,11 @@ export function getJSONFile() { function addDashboardContent() { dashboardContent += "\n\n"; - dashboardContent += `Today Coding Time: ${getTodayCodingTime(fileDuration)}`; + dashboardContent += `Today Coding Time: ${humanizeMinutes( + getTodayCodingTime(fileDuration) + )}`; dashboardContent += "\n\n"; - - dashboardContent += `Most Productive Day: ${getDateFormat( + dashboardContent += `Most Productive Day: ${humanizeDate( getMostProductiveDay(fileDuration) )}`; dashboardContent += "\n\n"; @@ -71,9 +73,9 @@ function addDashboardContent() { dashboardContent += `Sort File By Duration`; dashboardContent += "\n\n"; sortFileByDuration(fileDuration).forEach(el => { - dashboardContent += `File Name: ${el.fileName} Coding Time: ${ - el.duration - }`; + dashboardContent += `File Name: ${ + el.fileName + } Coding Time: ${humanizeMinutes(el.duration)}`; }); dashboardContent += "\n\n"; console.log(sortLanguageByDuration(fileDuration)); @@ -81,22 +83,23 @@ function addDashboardContent() { dashboardContent += `Sort File By Language`; dashboardContent += "\n\n"; sortLanguageByDuration(fileDuration).forEach(el => { - dashboardContent += `Language: ${el.language} Coding Time: ${el.duration}`; + dashboardContent += `Language: ${ + el.language + } Coding Time: ${humanizeMinutes(el.duration)}`; }); return dashboardContent; } // Format Date -function getDateFormat(date) { - const dd = new Date(date).getDate(); - const mm = new Date(date).getMonth() + 1; - const yy = new Date(date).getFullYear(); - return `${mm}-${dd}-${yy}`; +export function getDateFormat(date) { + return moment(date).format("MM-DD-YYYY"); } +function humanizeDate(date) { + return moment(date).format("dddd, MMMM Do YYYY"); +} function getHours(date) { - const hrs = new Date(date).getHours(); - return hrs; + return moment(date).format("hh:mm a"); } function getTodayCodingTime(duration) { @@ -154,12 +157,7 @@ function sortLanguageByDuration(durations) { } export function openDashboardFile() { - /* fs.writeFile(file, dashboardContent, (err) => { - if (err) throw err; - console.log('The file has been saved!'); - - });*/ - //fs.appendFileSync(file, dashboardContent, "UTF-8",{'flags': 'a+'}); + // @ts-ignore fs.writeFileSync(file, dashboardContent, "UTF-8", { flags: "as+" }); @@ -170,35 +168,5 @@ export function openDashboardFile() { }); }); console.log(fileDuration.length); - if (fileDuration.length > 0) { - console.log(getTodayCodingTime(fileDuration)); - console.log(getMostProductiveDay(fileDuration)); - console.log(getMostProductivTimeOfeDay(fileDuration)); - console.log(getMostUsedLanguage(fileDuration)); - console.log(sortFileByDuration(fileDuration)); - console.log(sortLanguageByDuration(fileDuration)); - } -} -function humanizeMinutes(sec) { - // convert Secondes to Minutes - let min = sec / 60; - min = min || 0; - let str = ""; - if (min === 1) { - str = "1 min"; - } else if (min === 60) { - str = "1 hr"; - } else if (min > 60) { - let hrs = min / 60; - if (hrs % 1 === 0) { - str = hrs.toFixed(0) + " hrs"; - } else { - str = (Math.round(hrs * 10) / 10).toFixed(1) + " hrs"; - } - } else { - // less than 60 seconds - str = min.toFixed(0) + " min"; - } - return str; } diff --git a/src/data.js b/src/data.js index ab7d600..1dbe404 100644 --- a/src/data.js +++ b/src/data.js @@ -1,11 +1,13 @@ const vscode = require("vscode"); let path = require("path"); const fs = require("fs"); -import { getJSONFile } from "./dashboard"; +import { getJSONFile, getDateFormat } from "./dashboard"; import { statusBar, fileDuration } from "./extension"; import { sendData } from "./client"; import { createJsonFile } from "./offline"; - +var moment = require("moment"); +var momentDurationFormatSetup = require("moment-duration-format"); +momentDurationFormatSetup(moment); // Gloabl Variables let lastFileName; let todayCodingTime = 0; @@ -39,13 +41,6 @@ export function getTodayCodingTime() { return todayCodingTime; } -function getDateFormat(date) { - const dd = new Date(date).getDate(); - const mm = new Date(date).getMonth() + 1; - const yy = new Date(date).getFullYear(); - return `${mm}-${dd}-${yy}`; -} - // Get Project Name const getProjectName = () => { let editor = vscode.window.activeTextEditor; @@ -77,31 +72,12 @@ function getFileName(doc) { export function showTodayTime() { statusBar.text = `Today ${humanizeMinutes(todayCodingTime)}`; + console.log(humanizeMinutes(todayCodingTime)); } -function humanizeMinutes(sec) { - // convert Secondes to Minutes - let min = sec / 60; - min = min || 0; - let str = ""; - if (min === 1) { - str = "1 min"; - } else if (min === 60) { - str = "1 hr"; - } else if (min > 60) { - let hrs = min / 60; - if (hrs % 1 === 0) { - str = hrs.toFixed(0) + " hrs"; - } else { - str = (Math.round(hrs * 10) / 10).toFixed(1) + " hrs"; - } - } else { - // less than 60 seconds - str = min.toFixed(0) + " min"; - } - return str; +export function humanizeMinutes(ms) { + return moment.duration(ms, "milliseconds").format("h [hrs], m [min]"); } - // When You Write Code export function onSave(isSaved, doc) { if (lastTimeSaved === 0) { @@ -130,8 +106,7 @@ export function onSave(isSaved, doc) { fileDuration.forEach(el => { if (el.fileName === lastFileName) { const pastDurations = el.duration; - const newDurations = - pastDurations + (Date.now() - lastTimeSaved) / 1000; + const newDurations = pastDurations + (Date.now() - lastTimeSaved); el.duration = newDurations; el.created_at = new Date().toISOString(); } @@ -149,7 +124,7 @@ export function onSave(isSaved, doc) { fileDuration.push({ fileName, - duration: (Date.now() - lastTimeSaved) / 1000, + duration: Date.now() - lastTimeSaved, created_at: new Date().toISOString(), projectName, language @@ -160,7 +135,7 @@ export function onSave(isSaved, doc) { else if (fileDuration.length <= 0) { fileDuration.push({ fileName, - duration: (Date.now() - lastTimeSaved) / 1000, + duration: Date.now() - lastTimeSaved, created_at: new Date().toISOString(), projectName, language diff --git a/src/extension.js b/src/extension.js index d56991d..b7cb671 100644 --- a/src/extension.js +++ b/src/extension.js @@ -2,12 +2,9 @@ // Import the module and reference it with the alias vscode in your code below const vscode = require("vscode"); - - import { getTodayCodingTime, showTodayTime, onSave } from "./data.js"; import { registerCommands } from "./commands"; - export let statusBar = vscode.window.createStatusBarItem( vscode.StatusBarAlignment.Left ); diff --git a/src/login.js b/src/login.js index b288fba..e788c70 100644 --- a/src/login.js +++ b/src/login.js @@ -1,6 +1,6 @@ const vscode = require("vscode"); import { checkApi } from "./client"; -import {context} from './extension' +import { context } from "./extension"; // Show Input Box to get API Key export function getApikey() { @@ -17,7 +17,7 @@ export function getApikey() { context.globalState.update("apiKey", API); checkApi(); } else { - vscode.window.showInformationMessage("Oops, API Key is not valid!"); + vscode.window.showInformationMessage("Oops, API Key is not valid!"); getApikey(); } diff --git a/src/offline.js b/src/offline.js index b82e3b0..98bcad6 100644 --- a/src/offline.js +++ b/src/offline.js @@ -1,4 +1,3 @@ - const fs = require("fs"); import { getJSONFile } from "./dashboard"; export function serverIsDown(fileDuration) { @@ -13,7 +12,6 @@ export function createJsonFile(fileDuration) { if (err) throw err; console.log("The file has been saved!"); }); - let durationsArr = []; fs.exists(file, function(exists) { @@ -63,4 +61,3 @@ export function createJsonFile(fileDuration) { } } } -