@react-x11/components 0.6.0 → 0.7.1

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.
Files changed (48) hide show
  1. package/README.md +49 -39
  2. package/dist/formula/node.d.ts.map +1 -1
  3. package/dist/formula/node.js +17 -6
  4. package/dist/formula/node.js.map +1 -1
  5. package/dist/html/dom.d.ts +8 -1
  6. package/dist/html/dom.d.ts.map +1 -1
  7. package/dist/html/dom.js +17 -2
  8. package/dist/html/dom.js.map +1 -1
  9. package/dist/html/index.d.ts +4 -0
  10. package/dist/html/index.d.ts.map +1 -1
  11. package/dist/html/index.js.map +1 -1
  12. package/dist/index.d.ts +0 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +0 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/richtext/node.d.ts.map +1 -1
  17. package/dist/richtext/node.js +7 -2
  18. package/dist/richtext/node.js.map +1 -1
  19. package/dist/table/index.d.ts +15 -0
  20. package/dist/table/index.d.ts.map +1 -1
  21. package/dist/table/index.js +95 -11
  22. package/dist/table/index.js.map +1 -1
  23. package/dist/tree/index.d.ts.map +1 -1
  24. package/dist/tree/index.js +77 -2
  25. package/dist/tree/index.js.map +1 -1
  26. package/package.json +3 -8
  27. package/src/formula/node.ts +22 -34
  28. package/src/html/dom.ts +17 -2
  29. package/src/html/index.ts +4 -0
  30. package/src/index.ts +0 -18
  31. package/src/richtext/node.ts +7 -2
  32. package/src/table/index.ts +114 -10
  33. package/src/tree/index.ts +77 -2
  34. package/dist/desktop-calendar/eds.d.ts +0 -102
  35. package/dist/desktop-calendar/eds.d.ts.map +0 -1
  36. package/dist/desktop-calendar/eds.js +0 -356
  37. package/dist/desktop-calendar/eds.js.map +0 -1
  38. package/dist/desktop-calendar/ical.d.ts +0 -63
  39. package/dist/desktop-calendar/ical.d.ts.map +0 -1
  40. package/dist/desktop-calendar/ical.js +0 -57
  41. package/dist/desktop-calendar/ical.js.map +0 -1
  42. package/dist/desktop-calendar/index.d.ts +0 -72
  43. package/dist/desktop-calendar/index.d.ts.map +0 -1
  44. package/dist/desktop-calendar/index.js +0 -213
  45. package/dist/desktop-calendar/index.js.map +0 -1
  46. package/src/desktop-calendar/eds.ts +0 -484
  47. package/src/desktop-calendar/ical.ts +0 -119
  48. package/src/desktop-calendar/index.ts +0 -287
package/src/tree/index.ts CHANGED
@@ -127,6 +127,22 @@ const TWISTY = 12;
127
127
  * is half of that, so `size` for one reads as its width. */
128
128
  const TWISTY_GLYPH = 10;
129
129
  const ROW_HEIGHT = 22;
