Skip to content

Commit 7641df6

Browse files
committed
break up tag utils
1 parent 3476ce2 commit 7641df6

File tree

7 files changed

+122
-116
lines changed

7 files changed

+122
-116
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
},
8585
{
8686
"path": "./build/releases/OneSignalSDK.page.es6.js",
87-
"limit": "47.44 kB",
87+
"limit": "47.33 kB",
8888
"gzip": true
8989
},
9090
{

src/page/managers/slidedownManager/SlidedownManager.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import {
1818
} from 'src/shared/prompts/constants';
1919
import { isSlidedownPushDependent } from 'src/shared/prompts/helpers';
2020
import type { DelayedPromptTypeValue } from 'src/shared/prompts/types';
21+
import {
22+
convertTagsApiToBooleans,
23+
markAllTagsAsSpecified,
24+
} from 'src/shared/utils/tags';
2125
import { logMethodCall } from 'src/shared/utils/utils';
2226
import { CoreModuleDirector } from '../../../core/CoreModuleDirector';
2327
import {
@@ -26,7 +30,6 @@ import {
2630
} from '../../../shared/helpers/DismissHelper';
2731
import Log from '../../../shared/libraries/Log';
2832
import type { PushSubscriptionState } from '../../../shared/models/PushSubscriptionState';
29-
import TagUtils from '../../../shared/utils/TagUtils';
3033
import { DismissPrompt } from '../../models/Dismiss';
3134
import ChannelCaptureContainer from '../../slidedown/ChannelCaptureContainer';
3235
import ConfirmationToast from '../../slidedown/ConfirmationToast';
@@ -307,12 +310,12 @@ export class SlidedownManager {
307310
this._context._tagManager._storeRemotePlayerTags(
308311
existingTags as TagsObjectForApi,
309312
);
310-
tagsForComponent = TagUtils.convertTagsApiToBooleans(
313+
tagsForComponent = convertTagsApiToBooleans(
311314
existingTags as TagsObjectForApi,
312315
);
313316
} else {
314317
// first subscription or no existing tags
315-
TagUtils.markAllTagsAsSpecified(categories, true);
318+
markAllTagsAsSpecified(categories, true);
316319
}
317320

318321
taggingContainer._mount(categories, tagsForComponent);

src/page/managers/tagManager/TagManager.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ import type {
33
TagsObjectWithBoolean,
44
} from 'src/page/tags/types';
55
import type { ContextInterface } from 'src/shared/context/types';
6+
import {
7+
convertTagsBooleansToApi,
8+
getObjectDifference,
9+
isTagObjectEmpty,
10+
} from 'src/shared/utils/tags';
611
import Log from '../../../shared/libraries/Log';
7-
import TagUtils from '../../../shared/utils/TagUtils';
812
import type { ITagManager } from './types';
913

1014
/**
@@ -26,15 +30,15 @@ export default class TagManager implements ITagManager {
2630
public async _sendTags(): Promise<TagsObjectForApi> {
2731
Log._info('Category Slidedown Local Tags:', this._tagsFromTaggingContainer);
2832

29-
const localTagsConvertedToApi = TagUtils.convertTagsBooleansToApi(
33+
const localTagsConvertedToApi = convertTagsBooleansToApi(
3034
this._tagsFromTaggingContainer,
3135
);
32-
const finalTagsObject = TagUtils.getObjectDifference(
36+
const finalTagsObject = getObjectDifference(
3337
localTagsConvertedToApi,
3438
this._remoteTags,
3539
);
3640

37-
const shouldSendUpdate = !TagUtils.isTagObjectEmpty(finalTagsObject);
41+
const shouldSendUpdate = !isTagObjectEmpty(finalTagsObject);
3842
if (shouldSendUpdate) {
3943
await OneSignal.User.addTags(finalTagsObject);
4044
return finalTagsObject;

src/page/slidedown/TaggingContainer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
removeCssClass,
77
removeDomElement,
88
} from 'src/shared/helpers/dom';
9+
import { getCheckedTagCategories } from 'src/shared/utils/tags';
910
import {
1011
COLORS,
1112
SLIDEDOWN_CSS_CLASSES,
@@ -14,7 +15,6 @@ import {
1415
TAGGING_CONTAINER_CSS_IDS,
1516
TAGGING_CONTAINER_STRINGS,
1617
} from '../../shared/slidedown/constants';
17-
import TagUtils from '../../shared/utils/TagUtils';
1818
import type { TagsObjectWithBoolean } from '../tags/types';
1919
import { getLoadingIndicatorWithColor } from './LoadingIndicator';
2020

@@ -79,7 +79,7 @@ export default class TaggingContainer {
7979
remoteTagCategories: TagCategory[],
8080
existingPlayerTags?: TagsObjectWithBoolean,
8181
): Element {
82-
const checkedTagCategories = TagUtils.getCheckedTagCategories(
82+
const checkedTagCategories = getCheckedTagCategories(
8383
remoteTagCategories,
8484
existingPlayerTags,
8585
);

src/shared/utils/TagUtils.ts

Lines changed: 0 additions & 105 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {
33
TagsObjectForApi,
44
TagsObjectWithBoolean,
55
} from 'src/page/tags/types';
6-
import TagUtils from './TagUtils';
6+
import * as TagUtils from './tags';
77

88
describe('TagUtils', () => {
99
test('should convert api tags to boolean format', () => {

src/shared/utils/tags.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import type {
2+
TagCategory,
3+
TagsObjectForApi,
4+
TagsObjectWithBoolean,
5+
} from 'src/page/tags/types';
6+
7+
export function convertTagsApiToBooleans(
8+
tags: TagsObjectForApi,
9+
): TagsObjectWithBoolean {
10+
const convertedTags: TagsObjectWithBoolean = {};
11+
Object.keys(tags).forEach((key) => {
12+
convertedTags[key] = tags[key] === '1' ? true : false;
13+
});
14+
return convertedTags;
15+
}
16+
17+
export function convertTagsBooleansToApi(
18+
tags: TagsObjectWithBoolean,
19+
): TagsObjectForApi {
20+
const convertedTags: TagsObjectForApi = {};
21+
Object.keys(tags).forEach((key) => {
22+
convertedTags[key] = tags[key] === true ? '1' : '0';
23+
});
24+
return convertedTags;
25+
}
26+
27+
/**
28+
* Used in determining what Tag/Category preferences changed in order
29+
* to only update what is necessary
30+
* @param {TagsObject} localTags - tags from taggingContainer with values of type "number"
31+
* @param {TagsObject} remoteTags - remote player tags with values of type "number"
32+
* @returns array of keys of corresponding different values (finds difference)
33+
*/
34+
export function getObjectDifference(
35+
localTags: TagsObjectForApi,
36+
remoteTags: TagsObjectForApi,
37+
): TagsObjectForApi {
38+
const finalTags: TagsObjectForApi = {};
39+
40+
// Going off local tags since it's our categories. Trying to find only changed tags and returning those
41+
// as a final object.
42+
Object.keys(localTags).forEach((key) => {
43+
// only if user's tag value did not change, skip it
44+
if (remoteTags[key] === localTags[key]) {
45+
return;
46+
}
47+
48+
finalTags[key] = localTags[key];
49+
});
50+
return finalTags;
51+
}
52+
53+
export function markAllTagsAsSpecified(
54+
categoryArray: TagCategory[],
55+
checked: boolean,
56+
): void {
57+
categoryArray.forEach((category) => {
58+
category.checked = checked;
59+
});
60+
}
61+
62+
export function isTagObjectEmpty(
63+
tags: TagsObjectForApi | TagsObjectWithBoolean,
64+
): boolean {
65+
return Object.keys(tags).length === 0;
66+
}
67+
/**
68+
* Uses configured categories and remote player tags to calculate which boxes should be checked
69+
* @param {TagCategory[]} categories
70+
* @param {TagsObjectWithBoolean} existingPlayerTags?
71+
*/
72+
export function getCheckedTagCategories(
73+
categories: TagCategory[],
74+
existingPlayerTags?: TagsObjectWithBoolean,
75+
): TagCategory[] {
76+
if (!existingPlayerTags) {
77+
return categories;
78+
}
79+
80+
const isExistingPlayerTagsEmpty = isTagObjectEmpty(existingPlayerTags);
81+
if (isExistingPlayerTagsEmpty) {
82+
const categoriesCopy = structuredClone(categories);
83+
markAllTagsAsSpecified(categoriesCopy, true);
84+
return categoriesCopy;
85+
}
86+
87+
const categoriesCopy = structuredClone<TagCategory[]>(categories);
88+
return categoriesCopy.map((category) => {
89+
const existingTagValue: boolean = existingPlayerTags[category.tag];
90+
category.checked = getCheckedStatusForTagValue(existingTagValue);
91+
return category;
92+
});
93+
}
94+
95+
export function getCheckedStatusForTagValue(
96+
tagValue: boolean | undefined,
97+
): boolean {
98+
// If user does not have tag assigned to them, consider it selected
99+
if (tagValue === undefined) {
100+
return true;
101+
}
102+
103+
return tagValue;
104+
}

0 commit comments

Comments
 (0)