├── .DS_Store ├── .expo ├── packager-info.json └── settings.json ├── api.js ├── index.js ├── package.json └── story ├── Constants.js ├── Story.js ├── StoryItem.js └── utils.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visilabs/Visilabs-React-Native/80d8467b3d9237280424b42b8f7484c9320b8299/.DS_Store -------------------------------------------------------------------------------- /.expo/packager-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "devToolsPort": 19002 3 | } -------------------------------------------------------------------------------- /.expo/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "hostType": "lan", 3 | "lanType": "ip", 4 | "dev": true, 5 | "minify": false, 6 | "urlRandomness": null 7 | } -------------------------------------------------------------------------------- /api.js: -------------------------------------------------------------------------------- 1 | import { Platform } from "react-native" 2 | import AsyncStorage from '@react-native-async-storage/async-storage' 3 | import Constants from 'expo-constants' 4 | var querystring = require('querystring'); 5 | 6 | function checkStatus(response) { 7 | if (response.status >= 200 && response.status < 300) { 8 | return response 9 | } else { 10 | var error = new Error(response.statusText) 11 | error.response = response 12 | throw error 13 | } 14 | } 15 | 16 | var create_api = function(organizationID, siteID, segmentURL, dataSource, realTimeURL, channel, euroMsgApplicationKey, euroMsgSubscriptionURL, euroMsgRetentionURL, local) { 17 | 18 | const sdkVersion = "1.0.34"; 19 | const euroSubscriptionKey = "subscription"; 20 | const suggestActionsKey = 'suggestActionsParams'; 21 | 22 | let runController = 0, _VTObjsID = 0; 23 | 24 | var api = {}; 25 | var keysToBeStored = ["OM.cookieID", "OM.exVisitorID", "OM.sys.AppID", "OM.sys.TokenID", "OM.channel", "OM.vchannel"]; 26 | const keysToBeStoredForActjs = ["OM.voss","OM.vcname","OM.vcmedium","OM.vcsource","OM.vpv","OM.lpvs","OM.lpp","OM.vq","OM.vrDomain"]; 27 | 28 | if(!organizationID || !siteID || !segmentURL || !dataSource || !realTimeURL || !channel || !euroMsgApplicationKey || !euroMsgSubscriptionURL || !euroMsgRetentionURL) { 29 | throw new Error("Missing parameters (Visilabs)!"); 30 | } 31 | 32 | api.organizationID = organizationID; 33 | api.siteID = siteID; 34 | api.segmentURL = segmentURL; 35 | api.dataSource = dataSource; 36 | api.realTimeURL = realTimeURL; 37 | api.suggestActionURL = "http://s.visilabs.net/"; 38 | api.suggestActionMobileURL = "https://s.visilabs.net/mobile"; 39 | api.channel = channel; 40 | api.euroMsgApplicationKey = euroMsgApplicationKey; 41 | api.euroMsgSubscriptionURL = euroMsgSubscriptionURL; 42 | api.euroMsgRetentionURL = euroMsgRetentionURL; 43 | api.local = local; 44 | 45 | AsyncStorage.setItem("OM.vchannel", channel); 46 | 47 | 48 | 49 | var guid = function(){ 50 | function s4() { 51 | return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); 52 | } 53 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); 54 | }; 55 | 56 | var send = function(url, method, data, callback){ 57 | var options = {}; 58 | options["method"] = method == null ? "GET" : method; 59 | 60 | if(method === "POST"){ 61 | options["headers"] = { "Content-Type" : "application/json", "Cache-Control" : "no-cache"} 62 | } 63 | 64 | if(data) { 65 | options["body"] = JSON.stringify(data); 66 | } 67 | fetch(url, options) 68 | .then(d => { callback(d);}) 69 | .catch(err => { 70 | callback(err); 71 | }); 72 | }; 73 | 74 | var setCookieID = function(){ 75 | var cookieID = guid(); 76 | AsyncStorage.setItem("OM.cookieID", cookieID); 77 | return cookieID; 78 | } 79 | 80 | var isEmptyOrSpaces = function (str){ 81 | return (str === undefined || str === null) || str.match(/^ *$/) !== null; 82 | } 83 | 84 | const getCustomTime = () => { 85 | var d = new Date(); 86 | var date_format_str = d.getFullYear().toString() + "-" + ((d.getMonth() + 1).toString().length == 2 ? (d.getMonth() + 1).toString() : "0" + (d.getMonth() + 1).toString()) + "-" + (d.getDate().toString().length == 2 ? d.getDate().toString() : "0" + d.getDate().toString()) + " " + (d.getHours().toString().length == 2 ? d.getHours().toString() : "0" + d.getHours().toString()) + ":" + ((d.getMinutes()).toString().length == 2 ? (d.getMinutes()).toString() : "0" + (d.getMinutes()).toString()) + ":" + (d.getSeconds()).toString(); 87 | return date_format_str 88 | } 89 | 90 | api.suggestActionsParams = { // api olduktan sonra bozulan bir parametre oldu mu kontrol et. İçeride erişilemeyen function var mı? 91 | set: async function (data) { 92 | if (!data) return 93 | 94 | AsyncStorage.setItem(suggestActionsKey, JSON.stringify(data)); 95 | }, 96 | get: async function () { 97 | return JSON.parse(await AsyncStorage.getItem(suggestActionsKey)); 98 | }, 99 | check: async function (clientData, story = false, callback = () => {}) { 100 | this.get().then((storageParams)=>{ 101 | let storageParameters = storageParams ? storageParams : {} 102 | let clientParameters = clientData ? clientData : {} 103 | 104 | let convertedClientParams = convertParams(clientParameters); 105 | 106 | let lpvsArr = []; 107 | 108 | if (storageParameters["OM.lpvs"]) 109 | lpvsArr = perseObjectLPVS(decodeURI(storageParameters["OM.lpvs"])) 110 | 111 | 112 | if (convertedClientParams["OM.vpv"]) { 113 | if (checkAlreadyDefined(convertedClientParams["OM.vpv"],lpvsArr)) { 114 | lpvsArr = isAlreadyDefined(convertedClientParams["OM.vpv"],lpvsArr) 115 | } 116 | else{ 117 | if (lpvsArr.length >= 10) { 118 | lpvsArr.pop(); 119 | } 120 | 121 | lpvsArr.unshift({ 122 | eventId:convertedClientParams["OM.vpv"], 123 | date:getCustomTime() 124 | }) 125 | } 126 | } 127 | 128 | let lpvs = objectArrayToString(lpvsArr) 129 | 130 | if (lpvs) { 131 | convertedClientParams["OM.lpvs"] = encodeURI(lpvs) 132 | } 133 | 134 | let requestParams = joinObjectArrays(storageParameters, convertedClientParams); 135 | 136 | requestParams["OM.obj"] = '_VTObjs["_VisilabsTarget_'+_VTObjsID+'"]'; 137 | 138 | const parametersToStorage = paramsToStorage(requestParams); 139 | 140 | this.set(parametersToStorage); 141 | 142 | if (story) { 143 | api.sendRequest(requestParams, (response)=>{ 144 | if(!response) return 145 | 146 | callback(response); 147 | _VTObjsID++; 148 | }, true, true); 149 | }else{ 150 | api.sendRequest(requestParams, (response)=>{ 151 | _VTObjsID++; 152 | }, true); 153 | } 154 | 155 | 156 | }) 157 | }, 158 | delete: async function () { 159 | AsyncStorage.removeItem(suggestActionsKey) 160 | } 161 | } 162 | 163 | function convertParams(data) { 164 | let obj = { 165 | "OM.voss":data["OM.OSS"] ? data["OM.OSS"] : null, 166 | "OM.vcname":data["OM.cname"] ? data["OM.cname"] : null, 167 | "OM.vcmedium":data["OM.cmedium"] ? data["OM.cmedium"] : null, 168 | "OM.vcsource":data["OM.csource"] ? data["OM.csource"] : null, 169 | "OM.vpv":data["OM.pv"] ? data["OM.pv"] : null, 170 | "OM.lpp":data["OM.pp"] ? (data["OM.ppr"] ? data["OM.pp"]+"|"+data["OM.ppr"]+"|"+getCustomTime() : data["OM.pp"]) : null, // son 1 ürün 171 | "OM.vq":data["OM.q"] ? data["OM.q"] : null, 172 | "OM.vrDomain":data["OM.rDomain"] ? data["OM.rDomain"] : null, 173 | ...data 174 | } 175 | 176 | for (var prop in obj) { 177 | if (!obj[prop]) 178 | delete obj[prop]; 179 | } 180 | 181 | return obj 182 | } 183 | 184 | function perseObjectLPVS(lpvs) { 185 | if(!lpvs) return 186 | 187 | let products = [], resultArr = []; 188 | products = lpvs.split('~'); 189 | products.forEach(product => { 190 | let productDetail = product.split('|'); 191 | resultArr.push( 192 | { 193 | eventId:productDetail[0], 194 | date:productDetail[1] 195 | } 196 | ) 197 | }); 198 | 199 | return resultArr 200 | } 201 | 202 | function objectArrayToString(arr) { 203 | if(!arr) return 204 | 205 | let resultArr = arr.map(function(product) { 206 | return product['eventId']+"|"+product['date']; 207 | }); 208 | 209 | let resultString = resultArr.join('~') 210 | 211 | return resultString 212 | } 213 | 214 | function checkAlreadyDefined(id,arr) { 215 | let result=false; 216 | 217 | arr.forEach(product => { 218 | if (product.eventId == id) { 219 | result = true 220 | } 221 | }); 222 | 223 | return result 224 | } 225 | 226 | function isAlreadyDefined(id,arr) { 227 | let alreadyDefinedProduct; 228 | 229 | arr.forEach(product => { 230 | if (product.eventId == id) { 231 | alreadyDefinedProduct = product; 232 | const index = arr.indexOf(product); 233 | if (index > -1) { 234 | arr.splice(index, 1); 235 | } 236 | } 237 | }); 238 | 239 | if (alreadyDefinedProduct) { 240 | alreadyDefinedProduct.date = getCustomTime(); 241 | arr.unshift(alreadyDefinedProduct) 242 | } 243 | 244 | return arr 245 | } 246 | 247 | function paramsToStorage(params) { 248 | let resutlArr = {} 249 | 250 | for (let i = 0; i < keysToBeStoredForActjs.length-1; i++) { 251 | if (params[keysToBeStoredForActjs[i]] != undefined) { 252 | resutlArr[keysToBeStoredForActjs[i]] = params[keysToBeStoredForActjs[i]] 253 | } 254 | } 255 | 256 | return resutlArr 257 | } 258 | 259 | function joinObjectArrays(obj1,obj2) { 260 | if (!obj1 || !obj1) return 261 | 262 | var obj3 = {}; 263 | for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; } 264 | for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; } 265 | 266 | return obj3; 267 | } 268 | 269 | api.sendRequest = function(data, callback, targetAction = false, story = false) { 270 | callback = callback || function() {}; 271 | data["OM.vchannel"] = api.channel; 272 | var valuesToSet = []; 273 | 274 | for(var i = 0; i < keysToBeStored.length; i++){ 275 | if(data[keysToBeStored[i]] != undefined){ 276 | valuesToSet.push([keysToBeStored[i], data[keysToBeStored[i]]]); 277 | delete data[keysToBeStored[i]]; 278 | } 279 | } 280 | 281 | data["OM.siteID"] = api.siteID; 282 | data["OM.oid"] = api.organizationID; 283 | 284 | AsyncStorage.getItem("OM.exVisitorID").then(exVisitorID => { 285 | AsyncStorage.multiSet(valuesToSet).finally(error => { 286 | AsyncStorage.multiGet(keysToBeStored).then(response => { 287 | for(var j = 0; j < response.length; j++){ 288 | if(response[j][1] != null) 289 | data[response[j][0]] = response[j][1]; 290 | } 291 | 292 | if(!data["OM.cookieID"] || (!isEmptyOrSpaces(exVisitorID) && !isEmptyOrSpaces(data["OM.exVisitorID"]) && exVisitorID != data["OM.exVisitorID"])){ 293 | data["OM.cookieID"] = setCookieID(); 294 | } 295 | 296 | if (targetAction) { 297 | if (story) { 298 | var sUrl = api.suggestActionMobileURL + "?" + querystring.stringify(data); 299 | send(sUrl, "GET", null, callback); 300 | }else{ 301 | var sUrl = api.suggestActionURL + "act.js?" + querystring.stringify(data); // actjson yap 302 | send(sUrl, "GET", null, callback); 303 | } 304 | 305 | }else{ 306 | var lgrUrl = api.segmentURL + "/" + api.dataSource + "/om.gif?" + querystring.stringify(data); 307 | var rtUrl = api.realTimeURL + "/" + api.dataSource + "/om.gif?" + querystring.stringify(data); 308 | 309 | send(lgrUrl, "GET", null, callback); 310 | send(rtUrl, "GET", null, callback); 311 | } 312 | }); 313 | 314 | }); 315 | }); 316 | 317 | }; 318 | 319 | api.customEvent = function(pageName, properties, callback) { 320 | if (!properties || typeof properties === "function") { 321 | callback = properties; 322 | properties = {}; 323 | } 324 | properties["OM.uri"] = pageName; 325 | api.suggestActionsParams.check(properties); 326 | api.sendRequest(properties, callback); 327 | }; 328 | 329 | api.registerToken = function(appAlias, token, callback) { 330 | var properties = {}; 331 | properties["OM.sys.AppID"] = appAlias; 332 | properties["OM.sys.TokenID"] = token; 333 | api.customEvent("RegisterToken", properties, callback); 334 | }; 335 | 336 | api.login = function(exVisitorID, properties, callback) { 337 | if(properties == null) 338 | properties = {}; 339 | properties["OM.exVisitorID"] = exVisitorID; 340 | properties["Login"] = exVisitorID; 341 | properties["OM.b_login"] = "Login"; 342 | api.customEvent("LoginPage", properties, callback); 343 | }; 344 | 345 | api.signUp = function(exVisitorID, properties, callback) { 346 | if(properties == null) 347 | properties = {}; 348 | properties["OM.exVisitorID"] = exVisitorID; 349 | properties["SignUp"] = exVisitorID; 350 | properties["OM.b_sgnp"] = "SignUp"; 351 | api.customEvent("SignUpPage", properties, callback); 352 | }; 353 | 354 | 355 | api.getExVisitorIDasync = async function () { 356 | return await AsyncStorage.getItem('OM.exVisitorID'); 357 | }; 358 | 359 | api.clearIDs = function () { 360 | AsyncStorage.multiGet(["OM.exVisitorID", "OM.cookieID"]).then(idArr => { 361 | 362 | api.customEvent("ClearIDs", { 363 | "OM.ClearIDs":"1", 364 | "OM.exVisitorID": idArr[0][1], 365 | "OM.cookieID": idArr[1][1] 366 | }, function () { 367 | if (runController % 2 == 0) { 368 | runController++; 369 | AsyncStorage.removeItem("OM.exVisitorID"), 370 | AsyncStorage.removeItem("OM.cookieID").then(res => setCookieID()) 371 | } 372 | }) 373 | 374 | }) 375 | } 376 | 377 | api.getIDsAsync = async function () { 378 | return await AsyncStorage.multiGet(["OM.exVisitorID", "OM.cookieID"]) 379 | } 380 | 381 | 382 | api.euromsg = { 383 | 384 | setUser : function(user){ 385 | 386 | if(user === undefined) 387 | return; 388 | 389 | AsyncStorage.getItem(euroSubscriptionKey).then(subscriptionString => { 390 | var subscription = JSON.parse(subscriptionString); 391 | if(!subscription){ 392 | subscription = {}; 393 | } 394 | // subscription["appVersion"] = isEmptyOrSpaces(subscription["appVersion"]) ? Constants.manifest.version : subscription["appVersion"]; 395 | subscription["appKey"] = api.euroMsgApplicationKey; 396 | subscription["os"] = Platform.OS; 397 | // subscription["deviceType"] = Constants.deviceName; 398 | // subscription["deviceName"] = Constants.deviceName; 399 | subscription["carrier"] = ""; //TODO: 400 | subscription["local"] = api.local; 401 | subscription["identifierForVendor"] = Constants.deviceId; 402 | subscription["advertisingIdentifier"] = ""; //TODO: 403 | subscription["sdkVersion"] = sdkVersion; 404 | subscription["firstTime"] = 1; 405 | subscription["identifierForVendor"] = Constants.deviceId; 406 | 407 | if(!subscription["extra"]){ 408 | subscription["extra"] = {}; 409 | } 410 | 411 | if(user["keyID"] != undefined) 412 | subscription["extra"]["keyID"] = user["keyID"]; 413 | 414 | if(user["email"] != undefined) 415 | subscription["extra"]["email"] = user["email"]; 416 | 417 | if(user["token"] != undefined && user["token"] != null) 418 | subscription["token"] = user["token"]; 419 | 420 | if(user["pushPermit"] != undefined && user["pushPermit"] != null) 421 | subscription["extra"]['pushPermit'] = user["pushPermit"] 422 | 423 | if(user["gsmPermit"] != undefined && user["gsmPermit"] != null) 424 | subscription["extra"]['gsmPermit'] = user["gsmPermit"] 425 | 426 | if(user["emailPermit"] != undefined && user["emailPermit"] != null) 427 | subscription["extra"]['emailPermit'] = user["emailPermit"] 428 | 429 | send(api.euroMsgSubscriptionURL, "POST", subscription, function() {}); 430 | AsyncStorage.setItem(euroSubscriptionKey, JSON.stringify(subscription)); 431 | }); 432 | }, 433 | 434 | subscribe: function(token) { 435 | AsyncStorage.getItem(euroSubscriptionKey).then(subscriptionString => { 436 | var subscription = JSON.parse(subscriptionString); 437 | try { 438 | if(!subscription){ 439 | subscription = {}; 440 | } 441 | 442 | // if(Constants.platform.ios !== undefined){ 443 | // subscription["osVersion"] = Constants.platform.ios.systemVersion === undefined ? "" : Constants.platform.ios.systemVersion; 444 | // } 445 | // else if(Constants.platform.android !== undefined){ 446 | // subscription["osVersion"] = Constants.platform.android.systemVersion === undefined ? "" : Constants.platform.android.systemVersion; 447 | // } 448 | 449 | subscription["token"] = token; 450 | // subscription["appVersion"] = isEmptyOrSpaces(subscription["appVersion"]) ? Constants.manifest.version : subscription["appVersion"]; 451 | subscription["appKey"] = api.euroMsgApplicationKey; 452 | subscription["os"] = Platform.OS; 453 | // subscription["deviceType"] = Constants.deviceName; 454 | // subscription["deviceName"] = Constants.deviceName; 455 | subscription["carrier"] = ""; //TODO: 456 | subscription["local"] = api.local; 457 | subscription["identifierForVendor"] = Constants.deviceId; 458 | subscription["advertisingIdentifier"] = ""; //TODO: 459 | subscription["sdkVersion"] = sdkVersion; 460 | subscription["firstTime"] = 1; 461 | subscription["identifierForVendor"] = Constants.deviceId; 462 | if(subscription["extra"] === undefined) 463 | subscription["extra"] = {}; 464 | 465 | if(subscription["extra"]['pushPermit'] !== undefined && subscription["extra"]['pushPermit'] !== null) 466 | subscription["extra"]['pushPermit'] = subscription["extra"]['pushPermit']; 467 | 468 | if(subscription["extra"]['gsmPermit'] !== undefined && subscription["extra"]['gsmPermit'] !== null) 469 | subscription["extra"]['gsmPermit'] = subscription["extra"]['gsmPermit']; 470 | 471 | if(subscription["extra"]['emailPermit'] !== undefined && subscription["extra"]['emailPermit'] !== null) 472 | subscription["extra"]['emailPermit'] = subscription["extra"]['emailPermit']; 473 | 474 | send(api.euroMsgSubscriptionURL, "POST", subscription, function() {}); 475 | AsyncStorage.setItem(euroSubscriptionKey, JSON.stringify(subscription)); 476 | 477 | } catch (error) { } 478 | }); 479 | 480 | }, 481 | 482 | reportRead : function(pushId){ 483 | if(!pushId) new Error("PushId missing!"); 484 | 485 | AsyncStorage.getItem(euroSubscriptionKey).then(subscriptionString => { 486 | var subscription = JSON.parse(subscriptionString); 487 | var retention = {}; 488 | retention["key"] = api.euroMsgApplicationKey; 489 | retention["pushId"] = pushId; 490 | retention["status"] = "O"; 491 | var subscription = JSON.parse(subscriptionString); 492 | if(subscription){ 493 | retention["token"] = subscription["token"]; 494 | } 495 | 496 | send(api.euroMsgRetentionURL, "POST", retention, function() {}); 497 | }); 498 | }, 499 | 500 | removeUserProperties : function(){ 501 | AsyncStorage.getItem(euroSubscriptionKey).then(subscriptionString => { 502 | var subscription = JSON.parse(subscriptionString); 503 | if(!subscription){ 504 | subscription = {}; 505 | } 506 | if(subscription["extra"]){ 507 | subscription["extra"] = {}; 508 | } 509 | AsyncStorage.setItem(euroSubscriptionKey, JSON.stringify(subscription)); 510 | }); 511 | } 512 | 513 | } 514 | 515 | return api; 516 | } 517 | 518 | module.exports = { 519 | create_api: create_api 520 | }; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import {create_api} from './api' 2 | import Story from './story/Story' 3 | 4 | module.exports = { 5 | create_api, 6 | Story 7 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@relateddigital/visilabs-react-native", 3 | "version": "1.0.33", 4 | "description": "visilabs react native sdk", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "visilabs", 11 | "relateddigital" 12 | ], 13 | "author": "visilabs", 14 | "license": "ISC", 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/visilabs/Visilabs-React-Native.git" 18 | }, 19 | "bugs": { 20 | "url": "https://github.com/visilabs/Visilabs-React-Native/issues" 21 | }, 22 | "homepage": "https://github.com/visilabs/Visilabs-React-Native#readme", 23 | "dependencies": { 24 | "querystring": "^0.2.0", 25 | "expo-constants": "^8.0.0", 26 | "@react-native-community/async-storage": "1.12.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /story/Constants.js: -------------------------------------------------------------------------------- 1 | import { Platform } from "react-native" 2 | 3 | export const storylb = "story_looking_banners" 4 | export const BORDER_COLOR = "#cb2d8c" 5 | export const BORDER_WIDTH = 2 6 | export const LABEL_COLOR = "white" 7 | export const isIOS = Platform.OS == "ios" ? true : false 8 | export const evtgif = "om_evt.gif" 9 | export const apiver = "expo" 10 | export const action_type = "Story" -------------------------------------------------------------------------------- /story/Story.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { View, ScrollView } from 'react-native'; 3 | import StoryItem from './StoryItem'; 4 | import { storylb,isIOS,evtgif,action_type,apiver } from './Constants' 5 | 6 | import { returnSeenStories, clearSeenList, splitParameters, returnBorderRadius, returnActid, returnId } from './utils' 7 | 8 | export default class Story extends Component { 9 | constructor(props) { 10 | super(props) 11 | this.size = this.props.size ? this.props.size : (isIOS ? 68 : 100) 12 | this.state = { 13 | data:[], 14 | ready: false 15 | } 16 | this.height = this.props.rectangle ? this.size * this.props.rectangle : this.size, 17 | this.rectangle = this.props.rectangle ? this.props.rectangle : 1 18 | this.callback = this.callback.bind(this) 19 | this.storyStyle = {}; 20 | 21 | // clearSeenList() 22 | 23 | let properties = this.props.eventParameters ? this.props.eventParameters : {} 24 | 25 | properties["action_type"] = action_type; 26 | properties["OM.apiver"] = apiver; 27 | if (this.props.pageName) properties["OM.uri"] = this.props.pageName; 28 | if (this.props.action_id) properties["action_id"] = this.props.action_id; 29 | 30 | this.api = this.props.api; 31 | this.api.suggestActionsParams.check(properties, true, (data) => { 32 | data.json().then((actions) => { 33 | if (!actions.Story[0]) return 34 | 35 | this.story = actions.Story[0].actiondata 36 | this.storyStyles = JSON.parse(unescape(this.story.ExtendedProps)) 37 | this.storyReportParameters = splitParameters(this.story.report.click) 38 | this.stories = this.story.stories 39 | this.storyTemplate = this.story.taTemplate 40 | this.actid = returnActid(this.storyReportParameters) 41 | 42 | this.stroylbProcess(this.storyTemplate,this.stories,this.storyStyles) 43 | }) 44 | }); 45 | } 46 | 47 | stroylbProcess(template, stories, styles) { 48 | if (!template || !stories || !styles) return 49 | 50 | if (template == storylb) { 51 | this.storyStyle.borderColor = styles.storylb_img_borderColor || false; 52 | this.storyStyle.borderRadius = returnBorderRadius(styles.storylb_img_borderRadius,this.size); 53 | this.storyStyle.labelColor = styles.storylb_label_color || false; 54 | this.storyStyle.borderWidth = styles.storylb_img_borderWidth || false; 55 | this.storyStyle.shadow = styles.storylb_img_boxShadow ? true : false; 56 | this.storyStyle.moveShownToEnd = styles.moveShownToEnd === "false" ? false : true; 57 | 58 | let data = []; 59 | stories.forEach((s,i) => { 60 | data.push({ 61 | key: i+1, 62 | url: s.link, 63 | title: s.title, 64 | image: s.smallImg, 65 | seen: false 66 | }) 67 | }); 68 | this.seenStories(data,this.storyStyle.moveShownToEnd) 69 | } 70 | } 71 | 72 | seenStories(rawData,moveShownToEnd) { 73 | returnSeenStories(rawData,(res)=>{ 74 | this.setState({ data: res},()=>{ 75 | this.setState({ready:true}) 76 | }) 77 | },this.actid,moveShownToEnd) 78 | } 79 | 80 | callback(key) { 81 | this.sendCampaignParams() 82 | let newData = this.state.data 83 | newData.forEach(obj => { 84 | if (returnId(this.actid,obj.title) === key) { 85 | obj.seen = true 86 | } 87 | }); 88 | this.setState({ data: newData }) 89 | } 90 | 91 | sendCampaignParams(){this.api.customEvent(evtgif,this.storyReportParameters)} 92 | 93 | storyItems = (items) => ( 94 | items.map((item) => { 95 | return ( 96 | {}} 101 | callback={this.callback} 102 | shape={this.storyStyle.borderRadius} 103 | rectangle={this.rectangle} 104 | borderColor={this.storyStyle.borderColor} 105 | borderWidth={this.storyStyle.borderWidth} 106 | labelColor={this.storyStyle.labelColor} 107 | shadow={this.storyStyle.shadow} 108 | actid={this.actid} 109 | /> 110 | ); 111 | }) 112 | ); 113 | 114 | render() { 115 | return ( 116 | 117 | {this.state.ready && 118 | 119 | {this.storyItems(this.state.data)} 120 | 121 | } 122 | 123 | ); 124 | } 125 | } -------------------------------------------------------------------------------- /story/StoryItem.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { View, Text, Image, TouchableOpacity, StyleSheet } from 'react-native'; 3 | 4 | import { dots, returnId, seen } from './utils' 5 | import { LABEL_COLOR, BORDER_COLOR, BORDER_WIDTH } from './Constants' 6 | 7 | export default class StoryItem extends Component { 8 | constructor(props) { 9 | super(props) 10 | this.size = this.props.size - (this.props.data.seen ? 27 : 30) 11 | this.id = returnId(this.props.actid,this.props.data.title) 12 | } 13 | 14 | press() { 15 | seen(this.id) 16 | this.props.action(this.props.data) 17 | this.props.callback(this.id) 18 | } 19 | 20 | render() { 21 | const width = this.size, 22 | height = this.props.rectangle ? this.size * this.props.rectangle : this.size, 23 | borderRadius = this.props.shape, 24 | borderColor = this.props.borderColor ? this.props.borderColor : BORDER_COLOR, 25 | borderWidth = this.props.borderWidth ? parseFloat(this.props.borderWidth) : BORDER_WIDTH, 26 | color = this.props.labelColor ? this.props.labelColor : LABEL_COLOR 27 | return ( 28 | this.press()}> 31 | 36 | 39 | 40 | {dots(this.props.data.title, 7)} 41 | 42 | ); 43 | } 44 | } 45 | 46 | const styles = StyleSheet.create({ 47 | itemContainer: { 48 | margin: 3, 49 | padding: 3, 50 | marginHorizontal: 5, 51 | }, 52 | seen: { 53 | padding: 4, 54 | borderWidth: 1, 55 | borderColor: "#aaa" 56 | }, 57 | center: { 58 | justifyContent: 'center', 59 | alignItems: 'center', 60 | }, 61 | title: { 62 | fontWeight: "400", 63 | }, 64 | item: { 65 | flex: 1, 66 | resizeMode: 'cover', 67 | }, 68 | shadow: { 69 | shadowColor: "#000", 70 | shadowOffset: { 71 | width: 0, 72 | height: 0, 73 | }, 74 | shadowOpacity: 0.32, 75 | shadowRadius: 5.46, 76 | elevation: 3, 77 | } 78 | }) -------------------------------------------------------------------------------- /story/utils.js: -------------------------------------------------------------------------------- 1 | import AsyncStorage from '@react-native-async-storage/async-storage'; 2 | 3 | const key = 'seen' 4 | 5 | export const dots = (str, len) => { 6 | if (str.length > len) { 7 | return str.substr(0, len) + "..." 8 | } 9 | return str 10 | } 11 | 12 | export const seen = (index) => { 13 | getSeenList().then(val => { 14 | let arr = (NUSC(val) ? [] : val.split(",")); 15 | if (arr.indexOf(index) < 0) { 16 | arr.push(index); 17 | setSeenList(arr); 18 | } 19 | }) 20 | } 21 | 22 | export const getSeenList = async () => { 23 | return (await AsyncStorage.getItem(key)) 24 | } 25 | 26 | export const setSeenList = (arr) => { 27 | if (!arr) var arr = [] 28 | 29 | AsyncStorage.setItem(key, arr.toString()); 30 | } 31 | 32 | export const returnSeenStories = (obj,callback,actid,moveShownToEnd) => { 33 | if (!obj) var obj = {} 34 | 35 | getSeenList().then(keys => { 36 | 37 | if (NUSC(keys)) { 38 | callback(obj) 39 | return 40 | } 41 | 42 | let seenKeys = keys.split(","), seenList = [], notSeenList = [] 43 | 44 | obj.forEach((story,i) => { 45 | if (seenKeys.indexOf(returnId(actid,story.title)) >= 0) { 46 | story.seen = true 47 | 48 | seenList = obj.filter((item)=>{ 49 | return item.seen == true 50 | }); 51 | 52 | notSeenList = obj.filter((item)=>{ 53 | return item.seen == false 54 | }); 55 | } 56 | 57 | if (i+1 >= obj.length) { 58 | if (moveShownToEnd) callback([...notSeenList,...seenList]) 59 | else callback(obj) 60 | } 61 | }); 62 | }) 63 | } 64 | 65 | export const clearSeenList = () => { 66 | AsyncStorage.setItem(key, ""); 67 | return "Success clean"; 68 | } 69 | 70 | export const returnBorderRadius = (shape, size) => { 71 | switch (shape) { 72 | case "50%": 73 | return size / 2 74 | break; 75 | case "10%": 76 | return 5 77 | break; 78 | case "": 79 | return 0 80 | break; 81 | default: 82 | return size / 2 83 | break; 84 | } 85 | } 86 | 87 | export const NUSC = (str) => { 88 | if (str === null || str === undefined || str === "") { 89 | return true 90 | } 91 | return false 92 | } 93 | 94 | export const splitParameters = (str) => { 95 | if (!str) return 96 | 97 | const parameters = str.split("&") 98 | 99 | let result = {} 100 | 101 | parameters.forEach(values => { 102 | let tempArr = values.split("=") 103 | result[tempArr[0]] = tempArr[1]; 104 | }); 105 | 106 | return result 107 | } 108 | 109 | export const returnActid = (str) => { 110 | if (!str || !str["OM.zn"]) return 111 | 112 | const parameters = str["OM.zn"].split("-") 113 | 114 | return parameters[1] 115 | } 116 | 117 | export const returnId = (actid,title) => { 118 | if (!actid || !title) return 119 | 120 | return escape(actid+"-"+title) 121 | } 122 | 123 | --------------------------------------------------------------------------------