Skip to content

Commit

Permalink
✨ support day-custom
Browse files Browse the repository at this point in the history
Signed-off-by: Wei Zhang <kweizh@gmail.com>
  • Loading branch information
zwpaper committed Feb 6, 2024
1 parent 82cf0d5 commit 04eb19a
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 32 deletions.
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ which support:
- **day-year**: a progress bar showing how many days passed in this year.
- **day-month**: a progress bar showing how many days passed in this month.
- **day-week**: a progress bar showing how many days passed in this week.
- **day-custom**: a progress bar showing how many days passed in custom start and end.
- **month**: a progress bar showing how many months passed in this year.
- **manual**: a progress bar specified by user

Expand Down Expand Up @@ -51,15 +52,25 @@ This is the example configuration obsidian progressbar support with some remarks
``` yaml
# == kind ==
# Required when specifying a time based progress bar
#
# Optional if manually specifying value
# Possible values: day-year, day-month, day-week, month
#
# Possible values:
# day-year:
# day-month:
# day-week:
# month:
# day-custom: min, and max is required, both min and max should in format: YYYY-MM-DD
kind: day-year
# == name ==
# Specify the progress bar name, in front of the bar
# support templates: max, value, percentage
#
# quote is recommanded if templates are used
#
# Optional, will use kind as name if not specified
name: {percentage} to {max}
name: name: "{percentage} from {min} to {max}"
# == width ==
# Specify the progress bar width
Expand All @@ -74,12 +85,27 @@ width: 50%
# Possible format: numbers
value: 10
# == min ==
# Specify the progress bar max value
#
# Optional when specified a valid kind
# Only Required when kind is day-custom
#
# Possible format:
# day-custom: YYYY-MM-DD
# others: number
max: 2024-02-01
# == max ==
# Specify the progress bar max value
#
# Optional when specified a valid kind
# Required when not having a kind
#
# Possible format: numbers
max: 25
# day-custom: YYYY-MM-DD
# others: number
max: 2024-04-30
```


Expand Down
78 changes: 50 additions & 28 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,23 @@ export default class ProgressBar extends Plugin {
// settings: ProgressBarSettings;

async onload() {
// await this.loadSettings();
// await this.loadSettings();

// This adds a settings tab so the user can configure various aspects of the plugin
// this.addSettingTab(new ProgressBarSettingTab(this.app, this));
// This adds a settings tab so the user can configure various aspects of the plugin
// this.addSettingTab(new ProgressBarSettingTab(this.app, this));

this.registerMarkdownCodeBlockProcessor("progressbar", (source, el, ctx) => {
const cfg = parseYaml(source);
if ( !cfg.kind && !cfg.value ) {
if (!cfg.kind && !cfg.value) {
newError(el, "No kind specified");
return;
}

if (cfg.kind === "day-custom" && !cfg.min && !cfg.max) {
newError(el, "Must specify min and max for day-custom");
return;
}

createProgressBar(el, cfg);
});
}
Expand All @@ -42,53 +47,70 @@ export default class ProgressBar extends Plugin {
}

function newError(el: HTMLElement, msg: string) {
el.createEl("div", { text: 'ProgressBarError: '+msg });
el.createEl("div", { text: 'ProgressBarError: ' + msg });
}

const generateUniqueID = (idLength: number) => [...Array(idLength).keys()].map((elem)=>Math.random().toString(36).substr(2, 1)).join("")
const generateUniqueID = (idLength: number) => [...Array(idLength).keys()].map((elem) => Math.random().toString(36).substr(2, 1)).join("")

function createProgressBar(el: HTMLElement, bar: any) {
switch (bar.kind) {
case "day-year":
return newDayYearProgressBar(el, bar);
case "day-month":
return newDayMonthProgressBar(el, bar);
case "month":
case "month":
return newMonthProgressBar(el, bar);
case "day-week":
return newDayWeekProgressBar(el, bar);
case "day-custom":
return newDayCustomProgressBar(el, bar);
default:
return newProgressBar(el, bar);
return newProgressBar(el, bar, bar);
}
}

function daysIntoYear(date: Date){
return (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(date.getFullYear(), 0, 0)) / 24 / 60 / 60 / 1000;
function daysIntoYear(date: Date) {
return (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
- Date.UTC(date.getFullYear(), 0, 0)) / 24 / 60 / 60 / 1000;
}

function newDayWeekProgressBar(el: HTMLElement, bar: any) {
bar.max = 7;
bar.value = new Date().getDay() === 0 ? 7 : new Date().getDay();
newProgressBar(el, bar);
newProgressBar(el, bar, bar);
}

function newMonthProgressBar(el: HTMLElement, bar: any) {
bar.max = 12;
bar.value = new Date().getMonth()+1;
newProgressBar(el, bar);
bar.value = new Date().getMonth() + 1;
newProgressBar(el, bar, bar);
}

function newDayMonthProgressBar(el: HTMLElement, bar: any) {
const now = new Date()
bar.max = new Date(now.getFullYear(), now.getMonth()+1, 0).getDate();
bar.max = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();
bar.value = now.getDate();
newProgressBar(el, bar);
newProgressBar(el, bar, bar);
}

function newDayYearProgressBar(el: HTMLElement, bar: any) {
bar.max = new Date().getFullYear() % 4 == 0 ? 366 : 365;
bar.value = daysIntoYear(new Date());
newProgressBar(el, bar);
newProgressBar(el, bar, bar);
}

// html progressbar has no min variable,
// both max and value should minus min
function newDayCustomProgressBar(el: HTMLElement, bar: any) {
let val = {
min: daysIntoYear(new Date(bar.min)),
max: daysIntoYear(new Date(bar.max)),
value: daysIntoYear(new Date()),
}
val.max = val.max - val.min;
val.value = val.value - val.min;

newProgressBar(el, bar, val);
}

interface Templater {
Expand All @@ -100,24 +122,24 @@ interface Templater {

function applyTemplate(template: string, data: Templater) {
const pattern = /{\s*(\w+?)\s*}/g; // {property}
return template.replace(pattern, (_: any, token: string) => data[token] || "{"+token+"}");
return template.replace(pattern, (_: any, token: string) => data[token] || "{" + token + "}");
}

function newProgressBar(el: HTMLElement, bar: any) {
const labelName = bar.name ? bar.name : bar.kind+"({percentage})";
const max: string = bar.max;
const value: string = bar.value;
function newProgressBar(el: HTMLElement, bar: any, val: any) {
const labelName = bar.name ? bar.name : bar.kind + "({percentage})";
const value: string = (Math.floor(bar.value * 10) / 10).toString();
const message = applyTemplate(labelName, {
max,
value,
percentage: Math.round(bar.value/bar.max*100)+"%",
min: bar.min,
max: bar.max,
value: value,
percentage: Math.round(val.value / val.max * 100) + "%",
});
const label = el.createEl("label", { text: message+": " });
const label = el.createEl("label", { text: message + ": " });

const progressbar = label.createEl("progress");
progressbar.value = bar.value;
progressbar.max = bar.max;
if ( bar.width ) {
progressbar.value = val.value;
progressbar.max = val.max;
if (bar.width) {
progressbar.style.width = bar.width;
}
}
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "progressbar",
"name": "ProgressBar",
"version": "0.2.0",
"version": "0.5.0",
"minAppVersion": "0.15.0",
"description": "Render CodeBlock into a ProgressBar based on Time or Manually.",
"author": "Wei Zhang",
Expand Down

0 comments on commit 04eb19a

Please sign in to comment.