130
+ /**
131
+ * How far a row's wash sits inside the tree's own edge.
132
+ *
133
+ * It is what makes a selection read as a **pill on** the list rather than a
134
+ * band across it. With no inset the wash runs into whatever the tree is
135
+ * mounted against — in a sidebar that is the pane's hairline — and the
136
+ * selected row reads as a stripe cut across the pane instead of a mark on a
137
+ * row. Core's `Menu` insets its rows from the sheet for exactly this reason,
138
+ * and `MENU_PAD` is this number.
139
+ *
140
+ * Horizontal only. Rows stack flush against each other: in a menu it is the
141
+ * sheet's own padding that clears the first and the last, and here it is
142
+ * whatever the app put the tree in. A vertical margin would not reshape the
143
+ * wash, it would spread the list out.
144
+ */
145
+ const ROW_INSET = 4;
130
146
  /**
131
147
  * Where `virtual="auto"` starts virtualizing.
132
148
  *
@@ -144,6 +160,13 @@ const s = createStyles({
144
160
  flexDirection: 'row',
145
161
  alignItems: 'center',
146
162
  gap: 4,
163
+ // The wash's inset — see `ROW_INSET`. It lives here rather than beside
164
+ // the colours so that the skeleton row wears the same shape, and so that
165
+ // an app can take it back off: `styles.row` merges last, and
166
+ // `{ marginStart: 0, marginEnd: 0, borderRadius: 0 }` is the full-bleed
167
+ // band this used to be.
168
+ marginStart: ROW_INSET,
169
+ marginEnd: ROW_INSET,
147
170
  paddingEnd: 8,
148
171
  paddingTop: 3,
149
172
  paddingBottom: 3,
@@ -667,10 +690,45 @@ function TreeRowView<T>(props: TreeRowViewProps<T>): ReactElement {
667
690
  // index reads back what it actually became.
668
691
  { minHeight: rowHeight },
669
692
  // The indent is what says "inside", so it is measured from the edge
670
- // the row's label begins at.
693
+ // the row's label begins at — which is the *wash's* edge now, not
694
+ // the tree's, and `ROW_INSET` is deliberately not subtracted back
695
+ // out here. Both readings move something: subtract it and the label
696
+ // stays where it was but ends up flush against the pill it sits in,
697
+ // which is what a pill with no padding looks like; leave it and the
698
+ // whole tree steps over by four pixels once, which nothing inside it
699
+ // can tell apart from a container four pixels narrower. So the
700
+ // padding is the pill's own clearance and the tree takes the shift.
701
+ // The guides are measured from the same edge and move with it, so a
702
+ // branch edge still meets the start of the row it belongs to.
671
703
  { paddingStart: renderGuide ? 4 : 4 + row.depth * indent },
672
704
  {
673
705
  backgroundColor: isSelected ? theme.hoverBackground : 'transparent',
706
+ // Rounded on the *window's* scale, not a popup's.
707
+ //
708
+ // `rowRadius` — what core's `Menu` and `Select` use — derives a
709
+ // row's radius from `radiusPopup`, less the sheet's border and
710
+ // padding, so that the pill's corner and the sheet's share a
711
+ // centre. That derivation needs an outer curve to be concentric
712
+ // with, and a tree has none: it fills whatever the app mounted it
713
+ // in — a sidebar, a split pane, a dialog — and cannot know that
714
+ // container's radius, or whether it has one. `radiusPopup` is the
715
+ // wrong parent by its own definition anyway ("a floating surface …
716
+ // half the text size"): a tree is content in the window, not a
717
+ // sheet laid over it.
718
+ //
719
+ // That leaves the two in-window tokens, and the row takes the
720
+ // tighter of them. `radius` is the control scale — a button, an
721
+ // input, a card cut into the surface — and this is not a control
722
+ // but a mark *on* the surface: transient, borderless, following
723
+ // the pointer. `radiusSmall` is that step down — the same relation
724
+ // `radiusPopupItem` has to `radiusPopup`, one scale in.
725
+ //
726
+ // An app that does own the sheet can still have the concentric
727
+ // version, because it is the one that knows the radius to be
728
+ // concentric with — `styles={{ row: { borderRadius:
729
+ // rowRadius(theme, border, inset) } }}`, with the inset it also
730
+ // sets here.
731
+ borderRadius: theme.radiusSmall,
674
732
  // The row's ink, said once: `color` inherits, so the label takes
675
733
  // it without being handed it.
676
734
  color,
@@ -684,9 +742,23 @@ function TreeRowView<T>(props: TreeRowViewProps<T>): ReactElement {
684
742
  // The selection only moves on the release, and `:active` marks
685
743
  // the whole press chain, so a press on the label or the twisty
686
744
  // still darkens the row it is in.
745
+ //
746
+ // The pressed colour comes from the ramp the row is already
747
+ // painted with. An unselected row is on the surface ramp, so it is
748
+ // `surfaceActive`. A selected row is washed with `hoverBackground`,
749
+ // and `accentActive` — what this used to say — is the pressed step
750
+ // of `accent`: a different token that merely *holds* the same
751
+ // colour in both stock palettes. Move the accent and the press
752
+ // flashes something the tree never wears at rest; a yellow accent
753
+ // over a blue selection gives a yellow press, and the row's ink is
754
+ // still `hoverText`, picked to be legible on the blue. There is no
755
+ // darker step of `hoverBackground` in the palette to reach for and
756
+ // the selected row is already the strongest fill in the list, so
757
+ // it keeps its wash: the click is answered by what it does, the
758
+ // selection or the activation on the second one.
687
759
  ':active': {
688
760
  backgroundColor: isSelected
689
- ? theme.accentActive
761
+ ? theme.hoverBackground
690
762
  : theme.surfaceActive,
691
763
  },
692
764
  },
@@ -1319,6 +1391,9 @@ export function Tree<T = TreeItem>({
1319
1391
  { height: index.heightAt(row.index) },
1320
1392
  {
1321
1393
  backgroundColor: isSelected ? theme.hoverBackground : 'transparent',
1394
+ // Same pill as a real row's, so a placeholder that is replaced
1395
+ // mid-scroll does not change shape as it arrives.
1396
+ borderRadius: theme.radiusSmall,
1322
1397
  },
1323
1398
  typeof rowStyleProp === 'function'
1324
1399
  ? rowStyleProp(state)
@@ -1,102 +0,0 @@
1
- import type { MessageBus } from 'react-x11';
2
- /** One calendar the desktop knows about. */
3
- export interface DesktopCalendarInfo {
4
- uid: string;
5
- /** The name shown in the desktop's own calendar UI. */
6
- name: string;
7
- enabled: boolean;
8
- /** The colour that UI draws it in — worth carrying into a day marker. */
9
- color?: string;
10
- /** `caldav`, `google`, `local`, `webcal`… */
11
- backend?: string;
12
- readOnly: boolean;
13
- /** Set when the calendar came from an Online Accounts login. */
14
- account?: string;
15
- }
16
- /** One occurrence, already expanded out of any recurrence rule. */
17
- export interface DesktopEvent {
18
- uid: string;
19
- summary: string;
20
- location?: string;
21
- description?: string;
22
- start: Date;
23
- end: Date;
24
- allDay: boolean;
25
- recurring: boolean;
26
- calendar: {
27
- uid: string;
28
- name: string;
29
- color?: string;
30
- };
31
- }
32
- /** A calendar that would not answer. One broken backend is not a failure. */
33
- export interface DesktopCalendarError {
34
- calendar: DesktopCalendarInfo;
35
- message: string;
36
- }
37
- export interface EventsResult {
38
- events: DesktopEvent[];
39
- errors: DesktopCalendarError[];
40
- }
41
- /** What `watch` reports. Deliberately thin: re-query rather than patch. */
42
- export interface CalendarChange {
43
- calendar: DesktopCalendarInfo;
44
- kind: 'ObjectsAdded' | 'ObjectsModified' | 'ObjectsRemoved';
45
- count: number;
46
- }
47
- /**
48
- * A source's whole configuration is an ini-style keyfile carried in one D-Bus
49
- * property, so it has to be parsed to find out whether a source is even a
50
- * calendar (as opposed to an address book, a mail account or a task list).
51
- */
52
- export declare function parseKeyFile(text: string): Record<string, Record<string, string>>;
53
- /**
54
- * The desktop's calendars, read over a bus someone else owns.
55
- *
56
- * ```ts
57
- * const ref = await sessionBus();
58
- * if (!ref) return; // no bus here; no calendars
59
- * const desktop = new DesktopCalendar(ref.bus);
60
- * const { events } = await desktop.eventsBetween(from, to);
61
- * ```
62
- *
63
- * Nothing here closes the connection, because nothing here opened it. Call
64
- * `dispose()` to drop the views this instance started, then release your own
65
- * reference to the bus.
66
- */
67
- export declare class DesktopCalendar {
68
- #private;
69
- constructor(bus: MessageBus);
70
- /** Every calendar the desktop knows about, colour included. */
71
- listCalendars(): Promise<DesktopCalendarInfo[]>;
72
- /**
73
- * Expanded occurrences between two `Date`s, across the calendars given (or
74
- * every enabled one). Sorted by start.
75
- *
76
- * A backend that is offline or broken contributes an entry in `errors`
77
- * rather than throwing: one unreachable CalDAV server must not blank a
78
- * whole month of the user's own local calendar.
79
- */
80
- eventsBetween(from: Date, to: Date, options?: {
81
- calendars?: DesktopCalendarInfo[];
82
- }): Promise<EventsResult>;
83
- /**
84
- * Live updates: `onChange` fires whenever anything in the range moves, so
85
- * the caller can re-query. Returns an unsubscribe function.
86
- *
87
- * Deliberately a "something changed" signal rather than a patch — a
88
- * recurrence master edited three months away can change what today looks
89
- * like, and re-running the query is both simpler and correct.
90
- *
91
- * **Changes only.** What is in the range already is what `eventsBetween`
92
- * answered; `onChange` fires for what happens after that. See
93
- * {@link VIEW_FLAGS_NONE} for the loop that reporting the initial contents
94
- * as a change costs a caller who re-queries on one.
95
- */
96
- watch(from: Date, to: Date, onChange: (change: CalendarChange) => void, options?: {
97
- calendars?: DesktopCalendarInfo[];
98
- }): Promise<() => Promise<void>>;
99
- /** Stop every view this instance started. Does **not** touch the bus. */
100
- dispose(): Promise<void>;
101
- }
102
- //# sourceMappingURL=eds.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eds.d.ts","sourceRoot":"","sources":["../../src/desktop-calendar/eds.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AA2B5C,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,IAAI,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;IACV,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAED,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAED,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,IAAI,EAAE,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAC5D,KAAK,EAAE,MAAM,CAAC;CACf;AAiBD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmBxC;AAkBD;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAe;;IAM1B,YAAY,GAAG,EAAE,UAAU,EAE1B;IAED,+DAA+D;IACzD,aAAa,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA6BpD;IAoDD;;;;;;;OAOG;IACG,aAAa,CACjB,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,IAAI,EACR,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAA;KAAO,GAClD,OAAO,CAAC,YAAY,CAAC,CAoCvB;IAgFD;;;;;;;;;;;;OAYG;IACG,KAAK,CACT,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,IAAI,EACR,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,EAC1C,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAA;KAAO,GAClD,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAgE9B;IAED,yEAAyE;IACnE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAY7B;CACF"}
@@ -1,356 +0,0 @@
1
- import { loadIcal } from './ical.js';
2
- const SOURCES_NAME = 'org.gnome.evolution.dataserver.Sources5';
3
- const SOURCES_PATH = '/org/gnome/evolution/dataserver/SourceManager';
4
- const OBJECT_MANAGER = 'org.freedesktop.DBus.ObjectManager';
5
- const FACTORY_NAME = 'org.gnome.evolution.dataserver.Calendar8';
6
- const FACTORY_PATH = '/org/gnome/evolution/dataserver/CalendarFactory';
7
- const FACTORY_IFACE = 'org.gnome.evolution.dataserver.CalendarFactory';
8
- const CAL_IFACE = 'org.gnome.evolution.dataserver.Calendar';
9
- const VIEW_IFACE = 'org.gnome.evolution.dataserver.CalendarView';
10
- /**
11
- * `E_CAL_CLIENT_VIEW_FLAGS_NONE`. A view is created with
12
- * `NOTIFY_INITIAL` instead, which makes `Start()` replay everything already
13
- * matching the query as `ObjectsAdded` — the current contents, announced as
14
- * if they had just changed.
15
- *
16
- * That is the wrong signal for a watcher whose answer to a change is to run
17
- * the query again: the re-query tears the view down, starts a new one, and is
18
- * told the same thing again, for as long as the app is open. Flags of NONE is
19
- * the whole of "only tell me what changes from here".
20
- */
21
- const VIEW_FLAGS_NONE = 0;
22
- const pad = (n) => String(n).padStart(2, '0');
23
- /** `20260807T113000Z` — what the S-expression query wants. */
24
- function icalStamp(d) {
25
- return (`${d.getUTCFullYear()}${pad(d.getUTCMonth() + 1)}${pad(d.getUTCDate())}T` +
26
- `${pad(d.getUTCHours())}${pad(d.getUTCMinutes())}${pad(d.getUTCSeconds())}Z`);
27
- }
28
- /** The query EDS understands for "anything happening between these two". */
29
- function rangeQuery(from, to) {
30
- return `(occur-in-time-range? (make-time "${icalStamp(from)}") (make-time "${icalStamp(to)}"))`;
31
- }
32
- /**
33
- * A source's whole configuration is an ini-style keyfile carried in one D-Bus
34
- * property, so it has to be parsed to find out whether a source is even a
35
- * calendar (as opposed to an address book, a mail account or a task list).
36
- */
37
- export function parseKeyFile(text) {
38
- const out = {};
39
- let section = null;
40
- for (const raw of text.split('\n')) {
41
- const line = raw.trim();
42
- if (!line || line.startsWith('#'))
43
- continue;
44
- if (line.startsWith('[') && line.endsWith(']')) {
45
- section = line.slice(1, -1);
46
- out[section] = out[section] ?? {};
47
- continue;
48
- }
49
- if (!section)
50
- continue;
51
- const eq = line.indexOf('=');
52
- if (eq === -1)
53
- continue;
54
- const key = line.slice(0, eq).trim();
55
- if (key.includes('['))
56
- continue; // a DisplayName[ru] translation
57
- out[section][key] = line.slice(eq + 1).trim();
58
- }
59
- return out;
60
- }
61
- /**
62
- * The desktop's calendars, read over a bus someone else owns.
63
- *
64
- * ```ts
65
- * const ref = await sessionBus();
66
- * if (!ref) return; // no bus here; no calendars
67
- * const desktop = new DesktopCalendar(ref.bus);
68
- * const { events } = await desktop.eventsBetween(from, to);
69
- * ```
70
- *
71
- * Nothing here closes the connection, because nothing here opened it. Call
72
- * `dispose()` to drop the views this instance started, then release your own
73
- * reference to the bus.
74
- */
75
- export class DesktopCalendar {
76
- #bus;
77
- #open = new Map();
78
- #views = [];
79
- #timezones = new Set();
80
- constructor(bus) {
81
- this.#bus = bus;
82
- }
83
- /** Every calendar the desktop knows about, colour included. */
84
- async listCalendars() {
85
- const om = (await this.#bus
86
- .getService(SOURCES_NAME)
87
- .getInterface(SOURCES_PATH, OBJECT_MANAGER));
88
- const managed = await om.GetManagedObjects();
89
- const calendars = [];
90
- for (const interfaces of Object.values(managed)) {
91
- const src = interfaces['org.gnome.evolution.dataserver.Source'];
92
- if (!src)
93
- continue;
94
- const cfg = parseKeyFile(String(src.Data ?? ''));
95
- // no [Calendar] section means an address book, a task list or mail
96
- if (!cfg.Calendar)
97
- continue;
98
- const ds = cfg['Data Source'] ?? {};
99
- calendars.push({
100
- uid: String(src.UID ?? ''),
101
- name: ds.DisplayName ?? '',
102
- enabled: ds.Enabled !== 'false',
103
- color: cfg.Calendar.Color,
104
- backend: cfg.Calendar.BackendName,
105
- readOnly: !interfaces['org.gnome.evolution.dataserver.Source.Writable'],
106
- account: cfg['GNOME Online Accounts']?.Account,
107
- });
108
- }
109
- return calendars;
110
- }
111
- async #openCalendar(uid) {
112
- const existing = this.#open.get(uid);
113
- if (existing)
114
- return existing;
115
- const factory = (await this.#bus
116
- .getService(FACTORY_NAME)
117
- .getInterface(FACTORY_PATH, FACTORY_IFACE));
118
- const [path, busName] = await factory.OpenCalendar(uid);
119
- const cal = (await this.#bus
120
- .getService(busName)
121
- .getInterface(path, CAL_IFACE));
122
- await cal.Open();
123
- const entry = { cal, busName };
124
- this.#open.set(uid, entry);
125
- return entry;
126
- }
127
- /**
128
- * Events reference timezones by id, but the payload rarely carries the
129
- * matching VTIMEZONE — so definitions are fetched on demand and registered
130
- * with ical.js. A backend that has none leaves the time floating, which is
131
- * ical.js's own fallback and better than refusing the event.
132
- */
133
- async #ensureTimezone(ICAL, cal, tzid) {
134
- if (!tzid || this.#timezones.has(tzid) || ICAL.TimezoneService.has(tzid)) {
135
- return;
136
- }
137
- this.#timezones.add(tzid);
138
- try {
139
- const vtz = await cal.GetTimezone(tzid);
140
- const comp = new ICAL.Component(ICAL.parse(vtz));
141
- const sub = comp.name === 'vtimezone'
142
- ? comp
143
- : comp.getFirstSubcomponent('vtimezone');
144
- if (sub)
145
- ICAL.TimezoneService.register(tzid, new ICAL.Timezone(sub));
146
- }
147
- catch {
148
- /* no definition for it; ical.js falls back to floating time */
149
- }
150
- }
151
- /**
152
- * Expanded occurrences between two `Date`s, across the calendars given (or
153
- * every enabled one). Sorted by start.
154
- *
155
- * A backend that is offline or broken contributes an entry in `errors`
156
- * rather than throwing: one unreachable CalDAV server must not blank a
157
- * whole month of the user's own local calendar.
158
- */
159
- async eventsBetween(from, to, options = {}) {
160
- const ICAL = await loadIcal();
161
- const list = options.calendars ??
162
- (await this.listCalendars()).filter((c) => c.enabled);
163
- const query = rangeQuery(from, to);
164
- const perCalendar = await Promise.all(list.map(async (meta) => {
165
- try {
166
- const { cal } = await this.#openCalendar(meta.uid);
167
- const objects = await cal.GetObjectList(query);
168
- return {
169
- events: await this.#expand(ICAL, cal, objects, from, to, meta),
170
- error: null,
171
- };
172
- }
173
- catch (err) {
174
- return {
175
- events: [],
176
- error: {
177
- calendar: meta,
178
- message: err instanceof Error ? err.message : String(err),
179
- },
180
- };
181
- }
182
- }));
183
- const events = [];
184
- const errors = [];
185
- for (const chunk of perCalendar) {
186
- events.push(...chunk.events);
187
- if (chunk.error)
188
- errors.push(chunk.error);
189
- }
190
- events.sort((a, b) => a.start.getTime() - b.start.getTime());
191
- return { events, errors };
192
- }
193
- async #expand(ICAL, cal, objects, from, to, meta) {
194
- const out = [];
195
- for (const ics of objects) {
196
- let comp;
197
- try {
198
- comp = new ICAL.Component(ICAL.parse(ics));
199
- }
200
- catch {
201
- continue; // one unparseable object is not the range's problem
202
- }
203
- // Register any VTIMEZONE shipped inline, then any referenced by id.
204
- for (const vtz of comp.getAllSubcomponents('vtimezone')) {
205
- const tz = new ICAL.Timezone(vtz);
206
- if (!ICAL.TimezoneService.has(tz.tzid)) {
207
- ICAL.TimezoneService.register(tz.tzid, tz);
208
- }
209
- }
210
- const vevents = comp.name === 'vevent' ? [comp] : comp.getAllSubcomponents('vevent');
211
- for (const ve of vevents) {
212
- for (const prop of ['dtstart', 'dtend']) {
213
- const p = ve.getFirstProperty(prop);
214
- if (p)
215
- await this.#ensureTimezone(ICAL, cal, p.getParameter('tzid'));
216
- }
217
- const event = new ICAL.Event(ve);
218
- // folded in by the recurrence iterator below
219
- if (event.isRecurrenceException())
220
- continue;
221
- const push = (startTime, endTime) => {
222
- const start = startTime.toJSDate();
223
- const end = endTime ? endTime.toJSDate() : start;
224
- if (end < from || start >= to)
225
- return;
226
- out.push({
227
- uid: event.uid,
228
- summary: event.summary || '',
229
- location: event.location || undefined,
230
- description: event.description || undefined,
231
- start,
232
- end,
233
- allDay: event.startDate.isDate,
234
- recurring: event.isRecurring(),
235
- calendar: { uid: meta.uid, name: meta.name, color: meta.color },
236
- });
237
- };
238
- if (!event.isRecurring()) {
239
- push(event.startDate, event.endDate);
240
- continue;
241
- }
242
- const duration = event.duration;
243
- const it = event.iterator();
244
- let next;
245
- // A malformed RRULE with no UNTIL and a tiny interval can iterate
246
- // forever; the range check below normally ends it, and this is the
247
- // backstop for the case where it cannot.
248
- let guard = 0;
249
- while ((next = it.next()) && guard++ < 2000) {
250
- if (next.toJSDate() >= to)
251
- break;
252
- const end = next.clone();
253
- end.addDuration(duration);
254
- if (end.toJSDate() < from)
255
- continue;
256
- const details = event.getOccurrenceDetails(next);
257
- push(details.startDate, details.endDate);
258
- }
259
- }
260
- }
261
- return out;
262
- }
263
- /**
264
- * Live updates: `onChange` fires whenever anything in the range moves, so
265
- * the caller can re-query. Returns an unsubscribe function.
266
- *
267
- * Deliberately a "something changed" signal rather than a patch — a
268
- * recurrence master edited three months away can change what today looks
269
- * like, and re-running the query is both simpler and correct.
270
- *
271
- * **Changes only.** What is in the range already is what `eventsBetween`
272
- * answered; `onChange` fires for what happens after that. See
273
- * {@link VIEW_FLAGS_NONE} for the loop that reporting the initial contents
274
- * as a change costs a caller who re-queries on one.
275
- */
276
- async watch(from, to, onChange, options = {}) {
277
- const list = options.calendars ??
278
- (await this.listCalendars()).filter((c) => c.enabled);
279
- const query = rangeQuery(from, to);
280
- const started = [];
281
- for (const meta of list) {
282
- try {
283
- const { cal, busName } = await this.#openCalendar(meta.uid);
284
- const viewPath = await cal.GetView(query);
285
- const view = (await this.#bus
286
- .getService(busName)
287
- .getInterface(viewPath, VIEW_IFACE));
288
- // Belt to `VIEW_FLAGS_NONE`'s braces, for a backend that would not
289
- // take the flags: `Complete` closes the initial delivery, so anything
290
- // before it is the replay rather than a change. Only armed when
291
- // `SetFlags` failed — a view that never reports `Complete` would
292
- // otherwise be watched in silence, and losing live updates is the
293
- // worse half of the trade.
294
- let replaying = false;
295
- try {
296
- await view.SetFlags(VIEW_FLAGS_NONE);
297
- }
298
- catch {
299
- replaying = true;
300
- }
301
- await view.$subscribe('Complete', () => {
302
- replaying = false;
303
- });
304
- for (const signal of [
305
- 'ObjectsAdded',
306
- 'ObjectsModified',
307
- 'ObjectsRemoved',
308
- ]) {
309
- await view.$subscribe(signal, (objects) => {
310
- if (replaying)
311
- return;
312
- onChange({
313
- calendar: meta,
314
- kind: signal,
315
- count: Array.isArray(objects) ? objects.length : 0,
316
- });
317
- });
318
- }
319
- await view.Start();
320
- started.push(view);
321
- this.#views.push(view);
322
- }
323
- catch {
324
- /* skip a calendar that will not open; the others still update */
325
- }
326
- }
327
- return async () => {
328
- for (const view of started) {
329
- this.#views = this.#views.filter((v) => v !== view);
330
- try {
331
- await view.Stop();
332
- await view.Dispose();
333
- }
334
- catch {
335
- /* already gone */
336
- }
337
- }
338
- };
339
- }
340
- /** Stop every view this instance started. Does **not** touch the bus. */
341
- async dispose() {
342
- const views = this.#views;
343
- this.#views = [];
344
- for (const view of views) {
345
- try {
346
- await view.Stop();
347
- await view.Dispose();
348
- }
349
- catch {
350
- /* already gone */
351
- }
352
- }
353
- this.#open.clear();
354
- }
355
- }
356
- //# sourceMappingURL=eds.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eds.js","sourceRoot":"","sources":["../../src/desktop-calendar/eds.ts"],"names":[],"mappings":"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"}
@@ -1,63 +0,0 @@
1
- /** An `ICAL.Time`. */
2
- export interface IcalTime {
3
- toJSDate(): Date;
4
- clone(): IcalTime;
5
- addDuration(duration: unknown): void;
6
- /** True for a date without a time — an all-day event's start. */
7
- isDate: boolean;
8
- }
9
- export interface IcalProperty {
10
- getParameter(name: string): string | undefined;
11
- }
12
- export interface IcalComponent {
13
- name: string;
14
- getFirstSubcomponent(name: string): IcalComponent | null;
15
- getAllSubcomponents(name: string): IcalComponent[];
16
- getFirstProperty(name: string): IcalProperty | null;
17
- }
18
- export interface IcalRecurExpansion {
19
- next(): IcalTime | null;
20
- }
21
- export interface IcalEvent {
22
- uid: string;
23
- summary: string;
24
- location: string;
25
- description: string;
26
- startDate: IcalTime;
27
- endDate: IcalTime;
28
- duration: unknown;
29
- isRecurring(): boolean;
30
- isRecurrenceException(): boolean;
31
- iterator(): IcalRecurExpansion;
32
- getOccurrenceDetails(time: IcalTime): {
33
- startDate: IcalTime;
34
- endDate: IcalTime;
35
- };
36
- }
37
- export interface IcalTimezone {
38
- tzid: string;
39
- }
40
- /** What `import('ical.js')` gives back, as far as this package is concerned. */
41
- export interface IcalModule {
42
- parse(input: string): unknown;
43
- Component: new (jcal: unknown) => IcalComponent;
44
- Event: new (component: IcalComponent) => IcalEvent;
45
- Timezone: new (component: IcalComponent) => IcalTimezone;
46
- TimezoneService: {
47
- has(tzid: string): boolean;
48
- register(tzid: string, zone: IcalTimezone): void;
49
- };
50
- }
51
- /** Thrown when the calendar is asked for events and `ical.js` is not there. */
52
- export declare class IcalUnavailableError extends Error {
53
- constructor(cause?: unknown);
54
- }
55
- /**
56
- * Load `ical.js`, once.
57
- *
58
- * Deliberately **not** cached as a rejection: a failed load is almost always
59
- * "not installed", but retrying costs nothing and a cached rejection would
60
- * outlive an app that installed it and re-rendered.
61
- */
62
- export declare function loadIcal(): Promise<IcalModule>;
63
- //# sourceMappingURL=ical.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ical.d.ts","sourceRoot":"","sources":["../../src/desktop-calendar/ical.ts"],"names":[],"mappings":"AAWA,sBAAsB;AACtB,MAAM,WAAW,QAAQ;IACvB,QAAQ,IAAI,IAAI,CAAC;IACjB,KAAK,IAAI,QAAQ,CAAC;IAClB,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,iEAAiE;IACjE,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;IACzD,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAAC;IACnD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,IAAI,QAAQ,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,QAAQ,CAAC;IACpB,OAAO,EAAE,QAAQ,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,IAAI,OAAO,CAAC;IACvB,qBAAqB,IAAI,OAAO,CAAC;IACjC,QAAQ,IAAI,kBAAkB,CAAC;IAC/B,oBAAoB,CAAC,IAAI,EAAE,QAAQ,GAAG;QACpC,SAAS,EAAE,QAAQ,CAAC;QACpB,OAAO,EAAE,QAAQ,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,SAAS,EAAE,KAAK,IAAI,EAAE,OAAO,KAAK,aAAa,CAAC;IAChD,KAAK,EAAE,KAAK,SAAS,EAAE,aAAa,KAAK,SAAS,CAAC;IACnD,QAAQ,EAAE,KAAK,SAAS,EAAE,aAAa,KAAK,YAAY,CAAC;IACzD,eAAe,EAAE;QACf,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;KAClD,CAAC;CACH;AAED,+EAA+E;AAC/E,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,KAAK,CAAC,EAAE,OAAO,EAQ1B;CACF;AAID;;;;;;GAMG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,CA4BpD"}