-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d83153a
commit 4d16c50
Showing
17 changed files
with
747 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
*.DS_Store | ||
# npm | ||
node_modules | ||
package-lock.json | ||
|
||
# build | ||
main.js | ||
*.js.map | ||
*.zip | ||
dist/ | ||
coverage/ | ||
.nyc_output/ | ||
test-vault/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Contributing | ||
|
||
When contributing to this repository, please first discuss the change you wish to make via an [issue](https://github.com/lynchjames/obsidian-day-planner/issues), or with the maintainer on the [Obsidian Forum](https://forum.obsidian.md/u/j_l/summary) before making a change. | ||
|
||
I have included a code of conduct, please follow it in all your interactions with the development of this plugin. | ||
|
||
## Pull Request Process | ||
|
||
1. Ensure any install or build dependencies are removed before the end of the layer when doing a | ||
build. | ||
2. Where appropriate, update the README.md with details of changes to the plugin, this includes additions and changes to configuration | ||
settings, plugin commands, useful file locations and additional installation instructions. | ||
3. If you can, please include tests in your Pull Request, particularly if you are making significant changes or additions to the behaviour of the plugin. | ||
4. A CI Test Github Action workflow will run when a new Pull Request is made. The Pull Request cannot be completed until that workflow is passing with the plugin successfully building and all tests passing. | ||
5. The repository maintainer will be responsible for increasing the version numbers in files and the README.md to the new version that this Pull Request would represent once it has been completed and merged. The versioning scheme used is [SemVer](http://semver.org/). | ||
|
||
## Code of Conduct | ||
|
||
### Our Pledge | ||
|
||
In the interest of fostering an open and welcoming environment, we as | ||
contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. | ||
|
||
### Our Standards | ||
|
||
Examples of behavior that contributes to creating a positive environment include: | ||
|
||
* Using welcoming and inclusive language | ||
* Being respectful of differing viewpoints and experiences | ||
* Gracefully accepting constructive criticism | ||
* Focusing on what is best for the community | ||
* Showing empathy towards other community members | ||
|
||
Examples of unacceptable behavior by participants include: | ||
|
||
* The use of sexualized language or imagery and unwelcome sexual attention or advances | ||
* Trolling, insulting/derogatory comments, and personal or political attacks | ||
* Public or private harassment | ||
* Publishing others' private information, such as a physical or electronic address, without explicit permission | ||
* Other conduct which could reasonably be considered inappropriate in a professional setting | ||
|
||
### Our Responsibilities | ||
|
||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. | ||
|
||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, | ||
threatening, offensive, or harmful. | ||
|
||
### Attribution | ||
|
||
This Code of Conduct is based on and adapted from the [Contributor Covenant][homepage], version 1.4, | ||
available at [http://contributor-covenant.org/version/1/4][version] | ||
|
||
[homepage]: http://contributor-covenant.org | ||
[version]: http://contributor-covenant.org/version/1/4/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Day Planner | ||
|
||
<!--   --> | ||
|
||
|
||
This repository contains a plugin for [Obsidian](https://obsidian.md/) for day planning and managing pomodoro timers in Markdown. | ||
|
||
|
||
## Usage | ||
|
||
## Commands | ||
|
||
|
||
## Configuration | ||
|
||
### Timezone | ||
<<<Details of timezone plugin TBC>>> | ||
|
||
## Compatibility | ||
|
||
Custom plugins are only available for Obsidian v0.9.7+. | ||
|
||
The current API of this repo targets Obsidian **v0.9.10**. | ||
|
||
## Installing | ||
|
||
As of version [0.9.7 of Obsidian](https://forum.obsidian.md/t/obsidian-release-v0-9-7-insider-build/7628), this plugin is available to be installed directly from within the app. The plugin can be found in the Community Plugins directory which can be accessed from the Settings pane under Third Party Plugins. | ||
|
||
## Manual installation | ||
|
||
1. Download the [latest release](https://github.com/lynchjames/obsidian-day-planner/releases/latest) | ||
1. Extract the obsidian-day-planner folder from the zip to your vault's plugins folder: `<vault>/.obsidian/plugins/` | ||
Note: On some machines the `.obsidian` folder may be hidden. On MacOS you should be able to press `Command+Shift+Dot` to show the folder in Finder. | ||
1. Reload Obsidian | ||
1. If prompted about Safe Mode, you can disable safe mode and enable the plugin. | ||
|
||
## Credits | ||
|
||
TBC | ||
|
||
## For developers | ||
Pull requests are both weclcome and appreciated. 😀 | ||
|
||
If you would like to contribute to the development of this plugin, please follow the guidelines provided in [CONTRIBUTING.md](CONTRIBUTING.md). | ||
|
||
## Donating | ||
|
||
This plugin is provided free of charge. If you would like to donate something to me, you can via [PayPal](https://paypal.me/lynchjames2020). Thank you! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"id": "obsidian-day-planner", | ||
"name": "Day Planner", | ||
"version": "0.0.1", | ||
"description": "A plugin to help you plan your day and setup pomodoro timers", | ||
"isDesktopOnly": false, | ||
"js": "main.js", | ||
"css": "style.css" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "obsidian-day-planner", | ||
"version": "0.1.0", | ||
"description": "A plugin to help you plan your day and setup pomodoro timers", | ||
"main": "main.js", | ||
"scripts": { | ||
"dev": "rollup --config rollup.config.js -w", | ||
"build": "rollup --config rollup.config.js", | ||
"test": "cross-env TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\" }' mocha -r ts-node/register -r ignore-styles -r jsdom-global/register tests/**/*.test.ts", | ||
"coverage": "nyc -r lcov -e .ts -x \"*.test.ts\" npm run test" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@rollup/plugin-commonjs": "^15.1.0", | ||
"@rollup/plugin-node-resolve": "^9.0.0", | ||
"@rollup/plugin-typescript": "^6.0.0", | ||
"@types/chai": "^4.2.14", | ||
"@types/mocha": "^8.0.3", | ||
"@types/node": "^14.14.2", | ||
"chai": "^4.2.0", | ||
"cross-env": "^7.0.2", | ||
"ignore-styles": "^5.0.1", | ||
"jsdom": "^16.4.0", | ||
"jsdom-global": "^3.0.2", | ||
"mocha": "^8.2.0", | ||
"nyc": "^15.1.0", | ||
"obsidian": "https://github.com/obsidianmd/obsidian-api/tarball/master", | ||
"rollup": "^2.32.1", | ||
"rollup-plugin-copy": "^3.3.0", | ||
"ts-node": "^9.0.0", | ||
"tslib": "^2.0.3", | ||
"typescript": "^4.0.5" | ||
}, | ||
"dependencies": { | ||
"moment": "^2.29.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import typescript from '@rollup/plugin-typescript'; | ||
import {nodeResolve} from '@rollup/plugin-node-resolve'; | ||
import commonjs from '@rollup/plugin-commonjs'; | ||
import copy from 'rollup-plugin-copy'; | ||
const TEST_VAULT = 'test-vault/.obsidian/plugins/day-planner'; | ||
|
||
export default { | ||
input: 'src/main.ts', | ||
output: { | ||
dir: 'dist/', | ||
sourcemap: 'inline', | ||
format: 'cjs', | ||
exports: 'default' | ||
}, | ||
external: ['obsidian'], | ||
plugins: [ | ||
typescript(), | ||
nodeResolve({browser: true}), | ||
commonjs(), | ||
copy({ | ||
targets: [ | ||
{ src: 'dist/main.js', dest: TEST_VAULT }, | ||
{ src: ['manifest.json', 'styles.css'], dest: TEST_VAULT } | ||
], flatten: true | ||
}) | ||
] | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export const HEADING_REGEX = /^[#\s-]*/; | ||
export const HEADING_FORMAT = '#'; | ||
|
||
export const DEFAULT_DATE_FORMAT = 'YYYYMMDDHHmm'; | ||
export const DATE_REGEX = /(?<target>{{date:?(?<date>[^}]*)}})/g; | ||
|
||
export const DAY_PLANNER_FILENAME = 'Day Planner.md'; | ||
export const PLAN_PARSER_REGEX = | ||
/^-?[\s]*\[?(?<completion>[x ]*)\]?(\d.)?\s*?(?<hours>\d{2}):(?<minutes>\d{2})(?<text>.*)$/gmi; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { | ||
MarkdownView, | ||
Plugin, | ||
Vault, | ||
DataAdapter, | ||
TFile, | ||
EventRef | ||
} from 'obsidian'; | ||
import MomentDateRegex from './moment-date-regex'; | ||
import moment from 'moment'; | ||
import { DayPlannerSettingsTab } from './settings-tab'; | ||
import { DayPlannerSettings } from './settings'; | ||
import { DAY_PLANNER_FILENAME } from './constants'; | ||
import Parser, { PlanItem, PlanSummaryData } from './parser'; | ||
|
||
export default class DayPlanner extends Plugin { | ||
settings: DayPlannerSettings; | ||
momentDateRegex: MomentDateRegex; | ||
parser: Parser; | ||
vault: Vault; | ||
statusBar: HTMLElement | ||
statusBarAdded: boolean; | ||
statusBarText: HTMLSpanElement; | ||
statusBarProgress: HTMLDivElement; | ||
statusBarCurrentProgress: HTMLDivElement; | ||
|
||
|
||
|
||
onInit() {} | ||
|
||
async onload() { | ||
console.log("Loading Day Planner plugin"); | ||
this.settings = (await this.loadData()) || new DayPlannerSettings(); | ||
this.vault = this.app.vault; | ||
this.statusBar = this.addStatusBarItem() | ||
this.momentDateRegex = new MomentDateRegex(); | ||
this.parser = new Parser(this.app.vault); | ||
|
||
this.linkToDayPlanBlock(); | ||
// this.registerEvent(this.app.workspace.on('file-open', this.parseDayPlanner)); | ||
this.registerEvent(this.app.on("codemirror", this.codeMirror)); | ||
|
||
this.addSettingTab(new DayPlannerSettingsTab(this.app, this)); | ||
this.parseDayPlanner(); | ||
|
||
this.registerInterval( | ||
window.setInterval(() => this.refreshStatusBar(), 2500) | ||
); | ||
} | ||
|
||
async refreshStatusBar() { | ||
const planSummary = await this.parseDayPlanner(); | ||
const current = planSummary.current(); | ||
this.updateProgress(current.current, current.next); | ||
} | ||
|
||
updateProgress(current: PlanItem, next: PlanItem) { | ||
if(!current || !next){ | ||
return; | ||
} | ||
const nowMoment = moment(new Date()); | ||
const currentMoment = moment(current.time); | ||
const nextMoment = moment(next.time); | ||
const diff = moment.duration(nextMoment.diff(currentMoment)); | ||
const fromStart = moment.duration(nowMoment.diff(currentMoment)); | ||
const fromNext = moment.duration(nextMoment.diff(nowMoment)); | ||
let percentageComplete = (fromStart.asMinutes()/diff.asMinutes())*100; | ||
console.log(fromStart.asMinutes(), fromNext.asMinutes(), diff.asMinutes(), percentageComplete); | ||
this.statusBarCurrentProgress.style.width = `${percentageComplete.toFixed(0)}%`; | ||
this.statusBarText.innerText = `${fromNext.asMinutes().toFixed(0)} mins left`; | ||
} | ||
|
||
async parseDayPlanner():Promise<PlanSummaryData> { | ||
const fileContent = await this.vault.adapter.read(DAY_PLANNER_FILENAME); | ||
const planData = await this.parser.parseMarkdown(fileContent); | ||
console.log('Current Task', planData.current()); | ||
return planData; | ||
} | ||
|
||
linkToDayPlanBlock() { | ||
if(this.statusBarAdded) { | ||
return; | ||
} | ||
let minutes = new Date().getMinutes(); | ||
let left = 60 - minutes; | ||
// let statusBarContent = new Array(count + 1).join('='); | ||
let status = this.statusBar.createEl('div', { cls: 'day-planner', 'title': 'View the Day Planner', prepend: true}); | ||
this.statusBarText = status.createEl('span', { cls: ['status-bar-item-segment', 'day-planner-status-bar-text']}); | ||
this.statusBarProgress = status.createEl('div', { cls: ['status-bar-item-segment', 'day-planner-progress-bar']}); | ||
this.statusBarCurrentProgress = this.statusBarProgress.createEl('div', { cls: 'day-planner-progress-value'}); | ||
status.onClickEvent((ev: any) => { | ||
this.app.workspace.openLinkText('Day Planner', '', false); | ||
}); | ||
|
||
this.statusBarAdded = true; | ||
} | ||
|
||
codeMirror = (cm: any) => { | ||
console.log(cm); | ||
} | ||
|
||
onunload() { | ||
console.log("Unloading Day Planner plugin"); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { DEFAULT_DATE_FORMAT, DATE_REGEX } from './constants'; | ||
import * as moment from 'moment'; | ||
|
||
export default class MomentDateRegex { | ||
replace(input: string): string { | ||
//A regex to capture multiple matches, each with a target group ({date:YYMMDD}) and date group (YYMMDD) | ||
const dateRegex = DATE_REGEX; | ||
const customFolderString = input; | ||
//Iterate through the matches to collect them in a single array | ||
const matches = []; | ||
let match; | ||
while(match = dateRegex.exec(customFolderString)){ | ||
matches.push(match) | ||
} | ||
//Return the custom folder setting value if no dates are found | ||
if(!matches || matches.length === 0){ | ||
return input; | ||
} | ||
const now = new Date(); | ||
//Transform date matches into moment formatted dates | ||
const formattedDates = matches.map(m => { | ||
//Default to YYYYMMDDHHmm if {{date}} is used | ||
const dateFormat = m.groups.date === '' ? DEFAULT_DATE_FORMAT : m.groups.date; | ||
return [m.groups.target, | ||
this.getMoment(now, dateFormat)]; | ||
}); | ||
|
||
//Check to see if any date formatting is needed. If not return the unformatted setting text. | ||
let output = customFolderString; | ||
formattedDates.forEach(fd => { | ||
output = output.replace(fd[0], fd[1]); | ||
}) | ||
return output; | ||
} | ||
|
||
getMoment(now: Date, dateFormat: string) { | ||
if((window as any).moment) { | ||
return (window as any) | ||
.moment(now) | ||
.format(dateFormat) | ||
} else { | ||
return moment(now).format(dateFormat); | ||
} | ||
} | ||
} |
Oops, something went wrong.