Compare commits

..

13 Commits
v9 ... 1.0.3

Author SHA1 Message Date
dhruvik7
12b94cf8ae versioning 2021-02-25 09:00:17 -05:00
dhruvik7
a4f747d65c Merge pull request #2 from dhruvik7/update/tracker
Update/tracker
2021-02-25 08:44:38 -05:00
dhruvik7
1cd5557787 Merge branch 'master' into update/tracker 2021-02-25 08:44:26 -05:00
dhruvik7
7cd552848f small edits 2021-02-25 08:43:50 -05:00
dhruvik7
3452c7b3a2 added coloring 2021-02-21 21:58:35 -05:00
dhruvik7
d8eee206c7 added icon 2021-02-21 17:10:04 -05:00
dhruvik7
2587ff5820 added tooltip 2021-02-21 16:31:55 -05:00
dhruvik7
4874cf4d4f working commit graph, needs tooltips 2021-02-21 14:50:22 -05:00
dhruvik7
09305323cb Progress with bad pkg 2021-02-21 13:08:28 -05:00
dhruvik7
caa732e423 inner content 2021-02-21 10:50:43 -05:00
dhruvik7
c3543942a3 Update README.md 2021-02-16 11:26:15 -05:00
dhruvik7
7d1dc84610 updating versions 2021-02-15 10:14:53 -05:00
dhruvik7
f94b207a77 Added debouncing 2021-02-14 21:16:24 -05:00
12 changed files with 1724 additions and 24 deletions

View File

