Skip to content

Commit 1310072

Browse files
authored
feat: onThemesChange callback (#48)
* feat: onThemesChange callback * chore: bundle * chore: increment version * test: onThemesChange callback Co-authored-by: Johnny Almonte <[email protected]>
1 parent 91a43eb commit 1310072

File tree

6 files changed

+73
-35
lines changed

6 files changed

+73
-35
lines changed

dist/@types/componentRelay.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ declare type ComponentRelayParams = {
3030
* A callback that is executed after the component has been registered.
3131
*/
3232
onReady?: () => void;
33+
/**
34+
* A callback that is executed after themes have been changed.
35+
*/
36+
onThemesChange?: () => void;
3337
};
3438
declare type ItemPayload = {
3539
content_type?: ContentType;
@@ -53,6 +57,7 @@ export default class ComponentRelay {
5357
private keyDownEventListener?;
5458
private keyUpEventListener?;
5559
private clickEventListener?;
60+
private onThemesChangeCallback?;
5661
constructor(params: ComponentRelayParams);
5762
private processParameters;
5863
deinit(): void;

dist/dist.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/dist.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/componentRelay.ts

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ type ComponentRelayParams = {
8282
/**
8383
* A callback that is executed after the component has been registered.
8484
*/
85-
onReady?: () => void
85+
onReady?: () => void,
86+
/**
87+
* A callback that is executed after themes have been changed.
88+
*/
89+
onThemesChange?: () => void,
8690
}
8791

8892
type ItemPayload = {
@@ -114,6 +118,7 @@ export default class ComponentRelay {
114118
private keyDownEventListener?: (event: KeyboardEvent) => void;
115119
private keyUpEventListener?: (event: KeyboardEvent) => void;
116120
private clickEventListener?: (event: MouseEvent) => void;
121+
private onThemesChangeCallback?: () => void;
117122

118123
constructor(params: ComponentRelayParams) {
119124
if (!params || !params.targetWindow) {
@@ -127,7 +132,7 @@ export default class ComponentRelay {
127132
}
128133

129134
private processParameters(params: ComponentRelayParams) {
130-
const { initialPermissions, options, onReady } = params
135+
const { initialPermissions, options, onReady, onThemesChange } = params
131136

132137
if (initialPermissions && initialPermissions.length > 0) {
133138
this.initialPermissions = initialPermissions
@@ -145,10 +150,14 @@ export default class ComponentRelay {
145150
if (isNotUndefinedOrNull(onReady)) {
146151
this.onReadyCallback = onReady
147152
}
153+
if (isNotUndefinedOrNull(onThemesChange)) {
154+
this.onThemesChangeCallback = onThemesChange
155+
}
156+
148157
Logger.enabled = options?.debug ?? false
149158
}
150159

151-
public deinit() : void {
160+
public deinit(): void {
152161
this.onReadyCallback = undefined
153162
this.component = {
154163
acceptsThemes: true,
@@ -351,21 +360,21 @@ export default class ComponentRelay {
351360
/**
352361
* Gets the component UUID.
353362
*/
354-
public getSelfComponentUUID() : string | undefined {
363+
public getSelfComponentUUID(): string | undefined {
355364
return this.component.uuid
356365
}
357366

358367
/**
359368
* Checks if the component is running in a Desktop application.
360369
*/
361-
public isRunningInDesktopApplication() : boolean {
370+
public isRunningInDesktopApplication(): boolean {
362371
return this.component.environment === environmentToString(Environment.Desktop)
363372
}
364373

365374
/**
366375
* Checks if the component is running in a Mobile application.
367376
*/
368-
public isRunningInMobileApplication() : boolean {
377+
public isRunningInMobileApplication(): boolean {
369378
return this.component.environment === environmentToString(Environment.Mobile)
370379
}
371380

@@ -374,7 +383,7 @@ export default class ComponentRelay {
374383
* @param key The key for the data object.
375384
* @returns `undefined` if the value for the key does not exist. Returns the stored value otherwise.
376385
*/
377-
public getComponentDataValueForKey(key: string) : any {
386+
public getComponentDataValueForKey(key: string): any {
378387
if (!this.component.data) {
379388
return
380389
}
@@ -386,7 +395,7 @@ export default class ComponentRelay {
386395
* @param key The key for the data object.
387396
* @param value The value to store under the specified key.
388397
*/
389-
public setComponentDataValueForKey(key: string, value: any) : void {
398+
public setComponentDataValueForKey(key: string, value: any): void {
390399
if (!this.component.data) {
391400
throw new Error('The component has not been initialized.')
392401
}
@@ -403,7 +412,7 @@ export default class ComponentRelay {
403412
/**
404413
* Clears the component's data object.
405414
*/
406-
public clearComponentData() : void {
415+
public clearComponentData(): void {
407416
this.component.data = {}
408417
this.postMessage(ComponentAction.SetComponentData, { componentData: this.component.data })
409418
}
@@ -506,6 +515,8 @@ export default class ComponentRelay {
506515
link.className = 'custom-theme'
507516
this.contentWindow.document.getElementsByTagName('head')[0].appendChild(link)
508517
}
518+
519+
this.onThemesChangeCallback && this.onThemesChangeCallback()
509520
}
510521

511522
private themeElementForUrl(themeUrl: string) {
@@ -531,14 +542,14 @@ export default class ComponentRelay {
531542
/**
532543
* Gets the current platform where the component is running.
533544
*/
534-
public get platform() : string | undefined {
545+
public get platform(): string | undefined {
535546
return this.component.platform
536547
}
537548

538549
/**
539550
* Gets the current environment where the component is running.
540551
*/
541-
public get environment() : string | undefined {
552+
public get environment(): string | undefined {
542553
return this.component.environment
543554
}
544555

@@ -548,7 +559,7 @@ export default class ComponentRelay {
548559
* @param contentTypes A collection of Content Types.
549560
* @param callback A callback to process the streamed items.
550561
*/
551-
public streamItems(contentTypes: ContentType[], callback: (data: any) => void) : void {
562+
public streamItems(contentTypes: ContentType[], callback: (data: any) => void): void {
552563
this.postMessage(ComponentAction.StreamItems, { content_types: contentTypes }, (data: any) => {
553564
callback(data.items)
554565
})
@@ -558,7 +569,7 @@ export default class ComponentRelay {
558569
* Streams the current Item in context.
559570
* @param callback A callback to process the streamed item.
560571
*/
561-
public streamContextItem(callback: (data: any) => void) : void {
572+
public streamContextItem(callback: (data: any) => void): void {
562573
this.postMessage(ComponentAction.StreamContextItem, {}, (data) => {
563574
const { item } = data
564575
/**
@@ -585,14 +596,14 @@ export default class ComponentRelay {
585596
* Selects a `Tag` item.
586597
* @param item The Item (`Tag` or `SmartTag`) to select.
587598
*/
588-
public selectItem(item: ItemPayload) : void {
599+
public selectItem(item: ItemPayload): void {
589600
this.postMessage(ComponentAction.SelectItem, { item: this.jsonObjectForItem(item) })
590601
}
591602

592603
/**
593604
* Clears current selected `Tag` (if any).
594605
*/
595-
public clearSelection() : void {
606+
public clearSelection(): void {
596607
this.postMessage(ComponentAction.ClearSelection, { content_type: ContentType.Tag })
597608
}
598609

@@ -601,7 +612,7 @@ export default class ComponentRelay {
601612
* @param item The Item's payload content.
602613
* @param callback The callback to process the created Item.
603614
*/
604-
public createItem(item: ItemPayload, callback: (data: any) => void) : void {
615+
public createItem(item: ItemPayload, callback: (data: any) => void): void {
605616
this.postMessage(ComponentAction.CreateItem, { item: this.jsonObjectForItem(item) }, (data: any) => {
606617
let { item } = data
607618
/**
@@ -621,7 +632,7 @@ export default class ComponentRelay {
621632
* @param items The Item(s) payload collection.
622633
* @param callback The callback to process the created Item(s).
623634
*/
624-
public createItems(items: ItemPayload[], callback: (data: any) => void) : void {
635+
public createItems(items: ItemPayload[], callback: (data: any) => void): void {
625636
const mapped = items.map((item) => this.jsonObjectForItem(item))
626637
this.postMessage(ComponentAction.CreateItems, { items: mapped }, (data: any) => {
627638
callback && callback(data.items)
@@ -632,24 +643,24 @@ export default class ComponentRelay {
632643
* Associates a `Tag` with the current Note.
633644
* @param item The `Tag` item to associate.
634645
*/
635-
public associateItem(item: ItemPayload) : void {
646+
public associateItem(item: ItemPayload): void {
636647
this.postMessage(ComponentAction.AssociateItem, { item: this.jsonObjectForItem(item) })
637648
}
638649

639650
/**
640651
* Deassociates a `Tag` with the current Note.
641652
* @param item The `Tag` item to deassociate.
642653
*/
643-
public deassociateItem(item: ItemPayload) : void {
644-
this.postMessage(ComponentAction.DeassociateItem, { item: this.jsonObjectForItem(item) } )
654+
public deassociateItem(item: ItemPayload): void {
655+
this.postMessage(ComponentAction.DeassociateItem, { item: this.jsonObjectForItem(item) })
645656
}
646657

647658
/**
648659
* Deletes an Item from the item store.
649660
* @param item The Item to delete.
650661
* @param callback The callback with the result of the operation.
651662
*/
652-
public deleteItem(item: ItemPayload, callback: (data: ItemMessagePayload) => void) : void {
663+
public deleteItem(item: ItemPayload, callback: (data: ItemMessagePayload) => void): void {
653664
this.deleteItems([item], callback)
654665
}
655666

@@ -658,7 +669,7 @@ export default class ComponentRelay {
658669
* @param items The Item(s) to delete.
659670
* @param callback The callback with the result of the operation.
660671
*/
661-
public deleteItems(items: ItemPayload[], callback: (data: ItemMessagePayload) => void) : void {
672+
public deleteItems(items: ItemPayload[], callback: (data: ItemMessagePayload) => void): void {
662673
const params = {
663674
items: items.map((item) => {
664675
return this.jsonObjectForItem(item)
@@ -675,7 +686,7 @@ export default class ComponentRelay {
675686
* @param data
676687
* @param callback The callback with the result of the operation.
677688
*/
678-
public sendCustomEvent(action: ComponentAction, data: any, callback?: (data: any) => void) : void {
689+
public sendCustomEvent(action: ComponentAction, data: any, callback?: (data: any) => void): void {
679690
this.postMessage(action, data, (data: any) => {
680691
callback && callback(data)
681692
})
@@ -687,7 +698,7 @@ export default class ComponentRelay {
687698
* @param callback
688699
* @param skipDebouncer
689700
*/
690-
public saveItem(item: ItemPayload, callback?: () => void, skipDebouncer = false) : void {
701+
public saveItem(item: ItemPayload, callback?: () => void, skipDebouncer = false): void {
691702
this.saveItems([item], callback, skipDebouncer)
692703
}
693704

@@ -699,7 +710,7 @@ export default class ComponentRelay {
699710
* hook into the debounce cycle so that clients don't have to implement their own debouncing.
700711
* @param callback
701712
*/
702-
public saveItemWithPresave(item: ItemPayload, presave: any, callback?: () => void) : void {
713+
public saveItemWithPresave(item: ItemPayload, presave: any, callback?: () => void): void {
703714
this.saveItemsWithPresave([item], presave, callback)
704715
}
705716

@@ -711,7 +722,7 @@ export default class ComponentRelay {
711722
* hook into the debounce cycle so that clients don't have to implement their own debouncing.
712723
* @param callback
713724
*/
714-
public saveItemsWithPresave(items: ItemPayload[], presave: any, callback?: () => void) : void {
725+
public saveItemsWithPresave(items: ItemPayload[], presave: any, callback?: () => void): void {
715726
this.saveItems(items, callback, false, presave)
716727
}
717728

@@ -739,7 +750,7 @@ export default class ComponentRelay {
739750
* This should be used when saving items via other means besides keystrokes.
740751
* @param presave
741752
*/
742-
public saveItems(items: ItemPayload[], callback?: () => void, skipDebouncer = false, presave?: any) : void {
753+
public saveItems(items: ItemPayload[], callback?: () => void, skipDebouncer = false, presave?: any): void {
743754
/**
744755
* We need to make sure that when we clear a pending save timeout,
745756
* we carry over those pending items into the new save.
@@ -788,30 +799,30 @@ export default class ComponentRelay {
788799
* @param width The new width.
789800
* @param height The new height.
790801
*/
791-
public setSize(width: string | number, height: string | number) : void {
802+
public setSize(width: string | number, height: string | number): void {
792803
this.postMessage(ComponentAction.SetSize, { type: 'container', width, height })
793804
}
794805

795806
/**
796807
* Sends the KeyDown keyboard event to the Standard Notes parent application.
797808
* @param keyboardModifier The keyboard modifier that was pressed.
798809
*/
799-
private keyDownEvent(keyboardModifier: KeyboardModifier) : void {
810+
private keyDownEvent(keyboardModifier: KeyboardModifier): void {
800811
this.postMessage(ComponentAction.KeyDown, { keyboardModifier })
801812
}
802813

803814
/**
804815
* Sends the KeyUp keyboard event to the Standard Notes parent application.
805816
* @param keyboardModifier The keyboard modifier that was released.
806817
*/
807-
private keyUpEvent(keyboardModifier: KeyboardModifier) : void {
818+
private keyUpEvent(keyboardModifier: KeyboardModifier): void {
808819
this.postMessage(ComponentAction.KeyUp, { keyboardModifier })
809820
}
810821

811822
/**
812823
* Sends the Click mouse event to the Standard Notes parent application.
813824
*/
814-
private mouseClickEvent() : void {
825+
private mouseClickEvent(): void {
815826
this.postMessage(ComponentAction.Click, {})
816827
}
817828

@@ -829,7 +840,7 @@ export default class ComponentRelay {
829840
* @param item The Item to get the appData value from.
830841
* @param key The key to get the value from.
831842
*/
832-
public getItemAppDataValue(item: ItemMessagePayload | undefined, key: AppDataField | string) : any {
843+
public getItemAppDataValue(item: ItemMessagePayload | undefined, key: AppDataField | string): any {
833844
const defaultDomain = 'org.standardnotes.sn'
834845
return item?.content?.appData?.[defaultDomain][key]
835846
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@standardnotes/component-relay",
3-
"version": "2.1.1",
3+
"version": "2.1.2",
44
"repository": {
55
"type": "git",
66
"url": "git://github.com/standardnotes/component-relay.git"

test/component-relay.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,28 @@ describe("Component Relay", () => {
124124
expect(onReady).toBeCalledTimes(1);
125125
});
126126

127+
it('should run onThemesChange callback when a theme is activated', async () => {
128+
expect.hasAssertions();
129+
const onThemesChange = jest.fn();
130+
componentRelay.deinit();
131+
componentRelay = new ComponentRelay({
132+
targetWindow: childWindow,
133+
onReady: jest.fn(),
134+
onThemesChange
135+
});
136+
await registerComponent(testSNApp, childWindow, testComponent);
137+
138+
await createComponentItem(testSNApp, testThemeDefaultPackage, {
139+
active: true
140+
}) as SNTheme;
141+
await registerComponent(testSNApp, childWindow, testComponent);
142+
143+
testSNApp.componentManager.postActiveThemesToComponent(testComponent);
144+
await sleep(0.001);
145+
146+
expect(onThemesChange).toBeCalledTimes(1);
147+
});
148+
127149
test('getSelfComponentUUID() before the component is registered should be undefined', () => {
128150
const uuid = componentRelay.getSelfComponentUUID();
129151
expect(uuid).toBeUndefined();

0 commit comments

Comments
 (0)