joplin-plugin-my-calendar 1.2.7 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +17 -7
- package/dist/manifest.json +2 -2
- package/dist/ui/calendar.js +125 -13
- package/dist/ui/mycalendar.css +179 -69
- package/manifest.json +2 -2
- package/package.json +1 -1
- package/publish/com.volodymyroliinyk.joplin.plugin.my-calendar.jpl +0 -0
- package/publish/com.volodymyroliinyk.joplin.plugin.my-calendar.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.3.0](https://github.com/volodymyroliinyk/joplin-plugin-my-calendar/compare/v1.2.7...v1.3.0) (2026-02-04)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ✨ Features
|
|
9
|
+
|
|
10
|
+
* ui enhancements ([af04211](https://github.com/volodymyroliinyk/joplin-plugin-my-calendar/commit/af04211e1efcb8816ebd3decec7da11a74048118))
|
|
11
|
+
|
|
5
12
|
### [1.2.7](https://github.com/volodymyroliinyk/joplin-plugin-my-calendar/compare/v1.2.6...v1.2.7) (2026-02-02)
|
|
6
13
|
|
|
7
14
|
|
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ note-taking app.
|
|
|
18
18
|
## 🌟 Key Features
|
|
19
19
|
|
|
20
20
|
- **Monthly Calendar Grid**: Navigate through months, view event bars, and see your schedule at a glance.
|
|
21
|
+
- **Quick Month-Year Navigation**: Click the month/year header to open a picker and jump instantly to any date in the
|
|
22
|
+
past or future.
|
|
21
23
|
- **Smart Day View**: Click any day to see a detailed list of scheduled events.
|
|
22
24
|
- **Notes as Events**: Any note can become a calendar event simply by adding a small Markdown block.
|
|
23
25
|
- **ICS Import**: Import standard `*.ics` files (from Google Calendar, Outlook, Apple, etc.) directly into your Joplin
|
|
@@ -64,8 +66,8 @@ You don't need to import files to use the calendar. Simply add the following blo
|
|
|
64
66
|
~~~markdown
|
|
65
67
|
```mycalendar-event
|
|
66
68
|
title: Meeting with Team
|
|
67
|
-
start:
|
|
68
|
-
end:
|
|
69
|
+
start: 2026-02-04 10:00+02:00
|
|
70
|
+
end: 2026-02-04 11:30+02:00
|
|
69
71
|
color: #3498db
|
|
70
72
|
location: Conference Room B
|
|
71
73
|
```
|
|
@@ -128,14 +130,14 @@ The calendar supports several ways to specify the time and timezone of your even
|
|
|
128
130
|
Explicitly define the time and its relation to UTC. This time will be automatically converted to your current
|
|
129
131
|
device's timezone.
|
|
130
132
|
```text
|
|
131
|
-
start:
|
|
133
|
+
start: 2026-02-04 10:00+02:00
|
|
132
134
|
```
|
|
133
135
|
|
|
134
136
|
2. **With `tz` Property (IANA)**
|
|
135
137
|
Specify the time and the exact IANA Timezone name. The plugin will handle the conversion based on daylight saving
|
|
136
138
|
rules.
|
|
137
139
|
```text
|
|
138
|
-
start:
|
|
140
|
+
start: 2026-02-04 10:00
|
|
139
141
|
tz: America/Toronto
|
|
140
142
|
```
|
|
141
143
|
|
|
@@ -143,7 +145,7 @@ The calendar supports several ways to specify the time and timezone of your even
|
|
|
143
145
|
If no offset or `tz` is provided, the time is considered "floating" and will be shown exactly as written, regardless
|
|
144
146
|
of the device's timezone settings.
|
|
145
147
|
```text
|
|
146
|
-
start:
|
|
148
|
+
start: 2026-02-04 10:00
|
|
147
149
|
```
|
|
148
150
|
|
|
149
151
|
---
|
|
@@ -189,10 +191,10 @@ Customize your experience in the Joplin Settings (`Tools` > `Options` > `My Cale
|
|
|
189
191
|
|
|
190
192
|
## 👨💻 Development
|
|
191
193
|
|
|
192
|
-
### Commands
|
|
194
|
+
### Commands
|
|
193
195
|
|
|
194
196
|
- `npm run build;`: Compile the project.
|
|
195
|
-
- `npm
|
|
197
|
+
- `npm pack;`: Create the `.jpl` distribution file.
|
|
196
198
|
- `npm test;`: Run the extensive test suite (250+ cases).
|
|
197
199
|
- `npm run lint;`: Check code style and common patterns.
|
|
198
200
|
- `pkill -f jest || true;pkill -f node || true;rm -rf node_modules/.cache;rm -rf ~/.cache/jest;npx jest --clearCache;`:
|
|
@@ -218,6 +220,14 @@ Automates the entire release workflow: bumps version, syncs manifest, tags, push
|
|
|
218
220
|
bash ./scripts/release.sh [patch|minor|major];
|
|
219
221
|
```
|
|
220
222
|
|
|
223
|
+
#### `scripts/update-demo-ics.py`
|
|
224
|
+
|
|
225
|
+
Automatically shifts dates in the demo ICS file to start from today. Useful for refreshing screenshots.
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
./scripts/update-demo-ics.py;
|
|
229
|
+
```
|
|
230
|
+
|
|
221
231
|
### Development Workflow
|
|
222
232
|
|
|
223
233
|
For a detailed guide on branch naming, commit message formats, and the release process, please see the *
|
package/dist/manifest.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"manifest_version": 1,
|
|
3
3
|
"id": "com.volodymyroliinyk.joplin.plugin.my-calendar",
|
|
4
4
|
"app_min_version": "3.3",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.3.0",
|
|
6
6
|
"name": "My Calendar",
|
|
7
|
-
"description": "Calendar
|
|
7
|
+
"description": "Calendar plugin for Joplin",
|
|
8
8
|
"author": "Volodymyr Oliinyk",
|
|
9
9
|
"homepage_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
|
|
10
10
|
"repository_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
|
package/dist/ui/calendar.js
CHANGED
|
@@ -244,6 +244,9 @@
|
|
|
244
244
|
let current = startOfMonthLocal(new Date());
|
|
245
245
|
let selectedDayUtc = localMidnightTs(new Date());
|
|
246
246
|
|
|
247
|
+
let isPickerOpen = false;
|
|
248
|
+
let pickerYear = null;
|
|
249
|
+
|
|
247
250
|
// Events received for the current range of calendar grid (42 days)
|
|
248
251
|
let gridEvents = [];
|
|
249
252
|
|
|
@@ -272,9 +275,10 @@
|
|
|
272
275
|
// Ensure immediate behavior on settings toggle without requiring a full re-render.
|
|
273
276
|
if (hidden) {
|
|
274
277
|
ul.querySelectorAll('.mc-event-timeline').forEach((el) => el.remove());
|
|
278
|
+
ul.querySelectorAll('.mc-events-timeline-now-line-wrap').forEach((el) => el.remove());
|
|
275
279
|
}
|
|
276
280
|
}
|
|
277
|
-
|
|
281
|
+
|
|
278
282
|
function markPastDayEvents() {
|
|
279
283
|
const ul = document.getElementById('mc-events-list');
|
|
280
284
|
if (!ul) return;
|
|
@@ -357,15 +361,16 @@
|
|
|
357
361
|
const inDay = now >= dayStartUtc && now < (dayStartUtc + DAY);
|
|
358
362
|
const pct = Math.max(0, Math.min(100, ((now - dayStartUtc) / DAY) * 100));
|
|
359
363
|
|
|
360
|
-
ul.
|
|
361
|
-
|
|
364
|
+
const line = ul.querySelector('.mc-events-timeline-now-line');
|
|
365
|
+
if (line) {
|
|
366
|
+
const el = /** @type {HTMLElement} */ (line);
|
|
362
367
|
if (!inDay) {
|
|
363
368
|
el.style.display = 'none';
|
|
364
|
-
|
|
369
|
+
} else {
|
|
370
|
+
el.style.display = 'block';
|
|
371
|
+
el.style.left = pct + '%';
|
|
365
372
|
}
|
|
366
|
-
|
|
367
|
-
el.style.left = pct + '%';
|
|
368
|
-
});
|
|
373
|
+
}
|
|
369
374
|
}
|
|
370
375
|
|
|
371
376
|
function scheduleDayNowTimelineTick() {
|
|
@@ -629,6 +634,83 @@
|
|
|
629
634
|
return b;
|
|
630
635
|
}
|
|
631
636
|
|
|
637
|
+
function renderMonthYearPicker() {
|
|
638
|
+
const dropdown = document.createElement('div');
|
|
639
|
+
dropdown.className = 'mc-picker-dropdown';
|
|
640
|
+
dropdown.addEventListener('click', (e) => e.stopPropagation());
|
|
641
|
+
|
|
642
|
+
if (pickerYear === null) {
|
|
643
|
+
pickerYear = current.getFullYear();
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
const yearRow = document.createElement('div');
|
|
647
|
+
yearRow.className = 'mc-picker-year-row';
|
|
648
|
+
|
|
649
|
+
const btnPrevYear = button('‹', 'Previous year', () => {
|
|
650
|
+
pickerYear--;
|
|
651
|
+
renderToolbar();
|
|
652
|
+
});
|
|
653
|
+
const yearLabel = document.createElement('div');
|
|
654
|
+
yearLabel.className = 'mc-picker-year';
|
|
655
|
+
yearLabel.textContent = String(pickerYear);
|
|
656
|
+
const btnNextYear = button('›', 'Next year', () => {
|
|
657
|
+
pickerYear++;
|
|
658
|
+
renderToolbar();
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
yearRow.appendChild(btnPrevYear);
|
|
662
|
+
yearRow.appendChild(yearLabel);
|
|
663
|
+
yearRow.appendChild(btnNextYear);
|
|
664
|
+
dropdown.appendChild(yearRow);
|
|
665
|
+
|
|
666
|
+
const monthsGrid = document.createElement('div');
|
|
667
|
+
monthsGrid.className = 'mc-picker-months';
|
|
668
|
+
|
|
669
|
+
const monthNames = [];
|
|
670
|
+
for (let m = 0; m < 12; m++) {
|
|
671
|
+
const d = new Date(2000, m, 1);
|
|
672
|
+
monthNames.push(d.toLocaleString(undefined, {month: 'short'}));
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
monthNames.forEach((name, idx) => {
|
|
676
|
+
const mBtn = document.createElement('div');
|
|
677
|
+
mBtn.className = 'mc-picker-month';
|
|
678
|
+
if (idx === current.getMonth() && pickerYear === current.getFullYear()) {
|
|
679
|
+
mBtn.classList.add('mc-active');
|
|
680
|
+
}
|
|
681
|
+
mBtn.textContent = name;
|
|
682
|
+
mBtn.addEventListener('click', () => {
|
|
683
|
+
current = new Date(pickerYear, idx, 1);
|
|
684
|
+
isPickerOpen = false;
|
|
685
|
+
pickerYear = null;
|
|
686
|
+
drawMonth();
|
|
687
|
+
});
|
|
688
|
+
monthsGrid.appendChild(mBtn);
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
dropdown.appendChild(monthsGrid);
|
|
692
|
+
|
|
693
|
+
// const footer = document.createElement('div');
|
|
694
|
+
// footer.style.display = 'flex';
|
|
695
|
+
// footer.style.justifyContent = 'center';
|
|
696
|
+
// footer.style.marginTop = '8px';
|
|
697
|
+
// footer.style.paddingTop = '8px';
|
|
698
|
+
// footer.style.borderTop = '1px solid var(--joplin-divider-color)';
|
|
699
|
+
//
|
|
700
|
+
// const btnTodayPicker = button('Go to Today', 'Go to current month', () => {
|
|
701
|
+
// current = startOfMonthLocal(new Date());
|
|
702
|
+
// selectedDayUtc = localMidnightTs(new Date());
|
|
703
|
+
// isPickerOpen = false;
|
|
704
|
+
// pickerYear = null;
|
|
705
|
+
// drawMonth();
|
|
706
|
+
// });
|
|
707
|
+
// btnTodayPicker.style.width = '100%';
|
|
708
|
+
// footer.appendChild(btnTodayPicker);
|
|
709
|
+
// dropdown.appendChild(footer);
|
|
710
|
+
|
|
711
|
+
return dropdown;
|
|
712
|
+
}
|
|
713
|
+
|
|
632
714
|
function renderToolbar() {
|
|
633
715
|
const root = $toolbar();
|
|
634
716
|
if (!root) return;
|
|
@@ -637,15 +719,18 @@
|
|
|
637
719
|
wrap.className = 'mc-toolbar-inner';
|
|
638
720
|
|
|
639
721
|
const btnPrev = button('‹', 'Previous month', () => {
|
|
722
|
+
isPickerOpen = false;
|
|
640
723
|
current = addMonthsLocal(current, -1);
|
|
641
724
|
drawMonth();
|
|
642
725
|
});
|
|
643
726
|
const btnToday = button('Today', 'Today', () => {
|
|
727
|
+
isPickerOpen = false;
|
|
644
728
|
current = startOfMonthLocal(new Date());
|
|
645
729
|
selectedDayUtc = localMidnightTs(new Date());
|
|
646
730
|
drawMonth();
|
|
647
731
|
});
|
|
648
732
|
const btnNext = button('›', 'Next month', () => {
|
|
733
|
+
isPickerOpen = false;
|
|
649
734
|
current = addMonthsLocal(current, +1);
|
|
650
735
|
drawMonth();
|
|
651
736
|
});
|
|
@@ -653,15 +738,37 @@
|
|
|
653
738
|
// Month YYYY title.
|
|
654
739
|
const title = document.createElement('div');
|
|
655
740
|
title.className = 'mc-title';
|
|
656
|
-
title.
|
|
741
|
+
title.id = 'mc-picker-trigger';
|
|
742
|
+
title.innerHTML = `${monthLabel(current)} <span class="mc-picker-arrow">▾</span>`;
|
|
743
|
+
title.addEventListener('click', (e) => {
|
|
744
|
+
e.stopPropagation();
|
|
745
|
+
isPickerOpen = !isPickerOpen;
|
|
746
|
+
if (isPickerOpen) {
|
|
747
|
+
pickerYear = current.getFullYear();
|
|
748
|
+
}
|
|
749
|
+
renderToolbar();
|
|
750
|
+
});
|
|
657
751
|
|
|
658
752
|
wrap.appendChild(btnPrev);
|
|
659
753
|
wrap.appendChild(btnToday);
|
|
660
754
|
wrap.appendChild(btnNext);
|
|
661
755
|
wrap.appendChild(title);
|
|
756
|
+
|
|
757
|
+
if (isPickerOpen) {
|
|
758
|
+
const picker = renderMonthYearPicker();
|
|
759
|
+
title.appendChild(picker);
|
|
760
|
+
}
|
|
761
|
+
|
|
662
762
|
root.appendChild(wrap);
|
|
663
763
|
}
|
|
664
764
|
|
|
765
|
+
document.addEventListener('click', () => {
|
|
766
|
+
if (isPickerOpen) {
|
|
767
|
+
isPickerOpen = false;
|
|
768
|
+
renderToolbar();
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
|
|
665
772
|
function drawMonth() {
|
|
666
773
|
if (!uiSettings.weekStart) {
|
|
667
774
|
log('drawMonth skipped: weekStart not set');
|
|
@@ -932,6 +1039,15 @@
|
|
|
932
1039
|
return;
|
|
933
1040
|
}
|
|
934
1041
|
|
|
1042
|
+
if (uiSettings.showEventTimeline !== false) {
|
|
1043
|
+
const wrap = document.createElement('div');
|
|
1044
|
+
wrap.className = 'mc-events-timeline-now-line-wrap';
|
|
1045
|
+
const line = document.createElement('div');
|
|
1046
|
+
line.className = 'mc-events-timeline-now-line';
|
|
1047
|
+
wrap.appendChild(line);
|
|
1048
|
+
ul.appendChild(wrap);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
935
1051
|
for (const item of daySlices) {
|
|
936
1052
|
const ev = item.ev;
|
|
937
1053
|
const slice = item.slice;
|
|
@@ -955,7 +1071,7 @@
|
|
|
955
1071
|
li.appendChild(title);
|
|
956
1072
|
li.appendChild(t);
|
|
957
1073
|
|
|
958
|
-
// 24h timeline under the event (segment = event slice
|
|
1074
|
+
// 24h timeline under the event (segment = event slice)
|
|
959
1075
|
if (uiSettings.showEventTimeline !== false) {
|
|
960
1076
|
const timeline = document.createElement('div');
|
|
961
1077
|
timeline.className = 'mc-event-timeline';
|
|
@@ -972,11 +1088,7 @@
|
|
|
972
1088
|
seg.style.left = left + '%';
|
|
973
1089
|
seg.style.width = Math.max(0, (right - left)) + '%';
|
|
974
1090
|
|
|
975
|
-
const nowDot = document.createElement('div');
|
|
976
|
-
nowDot.className = 'mc-event-timeline-now';
|
|
977
|
-
|
|
978
1091
|
timeline.appendChild(seg);
|
|
979
|
-
timeline.appendChild(nowDot);
|
|
980
1092
|
li.appendChild(timeline);
|
|
981
1093
|
}
|
|
982
1094
|
|
package/dist/ui/mycalendar.css
CHANGED
|
@@ -1,35 +1,42 @@
|
|
|
1
1
|
/* src/ui/mycalendar.css */
|
|
2
2
|
|
|
3
|
-
html,
|
|
3
|
+
html,
|
|
4
|
+
body {
|
|
4
5
|
height: 100%;
|
|
5
6
|
margin: 0;
|
|
6
7
|
overflow: auto;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
/* TODO:[1]: parent --scrollbar-size is invisible inside of iframe, and size is 7px always. How to solve that? */
|
|
10
|
-
body::-webkit-scrollbar,
|
|
11
|
+
body::-webkit-scrollbar,
|
|
12
|
+
select::-webkit-scrollbar {
|
|
11
13
|
width: var(--scrollbar-size, 7px);
|
|
12
14
|
height: var(--scrollbar-size, 7px);
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
body::-webkit-scrollbar-corner,
|
|
17
|
+
body::-webkit-scrollbar-corner,
|
|
18
|
+
select::-webkit-scrollbar-corner {
|
|
16
19
|
background: none;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
body::-webkit-scrollbar-track,
|
|
22
|
+
body::-webkit-scrollbar-track,
|
|
23
|
+
select::-webkit-scrollbar-track {
|
|
20
24
|
border: none;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
body::-webkit-scrollbar-thumb,
|
|
27
|
+
body::-webkit-scrollbar-thumb,
|
|
28
|
+
select::-webkit-scrollbar-thumb {
|
|
24
29
|
background: var(--scrollbar-thumb-color);
|
|
25
30
|
border-radius: calc(var(--scrollbar-size, 7px) * 0.7);
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
body::-webkit-scrollbar-track:hover,
|
|
33
|
+
body::-webkit-scrollbar-track:hover,
|
|
34
|
+
select::-webkit-scrollbar-track:hover {
|
|
29
35
|
background: rgba(0, 0, 0, 0.1);
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
body::-webkit-scrollbar-thumb:hover,
|
|
38
|
+
body::-webkit-scrollbar-thumb:hover,
|
|
39
|
+
select::-webkit-scrollbar-thumb:hover {
|
|
33
40
|
background: var(--scrollbar-thumb-color-hover);
|
|
34
41
|
}
|
|
35
42
|
|
|
@@ -37,6 +44,7 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
37
44
|
--scrollbar-thumb-color: var(--joplin-scrollbar-thumb-color);
|
|
38
45
|
--scrollbar-thumb-color-hover: var(--joplin-scrollbar-thumb-color-hover);
|
|
39
46
|
--mc-default-event-color: #1470d9;
|
|
47
|
+
--mc-default-current-time-v-line-color: #ffa334;
|
|
40
48
|
--mc-past-opacity: 0.45;
|
|
41
49
|
/* Subtle weekend highlight (theme-aware) */
|
|
42
50
|
--mc-weekend-head-bg: color-mix(in srgb, var(--joplin-background-color3) 70%, transparent);
|
|
@@ -44,11 +52,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
44
52
|
|
|
45
53
|
}
|
|
46
54
|
|
|
47
|
-
/*#joplin-plugin-content-root {*/
|
|
48
|
-
/* min-width: 315px;*/
|
|
49
|
-
/*}*/
|
|
50
|
-
|
|
51
|
-
|
|
52
55
|
/* Outer container that will actually scroll */
|
|
53
56
|
#mc-cal-scroll {
|
|
54
57
|
height: 100%;
|
|
@@ -94,6 +97,102 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
94
97
|
flex: 1;
|
|
95
98
|
}
|
|
96
99
|
|
|
100
|
+
.mc-toolbar-inner .mc-title {
|
|
101
|
+
margin-left: 4px;
|
|
102
|
+
font-weight: 700;
|
|
103
|
+
flex: 1;
|
|
104
|
+
cursor: pointer;
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
gap: 4px;
|
|
108
|
+
padding: 4px 8px;
|
|
109
|
+
border-radius: 4px;
|
|
110
|
+
transition: background 0.1s;
|
|
111
|
+
user-select: none;
|
|
112
|
+
position: relative;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.mc-toolbar-inner .mc-title:hover {
|
|
116
|
+
background: var(--joplin-background-color3);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.mc-btn.mc-calendar-nav-btn:hover {
|
|
120
|
+
background: var(--joplin-background-color3);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.mc-picker-dropdown {
|
|
124
|
+
position: absolute;
|
|
125
|
+
top: calc(100% + 4px);
|
|
126
|
+
right: 0;
|
|
127
|
+
background: var(--joplin-background-color);
|
|
128
|
+
border: 1px solid var(--joplin-divider-color);
|
|
129
|
+
border-radius: 8px;
|
|
130
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
131
|
+
z-index: 1000;
|
|
132
|
+
padding: 8px;
|
|
133
|
+
min-width: 200px;
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-direction: column;
|
|
136
|
+
gap: 8px;
|
|
137
|
+
animation: mc-fade-in 0.15s ease-out;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@keyframes mc-fade-in {
|
|
141
|
+
from {
|
|
142
|
+
opacity: 0;
|
|
143
|
+
transform: translateY(-4px);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
to {
|
|
147
|
+
opacity: 1;
|
|
148
|
+
transform: translateY(0);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.mc-picker-year-row {
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
justify-content: space-between;
|
|
156
|
+
gap: 4px;
|
|
157
|
+
border-bottom: 1px solid var(--joplin-divider-color);
|
|
158
|
+
padding-bottom: 8px;
|
|
159
|
+
margin-bottom: 4px;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.mc-picker-year {
|
|
163
|
+
font-size: 14px;
|
|
164
|
+
font-weight: bold;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.mc-picker-months {
|
|
168
|
+
display: grid;
|
|
169
|
+
grid-template-columns: repeat(3, 1fr);
|
|
170
|
+
gap: 4px;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.mc-picker-month {
|
|
174
|
+
padding: 6px;
|
|
175
|
+
font-size: 12px;
|
|
176
|
+
text-align: center;
|
|
177
|
+
border-radius: 4px;
|
|
178
|
+
cursor: pointer;
|
|
179
|
+
transition: background 0.1s;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.mc-picker-month:hover {
|
|
183
|
+
background: var(--joplin-background-color3);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.mc-picker-month.mc-active {
|
|
187
|
+
background: var(--joplin-background-color3);
|
|
188
|
+
color: var(--joplin-color);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.mc-picker-arrow {
|
|
192
|
+
font-size: 10px;
|
|
193
|
+
opacity: 0.6;
|
|
194
|
+
}
|
|
195
|
+
|
|
97
196
|
#mc-grid {
|
|
98
197
|
border: 1px solid var(--joplin-divider-color);
|
|
99
198
|
border-radius: 8px;
|
|
@@ -105,7 +204,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
105
204
|
#mc-grid .mc-grid-loader {
|
|
106
205
|
position: absolute;
|
|
107
206
|
inset: 0;
|
|
108
|
-
display: none;
|
|
207
|
+
display: none;
|
|
208
|
+
/* shown via .mc-loading */
|
|
109
209
|
align-items: center;
|
|
110
210
|
justify-content: center;
|
|
111
211
|
background: color-mix(in srgb, var(--joplin-background-color) 70%, transparent);
|
|
@@ -142,7 +242,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
142
242
|
}
|
|
143
243
|
}
|
|
144
244
|
|
|
145
|
-
.mc-grid-head,
|
|
245
|
+
.mc-grid-head,
|
|
246
|
+
.mc-grid-body {
|
|
146
247
|
display: grid;
|
|
147
248
|
grid-template-columns: repeat(7, 1fr);
|
|
148
249
|
gap: 4px;
|
|
@@ -208,8 +309,20 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
208
309
|
.mc-grid-body .mc-cell {
|
|
209
310
|
min-width: 0;
|
|
210
311
|
padding: var(--mc-cell-pad-y) var(--mc-cell-pad-x);
|
|
312
|
+
border-right: 1px solid var(--joplin-divider-color);
|
|
313
|
+
border-top: 1px solid var(--joplin-divider-color);
|
|
314
|
+
overflow: hidden;
|
|
211
315
|
}
|
|
212
316
|
|
|
317
|
+
.mc-grid-body .mc-cell.mc-weekend {
|
|
318
|
+
background: var(--mc-weekend-cell-bg);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.mc-grid-body .mc-cell:nth-child(7n) {
|
|
322
|
+
border-right: none;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
213
326
|
/* Scale typography inside cells */
|
|
214
327
|
.mc-daynum {
|
|
215
328
|
font-size: var(--mc-daynum-font);
|
|
@@ -258,24 +371,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
258
371
|
|
|
259
372
|
/*****/
|
|
260
373
|
|
|
261
|
-
.mc-grid-body .mc-cell {
|
|
262
|
-
/*position: relative;*/
|
|
263
|
-
/*min-height: 50px;*/
|
|
264
|
-
border-right: 1px solid var(--joplin-divider-color);
|
|
265
|
-
border-top: 1px solid var(--joplin-divider-color);
|
|
266
|
-
padding: 4px 6px;
|
|
267
|
-
overflow: hidden;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/* Highlight weekends inside the current month only (keep .mc-out styling as-is) */
|
|
271
|
-
.mc-grid-body .mc-cell.mc-weekend:not(.mc-out) {
|
|
272
|
-
background: var(--mc-weekend-cell-bg);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
.mc-grid-body .mc-cell:nth-child(7n) {
|
|
276
|
-
border-right: none;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
374
|
.mc-daynum {
|
|
280
375
|
font-size: 12px;
|
|
281
376
|
opacity: 0.8;
|
|
@@ -297,7 +392,7 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
297
392
|
}
|
|
298
393
|
|
|
299
394
|
.mc-out {
|
|
300
|
-
|
|
395
|
+
opacity: 0.6;
|
|
301
396
|
}
|
|
302
397
|
|
|
303
398
|
.mc-today {
|
|
@@ -309,16 +404,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
309
404
|
box-shadow: inset 0 0 0 2px var(--joplin-color);
|
|
310
405
|
}
|
|
311
406
|
|
|
312
|
-
/* Past days in the month grid */
|
|
313
|
-
.mc-cell.mc-past {
|
|
314
|
-
opacity: var(--mc-past-opacity);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/* Keep selection slightly more readable even if the day is in the past */
|
|
318
|
-
.mc-cell.mc-past.mc-selected {
|
|
319
|
-
opacity: 0.7;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
407
|
.mc-events-header {
|
|
323
408
|
display: flex;
|
|
324
409
|
align-items: center;
|
|
@@ -332,13 +417,15 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
332
417
|
white-space: nowrap;
|
|
333
418
|
}
|
|
334
419
|
|
|
335
|
-
#mc-events,
|
|
420
|
+
#mc-events,
|
|
421
|
+
#mc-import {
|
|
336
422
|
border: 1px solid var(--joplin-divider-color);
|
|
337
423
|
border-radius: 8px;
|
|
338
424
|
overflow: hidden;
|
|
339
425
|
}
|
|
340
426
|
|
|
341
|
-
.mc-events-header,
|
|
427
|
+
.mc-events-header,
|
|
428
|
+
.mc-import-header {
|
|
342
429
|
background: var(--joplin-background-color3);
|
|
343
430
|
padding: 6px 10px;
|
|
344
431
|
font-size: 12px;
|
|
@@ -349,6 +436,7 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
349
436
|
list-style: none;
|
|
350
437
|
margin: 0;
|
|
351
438
|
padding: 8px 6px;
|
|
439
|
+
position: relative;
|
|
352
440
|
}
|
|
353
441
|
|
|
354
442
|
.mc-event {
|
|
@@ -358,6 +446,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
358
446
|
padding: 6px;
|
|
359
447
|
border-radius: 6px;
|
|
360
448
|
cursor: pointer;
|
|
449
|
+
position: relative;
|
|
450
|
+
z-index: 2;
|
|
361
451
|
}
|
|
362
452
|
|
|
363
453
|
.mc-event:hover {
|
|
@@ -384,7 +474,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
384
474
|
|
|
385
475
|
/* The container of strips in the cell */
|
|
386
476
|
.mc-bars {
|
|
387
|
-
/*position: absolute;*/
|
|
388
477
|
left: 4px;
|
|
389
478
|
right: 4px;
|
|
390
479
|
bottom: 6px;
|
|
@@ -404,17 +493,16 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
404
493
|
|
|
405
494
|
/* Badge-chiller is up to the right */
|
|
406
495
|
.mc-count {
|
|
407
|
-
/*position: absolute;*/
|
|
408
496
|
top: 2px;
|
|
409
497
|
right: 4px;
|
|
410
498
|
font-size: 14px;
|
|
411
499
|
font-weight: bold;
|
|
412
500
|
text-align: center;
|
|
413
501
|
line-height: 1;
|
|
414
|
-
padding:
|
|
415
|
-
border-radius:
|
|
502
|
+
padding: 3px 4px;
|
|
503
|
+
border-radius: 4px;
|
|
416
504
|
background: var(--joplin-background-color3);
|
|
417
|
-
border:
|
|
505
|
+
border: 0px solid var(--joplin-divider-color);
|
|
418
506
|
opacity: 0.85;
|
|
419
507
|
z-index: 3;
|
|
420
508
|
}
|
|
@@ -424,8 +512,10 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
424
512
|
}
|
|
425
513
|
|
|
426
514
|
.mc-calendar-nav-btn {
|
|
427
|
-
color: var(--joplin-color) !important;
|
|
428
|
-
|
|
515
|
+
color: var(--joplin-color) !important;
|
|
516
|
+
/* make the text white */
|
|
517
|
+
background: transparent;
|
|
518
|
+
/* The background is transparent */
|
|
429
519
|
border: none;
|
|
430
520
|
font-size: 12px;
|
|
431
521
|
font-weight: 700;
|
|
@@ -433,7 +523,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
433
523
|
}
|
|
434
524
|
|
|
435
525
|
.mc-calendar-nav-btn:hover {
|
|
436
|
-
color: var(--joplin-color) !important;
|
|
526
|
+
color: var(--joplin-color) !important;
|
|
527
|
+
/* lighter when creeping */
|
|
437
528
|
}
|
|
438
529
|
|
|
439
530
|
/* --- Events panel layout: list scroll + import at bottom --- */
|
|
@@ -450,7 +541,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
450
541
|
#mc-ics-import-form .mc-grid-loader {
|
|
451
542
|
position: absolute;
|
|
452
543
|
inset: 0;
|
|
453
|
-
display: none;
|
|
544
|
+
display: none;
|
|
545
|
+
/* shown via .mc-loading */
|
|
454
546
|
align-items: center;
|
|
455
547
|
justify-content: center;
|
|
456
548
|
background: color-mix(in srgb, var(--joplin-background-color) 70%, transparent);
|
|
@@ -489,8 +581,10 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
489
581
|
/* Container to be scrolled */
|
|
490
582
|
#mc-import-body {
|
|
491
583
|
margin: 0;
|
|
492
|
-
max-height: 260px;
|
|
493
|
-
|
|
584
|
+
max-height: 260px;
|
|
585
|
+
/* choose the height that suits you */
|
|
586
|
+
padding: 8px 6px;
|
|
587
|
+
/* so that the scroll does not "stick" to the content */
|
|
494
588
|
}
|
|
495
589
|
|
|
496
590
|
/* Very important for <input type="file"> in flex-line: otherwise it can inflate the width */
|
|
@@ -545,7 +639,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
545
639
|
position: relative;
|
|
546
640
|
flex: 0 0 100%;
|
|
547
641
|
height: 2px;
|
|
548
|
-
/*margin-top: 4px;*/
|
|
549
642
|
border-radius: 999px;
|
|
550
643
|
background: color-mix(in srgb, var(--joplin-color) 18%, transparent);
|
|
551
644
|
overflow: hidden;
|
|
@@ -560,16 +653,28 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
560
653
|
opacity: 0.9;
|
|
561
654
|
}
|
|
562
655
|
|
|
563
|
-
/*
|
|
564
|
-
.mc-
|
|
656
|
+
/* shared vertical line “now” */
|
|
657
|
+
.mc-events-timeline-now-line-wrap {
|
|
565
658
|
position: absolute;
|
|
566
|
-
top:
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
659
|
+
top: 0;
|
|
660
|
+
bottom: 0;
|
|
661
|
+
left: 12px;
|
|
662
|
+
/* 6px (ul padding) + 6px (li padding) */
|
|
663
|
+
right: 12px;
|
|
664
|
+
pointer-events: none;
|
|
665
|
+
z-index: 1;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.mc-events-timeline-now-line {
|
|
669
|
+
position: absolute;
|
|
670
|
+
top: 0;
|
|
671
|
+
bottom: 0;
|
|
672
|
+
width: 1px;
|
|
673
|
+
background: color-mix(in srgb, var(--mc-default-current-time-v-line-color) 40%, transparent);
|
|
674
|
+
box-shadow: 0 0 2px color-mix(in srgb, var(--mc-default-current-time-v-line-color) 20%, transparent);
|
|
675
|
+
z-index: 1;
|
|
676
|
+
display: none;
|
|
677
|
+
/* shown via JS when inDay */
|
|
573
678
|
}
|
|
574
679
|
|
|
575
680
|
/* slightly mute the timeline for past events */
|
|
@@ -689,7 +794,7 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
689
794
|
gap: 2px;
|
|
690
795
|
}
|
|
691
796
|
|
|
692
|
-
.mc-cell {
|
|
797
|
+
.mc-grid-body .mc-cell {
|
|
693
798
|
padding: 6px;
|
|
694
799
|
}
|
|
695
800
|
|
|
@@ -697,7 +802,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
697
802
|
font-size: 12px;
|
|
698
803
|
}
|
|
699
804
|
|
|
700
|
-
.mc-events-header,
|
|
805
|
+
.mc-events-header,
|
|
806
|
+
.mc-import-header {
|
|
701
807
|
font-weight: normal;
|
|
702
808
|
font-size: 12px;
|
|
703
809
|
}
|
|
@@ -721,4 +827,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
|
|
|
721
827
|
.mc-grid-head-cell.mc-weekend {
|
|
722
828
|
background: var(--mc-weekend-head-bg);
|
|
723
829
|
}
|
|
724
|
-
|
|
830
|
+
|
|
831
|
+
.mc-count {
|
|
832
|
+
padding: 2px 4px;
|
|
833
|
+
}
|
|
834
|
+
}
|
package/manifest.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"manifest_version": 1,
|
|
3
3
|
"id": "com.volodymyroliinyk.joplin.plugin.my-calendar",
|
|
4
4
|
"app_min_version": "3.3",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.3.0",
|
|
6
6
|
"name": "My Calendar",
|
|
7
|
-
"description": "Calendar
|
|
7
|
+
"description": "Calendar plugin for Joplin",
|
|
8
8
|
"author": "Volodymyr Oliinyk",
|
|
9
9
|
"homepage_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
|
|
10
10
|
"repository_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"manifest_version": 1,
|
|
3
3
|
"id": "com.volodymyroliinyk.joplin.plugin.my-calendar",
|
|
4
4
|
"app_min_version": "3.3",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.3.0",
|
|
6
6
|
"name": "My Calendar",
|
|
7
|
-
"description": "Calendar
|
|
7
|
+
"description": "Calendar plugin for Joplin",
|
|
8
8
|
"author": "Volodymyr Oliinyk",
|
|
9
9
|
"homepage_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
|
|
10
10
|
"repository_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
|