@@ -1,7 +1,8 @@
## Obsidian Daily Stats
This is a daily word count plugin for Obsidian (https://obsidian.md). You can see today's word count in the bottom right corner of your screen, and also see the historical logs.
This plugin was inspired by liamcain's [Calender](https://github.com/liamcain/obsidian-calendar-plugin) and lukeleppan's [Better Word Count](https://github.com/lukeleppan/better-word-count).
![Example](./images/example.png)
## Obsidian Daily Stats
This is a daily word count plugin for Obsidian (https://obsidian.md). You can see today's word count in the bottom right corner of your screen, and also see the historical logs in a right panel view akin to Github's contribution graph.
This plugin was inspired by liamcain's [Calender](https://github.com/liamcain/obsidian-calendar-plugin) and lukeleppan's [Better Word Count](https://github.com/lukeleppan/better-word-count).
![Example](./images/example-graph.png)

BIN
images/example-graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

View File

@@ -1,8 +1,8 @@
{
"id": "obsidian-daily-stats",
"name": "Daily Stats",
"version": "1.0.0",
"minAppVersion": "0.9.10",
"version": "1.0.3",
"minAppVersion": "0.10.12",
"description": "Track your daily word count across all notes in your vault.",
"author": "Dhruvik Parikh",
"authorUrl": "https://github.com/dhruvik7",

View File

@@ -1,6 +1,6 @@
{
"name": "obsidian-daily-stats",
"version": "1.0.0",
"version": "1.0.3",
"description": "This is an Obsidian.md plugin that lets you view your daily word count.",
"main": "main.js",
"scripts": {
@@ -15,9 +15,17 @@
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-typescript": "^6.0.0",
"@types/node": "^14.14.2",
"@types/react-calendar-heatmap": "^1.6.2",
"@types/react-dom": "^17.0.1",
"obsidian": "https://github.com/obsidianmd/obsidian-api/tarball/master",
"postcss": "^8.2.6",
"react": "^17.0.1",
"react-calendar-heatmap": "^1.8.1",
"react-dom": "^17.0.1",
"rollup": "^2.32.1",
"rollup-plugin-postcss": "^4.0.0",
"tslib": "^2.0.3",
"typescript": "^4.0.3"
}
},
"dependencies": {}
}

View File

@@ -1,19 +1,23 @@
import typescript from '@rollup/plugin-typescript';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import postcss from 'rollup-plugin-postcss'
export default {
input: 'main.ts',
input: 'src/main.ts',
output: {
dir: '.',
sourcemap: 'inline',
format: 'cjs',
exports: 'default'
},
external: ['obsidian'],
external: ['obsidian', 'crypto'],
plugins: [
typescript(),
nodeResolve({browser: true}),
nodeResolve({ browser: true, preferBuiltins: true }),
commonjs(),
postcss({
plugins: []
})
]
};

54
src/calendar.tsx Normal file
View File

@@ -0,0 +1,54 @@
import * as React from "react";
import ReactCalendarHeatmap from "react-calendar-heatmap";
import { MAX_COLORS, COLOR_FREQ } from "./constants";
interface HeatmapProps {
data: any[];
}
class Heatmap extends React.Component<HeatmapProps> {
render() {
const element = document.getElementById("color-elem");
if (element) {
const base = getComputedStyle(element).getPropertyValue("color");
for (let elem of Array.from(document.getElementsByClassName("color1") as HTMLCollectionOf<HTMLElement>)) {
elem.style.fill = base;
elem.style.opacity = "0.44";
}
for (let elem of Array.from(document.getElementsByClassName("color2") as HTMLCollectionOf<HTMLElement>)) {
elem.style.fill = base;
elem.style.opacity = "0.6";
}
for (let elem of Array.from(document.getElementsByClassName("color3") as HTMLCollectionOf<HTMLElement>)) {
elem.style.fill = base;
elem.style.opacity = "0.76";
}
for (let elem of Array.from(document.getElementsByClassName("color4") as HTMLCollectionOf<HTMLElement>)) {
elem.style.fill = base;
elem.style.opacity = "0.92";
}
}
return <div style={{ padding: "10px 0px 0px 10px", maxWidth: "300px", marginLeft: "auto", marginRight: "auto", fontSize: "4px !important" }} id="calendar-container">
<ReactCalendarHeatmap
startDate={new Date(new Date().setFullYear(new Date().getFullYear() - 1))}
endDate={new Date()}
values={this.props.data}
horizontal={false}
showMonthLabels={true}
showWeekdayLabels={true}
weekdayLabels={["S", "M", "T", "W", "T", "F", "S"]}
classForValue={(value) => {
if (!value || value.count == 0) {
return 'color-empty';
}
return `color${Math.min(MAX_COLORS, Math.floor(Math.log(value.count) / Math.log(COLOR_FREQ)))}`;
}}
titleForValue={(value) => !value || value.date === null ? '' : value.count + ' words on ' + new Date(value.date).toLocaleDateString()}
/>
<div id="color-elem" />
</div>
}
}
export default Heatmap;

3
src/constants.ts Normal file
View File

@@ -0,0 +1,3 @@
export const VIEW_TYPE_STATS_TRACKER = "stats-tracker";
export const MAX_COLORS = 5;
export const COLOR_FREQ = 6;

View File

@@ -1,4 +1,6 @@
import { TFile, Plugin, MarkdownView } from 'obsidian';
import { TFile, Plugin, MarkdownView, debounce, Debouncer, WorkspaceLeaf, addIcon } from 'obsidian';
import { VIEW_TYPE_STATS_TRACKER } from './constants';
import StatsTrackerView from './view';
interface WordCount {
initial: number;
@@ -20,6 +22,9 @@ export default class DailyStats extends Plugin {
statusBarEl: HTMLElement;
currentWordCount: number;
today: string;
debouncedUpdate: Debouncer<[contents: string, filepath: string]>;
private view: StatsTrackerView;
async onload() {
await this.loadSettings();
@@ -32,6 +37,28 @@ export default class DailyStats extends Plugin {
this.currentWordCount = 0;
}
this.debouncedUpdate = debounce((contents: string, filepath: string) => {
this.updateWordCount(contents, filepath);
}, 400, false);
this.registerView(
VIEW_TYPE_STATS_TRACKER,
(leaf: WorkspaceLeaf) => (this.view = new StatsTrackerView(leaf, this.settings.dayCounts))
);
this.addCommand({
id: "show-daily-stats-tracker-view",
name: "Open tracker view",
checkCallback: (checking: boolean) => {
if (checking) {
return (
this.app.workspace.getLeavesOfType(VIEW_TYPE_STATS_TRACKER).length === 0
);
}
this.initLeaf();
},
});
this.registerEvent(
this.app.workspace.on("quit", this.onunload.bind(this))
);
@@ -46,10 +73,28 @@ export default class DailyStats extends Plugin {
}, 200)
);
addIcon("bar-graph", `<path fill="currentColor" stroke="currentColor" d="M122.88,105.98H9.59v-0.02c-2.65,0-5.05-1.08-6.78-2.81c-1.72-1.72-2.79-4.11-2.79-6.75H0V0h12.26v93.73h110.62V105.98 L122.88,105.98z M83.37,45.6h19.55c1.04,0,1.89,0.85,1.89,1.89v38.46c0,1.04-0.85,1.89-1.89,1.89H83.37 c-1.04,0-1.89-0.85-1.89-1.89V47.5C81.48,46.46,82.33,45.6,83.37,45.6L83.37,45.6z M25.36,22.07h19.55c1.04,0,1.89,0.85,1.89,1.89 v62c0,1.04-0.85,1.89-1.89,1.89H25.36c-1.04,0-1.89-0.85-1.89-1.89v-62C23.47,22.92,24.32,22.07,25.36,22.07L25.36,22.07 L25.36,22.07z M54.37,8.83h19.54c1.04,0,1.89,0.85,1.89,1.89v75.24c0,1.04-0.85,1.89-1.89,1.89H54.37c-1.04,0-1.89-0.85-1.89-1.89 V10.72C52.48,9.68,53.33,8.83,54.37,8.83L54.37,8.83z"/>`);
this.registerInterval(window.setInterval(() => {
this.updateDate();
this.saveSettings();
}, 1000));
if (this.app.workspace.layoutReady) {
this.initLeaf();
} else {
this.registerEvent(
this.app.workspace.on("layout-ready", this.initLeaf.bind(this))
);
}
}
initLeaf(): void {
if (this.app.workspace.getLeavesOfType(VIEW_TYPE_STATS_TRACKER).length) {
return;
}
this.app.workspace.getRightLeaf(false).setViewState({
type: VIEW_TYPE_STATS_TRACKER,
});
}
async onunload() {
@@ -58,7 +103,7 @@ export default class DailyStats extends Plugin {
onQuickPreview(file: TFile, contents: string) {
if (this.app.workspace.getActiveViewOfType(MarkdownView)) {
this.updateWordCount(contents, file.path);
this.debouncedUpdate(contents, file.path);
}
}
@@ -113,6 +158,8 @@ export default class DailyStats extends Plugin {
}
async saveSettings() {
await this.saveData(this.settings);
if (Object.keys(this.settings.dayCounts).length > 0) { //ensuring we never reset the data by accident
await this.saveData(this.settings);
}
}
}

45
src/view.ts Normal file
View File

@@ -0,0 +1,45 @@
import { ItemView, WorkspaceLeaf } from "obsidian";
import { VIEW_TYPE_STATS_TRACKER } from "./constants";
import * as ReactDOM from "react-dom";
import * as React from "react";
import Calendar from "./calendar";
import '../styles.css';
export default class StatsTrackerView extends ItemView {
private dayCounts: Record<string, number>;
constructor(leaf: WorkspaceLeaf, dayCounts: Record<string, number>) {
super(leaf);
this.dayCounts = dayCounts;
this.registerInterval(
window.setInterval(() => {
ReactDOM.render(React.createElement(Calendar, {
data: Object.keys(this.dayCounts).map(day => {
return { "date": new Date(new Date(day).setMonth(new Date(day).getMonth() + 1)), "count": this.dayCounts[day] }
}),
}), (this as any).contentEl);
}, 1000)
);
}
getDisplayText() {
return "Daily Stats";
}
getIcon() {
return "bar-graph";
}
getViewType() {
return VIEW_TYPE_STATS_TRACKER;
}
async onOpen() {
ReactDOM.render(React.createElement(Calendar, {
data: Object.keys(this.dayCounts).map(day => {
return { "date": new Date(new Date(day).setMonth(new Date(day).getMonth() + 1)), "count": this.dayCounts[day] }
}),
}), (this as any).contentEl);
}
}

View File

@@ -0,0 +1,24 @@
text {
fill: #aaa;
}
rect:hover {
stroke: #555;
stroke-width: 0.5px;
}
/*
* Default color scale
*/
.color-empty {
fill: var(--background-modifier-border);
}
.color-filled {
fill: var(--text-accent);
}
#color-elem {
color: var(--text-accent);
}

View File

@@ -13,10 +13,13 @@
"dom",
"es5",
"scripthost",
"es2015"
]
"es2015",
"DOM.Iterable"
],
"jsx": "react",
},
"include": [
"**/*.ts"
"**/*.ts",
"**/*.tsx",
]
}
}

1515
yarn.lock

File diff suppressed because it is too large Load Diff