diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml new file mode 100644 index 0000000..b857629 --- /dev/null +++ b/.github/workflows/CI.yaml @@ -0,0 +1,30 @@ +name: CI PR Checks + +on: pull_request + +jobs: + eslint: + name: bslint + permissions: + actions: write + contents: write + id-token: write + runs-on: ubuntu-latest + steps: + - uses: actions/setup-node@v3 + with: + node-version: "16" + + - name: 'Checkout ${{ inputs.ref }}' + uses: actions/checkout@v2 + with: + path: source + ref: '${{ inputs.ref }}' + + - name: Install dependencies + run: | + yarn install + + - name: Run Linter + run: | + npx bslint diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..687150d --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,25 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + - id: check-added-large-files + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-merge-conflict + - id: check-symlinks + - id: check-toml + - id: check-xml + - id: check-json + - id: check-yaml + - id: end-of-file-fixer + - id: fix-byte-order-marker + - id: forbid-new-submodules + - id: mixed-line-ending + args: [--fix=lf] + - id: no-commit-to-branch + args: [--branch, main, --branch, develop] + - id: pretty-format-json + args: [--autofix] + - id: sort-simple-yaml + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] diff --git a/Demo/.vscode/launch.json b/Demo/.vscode/launch.json index a930183..e633d42 100644 --- a/Demo/.vscode/launch.json +++ b/Demo/.vscode/launch.json @@ -1,16 +1,13 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "BrightScript Debug: Launch", - "type": "brightscript", - "request": "launch", - "host": "${promptForHost}", - "password": "${promptForPassword}", - "rootDir": "${workspaceFolder}" - } - ] + "configurations": [ + { + "host": "${promptForHost}", + "name": "BrightScript Debug: Launch", + "password": "${promptForPassword}", + "request": "launch", + "rootDir": "${workspaceFolder}", + "type": "brightscript" + } + ], + "version": "0.2.0" } diff --git a/Demo/components/CampaignView.brs b/Demo/components/CampaignView.brs index fe01f7a..42c536b 100644 --- a/Demo/components/CampaignView.brs +++ b/Demo/components/CampaignView.brs @@ -1,6 +1,8 @@ sub init() m.scene = m.top.getScene() m.namiPaywallManager = invalid + m.namiCustomerManager = invalid + m.namiCampaignManager = invalid m.campaignList = invalid m.llCampaign = m.top.findNode("llCampaign") @@ -8,6 +10,7 @@ sub init() m.llCampaign.observeField("itemSelected", "OnItemSelected") m.top.observeField("visible", "onVisibleChange") + m.top.observeField("focusedChild","OnFocusedChildChange") end sub sub onInitializeChanged(event as dynamic) @@ -15,9 +18,10 @@ sub onInitializeChanged(event as dynamic) print "CampaignView : onInitializeChanged : initialize : " initialize if initialize m.campaignList = m.top.namiDataSource.campaigns - print "CampaignView : onInitializeChanged : Campaign List " m.campaignList - m.namiPaywallManager = m.scene.namiSDK.nami.callFunc("getPaywallManager") - m.scene.observeField("paywallScreenDismissed", "OnPaywallScreenDismissed") + print "CampaignView : onInitializeChanged : Campaign List " ' m.campaignList + m.namiPaywallManager = m.scene.namiManager.namiPaywallManager + m.namiCustomerManager = m.scene.namiManager.namiCustomerManager + m.namiCampaignManager = m.scene.namiManager.namiCampaignManager m.top.namiDataSource.observeField("paywallScreenDismissed", "OnPaywallScreenDismissed") OnCampaignListReceived() end if @@ -36,6 +40,12 @@ sub onVisibleChange(event as dynamic) end if end sub +sub OnFocusedChildChange() + if m.top.hasFocus() + m.llCampaign.setFocus(true) + end if +end sub + sub OnPaywallScreenDismissed(event as dynamic) isDismissed = event.getData() print "CampaignView : OnPaywallScreenDismissed : " isDismissed @@ -55,6 +65,10 @@ sub OnCampaignListReceived() m.lNoItems.visible = false + ' deviceInfo = CreateObject("roDeviceInfo") + ' id = deviceInfo.GetRandomUUID() + ' m.namiCustomerManager.callFunc("login", id) + m.llCampaign.content = parseCampaignList(m.campaignList) m.llCampaign.visible = true @@ -74,22 +88,21 @@ end function sub onItemSelected(event as dynamic) selectedIndex = event.getData() - m.namiCampaignManager = m.scene.namiSDK.nami.callFunc("getCampaignManager") - paywallLaunchContext = CreateObject("roSGNode", "NamiSDK:PaywallLaunchContext") paywallLaunchContext.productGroups = ["group1","group2"] paywallLaunchContext.customAttributes = { "contextImage": "https://www.exmaple.com/contextImage.png" } - if selectedIndex = 0 - print "CampaignView : onItemSelected : Launching default campaign" - m.namiCampaignManager.callFunc("launchWithHandler", "", paywallLaunchContext, m.top, "campaignLaunchHandler", m.top.namiDataSource, "paywallActionHandler") - else - print "CampaignView : onItemSelected : Launching Campaign : " m.campaignList[selectedIndex - 1].valueField - m.namiCampaignManager.callFunc("launchWithHandler", m.campaignList[selectedIndex - 1].valueField, paywallLaunchContext, m.top, "campaignLaunchHandler", m.top.namiDataSource, "paywallActionHandler") + label = "" + if selectedIndex <> 0 + label = m.campaignList[selectedIndex - 1].valueField end if - m.scene.paywallScreenDismissed = false + + print "CampaignView : onItemSelected : Launching Campaign Label : " label + + m.namiPaywallManager.callFunc("registerCloseHandler", m.top, "campaignCloseHandler") + m.namiCampaignManager.callFunc("launchWithHandler", label, paywallLaunchContext, m.top, "campaignLaunchHandler", m.top.namiDataSource, "paywallActionHandler") end sub function campaignLaunchHandler(isSuccess as boolean, error as dynamic) @@ -106,6 +119,14 @@ function campaignLaunchHandler(isSuccess as boolean, error as dynamic) end if end function +sub campaignCloseHandler(isSuccess=true as boolean) + print "CampaignView : campaignCloseHandler : Is campaign closed successfully : "; isSuccess + if (isSuccess) + m.llCampaign.setFocus(true) + end if + ' m.top.namiDataSource.paywallScreenDismissed = isSuccess +end sub + sub showMessageDialog(error) m.dialog = createObject("roSgNode", "StandardMessageDialog") m.dialog.title = "ERROR - " + error.domain @@ -120,7 +141,7 @@ sub showMessageDialog(error) end sub sub closeDialog() - if (m.scene.dialog <> invalid) then + if (m.scene.dialog <> invalid) m.scene.dialog.close = true m.scene.dialog = invalid end if diff --git a/Demo/components/CampaignView.xml b/Demo/components/CampaignView.xml index 70db386..9c06ad0 100644 --- a/Demo/components/CampaignView.xml +++ b/Demo/components/CampaignView.xml @@ -6,11 +6,12 @@ + - diff --git a/Demo/components/ContentView.brs b/Demo/components/ContentView.brs index 458e67a..5f646a5 100644 --- a/Demo/components/ContentView.brs +++ b/Demo/components/ContentView.brs @@ -1,11 +1,12 @@ sub init() m.scene = m.top.getScene() + m.navbar = m.top.findNode("navbar") m.campaignViewControl = m.top.findNode("campaignViewControl") m.profileViewControl = m.top.findNode("profileViewControl") + m.entitlementViewControl = m.top.findNode("entitlementViewControl") - m.top.observeField("visible", "onVisibleChange") - - m.isFirstTime = true + m.navbarEntries = ["Campaigns", "Profile"] 'Add when show list "Entitlements" + m.navbar.observeField("itemSelected","OnNavbarItemSelected") end sub sub onInitializeChanged(event as dynamic) @@ -13,33 +14,98 @@ sub onInitializeChanged(event as dynamic) print "ContentView : onInitializeChanged : initialize : " initialize if initialize m.namiDataSource = m.top.CreateChild("NamiDataSource") + setNavbarItems() + setInitialFocus() + end if +end sub + +sub showCampaignView() + m.profileViewControl.visible = false + m.entitlementViewControl.visible = false + if (not m.campaignViewControl.initialize) m.campaignViewControl.namiDataSource = m.namiDataSource - ' m.profileViewControl.namiDataSource = m.namiDataSource m.campaignViewControl.initialize = true - showCampaignView() end if + m.campaignViewControl.visible = true end sub -sub onVisibleChange(event as dynamic) - isVisible = event.getData() - if isVisible - showCampaignView() +sub showProfileView() + m.campaignViewControl.visible = false + m.entitlementViewControl.visible = false + if (not m.profileViewControl.initialize) + m.profileViewControl.namiDataSource = m.namiDataSource + m.profileViewControl.initialize = true end if + m.profileViewControl.visible = true end sub -sub showCampaignView() - m.campaignViewControl.visible = true +sub showEntitlementView() + m.campaignViewControl.visible = false + m.profileViewControl.visible = false + if (not m.entitlementViewControl.initialize) + m.entitlementViewControl.namiDataSource = m.namiDataSource + m.entitlementViewControl.initialize = true + end if + m.entitlementViewControl.visible = true end sub -sub showProfileView() - m.profileViewControl.namiDataSource = m.namiDataSource - m.profileViewControl.visible = true +sub setNavbarItems() + navbarContent = createObject("roSGNode","ContentNode") + for each item in m.navbarEntries + navbarItem = navbarContent.createChild("NavbarContent") + navbarItem.title = item + navbarItem.isSelected = false + end for + m.navbar.content = navbarContent + m.navbar.translation = [(1920 - m.navbar.boundingRect().width)/2, 70] +end sub + +sub setInitialFocus() + m.navbar.setFocus(true) + m.navbar.itemSelected = 0 +end sub + +sub OnNavbarItemSelected(event as dynamic) + index = event.getData() + itemSelected = m.navbar.content.getChild(index) + updateSelectedItem(itemSelected.title) + if (itemSelected.title = "Campaigns") + showCampaignView() + else if (itemSelected.title = "Profile") + showProfileView() + else if (itemSelected.title = "Entitlements") + showEntitlementView() + end if +end sub + +sub updateSelectedItem(selectedtTitle as String) + for index = 0 to m.navbar.content.getChildCount() - 1 + child = m.navbar.content.getChild(index) + if child.title = selectedtTitle + child.isSelected = true + else + child.isSelected = false + end if + end for end sub function onKeyEvent(key as String, press as Boolean) as Boolean result = false if (press) print "ContentView : onKeyEvent : key = " key " press = " press + if key = "up" + m.navbar.setFocus(true) + result = true + else if key = "down" + if (m.navbar.hasFocus()) + if (m.campaignViewControl.visible) + m.campaignViewControl.setFocus(true) + else if (m.profileViewControl.visible) + m.profileViewControl.setFocus(true) + end if + end if + result = true + end if end if return result end function diff --git a/Demo/components/ContentView.xml b/Demo/components/ContentView.xml index 68a64b3..1f90926 100644 --- a/Demo/components/ContentView.xml +++ b/Demo/components/ContentView.xml @@ -7,11 +7,11 @@ - + - - - - + + diff --git a/Demo/components/EntitlementView.brs b/Demo/components/EntitlementView.brs new file mode 100644 index 0000000..0550211 --- /dev/null +++ b/Demo/components/EntitlementView.brs @@ -0,0 +1,33 @@ +sub init() + m.scene = m.top.getScene() + m.lTitle = m.top.findNode("lTitle") + + m.top.observeField("visible", "onVisibleChange") +end sub + +sub onVisibleChange(event as dynamic) + isVisible = event.getData() + if isVisible + m.lTitle.setFocus(true) + else + end if +end sub + +sub onIntializeChanged(event as dynamic) + initialize = event.getData() + print "EntitlementView : onIntializeChanged : initialize : " initialize + if initialize + m.namiPaywallManager = m.scene.namiManager.namiPaywallManager + m.namiCustomerManager = m.scene.namiManager.namiCustomerManager + m.top.namiDataSource.observeField("paywallScreenDismissed", "OnPaywallScreenDismissed") + end if +end sub + +function onKeyEvent(key as String, press as Boolean) as Boolean + result = false + if (press) + print "EntitlementView OnKeyEvent: press " press " key : " key + end if + + return result +end function diff --git a/Demo/components/EntitlementView.xml b/Demo/components/EntitlementView.xml new file mode 100644 index 0000000..9e5a99e --- /dev/null +++ b/Demo/components/EntitlementView.xml @@ -0,0 +1,13 @@ + + +