mirror of
https://github.com/ozntel/oz-calendar.git
synced 2026-07-22 07:40:24 +00:00
Compare commits
76 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5565665d44 | ||
|
|
f8741bdbf8 | ||
|
|
3504b38540 | ||
|
|
0a5ae28292 | ||
|
|
f383375883 | ||
|
|
78aae5b64c | ||
|
|
fcb3394a49 | ||
|
|
2ce55907ea | ||
|
|
0f18ba86c2 | ||
|
|
94e34eda3a | ||
|
|
2229d8c95c | ||
|
|
bb136ad115 | ||
|
|
c979cc04b2 | ||
|
|
997119fd13 | ||
|
|
3de6bbd0be | ||
|
|
3f45fa1d7d | ||
|
|
7644abe284 | ||
|
|
56e19dcaf3 | ||
|
|
cb578f9c55 | ||
|
|
752121be89 | ||
|
|
d954a3dd26 | ||
|
|
53b7c39371 | ||
|
|
3cc48dbdf4 | ||
|
|
4f30fe49bb | ||
|
|
96facd0ced | ||
|
|
4f561eee09 | ||
|
|
09ad7cf0a3 | ||
|
|
8f4635c43f | ||
|
|
361575ae91 | ||
|
|
aab3e02a56 | ||
|
|
c49afb830b | ||
|
|
8be898daf5 | ||
|
|
237c2be2ca | ||
|
|
8153b30cbd | ||
|
|
76a350a628 | ||
|
|
964f468f0f | ||
|
|
33b1c5a08e | ||
|
|
f3b0774796 | ||
|
|
3411ad3b0f | ||
|
|
6a19f79878 | ||
|
|
1b527db1d2 | ||
|
|
cf616320e4 | ||
|
|
36a9fe4287 | ||
|
|
5582edfd81 | ||
|
|
0952714ef0 | ||
|
|
e1023211a8 | ||
|
|
b3fcefead7 | ||
|
|
53bee1e847 | ||
|
|
afcd66577b | ||
|
|
91a1727fef | ||
|
|
3914972d9a | ||
|
|
829d919f52 | ||
|
|
936648aaba | ||
|
|
fde00acd89 | ||
|
|
56f0f1b481 | ||
|
|
0781965628 | ||
|
|
2ce08802e6 | ||
|
|
f82032885e | ||
|
|
0796c32554 | ||
|
|
27e38bfe41 | ||
|
|
533da4aad1 | ||
|
|
edb9505e25 | ||
|
|
a4de20347b | ||
|
|
654a4b4fd6 | ||
|
|
d0afa53a24 | ||
|
|
ddf510ac1e | ||
|
|
41684037a0 | ||
|
|
2129cab4de | ||
|
|
883ceb2675 | ||
|
|
ffe496a8b5 | ||
|
|
0234d75dc8 | ||
|
|
3024c14832 | ||
|
|
b9d83bb3f5 | ||
|
|
61d9acddfd | ||
|
|
90f68437c0 | ||
|
|
05c6cc6c69 |
12 changed files with 737 additions and 135 deletions
27
README.md
27
README.md
|
|
@ -1,6 +1,6 @@
|
|||
# OZ Calendar Plugin
|
||||
|
||||
If you like the see your notes on a Calendar and easily find them using a certain date, you are at the right place. This plugin is created to help users easily view notes on Calendar using any YAML key with a custom date value. You define the YAML key and Date Format to be used. Follow the **Configure** steps and you are ready to go.
|
||||
If you like the see your notes on a Calendar and easily find them using a certain date, you are at the right place. This plugin is created to help users easily view notes on Calendar using any YAML key or File Name with a custom date value. You define the YAML key and Date Format to be used. Or you can simply use the file name with your custom date format. Follow the **Configure** steps depending on your choice and you are ready to go.
|
||||
|
||||
## Sample View
|
||||
|
||||
|
|
@ -8,6 +8,10 @@ If you like the see your notes on a Calendar and easily find them using a certai
|
|||
|
||||
## Configure
|
||||
|
||||
> IMPORTANT: Please make sure that you check the date formatting of the library, which is used by this plugin following [Day.js Date Format Link](https://day.js.org/docs/en/display/format).
|
||||
|
||||
### 01 YAML Option as Date Source
|
||||
|
||||
1. Go to the plugin settings
|
||||
2. Define the **YAML** key you want to use as a date field. The default key is **created**
|
||||
3. Define the **Date Format** you are using within **YAML**. The default date format is **YYYY-MM-DD hh:mm:ss**
|
||||
|
|
@ -23,6 +27,17 @@ created: 2023-03-10 09:48:22
|
|||
|
||||
You can use any YAML key instead of "created" and any date format value for the key.
|
||||
|
||||
### 02 File Name Option as Date Source
|
||||
|
||||
The default date source is the YAML Key ("created") as mentioned above. If you want to use the file name as date source that feeds the calendar:
|
||||
|
||||
1. Go to the plugin settings
|
||||
2. Change Date Source from **YAML** to **File Name** since the plugin has **YAML** key as a default date source
|
||||
3. Make sure that you adjust the default date format (**Important**: The default date format has special characters that is not supported for file name like colon that needs to be adjusted for File Name option)
|
||||
4. After these changes, use **Reload Plugin** option to activate the changes in the vault.
|
||||
|
||||
> Both YAML and File Name options can include additional characters in the file name. As long as the custom date format defined in the plugin settings is at the beginning of the YAML key or File Name, the plugin will be smart enough to parse only the beginning of the key/filename. For instance, if you have a file name '**2023-03-10 This is the file**' and your date format defined in the plugin settings is **YYYY-MM-DD**, it will be parsed just fine in the calendar.
|
||||
|
||||
## Create File Option
|
||||
|
||||
You can use the **Plus(+)** icon within the calendar view to add a new note with the default YAML key and date format.
|
||||
|
|
@ -34,6 +49,16 @@ You can define this in the plugin settings:
|
|||
- You can right-click any date in the calendar view to create a note for a certain date
|
||||
- The plus icon is defaulted to create a note for today
|
||||
|
||||
## Plugin Commands
|
||||
|
||||
### Day Navigation
|
||||
|
||||
You can use directly **Go to Previous Day**, **Go to Next Day** and **Go to Today** commands to navigate between dates. You can also assign hotkey to these commands to change the active date easily from your keyboard.
|
||||
|
||||
### New Note Creation
|
||||
|
||||
You can use the **Create a New Note** command to trigger the create a new note action customized for the plugin. Same as day navigation, you can assign hotkey to this command for easy keyboard navigation.
|
||||
|
||||
## Style Settings Plugin Support
|
||||
|
||||
You can customize some of the calendar style settings using the **Style Settings Plugin**.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "oz-calendar",
|
||||
"name": "OZ Calendar",
|
||||
"version": "0.0.2",
|
||||
"version": "0.3.4",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "View your notes in Calendar using any YAML key with date",
|
||||
"author": "Ozan Tellioglu",
|
||||
|
|
|
|||
11
package.json
11
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "oz-calendar",
|
||||
"version": "0.0.2",
|
||||
"version": "0.3.4",
|
||||
"description": "View your notes in Calendar using any YAML key with date",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
@ -14,9 +14,9 @@
|
|||
"devDependencies": {
|
||||
"@types/common-tags": "^1.8.1",
|
||||
"@types/node": "^16.11.6",
|
||||
"@types/react": "17.0.2",
|
||||
"@types/react": "18.2.38",
|
||||
"@types/react-calendar": "^3.9.0",
|
||||
"@types/react-dom": "17.0.2",
|
||||
"@types/react-dom": "18.2.17",
|
||||
"@typescript-eslint/eslint-plugin": "5.29.0",
|
||||
"@typescript-eslint/parser": "5.29.0",
|
||||
"builtin-modules": "3.3.0",
|
||||
|
|
@ -30,10 +30,9 @@
|
|||
"@popperjs/core": "^2.11.6",
|
||||
"common-tags": "^1.8.2",
|
||||
"dayjs": "1.11.7",
|
||||
"preact": "10",
|
||||
"react": "npm:@preact/compat@17.0.2",
|
||||
"react": "18.2.0",
|
||||
"react-calendar": "4.0.0",
|
||||
"react-dom": "npm:@preact/compat@17.0.2",
|
||||
"react-dom": "18.2.0",
|
||||
"react-icons": "4.8.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import OZCalendarPlugin from '../main';
|
|||
import NoteListComponent from './noteList';
|
||||
import dayjs from 'dayjs';
|
||||
import useForceUpdate from 'hooks/forceUpdate';
|
||||
import { DayChangeCommandAction } from 'types';
|
||||
import { CreateNoteModal } from 'modal';
|
||||
|
||||
export default function MyCalendar(params: { plugin: OZCalendarPlugin }) {
|
||||
const { plugin } = params;
|
||||
|
|
@ -16,11 +18,57 @@ export default function MyCalendar(params: { plugin: OZCalendarPlugin }) {
|
|||
|
||||
useEffect(() => {
|
||||
window.addEventListener(plugin.EVENT_TYPES.forceUpdate, forceUpdate);
|
||||
window.addEventListener(plugin.EVENT_TYPES.changeDate, changeDate);
|
||||
window.addEventListener(plugin.EVENT_TYPES.createNote, createNote);
|
||||
return () => {
|
||||
window.removeEventListener(plugin.EVENT_TYPES.forceUpdate, forceUpdate);
|
||||
window.removeEventListener(plugin.EVENT_TYPES.changeDate, changeDate);
|
||||
window.removeEventListener(plugin.EVENT_TYPES.createNote, createNote);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const createNote = () => {
|
||||
let currentSelectedDay: Date = selectedDay;
|
||||
let dateNow: Date = new Date();
|
||||
setSelectedDay((selectedDay) => {
|
||||
currentSelectedDay = selectedDay;
|
||||
return selectedDay;
|
||||
});
|
||||
// Add now time details to the existing date if current date
|
||||
if (plugin.settings.newNoteDate === 'active-date') {
|
||||
currentSelectedDay.setHours(dateNow.getHours());
|
||||
currentSelectedDay.setMinutes(dateNow.getMinutes());
|
||||
currentSelectedDay.setMilliseconds(dateNow.getMilliseconds());
|
||||
}
|
||||
let newFileModal = new CreateNoteModal(
|
||||
plugin,
|
||||
plugin.settings.newNoteDate === 'current-date' ? dateNow : currentSelectedDay
|
||||
);
|
||||
newFileModal.open();
|
||||
};
|
||||
|
||||
const changeDate = (e: CustomEvent) => {
|
||||
let action = e.detail.action as DayChangeCommandAction;
|
||||
let currentSelectedDay = selectedDay;
|
||||
|
||||
// Event listener is not capable of getting the updates after event listener is added
|
||||
// This is created to capture current state value during the custom event dispatch
|
||||
setSelectedDay((selectedDay) => {
|
||||
currentSelectedDay = selectedDay;
|
||||
return selectedDay;
|
||||
});
|
||||
|
||||
let newDate = dayjs(currentSelectedDay);
|
||||
if (action === 'next-day') {
|
||||
newDate = dayjs(currentSelectedDay).add(1, 'day');
|
||||
} else if (action === 'previous-day') {
|
||||
newDate = dayjs(currentSelectedDay).add(-1, 'day');
|
||||
} else if (action === 'today') {
|
||||
newDate = dayjs();
|
||||
}
|
||||
setSelectedDay(newDate.toDate());
|
||||
};
|
||||
|
||||
const customTileContent = ({ date, view }: CalendarTileProperties) => {
|
||||
if (view === 'month') {
|
||||
const dateString = dayjs(date).format('YYYY-MM-DD');
|
||||
|
|
@ -29,7 +77,7 @@ export default function MyCalendar(params: { plugin: OZCalendarPlugin }) {
|
|||
return (
|
||||
<div className="dots-wrapper">
|
||||
{[...Array(Math.min(dotsCount, 2))].map((_, index) => (
|
||||
<RxDotFilled viewBox="0 0 15 15" />
|
||||
<RxDotFilled key={index} viewBox="0 0 15 15" />
|
||||
))}
|
||||
{dotsCount > 2 && <span>+{dotsCount - 2}</span>}
|
||||
</div>
|
||||
|
|
@ -38,15 +86,31 @@ export default function MyCalendar(params: { plugin: OZCalendarPlugin }) {
|
|||
return null;
|
||||
};
|
||||
|
||||
const customTileClass = ({ activeStartDate, date, view }: CalendarTileProperties) => {
|
||||
// Assign a custom class in case the day is the current day
|
||||
let today = new Date();
|
||||
return date.getFullYear() === today.getFullYear() &&
|
||||
date.getMonth() === today.getMonth() &&
|
||||
date.getDate() === today.getDate()
|
||||
? 'oz-calendar-plugin-today'
|
||||
: '';
|
||||
};
|
||||
|
||||
const fixedCalendarClass = plugin.settings.fixedCalendar ? 'fixed' : '';
|
||||
|
||||
return (
|
||||
<div className={'oz-calendar-plugin-view' + (plugin.settings.fixedCalendar ? ' fixed' : '')}>
|
||||
<div className={'oz-calendar-plugin-view ' + fixedCalendarClass}>
|
||||
<Calendar
|
||||
onChange={setSelectedDay}
|
||||
value={selectedDay}
|
||||
maxDetail="month"
|
||||
minDetail="month"
|
||||
showWeekNumbers={plugin.settings.showWeekNumbers}
|
||||
view="month"
|
||||
tileContent={customTileContent}
|
||||
tileClassName={customTileClass}
|
||||
calendarType={plugin.settings.calendarType}
|
||||
showFixedNumberOfWeeks={plugin.settings.fixedCalendar}
|
||||
activeStartDate={activeStartDate}
|
||||
onActiveStartDateChange={(props) => {
|
||||
if (props.action === 'next') {
|
||||
|
|
@ -69,6 +133,7 @@ export default function MyCalendar(params: { plugin: OZCalendarPlugin }) {
|
|||
setActiveStartDate={setActiveStartDate}
|
||||
plugin={plugin}
|
||||
forceValue={forceValue}
|
||||
createNote={createNote}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,18 +7,20 @@ import dayjs from 'dayjs';
|
|||
import OZCalendarPlugin from 'main';
|
||||
import { isMouseEvent, openFile } from '../util/utils';
|
||||
import { Menu, TFile } from 'obsidian';
|
||||
import { CreateNoteModal } from 'modal';
|
||||
import { VIEW_TYPE } from 'view';
|
||||
import { OZNote } from 'types';
|
||||
|
||||
interface NoteListComponentParams {
|
||||
selectedDay: Date;
|
||||
setSelectedDay: (selectedDay: Date) => void;
|
||||
setActiveStartDate: (newActiveStartDate: Date) => void;
|
||||
createNote: () => void;
|
||||
plugin: OZCalendarPlugin;
|
||||
forceValue: number;
|
||||
}
|
||||
|
||||
export default function NoteListComponent(params: NoteListComponentParams) {
|
||||
const { setSelectedDay, selectedDay, plugin, setActiveStartDate, forceValue } = params;
|
||||
const { setSelectedDay, selectedDay, plugin, setActiveStartDate, forceValue, createNote } = params;
|
||||
|
||||
const setNewSelectedDay = (nrChange: number) => {
|
||||
let newDate = dayjs(selectedDay).add(nrChange, 'day');
|
||||
|
|
@ -35,29 +37,48 @@ export default function NoteListComponent(params: NoteListComponentParams) {
|
|||
}
|
||||
};
|
||||
|
||||
const openFilePath = (filePath: string) => {
|
||||
const openFilePath = (e: React.MouseEvent<HTMLDivElement, MouseEvent>, filePath: string) => {
|
||||
let abstractFile = plugin.app.vault.getAbstractFileByPath(filePath);
|
||||
let openFileBehaviour = plugin.settings.openFileBehaviour;
|
||||
if (abstractFile) {
|
||||
if (abstractFile && abstractFile instanceof TFile) {
|
||||
// Define the Default Open Behaviour by looking at the plugin settings
|
||||
let openInNewLeaf: boolean = openFileBehaviour === 'new-tab';
|
||||
let openInNewTabGroup: boolean = openFileBehaviour === 'new-tab-group';
|
||||
if (openFileBehaviour === 'obsidian-default') {
|
||||
openInNewLeaf = (e.ctrlKey || e.metaKey) && !(e.shiftKey || e.altKey);
|
||||
openInNewTabGroup = (e.ctrlKey || e.metaKey) && (e.shiftKey || e.altKey);
|
||||
}
|
||||
// Open the file by using the open file behaviours above
|
||||
openFile({
|
||||
file: abstractFile as TFile,
|
||||
file: abstractFile,
|
||||
plugin: plugin,
|
||||
newLeaf: openFileBehaviour === 'new-tab',
|
||||
leafBySplit: openFileBehaviour === 'new-tab-group',
|
||||
newLeaf: openInNewLeaf,
|
||||
leafBySplit: openInNewTabGroup,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const selectedDayNotes = useMemo(() => {
|
||||
const selectedDayNotes: OZNote[] = useMemo(() => {
|
||||
const selectedDayIso = dayjs(selectedDay).format('YYYY-MM-DD');
|
||||
return selectedDayIso in plugin.OZCALENDARDAYS_STATE ? plugin.OZCALENDARDAYS_STATE[selectedDayIso] : [];
|
||||
let sortedList: OZNote[] = [];
|
||||
if (selectedDayIso in plugin.OZCALENDARDAYS_STATE) {
|
||||
sortedList = plugin.OZCALENDARDAYS_STATE[selectedDayIso].filter(
|
||||
(ozItem) => ozItem.type === 'note'
|
||||
) as OZNote[];
|
||||
}
|
||||
sortedList = sortedList.sort((a, b) => {
|
||||
if (plugin.settings.sortingOption === 'name-rev')
|
||||
[a.displayName, b.displayName] = [b.displayName, a.displayName];
|
||||
return a.displayName.localeCompare(b.displayName, 'en', { numeric: true });
|
||||
});
|
||||
return sortedList;
|
||||
}, [selectedDay, forceValue]);
|
||||
|
||||
const triggerFileContextMenu = (e: React.MouseEvent | React.TouchEvent, filePath: string) => {
|
||||
let abstractFile = plugin.app.vault.getAbstractFileByPath(filePath);
|
||||
if (abstractFile) {
|
||||
const fileMenu = new Menu();
|
||||
plugin.app.workspace.trigger('file-menu', fileMenu, abstractFile, 'file-explorer');
|
||||
plugin.app.workspace.trigger('file-menu', fileMenu, abstractFile, VIEW_TYPE);
|
||||
if (isMouseEvent(e)) {
|
||||
fileMenu.showAtPosition({ x: e.pageX, y: e.pageY });
|
||||
} else {
|
||||
|
|
@ -71,14 +92,7 @@ export default function NoteListComponent(params: NoteListComponentParams) {
|
|||
<>
|
||||
<div className="oz-calendar-notelist-header-container">
|
||||
<div className="oz-calendar-nav-action-plus">
|
||||
<RiAddCircleLine
|
||||
size={20}
|
||||
aria-label="Create note for today"
|
||||
onClick={() => {
|
||||
let newFileModal = new CreateNoteModal(plugin, new Date());
|
||||
newFileModal.open();
|
||||
}}
|
||||
/>
|
||||
<RiAddCircleLine size={20} aria-label="Create note for today" onClick={createNote} />
|
||||
</div>
|
||||
<div className="oz-calendar-nav-action-left">
|
||||
<BsArrowLeft size={22} aria-label="Go to previous day" onClick={() => setNewSelectedDay(-1)} />
|
||||
|
|
@ -103,22 +117,32 @@ export default function NoteListComponent(params: NoteListComponentParams) {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="oz-calendar-notelist-container">
|
||||
<div
|
||||
className={
|
||||
'oz-calendar-notelist-container ' +
|
||||
(plugin.settings.fileNameOverflowBehaviour == 'scroll' ? 'oz-calendar-overflow-scroll' : '')
|
||||
}>
|
||||
{selectedDayNotes.length === 0 && (
|
||||
<div className="oz-calendar-note-no-note">
|
||||
<RiPhoneFindLine className="oz-calendar-no-note-icon" />
|
||||
No note found
|
||||
</div>
|
||||
)}
|
||||
{selectedDayNotes.map((notePath) => {
|
||||
{selectedDayNotes.map((ozNote) => {
|
||||
return (
|
||||
<div
|
||||
className="oz-calendar-note-line"
|
||||
id={notePath}
|
||||
onClick={() => openFilePath(notePath)}
|
||||
onContextMenu={(e) => triggerFileContextMenu(e, notePath)}>
|
||||
className={
|
||||
'oz-calendar-note-line' +
|
||||
(plugin.settings.fileNameOverflowBehaviour == 'hide'
|
||||
? ' oz-calendar-overflow-hide'
|
||||
: '')
|
||||
}
|
||||
id={ozNote.path}
|
||||
key={ozNote.path}
|
||||
onClick={(e) => openFilePath(e, ozNote.path)}
|
||||
onContextMenu={(e) => triggerFileContextMenu(e, ozNote.path)}>
|
||||
<HiOutlineDocumentText className="oz-calendar-note-line-icon" />
|
||||
<span>{extractFileName(notePath)}</span>
|
||||
<span>{ozNote.displayName}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
263
src/main.ts
263
src/main.ts
|
|
@ -2,16 +2,20 @@ import { CachedMetadata, Menu, Plugin, TAbstractFile, TFile, addIcon } from 'obs
|
|||
import { OZCalendarView, VIEW_TYPE } from 'view';
|
||||
import dayjs from 'dayjs';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
import { OZCalendarDaysMap } from 'types';
|
||||
import { DayChangeCommandAction, OZCalendarDaysMap, fileToOZItem } from 'types';
|
||||
import { OZCAL_ICON } from './util/icons';
|
||||
import { OZCalendarPluginSettings, DEFAULT_SETTINGS, OZCalendarPluginSettingsTab } from './settings/settings';
|
||||
import { CreateNoteModal } from 'modal';
|
||||
|
||||
export default class OZCalendarPlugin extends Plugin {
|
||||
settings: OZCalendarPluginSettings;
|
||||
dayjs = dayjs;
|
||||
OZCALENDARDAYS_STATE: OZCalendarDaysMap = {};
|
||||
initialScanCompleted: boolean = false;
|
||||
EVENT_TYPES = {
|
||||
forceUpdate: 'ozCalendarForceUpdate',
|
||||
changeDate: 'ozCalendarChangeDate',
|
||||
createNote: 'ozCalendarCreateNote',
|
||||
};
|
||||
|
||||
dayMonthSelectorQuery = '.oz-calendar-plugin-view .react-calendar__tile.react-calendar__month-view__days__day';
|
||||
|
|
@ -29,19 +33,91 @@ export default class OZCalendarPlugin extends Plugin {
|
|||
return new OZCalendarView(leaf, this);
|
||||
});
|
||||
|
||||
this.app.metadataCache.on('resolved', () => {
|
||||
// Run only during initial vault load, changes are handled separately
|
||||
if (!this.initialScanCompleted) {
|
||||
this.OZCALENDARDAYS_STATE = this.getNotesWithDates();
|
||||
this.initialScanCompleted = true;
|
||||
this.calendarForceUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
this.app.workspace.onLayoutReady(() => {
|
||||
this.OZCALENDARDAYS_STATE = this.getNotesWithDates();
|
||||
if (this.settings.openViewOnStart) {
|
||||
this.openOZCalendarLeaf({ showAfterAttach: true });
|
||||
}
|
||||
this.OZCALENDARDAYS_STATE = this.getNotesWithDates();
|
||||
});
|
||||
|
||||
this.app.metadataCache.on('changed', this.handleCacheChange);
|
||||
this.app.vault.on('rename', this.handleRename);
|
||||
this.app.vault.on('delete', this.handleDelete);
|
||||
this.registerEvent(this.app.metadataCache.on('changed', this.handleCacheChange));
|
||||
this.registerEvent(this.app.vault.on('rename', this.handleRename));
|
||||
this.registerEvent(this.app.vault.on('delete', this.handleDelete));
|
||||
this.registerEvent(this.app.vault.on('create', this.handleCreate));
|
||||
|
||||
// Add Event Handler for Custom Note Creation
|
||||
document.on('contextmenu', this.dayMonthSelectorQuery, this.handleMonthDayContextMenu);
|
||||
|
||||
this.addCommand({
|
||||
id: 'oz-calendar-next-day',
|
||||
name: 'Go to Next Day',
|
||||
callback: () => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(this.EVENT_TYPES.changeDate, {
|
||||
detail: {
|
||||
action: 'next-day' as DayChangeCommandAction,
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: 'oz-calendar-previous-day',
|
||||
name: 'Go to Previous Day',
|
||||
callback: () => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(this.EVENT_TYPES.changeDate, {
|
||||
detail: {
|
||||
action: 'previous-day' as DayChangeCommandAction,
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: 'oz-calendar-today',
|
||||
name: 'Go to Today',
|
||||
callback: () => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(this.EVENT_TYPES.changeDate, {
|
||||
detail: {
|
||||
action: 'today' as DayChangeCommandAction,
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: 'oz-calendar-new-note',
|
||||
name: 'Create a New Note',
|
||||
callback: () => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(this.EVENT_TYPES.createNote, {
|
||||
detail: {},
|
||||
})
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: 'oz-calendar-open-leaf',
|
||||
name: 'Open OZ Calendar',
|
||||
callback: () => {
|
||||
this.openOZCalendarLeaf({ showAfterAttach: true });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onunload() {
|
||||
|
|
@ -59,23 +135,35 @@ export default class OZCalendarPlugin extends Plugin {
|
|||
|
||||
/* ------------ HANDLE VAULT CHANGES - HELPERS ------------ */
|
||||
|
||||
addFilePathToState = (date: string, filePath: string) => {
|
||||
/**
|
||||
* Adds the provided filePath to the corresponding date within plugin state
|
||||
* @param date
|
||||
* @param filePath
|
||||
*/
|
||||
addFilePathToState = (date: string, file: TFile) => {
|
||||
let newStateMap = this.OZCALENDARDAYS_STATE;
|
||||
// if exists, add the new file path
|
||||
if (date in newStateMap) {
|
||||
newStateMap[date] = [...newStateMap[date], filePath];
|
||||
newStateMap[date] = [...newStateMap[date], fileToOZItem({ note: file })];
|
||||
} else {
|
||||
newStateMap[date] = [filePath];
|
||||
newStateMap[date] = [fileToOZItem({ note: file })];
|
||||
}
|
||||
this.OZCALENDARDAYS_STATE = newStateMap;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scans the plugin state and removes the file path if found
|
||||
* @param filePath
|
||||
* @returns true if the file path is found and deleted
|
||||
*/
|
||||
removeFilePathFromState = (filePath: string): boolean => {
|
||||
let changeFlag = false;
|
||||
let newStateMap = this.OZCALENDARDAYS_STATE;
|
||||
for (let k of Object.keys(newStateMap)) {
|
||||
if (newStateMap[k].contains(filePath)) {
|
||||
newStateMap[k] = newStateMap[k].filter((p) => p !== filePath);
|
||||
if (newStateMap[k].some((ozItem) => ozItem.type === 'note' && ozItem.path === filePath)) {
|
||||
newStateMap[k] = newStateMap[k].filter((ozItem) => {
|
||||
return !(ozItem.type === 'note' && ozItem.path === filePath);
|
||||
});
|
||||
changeFlag = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -83,6 +171,11 @@ export default class OZCalendarPlugin extends Plugin {
|
|||
return changeFlag;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scans the file provided for users date key and adds to the plugin state
|
||||
* @param file
|
||||
* @returns boolean (if any change happened, true)
|
||||
*/
|
||||
scanTFileDate = (file: TFile): boolean => {
|
||||
let cache = this.app.metadataCache.getCache(file.path);
|
||||
let changeFlag = false;
|
||||
|
|
@ -90,9 +183,9 @@ export default class OZCalendarPlugin extends Plugin {
|
|||
let fm = cache.frontmatter;
|
||||
for (let k of Object.keys(cache.frontmatter)) {
|
||||
if (k === this.settings.yamlKey) {
|
||||
let fmValue = fm[k];
|
||||
let fmValue = String(fm[k]);
|
||||
let parsedDayISOString = dayjs(fmValue, this.settings.dateFormat).format('YYYY-MM-DD');
|
||||
this.addFilePathToState(parsedDayISOString, file.path);
|
||||
this.addFilePathToState(parsedDayISOString, file);
|
||||
changeFlag = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -100,6 +193,9 @@ export default class OZCalendarPlugin extends Plugin {
|
|||
return changeFlag;
|
||||
};
|
||||
|
||||
/**
|
||||
* Use this function to force update the calendar and file list view
|
||||
*/
|
||||
calendarForceUpdate = () => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(this.EVENT_TYPES.forceUpdate, {
|
||||
|
|
@ -111,34 +207,69 @@ export default class OZCalendarPlugin extends Plugin {
|
|||
/* ------------ HANDLE VAULT CHANGES - LISTENER FUNCTIONS ------------ */
|
||||
|
||||
handleCacheChange = (file: TFile, data: string, cache: CachedMetadata) => {
|
||||
this.removeFilePathFromState(file.path);
|
||||
if (cache && cache.frontmatter) {
|
||||
let fm = cache.frontmatter;
|
||||
for (let k of Object.keys(cache.frontmatter)) {
|
||||
if (k === this.settings.yamlKey) {
|
||||
let fmValue = fm[k];
|
||||
let parsedDayISOString = dayjs(fmValue, this.settings.dateFormat).format('YYYY-MM-DD');
|
||||
// If date doesn't exist, create a new one
|
||||
if (!(parsedDayISOString in this.OZCALENDARDAYS_STATE)) {
|
||||
this.addFilePathToState(parsedDayISOString, file.path);
|
||||
} else {
|
||||
// if date exists and note is not in the date list
|
||||
if (!(file.path in this.OZCALENDARDAYS_STATE[parsedDayISOString])) {
|
||||
this.addFilePathToState(parsedDayISOString, file.path);
|
||||
if (this.settings.dateSource === 'yaml') {
|
||||
this.removeFilePathFromState(file.path);
|
||||
if (cache && cache.frontmatter) {
|
||||
let fm = cache.frontmatter;
|
||||
for (let k of Object.keys(cache.frontmatter)) {
|
||||
if (k === this.settings.yamlKey) {
|
||||
let fmValue = String(fm[k]);
|
||||
let parsedDayISOString = dayjs(fmValue, this.settings.dateFormat).format('YYYY-MM-DD');
|
||||
// If date doesn't exist, create a new one
|
||||
if (!(parsedDayISOString in this.OZCALENDARDAYS_STATE)) {
|
||||
this.addFilePathToState(parsedDayISOString, file);
|
||||
} else {
|
||||
// if date exists and note is not in the date list
|
||||
if (!(file.path in this.OZCALENDARDAYS_STATE[parsedDayISOString])) {
|
||||
this.addFilePathToState(parsedDayISOString, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.calendarForceUpdate();
|
||||
} else if (this.settings.dateSource === 'filename') {
|
||||
// No action needed
|
||||
}
|
||||
};
|
||||
|
||||
handleRename = (file: TFile, oldPath: string) => {
|
||||
let changeFlag = false;
|
||||
if (file instanceof TFile && file.extension === 'md') {
|
||||
for (let k of Object.keys(this.OZCALENDARDAYS_STATE)) {
|
||||
for (let ozItem of this.OZCALENDARDAYS_STATE[k]) {
|
||||
if (ozItem.type === 'note' && ozItem.path === oldPath) {
|
||||
if (this.settings.dateSource === 'yaml') {
|
||||
ozItem.path = file.path;
|
||||
ozItem.displayName = file.basename;
|
||||
changeFlag = true;
|
||||
} else if (this.settings.dateSource === 'filename') {
|
||||
this.OZCALENDARDAYS_STATE[k] = this.OZCALENDARDAYS_STATE[k].filter((ozItem) => {
|
||||
return !(ozItem.type === 'note' && ozItem.path === oldPath);
|
||||
});
|
||||
changeFlag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.calendarForceUpdate();
|
||||
};
|
||||
|
||||
handleRename = (file: TFile, oldPath: string) => {
|
||||
if (file instanceof TFile && file.extension === 'md') {
|
||||
let changeFlag = this.removeFilePathFromState(oldPath);
|
||||
let changeFlag2 = this.scanTFileDate(file);
|
||||
if (changeFlag || changeFlag2) this.calendarForceUpdate();
|
||||
// Make sure that you scan the new file name for filename source
|
||||
if (this.settings.dateSource === 'filename' && dayjs(file.name, this.settings.dateFormat).isValid()) {
|
||||
let parsedDayISOString = dayjs(file.name, this.settings.dateFormat).format('YYYY-MM-DD');
|
||||
if (parsedDayISOString in this.OZCALENDARDAYS_STATE) {
|
||||
this.OZCALENDARDAYS_STATE[parsedDayISOString] = [
|
||||
...this.OZCALENDARDAYS_STATE[parsedDayISOString],
|
||||
fileToOZItem({ note: file }),
|
||||
];
|
||||
} else {
|
||||
this.OZCALENDARDAYS_STATE[parsedDayISOString] = [fileToOZItem({ note: file })];
|
||||
}
|
||||
changeFlag = true;
|
||||
}
|
||||
|
||||
// If change happened force update the component
|
||||
if (changeFlag) this.calendarForceUpdate();
|
||||
};
|
||||
|
||||
handleDelete = (file: TAbstractFile) => {
|
||||
|
|
@ -146,6 +277,23 @@ export default class OZCalendarPlugin extends Plugin {
|
|||
if (changeFlag) this.calendarForceUpdate();
|
||||
};
|
||||
|
||||
handleCreate = (file: TAbstractFile) => {
|
||||
if (file instanceof TFile && file.extension === 'md' && this.settings.dateSource === 'filename') {
|
||||
if (dayjs(file.name, this.settings.dateFormat).isValid()) {
|
||||
let parsedDayISOString = dayjs(file.name, this.settings.dateFormat).format('YYYY-MM-DD');
|
||||
if (parsedDayISOString in this.OZCALENDARDAYS_STATE) {
|
||||
this.OZCALENDARDAYS_STATE[parsedDayISOString] = [
|
||||
...this.OZCALENDARDAYS_STATE[parsedDayISOString],
|
||||
fileToOZItem({ note: file }),
|
||||
];
|
||||
} else {
|
||||
this.OZCALENDARDAYS_STATE[parsedDayISOString] = [fileToOZItem({ note: file })];
|
||||
}
|
||||
}
|
||||
this.calendarForceUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------ OTHER FUNCTIONS ------------ */
|
||||
|
||||
openOZCalendarLeaf = async (params: { showAfterAttach: boolean }) => {
|
||||
|
|
@ -173,27 +321,44 @@ export default class OZCalendarPlugin extends Plugin {
|
|||
let mdFiles = this.app.vault.getMarkdownFiles();
|
||||
let OZCalendarDays: OZCalendarDaysMap = {};
|
||||
for (let mdFile of mdFiles) {
|
||||
// Get the file Cache
|
||||
let fileCache = app.metadataCache.getFileCache(mdFile);
|
||||
// Check if there is Frontmatter
|
||||
if (fileCache && fileCache.frontmatter) {
|
||||
let fm = fileCache.frontmatter;
|
||||
// Check the FM keys vs the provided key by the user in settings
|
||||
for (let k of Object.keys(fm)) {
|
||||
if (k === this.settings.yamlKey) {
|
||||
let fmValue = (fm[k] as string).substring(0, this.settings.dateFormat.length);
|
||||
// Parse the date with provided date format
|
||||
let parsedDayJsDate = dayjs(fmValue, this.settings.dateFormat);
|
||||
// Take only YYYY-MM-DD part fromt the date as String
|
||||
let parsedDayISOString = parsedDayJsDate.format('YYYY-MM-DD');
|
||||
// Check if it already exists
|
||||
if (this.settings.dateSource === 'yaml') {
|
||||
// Get the file Cache
|
||||
let fileCache = app.metadataCache.getFileCache(mdFile);
|
||||
// Check if there is Frontmatter
|
||||
if (fileCache && fileCache.frontmatter) {
|
||||
let fm = fileCache.frontmatter;
|
||||
// Check the FM keys vs the provided key by the user in settings
|
||||
for (let k of Object.keys(fm)) {
|
||||
if (k === this.settings.yamlKey) {
|
||||
let fmValue = String(fm[k]);
|
||||
// Parse the date with provided date format
|
||||
let parsedDayJsDate = dayjs(fmValue, this.settings.dateFormat);
|
||||
// Take only YYYY-MM-DD part fromt the date as String
|
||||
let parsedDayISOString = parsedDayJsDate.format('YYYY-MM-DD');
|
||||
// Check if it already exists
|
||||
if (parsedDayISOString in OZCalendarDays) {
|
||||
OZCalendarDays[parsedDayISOString] = [
|
||||
...OZCalendarDays[parsedDayISOString],
|
||||
fileToOZItem({ note: mdFile }),
|
||||
];
|
||||
} else {
|
||||
OZCalendarDays[parsedDayISOString] = [fileToOZItem({ note: mdFile })];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (this.settings.dateSource === 'filename') {
|
||||
let dateFormatLength = this.settings.dateFormat.length;
|
||||
if (mdFile.name.length >= dateFormatLength) {
|
||||
if (dayjs(mdFile.name, this.settings.dateFormat).isValid()) {
|
||||
let parsedDayISOString = dayjs(mdFile.name, this.settings.dateFormat).format('YYYY-MM-DD');
|
||||
if (parsedDayISOString in OZCalendarDays) {
|
||||
OZCalendarDays[parsedDayISOString] = [
|
||||
...OZCalendarDays[parsedDayISOString],
|
||||
mdFile.path,
|
||||
fileToOZItem({ note: mdFile }),
|
||||
];
|
||||
} else {
|
||||
OZCalendarDays[parsedDayISOString] = [mdFile.path];
|
||||
OZCalendarDays[parsedDayISOString] = [fileToOZItem({ note: mdFile })];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
76
src/modal.ts
76
src/modal.ts
|
|
@ -22,15 +22,12 @@ export class CreateNoteModal extends Modal {
|
|||
const headerEl = contentEl.createEl('div', { text: 'Create Note' });
|
||||
headerEl.addClass('modal-title');
|
||||
|
||||
let inputCss = 'width: 100%; height: 2.5em;';
|
||||
|
||||
// Input El
|
||||
contentEl.createEl('p', { text: 'File Name:' });
|
||||
const fileNameInputEl = contentEl.createEl('input');
|
||||
fileNameInputEl.style.cssText = inputCss;
|
||||
const fileNameInputEl = contentEl.createEl('input', { cls: 'oz-calendar-modal-inputel' });
|
||||
|
||||
let defFileNamePref = this.plugin.settings.defaultFileNamePrefix;
|
||||
if (defFileNamePref !== '' && dayjs(new Date(), defFileNamePref, true).isValid()) {
|
||||
if (defFileNamePref !== '') {
|
||||
fileNameInputEl.value = dayjs(this.destinationDate).format(defFileNamePref) + ' ';
|
||||
}
|
||||
|
||||
|
|
@ -40,47 +37,64 @@ export class CreateNoteModal extends Modal {
|
|||
let folderInputEl: HTMLInputElement = null;
|
||||
if (this.plugin.settings.showDestinationFolderDuringCreate) {
|
||||
contentEl.createEl('p', { text: 'Destination Folder:' });
|
||||
folderInputEl = contentEl.createEl('input');
|
||||
folderInputEl = contentEl.createEl('input', { cls: 'oz-calendar-modal-inputel' });
|
||||
new FolderSuggest(folderInputEl);
|
||||
folderInputEl.value = this.plugin.settings.defaultFolder;
|
||||
folderInputEl.style.cssText = inputCss;
|
||||
}
|
||||
|
||||
// Additional Space
|
||||
let addSpace = contentEl.createEl('div');
|
||||
addSpace.style.cssText = 'height: 20px;';
|
||||
let addSpace = contentEl.createEl('div', { cls: 'oz-calendar-modal-addspacediv ' });
|
||||
|
||||
// Create - Cancel Buttons
|
||||
const createButton = contentEl.createEl('button', { text: 'Create Note' });
|
||||
const cancelButton = contentEl.createEl('button', { text: 'Cancel' });
|
||||
cancelButton.style.cssText = 'float: right;';
|
||||
const createButton = contentEl.createEl('button', {
|
||||
text: 'Create Note',
|
||||
cls: this.plugin.settings.newNoteCancelButtonReverse ? 'oz-calendar-modal-float-right' : '',
|
||||
});
|
||||
const cancelButton = contentEl.createEl('button', {
|
||||
text: 'Cancel',
|
||||
cls: this.plugin.settings.newNoteCancelButtonReverse ? '' : 'oz-calendar-modal-float-right',
|
||||
});
|
||||
cancelButton.addEventListener('click', () => {
|
||||
thisModal.close();
|
||||
});
|
||||
|
||||
const onClickCreateButton = async () => {
|
||||
let newFileName = fileNameInputEl.value;
|
||||
if (newFileName !== '') {
|
||||
let defFolderSrc = folderInputEl ? folderInputEl.value : this.plugin.settings.defaultFolder;
|
||||
let defFolder = this.app.vault.getAbstractFileByPath(defFolderSrc);
|
||||
if (defFolder && defFolder instanceof TFolder) {
|
||||
// Default Text Preparation for File with YAML and Date
|
||||
let defaultNewFileText = stripIndents`
|
||||
---
|
||||
${this.plugin.settings.yamlKey}: ${dayjs(this.destinationDate).format(
|
||||
this.plugin.settings.dateFormat
|
||||
)}
|
||||
---
|
||||
`;
|
||||
// Create the MD File and close the modal
|
||||
await createNewMarkdownFile(this.plugin, defFolder, newFileName, defaultNewFileText);
|
||||
thisModal.close();
|
||||
} else {
|
||||
new Notice('Folder couldnt be found in the Vault');
|
||||
}
|
||||
} else {
|
||||
|
||||
if (newFileName === '') {
|
||||
new Notice('You didnt provide file name');
|
||||
return;
|
||||
}
|
||||
|
||||
if (newFileName.includes('/') && !this.plugin.settings.allowSlashhDuringCreate) {
|
||||
new Notice('You can not have a slash (/) in file name');
|
||||
return;
|
||||
}
|
||||
|
||||
let defFolderSrc = folderInputEl ? folderInputEl.value : this.plugin.settings.defaultFolder;
|
||||
let defFolder = this.app.vault.getAbstractFileByPath(defFolderSrc);
|
||||
|
||||
if (!defFolder || !(defFolder instanceof TFolder)) {
|
||||
new Notice('Folder couldnt be found in the Vault');
|
||||
return;
|
||||
}
|
||||
|
||||
// Default Text Preparation for File with YAML and Date
|
||||
let defaultNewFileText = stripIndents`
|
||||
---
|
||||
${this.plugin.settings.yamlKey}: ${dayjs(this.destinationDate).format(this.plugin.settings.dateFormat)}
|
||||
---
|
||||
`;
|
||||
|
||||
// Create the MD File and close the modal
|
||||
await createNewMarkdownFile(
|
||||
this.plugin,
|
||||
defFolder as TFolder,
|
||||
newFileName,
|
||||
this.plugin.settings.dateSource === 'yaml' ? defaultNewFileText : ''
|
||||
);
|
||||
|
||||
thisModal.close();
|
||||
};
|
||||
|
||||
createButton.addEventListener('click', onClickCreateButton);
|
||||
|
|
|
|||
|
|
@ -2,28 +2,49 @@ import OZCalendarPlugin from 'main';
|
|||
import { PluginSettingTab, App, Setting } from 'obsidian';
|
||||
import { FolderSuggest } from 'settings/suggestor';
|
||||
|
||||
export type OpenFileBehaviourType = 'new-tab' | 'new-tab-group' | 'current-tab';
|
||||
export type OpenFileBehaviourType = 'new-tab' | 'new-tab-group' | 'current-tab' | 'obsidian-default';
|
||||
export type SortingOption = 'name' | 'name-rev';
|
||||
export type DateSourceOption = 'filename' | 'yaml';
|
||||
export type NewNoteDateType = 'current-date' | 'active-date';
|
||||
export type CalendarType = 'US' | 'ISO 8601';
|
||||
export type OverflowBehaviour = 'scroll' | 'hide' | 'next-line';
|
||||
|
||||
export interface OZCalendarPluginSettings {
|
||||
openViewOnStart: boolean;
|
||||
calendarType: CalendarType;
|
||||
dateSource: DateSourceOption;
|
||||
yamlKey: string;
|
||||
dateFormat: string;
|
||||
defaultFolder: string;
|
||||
defaultFileNamePrefix: string;
|
||||
fixedCalendar: boolean;
|
||||
showDestinationFolderDuringCreate: boolean;
|
||||
allowSlashhDuringCreate: boolean;
|
||||
openFileBehaviour: OpenFileBehaviourType;
|
||||
sortingOption: SortingOption;
|
||||
newNoteDate: NewNoteDateType;
|
||||
newNoteCancelButtonReverse: boolean;
|
||||
fileNameOverflowBehaviour: OverflowBehaviour;
|
||||
showWeekNumbers: boolean;
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: OZCalendarPluginSettings = {
|
||||
openViewOnStart: true,
|
||||
calendarType: 'ISO 8601',
|
||||
dateSource: 'yaml',
|
||||
yamlKey: 'created',
|
||||
dateFormat: 'YYYY-MM-DD hh:mm:ss',
|
||||
defaultFolder: '/',
|
||||
defaultFileNamePrefix: 'YYYY-MM-DD',
|
||||
fixedCalendar: true,
|
||||
showDestinationFolderDuringCreate: true,
|
||||
allowSlashhDuringCreate: false,
|
||||
openFileBehaviour: 'current-tab',
|
||||
sortingOption: 'name',
|
||||
newNoteDate: 'current-date',
|
||||
newNoteCancelButtonReverse: false,
|
||||
fileNameOverflowBehaviour: 'hide',
|
||||
showWeekNumbers: false,
|
||||
};
|
||||
|
||||
export class OZCalendarPluginSettingsTab extends PluginSettingTab {
|
||||
|
|
@ -76,11 +97,42 @@ export class OZCalendarPluginSettingsTab extends PluginSettingTab {
|
|||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Calendar Type')
|
||||
.setDesc(
|
||||
`
|
||||
Select the calendar type to be displayed. While the week in the US type starts from Sunday,
|
||||
in the ISO 8601 type, the week starts from Monday`
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('ISO 8601', 'ISO 8601')
|
||||
.addOption('US', 'US')
|
||||
.setValue(this.plugin.settings.calendarType)
|
||||
.onChange((newValue: CalendarType) => {
|
||||
this.plugin.settings.calendarType = newValue;
|
||||
this.plugin.saveSettings();
|
||||
this.plugin.calendarForceUpdate();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Show Week Numbers')
|
||||
.setDesc('Enable if you want to have week numbers within the calendar view')
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(this.plugin.settings.showWeekNumbers).onChange((newValue) => {
|
||||
this.plugin.settings.showWeekNumbers = newValue;
|
||||
this.plugin.saveSettings();
|
||||
this.plugin.calendarForceUpdate();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Open File Behaviour')
|
||||
.setDesc('Select the behaviour you want to have when you click on file name in the calendar view')
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('obsidian-default', "Obsidian's Default")
|
||||
.addOption('new-tab', 'Open in a New Tab')
|
||||
.addOption('new-tab-group', 'Open in a New Tab Group')
|
||||
.addOption('current-tab', 'Open in the Active Tab')
|
||||
|
|
@ -91,7 +143,22 @@ export class OZCalendarPluginSettingsTab extends PluginSettingTab {
|
|||
});
|
||||
});
|
||||
|
||||
containerEl.createEl('h2', { text: 'YAML and Date Format' });
|
||||
new Setting(containerEl)
|
||||
.setName('File List Sorting')
|
||||
.setDesc('Select the sorting behaviour in the file list')
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('name', 'File Name (A to Z)')
|
||||
.addOption('name-rev', 'File Name (Z to A)')
|
||||
.setValue(this.plugin.settings.sortingOption)
|
||||
.onChange((newValue: SortingOption) => {
|
||||
this.plugin.settings.sortingOption = newValue;
|
||||
this.plugin.saveSettings();
|
||||
this.plugin.calendarForceUpdate();
|
||||
});
|
||||
});
|
||||
|
||||
containerEl.createEl('h2', { text: 'YAML, File Name and Date Format Settings' });
|
||||
|
||||
containerEl.createEl('p', {
|
||||
text: `
|
||||
|
|
@ -102,6 +169,35 @@ export class OZCalendarPluginSettingsTab extends PluginSettingTab {
|
|||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Date Source')
|
||||
.setDesc(
|
||||
`Select the date source to be used in each folder. It can be either YAML Key or File Name.
|
||||
Depending on what you provide within the date format, it will try to parse the date source.`
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('filename', 'File Name')
|
||||
.addOption('yaml', 'YAML Key')
|
||||
.setValue(this.plugin.settings.dateSource)
|
||||
.onChange((newValue: DateSourceOption) => {
|
||||
this.plugin.settings.dateSource = newValue;
|
||||
this.plugin.saveSettings();
|
||||
this.plugin.OZCALENDARDAYS_STATE = this.plugin.getNotesWithDates();
|
||||
this.plugin.calendarForceUpdate();
|
||||
// If YAML selected, show the YAML key below, or hide if changed back to filename
|
||||
let yamlKeySettingEl = document.querySelector('.oz-calendar-setting-yaml-key-value');
|
||||
if (yamlKeySettingEl) {
|
||||
if (newValue === 'filename') {
|
||||
yamlKeySettingEl.addClass('oz-calendar-custom-hidden');
|
||||
} else {
|
||||
yamlKeySettingEl.removeClass('oz-calendar-custom-hidden');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let yamlKeySetting = new Setting(containerEl)
|
||||
.setClass('oz-calendar-setting-yaml-key-value')
|
||||
.setName('YAML Key')
|
||||
.setDesc('Set the YAML Key that should be used for displaying in the calendar')
|
||||
.addText((text) => {
|
||||
|
|
@ -111,9 +207,16 @@ export class OZCalendarPluginSettingsTab extends PluginSettingTab {
|
|||
});
|
||||
});
|
||||
|
||||
if (this.plugin.settings.dateSource === 'filename') yamlKeySetting.setClass('oz-calendar-custom-hidden');
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Date Format')
|
||||
.setDesc('Set the Date format you are using within the YAML key provided above')
|
||||
.setDesc(
|
||||
`Set the Date format you are using within the YAML key or File Name provided above.
|
||||
If you are using File Name, make sure that you dont have any special characters since Obsidian doesnt
|
||||
support special characters in the file name like colon. Reload the plugin using the following button
|
||||
in case you change this value`
|
||||
)
|
||||
.addText((text) => {
|
||||
text.setValue(this.plugin.settings.dateFormat).onChange((newValue) => {
|
||||
this.plugin.settings.dateFormat = newValue;
|
||||
|
|
@ -133,7 +236,35 @@ export class OZCalendarPluginSettingsTab extends PluginSettingTab {
|
|||
|
||||
containerEl.createEl('h2', { text: 'New Note Settings' });
|
||||
|
||||
new Setting(this.containerEl)
|
||||
containerEl.createEl('p', {
|
||||
text: `
|
||||
The plugin will add the YAML key and date to the newly created note using the date format provided above
|
||||
if Date Source is YAML. However, auto YAML key generation for the notes is going to be disabled if you use
|
||||
File Name as date source.
|
||||
`,
|
||||
cls: 'setting-item-description',
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('New Note Date')
|
||||
.setDesc(
|
||||
`
|
||||
Define the default behaviour for new note button if it should create under the active date or current date (today).
|
||||
This setting will drive the date for the YAML Key value and File Name.
|
||||
`
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('active-date', 'Active Date (Selected)')
|
||||
.addOption('current-date', 'Current Date (Today)')
|
||||
.setValue(this.plugin.settings.newNoteDate)
|
||||
.onChange((newValue: NewNoteDateType) => {
|
||||
this.plugin.settings.newNoteDate = newValue;
|
||||
this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Default Folder Location')
|
||||
.setDesc('Select the default folder, under which the new files should be saved when use plugin + icon')
|
||||
.addSearch((cb) => {
|
||||
|
|
@ -175,6 +306,35 @@ export class OZCalendarPluginSettingsTab extends PluginSettingTab {
|
|||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Allow to provide slash during the file creation')
|
||||
.setDesc(
|
||||
`
|
||||
Enable this option if you want to allow file creation modal to allow slash (/) in the filename, which will help creating a folder.
|
||||
i.e. if this option is enabled and you provide an input like Folder1/File1, this will create Folder1 and place File1 under it. If
|
||||
the folder exists, the file will be placed under the existing folder. This will respect the default folder location and create the
|
||||
new folder as a subfolder under the default one.
|
||||
`
|
||||
)
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(this.plugin.settings.allowSlashhDuringCreate).onChange((newValue) => {
|
||||
this.plugin.settings.allowSlashhDuringCreate = newValue;
|
||||
this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Reverse direction of Cancel and New Note Buttons')
|
||||
.setDesc(
|
||||
`Enable this setting to change the direction of Cancel and New Note buttons within the New Note Creation Modal`
|
||||
)
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(this.plugin.settings.newNoteCancelButtonReverse).onChange((newValue) => {
|
||||
this.plugin.settings.newNoteCancelButtonReverse = newValue;
|
||||
this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
containerEl.createEl('h2', { text: 'Style Settings' });
|
||||
|
||||
containerEl.createEl('p', {
|
||||
|
|
@ -196,5 +356,21 @@ export class OZCalendarPluginSettingsTab extends PluginSettingTab {
|
|||
this.plugin.calendarForceUpdate();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('File Names Overflow Behaviour')
|
||||
.setDesc('Change the default behaviour for file names when they dont fit to the view')
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('hide', 'Hide Overflow')
|
||||
.addOption('scroll', 'Scroll Overflow')
|
||||
.addOption('next-line', 'Show Overflow in the Next Line')
|
||||
.setValue(this.plugin.settings.fileNameOverflowBehaviour)
|
||||
.onChange((newValue: OverflowBehaviour) => {
|
||||
this.plugin.settings.fileNameOverflowBehaviour = newValue;
|
||||
this.plugin.saveSettings();
|
||||
this.plugin.calendarForceUpdate();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
28
src/types.ts
28
src/types.ts
|
|
@ -1,3 +1,29 @@
|
|||
import { TFile } from 'obsidian';
|
||||
|
||||
export type OZNote = {
|
||||
type: 'note';
|
||||
displayName: string;
|
||||
path: string;
|
||||
};
|
||||
|
||||
export type OZReminder = {
|
||||
type: 'task' | 'periodic';
|
||||
displayName: string;
|
||||
date: string;
|
||||
};
|
||||
|
||||
type OZItem = OZNote | OZReminder;
|
||||
|
||||
export interface OZCalendarDaysMap {
|
||||
[key: string]: string[];
|
||||
[key: string]: OZItem[];
|
||||
}
|
||||
|
||||
export type DayChangeCommandAction = 'next-day' | 'previous-day' | 'today';
|
||||
|
||||
export const fileToOZItem = (params: { note: TFile }): OZItem => {
|
||||
return {
|
||||
type: 'note',
|
||||
displayName: params.note.basename,
|
||||
path: params.note.path,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { ItemView, WorkspaceLeaf } from 'obsidian';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import OZCalendarPlugin from './main';
|
||||
import MyCalendar from './components/calendar';
|
||||
import { createRoot, Root } from 'react-dom/client';
|
||||
|
||||
export const VIEW_TYPE = 'oz-calendar';
|
||||
export const VIEW_DISPLAY_TEXT = 'OZ Calendar';
|
||||
|
|
@ -10,6 +10,7 @@ export const ICON = 'OZCAL_ICON';
|
|||
|
||||
export class OZCalendarView extends ItemView {
|
||||
plugin: OZCalendarPlugin;
|
||||
root: Root;
|
||||
|
||||
constructor(leaf: WorkspaceLeaf, plugin: OZCalendarPlugin) {
|
||||
super(leaf);
|
||||
|
|
@ -33,11 +34,12 @@ export class OZCalendarView extends ItemView {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
ReactDOM.unmountComponentAtNode(this.contentEl);
|
||||
if (this.root) this.root.unmount();
|
||||
}
|
||||
|
||||
async onOpen() {
|
||||
this.destroy();
|
||||
ReactDOM.render(<MyCalendar plugin={this.plugin} />, this.contentEl);
|
||||
this.root = createRoot(this.contentEl)
|
||||
this.root.render(<MyCalendar plugin={this.plugin} />);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
98
styles.css
98
styles.css
|
|
@ -14,7 +14,21 @@ settings:
|
|||
-
|
||||
id: oz-calendar-selected-daycolor
|
||||
title: Selected Day Text Color
|
||||
description: Set the color of selected day in the month view, defaulted to the interactive-accent
|
||||
description: Set the color of selected day in the month view, defaulted to text-normal
|
||||
type: variable-color
|
||||
format: hex
|
||||
default: '#'
|
||||
-
|
||||
id: oz-calendar-current-day-color
|
||||
title: Current Day (Today) Text Color
|
||||
description: Set the color of the current day in the month view
|
||||
type: variable-color
|
||||
format: hex
|
||||
default: '#'
|
||||
-
|
||||
id: oz-calendar-selected-day-background
|
||||
title: Selected Day Background Color
|
||||
description: Set the color of selected day background in the month view, defaulted to the interactive-accent
|
||||
type: variable-color
|
||||
format: hex
|
||||
default: '#'
|
||||
|
|
@ -25,13 +39,23 @@ settings:
|
|||
type: variable-color
|
||||
format: hex
|
||||
default: '#'
|
||||
-
|
||||
id: oz-calendar-weeknr-date-color
|
||||
title: Week Number Text Color
|
||||
description: Set the color of week numbers, defaulted to the interactive-accent
|
||||
type: variable-color
|
||||
format: hex
|
||||
default: '#'
|
||||
*/
|
||||
|
||||
.theme-light,
|
||||
.theme-dark {
|
||||
--oz-calendar-weekend-color: #f76a6a;
|
||||
--oz-calendar-selected-daycolor: var(----interactive-accent);
|
||||
--oz-calendar-header-date-color: var(----interactive-accent);
|
||||
--oz-calendar-selected-daycolor: var(--text-normal);
|
||||
--oz-calendar-selected-day-background: var(--interactive-accent);
|
||||
--oz-calendar-header-date-color: var(--interactive-accent);
|
||||
--oz-calendar-current-day-color: #74dd58;
|
||||
--oz-calendar-weeknr-date-color: var(--color-accent-2);
|
||||
}
|
||||
|
||||
.oz-cal-coffee-div,
|
||||
|
|
@ -48,10 +72,20 @@ settings:
|
|||
fill: var(--icon-color) !important;
|
||||
}
|
||||
|
||||
.oz-calendar-plugin-view {
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.oz-calendar-plugin-view .react-calendar__tile.react-calendar__month-view__days__day:hover {
|
||||
background: var(--background-secondary-alt);
|
||||
}
|
||||
|
||||
.oz-calendar-plugin-view .react-calendar__tile--active {
|
||||
background-color: var(--oz-calendar-selected-day-background) !important;
|
||||
}
|
||||
|
||||
.oz-calendar-plugin-view .react-calendar button:enabled:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -132,10 +166,10 @@ settings:
|
|||
}
|
||||
|
||||
.oz-calendar-notelist-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
vertical-align: middle;
|
||||
display: block;
|
||||
padding: 5px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.oz-calendar-nav-action-plus {
|
||||
|
|
@ -181,11 +215,6 @@ settings:
|
|||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.oz-calendar-notelist-container {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.oz-calendar-note-line {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
|
|
@ -217,6 +246,11 @@ settings:
|
|||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.oz-calendar-plugin-today abbr {
|
||||
color: var(--oz-calendar-current-day-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* START - Fixed Calendar Except Note List - Scroll */
|
||||
|
||||
.oz-calendar-plugin-view.fixed {
|
||||
|
|
@ -227,7 +261,7 @@ settings:
|
|||
}
|
||||
|
||||
.oz-calendar-plugin-view.fixed .react-calendar {
|
||||
height: 255px;
|
||||
height: 295px;
|
||||
}
|
||||
|
||||
.oz-calendar-plugin-view.fixed #oz-calendar-divider {
|
||||
|
|
@ -244,4 +278,44 @@ settings:
|
|||
vertical-align: top;
|
||||
}
|
||||
|
||||
.oz-calendar-plugin-view .react-calendar__month-view__weekNumbers {
|
||||
display: block !important;
|
||||
color: var(--oz-calendar-weeknr-date-color);
|
||||
flex-basis: auto !important;
|
||||
background-color: var(--background-modifier-cover);
|
||||
font-size: var(--nav-item-size);
|
||||
}
|
||||
|
||||
/* END - Fixed Calendar */
|
||||
|
||||
.oz-calendar-modal-inputel {
|
||||
width: 100%;
|
||||
height: 2.5em;
|
||||
}
|
||||
|
||||
.oz-calendar-modal-addspacediv {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.oz-calendar-modal-float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.oz-calendar-custom-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.oz-calendar-note-line {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.oz-calendar-overflow-scroll {
|
||||
overflow: scroll;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.oz-calendar-overflow-hide {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,36 @@
|
|||
{
|
||||
"0.3.4": "0.15.0",
|
||||
"0.3.3": "0.15.0",
|
||||
"0.3.2": "0.15.0",
|
||||
"0.3.1": "0.15.0",
|
||||
"0.3.0": "0.15.0",
|
||||
"0.2.9": "0.15.0",
|
||||
"0.2.8": "0.15.0",
|
||||
"0.2.7": "0.15.0",
|
||||
"0.2.6": "0.15.0",
|
||||
"0.2.5": "0.15.0",
|
||||
"0.2.4": "0.15.0",
|
||||
"0.2.3": "0.15.0",
|
||||
"0.2.2": "0.15.0",
|
||||
"0.2.1": "0.15.0",
|
||||
"0.2.0": "0.15.0",
|
||||
"0.1.9": "0.15.0",
|
||||
"0.1.8": "0.15.0",
|
||||
"0.1.7": "0.15.0",
|
||||
"0.1.6": "0.15.0",
|
||||
"0.1.5": "0.15.0",
|
||||
"0.1.4": "0.15.0",
|
||||
"0.1.3": "0.15.0",
|
||||
"0.1.2": "0.15.0",
|
||||
"0.1.1": "0.15.0",
|
||||
"0.1.0": "0.15.0",
|
||||
"0.0.9": "0.15.0",
|
||||
"0.0.8": "0.15.0",
|
||||
"0.0.7": "0.15.0",
|
||||
"0.0.6": "0.15.0",
|
||||
"0.0.5": "0.15.0",
|
||||
"0.0.4": "0.15.0",
|
||||
"0.0.3": "0.15.0",
|
||||
"0.0.2": "0.15.0",
|
||||
"0.0.1": "0.15.0",
|
||||
"0.0.0": "0.15.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue