Skip to content

Commit

Permalink
Merge pull request #121 from adjust/DSM-2999-third-party-sharing
Browse files Browse the repository at this point in the history
[DSM-2999] Enhance marketing Opt-out
  • Loading branch information
YaraMatkova authored Aug 14, 2024
2 parents d09f1a5 + ba278b5 commit 1ddda6b
Show file tree
Hide file tree
Showing 22 changed files with 706 additions and 688 deletions.
1 change: 1 addition & 0 deletions src/assets/scss/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@import "flex-grid";
@import "../../demo/tabs/tabs";
@import "../../demo/key-value-params/key-value-params";
@import "../../demo/dynamic-params/dynamic-params";

html, body {
margin: 0;
Expand Down

This file was deleted.

This file was deleted.

148 changes: 148 additions & 0 deletions src/demo/dynamic-params/dynamic-params.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { capitalize } from '../utils'

const ACTION_SYMBOLS = {
add: '+',
remove: '×'
}

function _createNode(name, classes = [], content, attrs = {}) {
const element = document.createElement(name)

element.classList.add(...classes)

if (content) {
element.appendChild(document.createTextNode(content))
}

Object.keys(attrs)
.map(key => [key, attrs[key]])
.map(([key, value]) => element[key] = value)

return element
}

function _createInput(inputCls, label, value = '') {
const keyParent = _createNode('div', ['flex-box-column'])
keyParent.style.height = '45px'
const keyLabel = _createNode('label', ['flex-auto'], label)
const keyInput = _createNode('input', ['flex-one', inputCls], null, { type: 'text', value })

keyParent.appendChild(keyLabel)
keyParent.appendChild(keyInput)

return keyParent
}

function _append(parent, handle, isLast, fields, param = {}) {
const group = _createNode('div', ['flex-box-row', 'form-row-group'])

const elements = []
fields.forEach(field => {
elements.push(_createInput(`${field}-input`, capitalize(field), param[field]))
})
group.append(...elements)

const actionName = isLast ? 'add' : 'remove'
const action = _createNode('button', ['flex-auto', actionName], ACTION_SYMBOLS[actionName], { type: 'button' })

action.addEventListener('click', handle, false)
group.appendChild(action)

parent.appendChild(group)
}

const DynamicParams = (id, fields = ['key', 'value'], params = [], onChange) => {
const _id = id
const _fields = fields
const _params = params
let _parent = null

function init() {
_parent = document.getElementById(_id)

if (_params.length) {
_params.forEach((param, idx) => {
const isLast = idx === params.length - 1
const handle = isLast ? _handleAdd : _handleRemove
_append(_parent, handle, isLast, _fields, param)
})
} else {
_append(_parent, _handleAdd, true, _fields)
}
}

function query() {
const rows = _parent.querySelectorAll('.form-row-group')
return Array.from(rows)
.map(row => {
const pairs = _fields
.map(field => [field, row.querySelector(`.${field}-input`).value])

if (pairs.some(([, value]) => value === '')) {
return null
}

return pairs.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
})
.filter(row => !!row)
}

function reset() {
Array.from(_parent.querySelectorAll('.form-row-group'))
.map(row => {
const action = row.querySelector('button')
const handle = action.classList.contains('add') ? _handleAdd : _handleRemove
action.removeEventListener('click', handle, false)
row.remove()
})

_append(_parent, _handleAdd, true, _fields)
}

function _handleRemove(e) {
const action = e.target
action.removeEventListener('click', _handleRemove, false)
action.parentNode.remove()

if (typeof onChange === 'function') {
onChange()
}
}

function _handleAdd(e) {
const row = e.target.parentNode

const pairs = _fields
.map(field => [field, row.querySelector(`.${field}-input`).value])

if (pairs.some(([, value]) => value === '')) {
return
}

_append(_parent, _handleAdd, true, _fields)
_swapAction(row)

if (typeof onChange === 'function') {
onChange()
}
}

function _swapAction(parent) {
const removeAction = _createNode('button', ['flex-auto', 'remove'], ACTION_SYMBOLS.remove, { type: 'button' })
const addAction = parent.querySelector('.add')

removeAction.addEventListener('click', _handleRemove, false)
addAction.removeEventListener('click', _handleAdd, false)

addAction.remove()
parent.appendChild(removeAction)
}

return {
init,
query,
reset
}
}

export default DynamicParams
20 changes: 20 additions & 0 deletions src/demo/dynamic-params/dynamic-params.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.dynamic-params {
h3 {
font-weight: normal;
color: $fontColor;
font-size: 15px;
margin-bottom: 10px;
}

.form-row-group {
margin-bottom: 10px;
align-items: end;
justify-content: space-between;
gap: 3px;
}

button {
padding: 5px 10px;
margin-left: 5px;
}
}
4 changes: 2 additions & 2 deletions src/demo/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import switchBackToOnlineModeInit from './switch-back-to-online-mode/switch-back
import stopInit from './stop/stop'
import restartInit from './restart/restart'
import gdprForgetMeInit from './gdpr-forget-me/gdpr-forget-me'
import disableThirdPartySharingInit from './disable-third-party-sharing/disable-third-party-sharing'
import trackThirdPartySharingInit from './track-third-party-sharing/track-third-party-sharing'
import getWebUUID from './get-web-uuid/get-web-uuid'
import getAttribution from './get-attribution/get-attribution'
import setReferrer from './set-referrer/set-referrer'
Expand All @@ -32,7 +32,7 @@ function init (defaultAppConfig, defaultEventConfig) {
stopInit()
restartInit()
gdprForgetMeInit()
disableThirdPartySharingInit()
trackThirdPartySharingInit()
getWebUUID()
getAttribution()
setReferrer()
Expand Down
32 changes: 32 additions & 0 deletions src/demo/track-third-party-sharing/track-third-party-sharing.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div class="action-block">
<div class="action-wrap flex-box-row">
<button id="track-tps-button" class="action flex-one">Track Third Party Sharing</button>
<button type="button" id="tps-side-form-toggle" class="form-toggle flex-auto">...</button>
</div>

<div class="side-form fixed" id="track-tps">
<div class="flex-box-row">
<form class="flex-one" id="tps-config-form">
<div class="flex-box-column flex-two">
<div class="flex-box-row" style="margin-bottom: 10px;">
<label for="enable-tps">Enable/disable third party sharing</label>
<input type="checkbox" id="enable-tps" checked />
</div>

<div id="tps-granular" class="form-row flex-box-column dynamic-params">
<h3>Granular options</h3>
</div>

<div id="tps-partner-sharing" class="form-row flex-box-column dynamic-params">
<h3>Partner sharing settings</h3>
</div>

</div>

<button type="submit">Save and Run</button>
</form>

<pre class="flex-one config" id="tps-config-json"></pre>
</div>
</div>
</div>
130 changes: 130 additions & 0 deletions src/demo/track-third-party-sharing/track-third-party-sharing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import Adjust from '../../sdk/main'
import { getItem, setItem } from '../storage'
import DynamicParams from '../dynamic-params/dynamic-params'

const _ui = {}
let _tpsOptions = {}
let _disabled = false
let _timeoutId = null
let _granularOptions = null
let _partnerSharingSettings = null

function init() {
_tpsOptions = getItem('tpsOptions') || { isEnabled: true, granularOptions: [], partnerSharingSettings: [] }

_ui.tpsOptionsForm = document.getElementById('tps-config-form')
_ui.tpsOptionsJson = document.getElementById('tps-config-json')
_ui.trackTPSButton = document.getElementById('track-tps-button')
_ui.toggleButton = document.getElementById('tps-side-form-toggle')
_ui.enableTPS = document.getElementById('enable-tps')
_ui.submitButton = _ui.tpsOptionsForm.querySelector('button[type="submit"]')

_ui.tpsOptionsForm.addEventListener('submit', _handleSave)
_ui.toggleButton.addEventListener('click', _handleToggle)
_ui.trackTPSButton.addEventListener('click', _handleTrackTPS)

_ui.enableTPS.addEventListener('change', () => {
_tpsOptions.isEnabled = _ui.enableTPS.checked
setItem('tpsOptions', _tpsOptions)
_setJson(_tpsOptions)
})

_granularOptions = DynamicParams('tps-granular', ['partnerName', 'key', 'value'], _tpsOptions.granularOptions,
() => {
_tpsOptions.granularOptions = _granularOptions.query()
_setJson(_tpsOptions)
setItem('tpsOptions', _tpsOptions)
})
_granularOptions.init()

_partnerSharingSettings = DynamicParams('tps-partner-sharing', ['partnerName', 'key', 'value'], _tpsOptions.partnerSharingSettings,
() => {
_tpsOptions.partnerSharingSettings = _partnerSharingSettings.query()
_setJson(_tpsOptions)
setItem('tpsOptions', _tpsOptions)
})
_partnerSharingSettings.init()

_setJson(_tpsOptions)
}

function _trackThirdPartySharing(tpsOptions) {
const options = new Adjust.ThirdPartySharing(tpsOptions.isEnabled)

for (const option of tpsOptions.granularOptions) {
options.addGranularOption(option.partnerName, option.key, option.value)
}

for (const option of tpsOptions.partnerSharingSettings) {
const value = option.value === 'false' ? false : !!option.value
options.addPartnerSharingSetting(option.partnerName, option.key, value)
}

Adjust.trackThirdPartySharing(options)
}

function _handleSave(e) {
e.preventDefault()

if (_disabled) {
return
}

_disabled = true
_ui.submitButton.classList.add('loading')
_ui.submitButton.disabled = true

clearTimeout(_timeoutId)
_timeoutId = setTimeout(() => {
_disabled = false
_ui.submitButton.classList.remove('loading')
_ui.submitButton.disabled = false

_trackThirdPartySharing(_tpsOptions)
}, 1000)
}

function _handleTrackTPS() {
if (_disabled) {
return
}

_disabled = true
_ui.trackTPSButton.classList.add('loading')
_ui.trackTPSButton.disabled = true

clearTimeout(_timeoutId)
_timeoutId = setTimeout(() => {
_disabled = false
_ui.trackTPSButton.classList.remove('loading')
_ui.trackTPSButton.disabled = false

_trackThirdPartySharing(_tpsOptions)
}, 1000)
}

function _handleToggle(e) {
const target = e.target
const sideForm = target.parentNode.nextElementSibling

sideForm.classList.toggle('show')
target.classList.toggle('active')
}

function _setJson(tpsOptions) {
let text = `const options = new Adjust.ThirdPartySharingOptions(${tpsOptions.isEnabled});\n`

for (const option of tpsOptions.granularOptions) {
text += `option.addGranularOption('${option.partnerName}', '${option.key}', '${option.value}')\n`
}

for (const option of tpsOptions.partnerSharingSettings) {
text += `option.addPartnerSharingSetting('${option.partnerName}', '${option.key}', '${option.value}')\n`
}

text += 'Adjust.trackThirdPartySharing(options);'

_ui.tpsOptionsJson.textContent = text
}

export default init
5 changes: 5 additions & 0 deletions src/demo/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ function hyphenToCamelCase (string) {
return string.replace(/(-\w)/g, ([, m]) => m.toUpperCase())
}

function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

function debounce (fn, wait = 500) {
let timeout
return function () {
Expand All @@ -12,5 +16,6 @@ function debounce (fn, wait = 500) {

export {
hyphenToCamelCase,
capitalize,
debounce
}
Loading

0 comments on commit 1ddda6b

Please sign in to comment.