Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(icon-registry): add broadcast channel to sync icons. #1295

Merged
merged 19 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
369ee11
feat(IgxIconService): POC - Add broadcast channel to sync icons.
MayaKirova Jul 9, 2024
017e7d5
chore(*): Fix lint.
MayaKirova Jul 10, 2024
6262015
chore(*): Merge from base.
MayaKirova Jul 25, 2024
b76dd57
chore(*): Update types and messages.
MayaKirova Jul 25, 2024
ecc35c1
chore(*): Refactor and apply review comments.
MayaKirova Jul 29, 2024
d956130
chore(*): Fix lint.
MayaKirova Jul 29, 2024
03c4040
chore(*): Fix formatting.
MayaKirova Jul 29, 2024
4b2f8d0
chore(*): Add react/blazor method on icon to set ref.
MayaKirova Jul 29, 2024
356ffe3
test: Add initial tests for the icon broadcast service
rkaraivanov Jul 30, 2024
dcffd3b
chore(*): More refactoring.
MayaKirova Jul 30, 2024
62bd2d7
Merge branch 'mkirova/poc-icon-service-sync' of https://github.com/Ig…
MayaKirova Jul 30, 2024
2a44fdf
chore(*): Minor fixes. Update test.
MayaKirova Jul 30, 2024
589d43d
refactor: Add reference test. Some code restructuring.
rkaraivanov Jul 31, 2024
e23d8cc
Merge branch 'master' of https://github.com/IgniteUI/igniteui-webcomp…
rkaraivanov Jul 31, 2024
3acf475
Merge branch 'master' of https://github.com/IgniteUI/igniteui-webcomp…
rkaraivanov Aug 1, 2024
1a7a80a
refactor: Restructured the code and types around the icon services
rkaraivanov Aug 1, 2024
6893fae
Merge branch 'master' into mkirova/poc-icon-service-sync
rkaraivanov Aug 2, 2024
3da2c20
Merge branch 'master' into mkirova/poc-icon-service-sync
ChronosSF Aug 5, 2024
78b00ab
Merge branch 'master' into mkirova/poc-icon-service-sync
damyanpetev Aug 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions src/components/icon/icon-state.broadcast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { internalIcons } from './internal-icons-lib.js';
import { SvgIconParser } from './registry/parser.js';
import type {
BroadcastIconsChangeMessage,
Collection,
IconMeta,
SvgIcon,
} from './registry/types.js';
import { ActionType } from './registry/types.js';

export class IconsStateBroadcast {
private parser: SvgIconParser;
private iconBroadcastChannel: BroadcastChannel;
constructor(
collections: Collection<string, Map<string, SvgIcon>>,
refsCollection: Collection<string, Map<string, IconMeta>>
) {
this.parser = new SvgIconParser();
this.iconBroadcastChannel = new BroadcastChannel('ignite-ui-icon-channel');
this.iconBroadcastChannel.onmessage = (event) => {
const message = event.data as BroadcastIconsChangeMessage;
if (message.actionType === ActionType.SyncState) {
// send state
const userSetCollection: Map<
string,
Map<string, SvgIcon>
> = this.getUserSetCollection(collections);
const refs: Map<string, Map<string, IconMeta>> = this.getMapCollection(
refsCollection
);
const message: BroadcastIconsChangeMessage = {
actionType: ActionType.SyncState,
collections: userSetCollection,
references: refs,
};
this.iconBroadcastChannel.postMessage(message);
}
};
}

public broadcastState(
actionType: ActionType,
collections?: Collection<string, Map<string, SvgIcon>>,
refs?: Collection<string, Map<string, IconMeta>>
) {
const message: BroadcastIconsChangeMessage = {
actionType: actionType,
references: refs ? this.getMapCollection(refs) : undefined,
collections: collections ? this.getMapCollection(collections) : undefined,
};
this.iconBroadcastChannel.postMessage(message);
}

private getUserSetCollection(
collections: Collection<string, Map<string, SvgIcon>>
) {
const userSetIcons: Map<string, Map<string, SvgIcon>> = new Map();
const collectionKeys = collections.keys();
for (const collectionKey of collectionKeys) {
const collection = collections.get(collectionKey);
for (const iconKey in collection) {
const val = collection.get(iconKey)?.svg;
const internalValue = internalIcons.get(iconKey)?.svg;
if (val && val !== internalValue) {
let icons = userSetIcons.get(collectionKey);
if (!icons) {
userSetIcons.set(collectionKey, new Map<string, SvgIcon>());
icons = userSetIcons.get(collectionKey);
}
if (icons) {
icons.set(iconKey, this.parser.parse(val));
}
}
}
}
return userSetIcons;
}

private getMapCollection(
collection: Collection<string, Map<string, any>>
): Map<string, Map<string, any>> {
const refs: Map<string, Map<string, any>> = new Map();
const refKeys = collection.keys();
for (const collectionKey of refKeys) {
refs.set(collectionKey, collection.get(collectionKey) || new Map());
}
return refs;
}
}
27 changes: 26 additions & 1 deletion src/components/icon/icon.registry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Theme } from '../../theming/types.js';
import { iconReferences } from './icon-references.js';
import { IconsStateBroadcast } from './icon-state.broadcast.js';
import { internalIcons } from './internal-icons-lib.js';
import { DefaultMap } from './registry/default-map.js';
import { SvgIconParser } from './registry/parser.js';
Expand All @@ -10,21 +11,26 @@ import type {
IconReferencePair,
SvgIcon,
} from './registry/types.js';
import { ActionType } from './registry/types.js';

export class IconsRegistry {
private parser: SvgIconParser;
private collections: Collection<string, Map<string, SvgIcon>>;
private references: Collection<string, Map<string, IconMeta>>;
private listeners: Set<IconCallback>;
private theme!: Theme;
private stateBroadcast: IconsStateBroadcast;

constructor() {
this.parser = new SvgIconParser();
this.listeners = new Set();
this.collections = new DefaultMap(() => new Map());
this.references = new DefaultMap(() => new Map());

this.collections.set('internal', internalIcons);
this.stateBroadcast = new IconsStateBroadcast(
this.collections,
this.references
);
}

public register(name: string, iconText: string, collection = 'default') {
Expand All @@ -33,6 +39,12 @@ export class IconsRegistry {
.set(name, this.parser.parse(iconText));

this.notifyAll(name, collection);

const icons: Collection<string, Map<string, SvgIcon>> = new DefaultMap(
() => new Map()
);
icons.getOrCreate(collection).set(name, this.parser.parse(iconText));
this.stateBroadcast.broadcastState(ActionType.RegisterIcon, icons);
}

public subscribe(callback: IconCallback) {
Expand Down Expand Up @@ -70,6 +82,19 @@ export class IconsRegistry {
}

this.notifyAll(alias.name, alias.collection);

const refs: Collection<string, Map<string, IconMeta>> = new DefaultMap(
() => new Map()
);
refs.getOrCreate(alias.collection).set(alias.name, {
collection: target.collection,
name: target.name,
});
this.stateBroadcast.broadcastState(
ActionType.UpdateIconReference,
undefined,
refs
);
}

public getIconRef(name: string, collection: string): IconMeta {
Expand Down
8 changes: 8 additions & 0 deletions src/components/icon/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import {
getIconRegistry,
registerIconFromText as registerIconFromText_impl,
registerIcon as registerIcon_impl,
setIconRef as setIconRef_impl,
} from './icon.registry.js';
import type { IconMeta } from './registry/types.js';
import { styles } from './themes/icon.base.css.js';
import { styles as shared } from './themes/shared/icon.common.css.js';
import { all } from './themes/themes.js';
Expand Down Expand Up @@ -127,6 +129,12 @@ export default class IgcIconComponent extends LitElement {
) {
registerIconFromText_impl(name, iconText, collection);
}

/* c8 ignore next 4 */
@blazorInclude()
protected async setIconRef(name: string, collection: string, icon: IconMeta) {
await setIconRef_impl(name, collection, icon);
}
}

declare global {
Expand Down
4 changes: 4 additions & 0 deletions src/components/icon/registry/default-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ export class DefaultMap<T, U> {
public has(key: T) {
return this._map.has(key);
}

public keys() {
return this._map.keys();
}
}
12 changes: 12 additions & 0 deletions src/components/icon/registry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,15 @@ export interface IconMeta {
collection: string;
external?: boolean;
}

export enum ActionType {
SyncState = 0,
RegisterIcon = 1,
UpdateIconReference = 2,
}

export interface BroadcastIconsChangeMessage {
actionType: ActionType;
collections?: Map<string, Map<string, SvgIcon>>;
references?: Map<string, Map<string, IconMeta>>;
}
Loading