Skip to content

Commit

Permalink
Merge pull request #10 from adjust/v100
Browse files Browse the repository at this point in the history
Version 1.0.0
  • Loading branch information
YaraMatkova authored Nov 22, 2023
2 parents 777deb3 + 91c5d58 commit 74895a3
Show file tree
Hide file tree
Showing 45 changed files with 532 additions and 474 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"rules": {
"indent": [
"error",
2
2,
{
"SwitchCase": 1
}
],
"quotes": [
"error",
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
### Version 1.0.0 (23rd November 2023)

The first release of a new Adjust Smart Banner SDK!

#### Added
- Three sizes of banner: small, medium and large.
- Banner custom colors and images support.
- Automatic detection of browser language and ability to force SDK to show banners in chosen language.
- Placement conditions support: choose pages where show banners.
- UTM parameters passing to campaign parameters.
- Dynamic deeplinks.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Adjust GmbH, https://www.adjust.com
Copyright (c) 2023 Adjust GmbH, https://www.adjust.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
24 changes: 2 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ The sdk is also available through CDN and then accessible through global `Adjust
To <a id="loading-snippet">load Smart Banner SDK through CDN</a> paste the following snippet into the `<head>` tag:
```html
<script type="application/javascript">
!function(e,n,t,a,o,s,r,i,c){var d=o+"_q";e[o]=e[o]||{},e[d]=e[d]||[];for(var u=0;u<s.length;u++)r(e[o],e[d],s[u]);i=n.createElement(t),c=n.getElementsByTagName(t)[0],i.async=!0,i.src="https://cdn.adjust.com/adjust-smart-banner-latest.min.js",i.onload=function(){e[o]=e[o].default;for(var n=0;n<e[d].length;n++)e[o][e[d][n][0]]?e[o][e[d][n][0]].apply(e[o],e[d][n][1]):console.error("No such function found in "+o+": "+e[d][n][0]);e[d]=[]},c.parentNode.insertBefore(i,c)}(window,document,"script",0,"AdjustSmartBanner",["init","show","hide","setLanguage","setIosDeepLinkPath","setAndroidDeepLinkPath","setContext","setAndroidAppSchema","setDeepLinkPath"],(function(e,n,t){e[t]=function(){n.push([t,arguments])}}));
!function(n,t,e,o,a,s,r,i,c){var u=a+"_q";n[a]=n[a]||{},n[u]=n[u]||[];for(var d=0;d<s.length;d++)r(n[a],n[u],s[d]);i=t.createElement(e),c=t.getElementsByTagName(e)[0],i.async=!0,i.src="https://cdn.adjust.com/adjust-smart-banner-latest.min.js",i.onload=function(){n[a]=n[a].default;for(var t=0;t<n[u].length;t++)n[a][n[u][t][0]]?n[a][n[u][t][0]].apply(n[a],n[u][t][1]):console.error("No such function found in "+a+": "+n[u][t][0]);n[u]=[]},c.parentNode.insertBefore(i,c)}(window,document,"script",0,"AdjustSmartBanner",["init","show","hide","setLanguage","setIosDeepLinkPath","setAndroidDeepLinkPath","setContext"],(function(n,t,e){n[e]=function(){t.push([e,arguments])}}));
</script>
```

When loading the sdk through CDN we suggest using minified version. You can target specific version like `https://cdn.adjust.com/adjust-smart-banner-0.0.7.min.js`, or you can target latest version `https://cdn.adjust.com/adjust-smart-banner-latest.min.js` if you want automatic updates without need to change the target file. The sdk files are cached so they are served as fast as possible, and the cache is refreshed every half an hour. If you want updates immediately make sure to target specific version.
When loading the sdk through CDN we suggest using minified version. You can target specific version like `https://cdn.adjust.com/adjust-smart-banner-1.0.0.min.js`, or you can target latest version `https://cdn.adjust.com/adjust-smart-banner-latest.min.js` if you want automatic updates without need to change the target file. The sdk files are cached so they are served as fast as possible, and the cache is refreshed every half an hour. If you want updates immediately make sure to target specific version.


## <a id="initialization">Initialization</a>
Expand Down Expand Up @@ -100,16 +100,6 @@ AdjustSmartBanner.init({

These parameters allow you to specify where your user lands in your app when they click on banner. For further information see [Deeplinks](#deeplinks).

##### <a id="init-schema">**androidAppSchema**</a> `string`

> [!WARNING]
> Parameter `androidAppSchema` is deprecated, please don't use it anymore.
##### <a id="init-deeplinkpath">**deepLinkPath**</a> `string`

> [!WARNING]
> Parameter `deepLinkPath` is deprecated, please use [`androidDeepLinkPath`](#init-androiddeeplinkpath) and [`iosDeepLinkPath`](#init-iosdeeplinkpath) respectivetely the platform where you want deeplink path to be changed.
##### <a id="init-androiddeeplinkpath">**androidDeepLinkPath**</a> `string`

Overrides Android deeplink path, which allows you to change user destination in your mobile app when they click on banner.
Expand Down Expand Up @@ -349,16 +339,6 @@ AdjustSmartBanner.setContext({ product_id: "999888" });

There are several functions to set custom deeplink path or deeplink path template and its context.

#### <a id="deeplinks-setters-schema">**setAndroidAppScheme**</a>

> [!WARNING]
> Method `setAndroidAppSchema` is deprecated, please don't use it anymore.
#### <a id="deeplinks-setters-deeplinkpath">**setDeepLinkPath**</a>

> [!WARNING]
> Method `setDeepLinkPath` is deprecated and will be removed, please use [`setAndroidDeepLinkPath`](#init-androiddeeplinkpath) and [`setIosDeepLinkPath`](#init-iosdeeplinkpath) respectivetely the platform where you want deeplink path to be changed.
#### <a id="deeplinks-setters-androidDeeplinkpath">**setAndroidDeepLinkPath**</a>

Accepts a string representing deep link path or deeplint path template.
Expand Down
2 changes: 1 addition & 1 deletion demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@adjustcom/smart-banner-sdk": "^0.0.7",
"@adjustcom/smart-banner-sdk": "^1.0.0",
"lorem-ipsum": "^2.0.8"
},
"author": "Adjust GmbH",
Expand Down
6 changes: 1 addition & 5 deletions loading-snippet.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@
'setLanguage',
'setIosDeepLinkPath',
'setAndroidDeepLinkPath',
'setContext',

/* deprecated functions */
'setAndroidAppSchema',
'setDeepLinkPath'
'setContext'
],
function (context, queue, methodName) {
context[methodName] = function () {
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adjustcom/smart-banner-sdk-project",
"version": "0.0.1",
"version": "1.0.0",
"description": "Adjust Smart Banner SDK",
"scripts": {
"build": "npm run build --workspace=layout && npm run build --workspace=sdk && npm run build:snippet && npm run copy",
Expand Down
2 changes: 1 addition & 1 deletion sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adjustcom/smart-banner-sdk",
"version": "0.0.7",
"version": "1.0.0",
"description": "Adjust Smart Banner SDK",
"scripts": {
"build:sdk": "webpack --config ./webpack.config.js",
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/data/api.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DeviceOS } from '@utils/detect-os';
import { Logger } from '@utils/logger';
import { SmartBannerResponseData, SmartBannerData } from './types';
import { AsyncDataSource } from './data-source';
import { convertResponseToSmartBanners } from './converters/response-to-smart-banners';
import { DeviceOS } from '../utils/detect-os';
import { Logger } from '../utils/logger';
import { Network } from '../network/network';

/**
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/data/converters/smart-banner-for-view.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Localization, SmartBannerData } from '../types';
import { SnakeCaseKeysToCamelCase, snakeToCamelCase } from '../../utils/snake-to-camel-case';
import { SmartBannerViewData } from '@layout';
import { SnakeCaseKeysToCamelCase, snakeToCamelCase } from '@utils/snake-to-camel-case';
import { Localization, SmartBannerData } from '../types';

type LocalizedTexts = SnakeCaseKeysToCamelCase<Omit<Localization, 'context'>>

Expand Down
8 changes: 5 additions & 3 deletions sdk/src/data/storage/in-memory-storage.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Storage } from './storage';

type Anything = any; // eslint-disable-line @typescript-eslint/no-explicit-any

export class InMemoryStorage implements Storage {
private items: Record<string, any> = {};
private items: Record<string, Anything> = {};

public setItem(key: string, value: any): void {
public setItem(key: string, value: Anything): void {
this.items[key] = value;
}

public getItem(key: string): any | null {
public getItem(key: string): Anything | null {
return Object.prototype.hasOwnProperty.call(this.items, key) ? this.items[key] : null;
}

Expand Down
8 changes: 5 additions & 3 deletions sdk/src/data/storage/local-storage.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { parseJson } from '../../utils/json';
import { parseJson } from '@utils/json';
import { Storage } from './storage';

type Anything = any; // eslint-disable-line @typescript-eslint/no-explicit-any

export class LocalStorage implements Storage {
constructor(private storageName: string = 'adjust-smart-banner') { }

setItem(key: string, value: any): void {
setItem(key: string, value: Anything): void {
localStorage.setItem(`${this.storageName}.${key}`, JSON.stringify(value));
}

getItem(key: string): any | null {
getItem(key: string): Anything | null {
const value = localStorage.getItem(`${this.storageName}.${key}`);
return parseJson(value);
}
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/data/storage/storage-factory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Logger } from '@utils/logger';
import { LocalStorage } from './local-storage';
import { InMemoryStorage } from './in-memory-storage';
import { Storage } from './storage';
import { Logger } from '../../utils/logger';

class StorageFactory {
private static isLocalStorageSupported(): boolean {
Expand Down
7 changes: 7 additions & 0 deletions sdk/src/data/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface SmartBannerResponseData {
name: string;
app_name?: string;
display_rule: string | null;
display_rules: PlacementCondition | null;
is_previous_attribution_priority: boolean;
position: Position;
size: BannerSize;
Expand All @@ -60,11 +61,17 @@ export interface SmartBannerResponseData {
};
}

export interface PlacementCondition {
operator: 'or' | 'and';
rules: Array<PlacementCondition | string>;
}

export interface SmartBannerData {
id: string;
name: string;
app_name: string;
display_rule: string | null;
display_rules: PlacementCondition | null;
is_previous_attribution_priority: boolean;
position: Position;
size: BannerSize;
Expand Down
38 changes: 10 additions & 28 deletions sdk/src/domain/banners-filter/banner-selector.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,36 @@
import { Logger } from '@utils/logger';
import { random } from '@utils/random';
import { SmartBannerData } from '../../data/types';
import { DisplayRule } from './display-rule';
import { DismissedFilter } from './dismissed-filter';
import { DismissHandler } from '../dismiss-handler';
import { Logger } from '../../utils/logger';
import { DisplayRules } from './display-rules';

export const NO_DELAY = -1;

export class BannerSelector {
private displayRule: DisplayRule;
private dismissedFilter: DismissedFilter;

constructor(private dismissHandler: DismissHandler) {
this.displayRule = new DisplayRule();
this.dismissedFilter = new DismissedFilter(dismissHandler);
}

/**
* Get an array of banners which match display_rule
*/
private getSuitableBanners(banners: SmartBannerData[], url: string) {
const suitableBanners = this.displayRule.filter(banners, url);
return this.displayRule.sort(suitableBanners);
}

private getRandomFromArray(banners: SmartBannerData[]): SmartBannerData {
const index = Math.floor(Math.random() * banners.length);
return banners[index];
}
constructor(private dismissHandler: DismissHandler) { }

/**
* Returns next suitable banner and a number of seconds to wait until show the banner
*/
public next(banners: SmartBannerData[], url: string): { banner: SmartBannerData, when: number } | null {
const suitableBanners = this.getSuitableBanners(banners, url);
const suitableBanners = new DisplayRules(url).filter(banners);

if (suitableBanners.length <= 0) {
Logger.log(`No Smart Banners for ${url} page found`);
return null;
}

// If one of banners was dismissed, we should wait till 'the oldest' dismissalPeriod passed
// If at least one of banners was dismissed, we should wait till 'the oldest' dismissalPeriod passed
let dateToShow: number | null = null;
const dismissed = this.dismissedFilter.getDismissed(suitableBanners);
const dismissed = suitableBanners.filter(banner => this.dismissHandler.isDismissed(banner));
if (dismissed.length > 0) {
const sortedDismissed = this.dismissedFilter.sort(dismissed);
dateToShow = this.dismissHandler.getDateToShowAgain(sortedDismissed[0]);
dismissed.sort((a, b) => this.dismissHandler.getDateToShowAgain(a) - this.dismissHandler.getDateToShowAgain(b));
dateToShow = this.dismissHandler.getDateToShowAgain(dismissed[0]);
}

return {
banner: this.getRandomFromArray(suitableBanners), // Show any banner with equal probability
banner: suitableBanners[random(0, suitableBanners.length)], // Show any banner with equal probability
when: dateToShow || NO_DELAY
};
}
Expand Down
24 changes: 0 additions & 24 deletions sdk/src/domain/banners-filter/dismissed-filter.ts

This file was deleted.

44 changes: 0 additions & 44 deletions sdk/src/domain/banners-filter/display-rule.ts

This file was deleted.

Loading

0 comments on commit 74895a3

Please sign in to comment.