Migration to new BLEK library (#143)

* Changed view.

* Clear messages.

* Clear messages.

* Add or delete configuration.

* Fixed configuration picker.

* Edit configuration.

* Create new macro.

* removed unnecessary resource files.

* Fixed running macro command.

* Delete macro

* Edit macro

* Changed to peripheral name.

* Show peripheral name.

* Fixed Eol tab design.

* Removed icon resource

* String changes

* Removed any permission from home view.

* Clear device after disconnection.

* 1 line app bar

* Changed missing services text.

* Throughput service view changes.

* Throughput service fixes.

* Removed unused resources.

* Fixed Health temperature profile.

* Show heart rate.

* Fixed hrs view.

* Show heart rate data from left to right in the chart.

* Changed chart color, solid, and scroll to see history.

* Horizontal grid hidden, in case needed.

* HTS view update

* Changed padding.

* Removed circular icon background.

* Updated Battery level view.

* Updated hrs body sensor location.

* Moved ui mappers into view.

* Updated gls view.

* Changed focus color.

* Fixed issue with job.

* Fixed bps.

* Added Blood pressure feature uuid.

* Added blood pressure feature data.

* Added rscs feature data.

* Fixed cscs view.

* Show supported features.

* Fixed ui

* Suspend the service discovery for GLS and CGMS until bonding is completed.

* Added suspend on the function level.

* Bonding state check only to cgms service

* Removed stacktrace print.

* Make cgms record available within a scrollable box

* Changed to gray color.

* removed padding

* Fix height for output section.

* onExpand click event.

* Added todo for 9th item.

* Removed unused code block.

* When in focus, reduce the hint text alpha value.

* Show empty text error.

* Clear focus on tap outside.

* Add border when focused.

* Propagate focus changes.

* CGM graph

* Added sample of one to many uart configuration database.

* Added device and configuration entities.

* Fixed issue with only showing last item from the list.

* Changed configuration database irrespective of device address.

* File rename.

* Added last configuration datastore.

* Check if configuration name is unique

* Removed Macro text.

* Included x and y axis data points.

* Added channel sounding service uuid.

* Upgraded agp version to 2.7.

* Added channel sounding manager.

* Downgraded datastore preference to 1.1.4.

* Changed to nordic colors.

* Added ranging permission.

* channel sounding repository

* channel sounding service data

* channel sounding profile

* channel sounding profile in viewmodel

* channel sounding manager class

* channel sounding testing

* CS service characteristics

* Create bonding before channel sounding connection.

* Clean up.

* Added LBS profile

* Read/write data to LBS

* LBS ui events

* LBS service

* LBS profile

* LBS ui

* Agp upgrade

* Fixed LBS profile

* Removed focus

* Changed macro size to 9

* Changed macro color

* Show macro in bottom sheet

* View refactoring

* Added Blek dependency

* Added utils dependency

* rename

* Removed unused event

* reorganization

* uart macro view update

* background color update

* different color for input and output message type

* Changed to uart event

* removed duplicate

* rename

* auto scroll to new record

* removed unused dependency

* Fixed crash with ChannelSoundingManager injection.

* Require bonding only if it has bonding information

* Changed disconnection

* CGMS graph

* changes in the home view

* Home view fixes

* changed color

* Show MacroEol character in the input message.

* Home view icon fixes.

* Cadence data parser fixes

* Fixed CSC settings view.

* Fixed rscs view

* hiding graphs until its finished

* Removed duplicate

* Fixed RSCS view

* Fixed notification icon

* fixed csc module name

* Fixed icon cutoff

* Fixed CSCDataParser

* Fixed CGMS profile

* Fixed GLS view

* Fixed GLS strings

* Fixed HTS view

* Fixed HTS view

* title change

* Added hts timestamp

* Deleted verbose text

* UART: changed macro/configuration to preset

* UART: fixed input text field

* UART: removed expandable/collapsable preset

* UART: added extra warning to delete action

* UART: don't trim message end.

* UART: message section

* UART: configuration fixed

* UART: configuration fixed

* Fix crash when disconnecting before MTU change completes

* Disabled incomplete PRX profile

* Moved non-composable lambdas to parameters

* refactoring display text

* Fixed channel sounding screen

* Disconnect on missing services before navigation

* Fixed label name

* Tailored disconnection message.

* Tailored disconnection message.

* Moved profile file to utils

* App analytics events and modes

* Integrated analytics with the profile actions.

* Show only first non-battery service if multiple services are present.

* Fixed window insets for camera notch.

* Fixed glucose measurement context.

* Fixed glucose concentration unit.

* Fixed duplicate analytics update.

* rename

* refactoring text

* Handled disconnecting event.

* Replaced with LazyColumn

* Fixed window insets

* Replaced TitleAppBar with NordicAppBar

* Show device address

* Show multiple service names if available.

* Fixed padding

* BPS: Fixed waiting for measurement view.

* BPS: view

* GLS: Fixed padding

* Ui: Fixed dialog

* RSCS: fixed distance formatting error

* CGMS: ui consistency

* DFS: ui fixes

* Replaced local scanner with common library scanner.

* Fixed padding

* reorganization

* Removed previous uart module

* Text with animated three dots

* HTS: text fixes

* formatting texts

* changed text style

* fixed string

* Fixed HRS, not completed

* DFS: fixed ui

* HRS: graph fixes

* UART: scroll up when keyboard is visible

* Uart input: Add focus

* Uart fix: input text field

* UART: created rememberImeState

* HRS: heart rate ui fixes

* profile view scrollable fix

* DFS: ui fixes

* Fixed logger

* Check if the battery characteristics supports NOTIFY or INDICATE property

* Dependency update

* Changed background color

* cleanup

* Fixed distance measurement data update.

* Filtered devices with testing address

* Added preview data

* Fixed section view

* Fixed elevation view

* Removed duplicate views

* Fixes control points

* String fixes

* Elevation view fixes

* Range slider view update

* Fixed DFS views

* Fixed DFS ui

* Fixed DFS views

* Separated views

* Separated profile viewmodel into individual profile view models.

* AGP upgrade

* Job canceled and make jobs null on clear

* Profile name update

* Request maximum MTU size only if it is not already set.

* Fixed null pointer exception

* Battery characteristics read property check

* Fixed early mtu request

* Removed garbage states

* Removed logs

* Removed multiple vertical scroll

* Fixed padding

* Ui fixes

* File reorganization

* Fixed previous configuration not loading on reconnection

* Removed unused files

* Dependency update

* Renamed module name

* Removed unused dependencies

* Added param

* Removed unused code block

* Code optimization

* Removed unused file

* Readme update

* Hide Channel sounding until implementation is complete

* Handled initial state closed

* revert changes

* Added library as module placeholder

* Fixed multiple flows for the same peripheral

* Request mtu size only when needed

* Readme update
This commit is contained in:
Himali Aryal
2025-07-30 14:51:02 +02:00
committed by GitHub
parent 9a71e66c10
commit b67abd60e6
513 changed files with 19164 additions and 14446 deletions

View File

@@ -35,8 +35,6 @@ import android.app.Application
import dagger.hilt.android.HiltAndroidApp
import no.nordicsemi.android.analytics.AppAnalytics
import no.nordicsemi.android.analytics.AppOpenEvent
import no.nordicsemi.android.gls.GLSServer
import no.nordicsemi.android.uart.UartServer
import timber.log.Timber
import javax.inject.Inject
@@ -46,20 +44,11 @@ class NrfToolboxApplication : Application() {
@Inject
lateinit var analytics: AppAnalytics
@Inject
lateinit var uartServer: UartServer
@Inject
lateinit var glsServer: GLSServer
override fun onCreate() {
super.onCreate()
analytics.logEvent(AppOpenEvent)
uartServer.start(this)
glsServer.start(this)
Timber.plant(Timber.DebugTree())
}
}

View File

@@ -33,6 +33,13 @@
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<queries>
<package android:name="no.nordicsemi.android.dfu" />

View File

@@ -31,45 +31,10 @@
package no.nordicsemi.android.nrftoolbox
import no.nordicsemi.android.bps.view.BPSScreen
import no.nordicsemi.android.cgms.view.CGMScreen
import no.nordicsemi.android.common.navigation.createSimpleDestination
import no.nordicsemi.android.common.navigation.defineDestination
import no.nordicsemi.android.csc.view.CSCScreen
import no.nordicsemi.android.gls.main.view.GLSScreen
import no.nordicsemi.android.hrs.view.HRSScreen
import no.nordicsemi.android.hts.view.HTSScreen
import no.nordicsemi.android.nrftoolbox.view.HomeScreen
import no.nordicsemi.android.prx.view.PRXScreen
import no.nordicsemi.android.rscs.view.RSCSScreen
import no.nordicsemi.android.toolbox.scanner.ScannerDestination
import no.nordicsemi.android.uart.view.UARTScreen
import no.nordicsemi.android.nrftoolbox.view.HomeView
val HomeDestinationId = createSimpleDestination("home-destination")
val HomeDestinations = listOf(
defineDestination(HomeDestinationId) { HomeScreen() },
ScannerDestination
)
val CSCDestinationId = createSimpleDestination("csc-destination")
val HRSDestinationId = createSimpleDestination("hrs-destination")
val HTSDestinationId = createSimpleDestination("hts-destination")
val GLSDestinationId = createSimpleDestination("gls-destination")
val BPSDestinationId = createSimpleDestination("bps-destination")
val PRXDestinationId = createSimpleDestination("prx-destination")
val RSCSDestinationId = createSimpleDestination("rscs-destination")
val CGMSDestinationId = createSimpleDestination("cgms-destination")
val UARTDestinationId = createSimpleDestination("uart-destination")
val ProfileDestinations = listOf(
defineDestination(CSCDestinationId) { CSCScreen() },
defineDestination(HRSDestinationId) { HRSScreen() },
defineDestination(HTSDestinationId) { HTSScreen() },
defineDestination(GLSDestinationId) { GLSScreen() },
defineDestination(BPSDestinationId) { BPSScreen() },
defineDestination(PRXDestinationId) { PRXScreen() },
defineDestination(RSCSDestinationId) { RSCSScreen() },
defineDestination(CGMSDestinationId) { CGMScreen() },
defineDestination(UARTDestinationId) { UARTScreen() },
)
val HomeDestinations = defineDestination(HomeDestinationId) { HomeView() }

View File

@@ -42,17 +42,11 @@ import no.nordicsemi.android.common.analytics.view.AnalyticsPermissionRequestDia
import no.nordicsemi.android.common.navigation.NavigationView
import no.nordicsemi.android.common.theme.NordicActivity
import no.nordicsemi.android.common.theme.NordicTheme
import no.nordicsemi.android.gls.GLSDestination
import no.nordicsemi.android.nrftoolbox.repository.ActivitySignals
import no.nordicsemi.android.toolbox.scanner.ScannerDestination
import javax.inject.Inject
import no.nordicsemi.android.toolbox.profile.ProfileDestination
@AndroidEntryPoint
class MainActivity : NordicActivity() {
@Inject
lateinit var activitySignals: ActivitySignals
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -62,7 +56,7 @@ class MainActivity : NordicActivity() {
color = MaterialTheme.colorScheme.surface,
modifier = Modifier.fillMaxSize()
) {
NavigationView(HomeDestinations + ProfileDestinations + ScannerDestination + GLSDestination)
NavigationView(HomeDestinations + ScannerDestination + ProfileDestination)
}
AnalyticsPermissionRequestDialog()
@@ -70,8 +64,4 @@ class MainActivity : NordicActivity() {
}
}
override fun onResume() {
super.onResume()
activitySignals.onResume()
}
}

View File

@@ -0,0 +1,46 @@
package no.nordicsemi.android.nrftoolbox
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.navigation.createDestination
import no.nordicsemi.android.common.navigation.defineDestination
import no.nordicsemi.android.common.navigation.viewmodel.SimpleNavigationViewModel
import no.nordicsemi.android.common.scanner.DeviceSelected
import no.nordicsemi.android.common.scanner.ScannerScreen
import no.nordicsemi.android.common.scanner.ScanningCancelled
import no.nordicsemi.android.common.scanner.data.OnlyNearby
import no.nordicsemi.android.common.scanner.data.OnlyWithNames
import no.nordicsemi.android.common.scanner.rememberFilterState
import no.nordicsemi.android.toolbox.profile.ProfileDestinationId
import no.nordicsemi.kotlin.ble.client.android.ScanResult
val ScannerDestinationId = createDestination<Unit, ScanResult>("ble-scanner")
val ScannerDestination = defineDestination(ScannerDestinationId) {
val navigationVM = hiltViewModel<SimpleNavigationViewModel>()
ScannerScreen(
cancellable = true,
state = rememberFilterState(
dynamicFilters = listOf(
OnlyNearby(),
OnlyWithNames(),
)
),
onResultSelected = {
when (it) {
is DeviceSelected -> {
navigationVM.navigateTo(ProfileDestinationId, it.scanResult.peripheral.address)
{
popUpTo(ScannerDestinationId.toString()) {
inclusive = true
}
}
}
ScanningCancelled -> {
navigationVM.navigateUp()
}
}
}
)
}

View File

@@ -1,10 +1,11 @@
package no.nordicsemi.android.nrftoolbox
package no.nordicsemi.android.nrftoolbox.di
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
@Module
@@ -12,5 +13,5 @@ import kotlinx.coroutines.SupervisorJob
class ApplicationScopeModule {
@Provides
fun applicationScope() = CoroutineScope(SupervisorJob())
fun applicationScope() = CoroutineScope(SupervisorJob() + Dispatchers.IO)
}

View File

@@ -0,0 +1,24 @@
package no.nordicsemi.android.nrftoolbox.di
import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import no.nordicsemi.kotlin.ble.client.android.CentralManager
import no.nordicsemi.kotlin.ble.client.android.native
@Module
@InstallIn(SingletonComponent::class)
object CentralManagerModule {
@Provides
fun provideCentralManager(
@ApplicationContext context: Context,
scope: CoroutineScope
): CentralManager {
return CentralManager.Factory.native(context, scope)
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (c) 2022, Nordic Semiconductor
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package no.nordicsemi.android.nrftoolbox.repository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ActivitySignals @Inject constructor() {
private val _onResumeTrigger = MutableStateFlow(false)
val state = _onResumeTrigger.asStateFlow()
fun onResume() {
_onResumeTrigger.value = !_onResumeTrigger.value
}
}

View File

@@ -1,120 +1,76 @@
/*
* Copyright (c) 2022, Nordic Semiconductor
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package no.nordicsemi.android.nrftoolbox.view
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.nrftoolbox.R
@Composable
fun FeatureButton(
internal fun FeatureButton(
@DrawableRes iconId: Int,
@StringRes nameCode: Int,
@StringRes name: Int,
isRunning: Boolean? = null,
@StringRes description: Int? = null,
@StringRes description: Int,
profileNames: List<String> = listOf(stringResource(description)),
deviceName: String?,
deviceAddress: String,
onClick: () -> Unit
) {
OutlinedCard(onClick = onClick) {
OutlinedCard(onClick = onClick, modifier = Modifier.fillMaxWidth()) {
Row(
modifier = Modifier.padding(16.dp).fillMaxWidth(),
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
val color = if (isRunning == true) {
colorResource(id = R.color.nordicGrass)
} else {
MaterialTheme.colorScheme.secondary
}
Image(
painter = painterResource(iconId),
contentDescription = stringResource(id = name),
contentScale = ContentScale.Crop,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSecondary),
contentDescription = stringResource(id = description),
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary),
modifier = Modifier
.size(64.dp)
.clip(CircleShape)
.background(color)
.padding(16.dp)
.size(40.dp)
)
Spacer(modifier = Modifier.size(16.dp))
Column(modifier = Modifier.weight(1f)) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = name),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center
text = deviceName ?: stringResource(R.string.unknown_device),
style = MaterialTheme.typography.titleMedium,
)
Text(
modifier = Modifier.fillMaxWidth(),
text = profileNames.joinToString(", "),
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
description?.let {
Spacer(modifier = Modifier.size(4.dp))
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = it),
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
Text(
modifier = Modifier.fillMaxWidth(),
text = deviceAddress,
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
@@ -123,5 +79,64 @@ fun FeatureButton(
@Preview
@Composable
private fun FeatureButtonPreview() {
FeatureButton(R.drawable.ic_csc, R.string.csc_module, R.string.csc_module_full) { }
FeatureButton(
R.drawable.ic_csc,
R.string.csc_module_full,
listOf("Cycling Speed and Cadence", "Cycling Speed Sensor"),
"Testing peripheral",
deviceAddress = "AA:BB:CC:DD:EE:FF",
) { }
}
@Composable
internal fun FeatureButton(
iconId: ImageVector,
@StringRes description: Int,
profileNames: List<String> = listOf(stringResource(description)),
deviceName: String?,
deviceAddress: String,
onClick: () -> Unit
) {
OutlinedCard(onClick = onClick, modifier = Modifier.fillMaxWidth()) {
Row(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Image(
imageVector = iconId,
contentDescription = deviceAddress,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary),
modifier = Modifier
.size(40.dp)
)
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.fillMaxWidth(),
text = deviceName ?: stringResource(R.string.unknown_device),
style = MaterialTheme.typography.titleMedium,
)
Text(
modifier = Modifier.fillMaxWidth(),
text = profileNames.joinToString(", "),
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
modifier = Modifier.fillMaxWidth(),
text = deviceAddress,
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
}

View File

@@ -1,263 +1,344 @@
/*
* Copyright (c) 2022, Nordic Semiconductor
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package no.nordicsemi.android.nrftoolbox.view
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.displayCutout
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Lightbulb
import androidx.compose.material.icons.filled.SocialDistance
import androidx.compose.material.icons.filled.SyncAlt
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import no.nordicsemi.android.analytics.Link
import no.nordicsemi.android.analytics.Profile
import no.nordicsemi.android.analytics.ProfileOpenEvent
import no.nordicsemi.android.nrftoolbox.BPSDestinationId
import no.nordicsemi.android.nrftoolbox.BuildConfig
import no.nordicsemi.android.nrftoolbox.CGMSDestinationId
import no.nordicsemi.android.nrftoolbox.CSCDestinationId
import no.nordicsemi.android.nrftoolbox.GLSDestinationId
import no.nordicsemi.android.nrftoolbox.HRSDestinationId
import no.nordicsemi.android.nrftoolbox.HTSDestinationId
import no.nordicsemi.android.nrftoolbox.PRXDestinationId
import no.nordicsemi.android.common.analytics.view.AnalyticsPermissionButton
import no.nordicsemi.android.common.ui.view.NordicAppBar
import no.nordicsemi.android.nrftoolbox.R
import no.nordicsemi.android.nrftoolbox.RSCSDestinationId
import no.nordicsemi.android.nrftoolbox.UARTDestinationId
import no.nordicsemi.android.nrftoolbox.viewmodel.HomeViewModel
import no.nordicsemi.android.nrftoolbox.viewmodel.UiEvent
import no.nordicsemi.android.toolbox.lib.utils.Profile
private const val DFU_PACKAGE_NAME = "no.nordicsemi.android.dfu"
private const val DFU_LINK = "https://play.google.com/store/apps/details?id=no.nordicsemi.android.dfu"
private const val LOGGER_PACKAGE_NAME = "no.nordicsemi.android.log"
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreen() {
val viewModel: HomeViewModel = hiltViewModel()
internal fun HomeView() {
val viewModel = hiltViewModel<HomeViewModel>()
val state by viewModel.state.collectAsStateWithLifecycle()
val onEvent: (UiEvent) -> Unit = { viewModel.onClickEvent(it) }
Scaffold(
contentWindowInsets = WindowInsets(0, 0, 0, 0),
topBar = {
TitleAppBar(stringResource(id = R.string.app_name))
}
) {
Column(
modifier = Modifier
.padding(it)
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp)
NordicAppBar(
title = { Text(stringResource(id = R.string.app_name)) },
showBackButton = false,
) {
Spacer(modifier = Modifier.height(16.dp))
AnalyticsPermissionButton()
}
},
floatingActionButton = {
ExtendedFloatingActionButton(
onClick = { onEvent(UiEvent.OnConnectDeviceClick) },
modifier = Modifier.padding(top = 8.dp, bottom = 16.dp, end = 8.dp, start = 8.dp),
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Add device from scanner"
)
Text(text = stringResource(R.string.connect_device))
}
}
}
) { paddingValues ->
// Get notch padding for devices with a display cutout (notch)
val notchPadding = WindowInsets.displayCutout
.union(WindowInsets(left = 8.dp, right = 8.dp, top = 8.dp, bottom = 8.dp))
.only(WindowInsetsSides.Horizontal)
.asPaddingValues()
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
.padding(paddingValues),
contentPadding = notchPadding,
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
item {
// Show the title at the top
Text(
text = stringResource(id = R.string.viewmodel_profiles),
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.connected_devices),
modifier = Modifier
.alpha(0.5f)
.padding(start = 16.dp),
)
if (state.connectedDevices.isNotEmpty()) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxWidth()
) {
state.connectedDevices.values.forEach { (peripheral, services) ->
// Skip if no services
if (services.isEmpty()) return@forEach
// Case 1: If only one service, show it directly like battery service
if (services.size == 1 && services.first().profile == Profile.BATTERY) {
FeatureButton(
iconId = R.drawable.ic_battery,
description = R.string.battery_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
services.first().profile
)
)
},
)
}
// Case 2: Show the first *non-Battery* profile.
// This ensures only one service is shown per peripheral when multiple services are available.
services.firstOrNull { it.profile != Profile.BATTERY }
?.let { serviceManager ->
when (serviceManager.profile) {
Profile.HRS -> FeatureButton(
iconId = R.drawable.ic_hrs,
description = R.string.hrs_module_full,
deviceName = peripheral.name,
profileNames = services.map { it.profile.toString() },
deviceAddress = peripheral.address,
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
Spacer(modifier = Modifier.height(16.dp))
Profile.HTS -> FeatureButton(
iconId = R.drawable.ic_hts,
description = R.string.hts_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
FeatureButton(R.drawable.ic_gls, R.string.gls_module, R.string.gls_module_full) {
viewModel.openProfile(GLSDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.GLS))
}
Profile.BPS -> FeatureButton(
iconId = R.drawable.ic_bps,
description = R.string.bps_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
Spacer(modifier = Modifier.height(16.dp))
Profile.GLS -> FeatureButton(
iconId = R.drawable.ic_gls,
description = R.string.gls_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
FeatureButton(R.drawable.ic_bps, R.string.bps_module, R.string.bps_module_full) {
viewModel.openProfile(BPSDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.BPS))
}
Profile.CGM -> FeatureButton(
iconId = R.drawable.ic_cgm,
description = R.string.cgm_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
Spacer(modifier = Modifier.height(16.dp))
Profile.RSCS -> FeatureButton(
iconId = R.drawable.ic_rscs,
description = R.string.rscs_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
Text(
text = stringResource(id = R.string.service_profiles),
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.fillMaxWidth(),
)
Profile.DFS -> FeatureButton(
iconId = R.drawable.ic_distance,
description = R.string.direction_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
Spacer(modifier = Modifier.height(16.dp))
Profile.CSC -> FeatureButton(
iconId = R.drawable.ic_csc,
description = R.string.csc_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
FeatureButton(
R.drawable.ic_csc,
R.string.csc_module,
R.string.csc_module_full,
state.isCSCModuleRunning
) {
viewModel.openProfile(CSCDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.CSC))
}
Profile.THROUGHPUT -> {
FeatureButton(
iconId = Icons.Default.SyncAlt,
description = R.string.throughput_module,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
}
Spacer(modifier = Modifier.height(16.dp))
Profile.UART -> {
FeatureButton(
iconId = R.drawable.ic_uart,
description = R.string.uart_module_full,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
}
FeatureButton(
R.drawable.ic_hrs,
R.string.hrs_module,
R.string.hrs_module_full,
state.isHRSModuleRunning
) {
viewModel.openProfile(HRSDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.HRS))
}
Profile.CHANNEL_SOUNDING -> {
FeatureButton(
iconId = Icons.Default.SocialDistance,
description = R.string.channel_sounding_module,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
}
Spacer(modifier = Modifier.height(16.dp))
Profile.LBS -> {
FeatureButton(
iconId = Icons.Default.Lightbulb,
description = R.string.lbs_blinky_module,
deviceName = peripheral.name,
deviceAddress = peripheral.address,
profileNames = services.map { it.profile.toString() },
onClick = {
onEvent(
UiEvent.OnDeviceClick(
peripheral.address,
serviceManager.profile
)
)
},
)
}
FeatureButton(
R.drawable.ic_hts,
R.string.hts_module,
R.string.hts_module_full,
state.isHTSModuleRunning
) {
viewModel.openProfile(HTSDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.HTS))
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(
R.drawable.ic_rscs,
R.string.rscs_module,
R.string.rscs_module_full,
state.isRSCSModuleRunning
) {
viewModel.openProfile(RSCSDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.RSCS))
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(
R.drawable.ic_cgm,
R.string.cgm_module,
R.string.cgm_module_full,
state.isCGMModuleRunning
) {
viewModel.openProfile(CGMSDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.CGMS))
}
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(
R.drawable.ic_prx,
R.string.prx_module,
R.string.prx_module_full,
state.isPRXModuleRunning
) {
viewModel.openProfile(PRXDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.PRX))
}
Spacer(modifier = Modifier.height(16.dp))
Text(
text = stringResource(id = R.string.utils_services),
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.fillMaxWidth(),
)
Spacer(modifier = Modifier.height(16.dp))
FeatureButton(
R.drawable.ic_uart,
R.string.uart_module,
R.string.uart_module_full,
state.isUARTModuleRunning
) {
viewModel.openProfile(UARTDestinationId)
viewModel.logEvent(ProfileOpenEvent(Profile.UART))
}
Spacer(modifier = Modifier.height(16.dp))
val uriHandler = LocalUriHandler.current
val context = LocalContext.current
val packageManger = context.packageManager
val description = packageManger.getLaunchIntentForPackage(DFU_PACKAGE_NAME)?.let {
R.string.dfu_module_info
} ?: R.string.dfu_module_install
FeatureButton(R.drawable.ic_dfu, R.string.dfu_module, R.string.dfu_module_full, null, description) {
val intent = packageManger.getLaunchIntentForPackage(DFU_PACKAGE_NAME)
if (intent != null) {
context.startActivity(intent)
} else {
uriHandler.openUri(DFU_LINK)
else -> {
// TODO: Add more profiles
}
}
}
}
}
viewModel.logEvent(ProfileOpenEvent(Link.DFU))
} else {
NoConnectedDeviceView()
}
Spacer(modifier = Modifier.height(16.dp))
val loggerDescription = packageManger.getLaunchIntentForPackage(LOGGER_PACKAGE_NAME)?.let {
R.string.logger_module_info
} ?: R.string.dfu_module_install
FeatureButton(
R.drawable.ic_logger,
R.string.logger_module,
R.string.logger_module_full,
null,
loggerDescription
) {
viewModel.openLogger()
viewModel.logEvent(ProfileOpenEvent(Link.LOGGER))
}
Spacer(modifier = Modifier.height(16.dp))
Text(
text = BuildConfig.VERSION_NAME,
style = MaterialTheme.typography.labelSmall,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(16.dp))
}
item {
Links { onEvent(it) }
}
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (c) 2022, Nordic Semiconductor
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package no.nordicsemi.android.nrftoolbox.view
data class HomeViewState(
val isCSCModuleRunning: Boolean = false,
val isHRSModuleRunning: Boolean = false,
val isHTSModuleRunning: Boolean = false,
val isRSCSModuleRunning: Boolean = false,
val isPRXModuleRunning: Boolean = false,
val isCGMModuleRunning: Boolean = false,
val isUARTModuleRunning: Boolean = false,
val refreshToggle: Boolean = false
) {
fun copyWithRefresh(): HomeViewState {
return copy(refreshToggle = !refreshToggle)
}
}

View File

@@ -0,0 +1,103 @@
package no.nordicsemi.android.nrftoolbox.view
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Code
import androidx.compose.material.icons.filled.Language
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.nrftoolbox.R
import no.nordicsemi.android.nrftoolbox.viewmodel.UiEvent
@Composable
internal fun Links(onEvent: (UiEvent) -> Unit) {
Column {
Text(
text = stringResource(R.string.links),
modifier = Modifier
.alpha(0.5f)
.padding(start = 16.dp),
)
OutlinedCard(
modifier = Modifier.fillMaxWidth()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp))
.clickable { onEvent(UiEvent.OnGitHubClick) }
.background(MaterialTheme.colorScheme.surface)
.padding(16.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Icon(
imageVector = Icons.Default.Code,
contentDescription = stringResource(R.string.github_repo),
modifier = Modifier.size(40.dp),
tint = MaterialTheme.colorScheme.primary
)
Text(
text = stringResource(R.string.github_repo),
style = MaterialTheme.typography.bodyLarge,
)
}
}
HorizontalDivider()
Box(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(bottomStart = 8.dp, bottomEnd = 8.dp))
.clickable { onEvent(UiEvent.OnNordicDevZoneClick) }
.background(MaterialTheme.colorScheme.surface)
.padding(16.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Icon(
imageVector = Icons.Default.Language,
contentDescription = stringResource(R.string.nordic_dev_zone),
modifier = Modifier.size(40.dp),
tint = MaterialTheme.colorScheme.primary
)
Text(
text = stringResource(R.string.nordic_dev_zone),
style = MaterialTheme.typography.bodyLarge,
)
}
}
}
}
}
@Preview
@Composable
private fun LinksPreview() {
Links { }
}

View File

@@ -0,0 +1,83 @@
package no.nordicsemi.android.nrftoolbox.view
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.common.theme.NordicTheme
import no.nordicsemi.android.nrftoolbox.R
@Composable
internal fun NoConnectedDeviceView() {
val infiniteTransition = rememberInfiniteTransition()
val scale by infiniteTransition.animateFloat(
initialValue = 1f,
targetValue = 1.1f,
animationSpec = infiniteRepeatable(
animation = tween(1000, easing = LinearEasing),
repeatMode = RepeatMode.Reverse
)
)
OutlinedCard(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
painter = painterResource(id = R.drawable.ic_notification_icon),
contentDescription = null,
modifier = Modifier
.size(80.dp)
.graphicsLayer {
scaleX = scale
scaleY = scale
},
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary),
)
Text(
text = stringResource(R.string.device_not_connected_title),
style = MaterialTheme.typography.titleMedium,
textAlign = TextAlign.Center
)
Text(
text = stringResource(R.string.device_not_connected_message),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
)
}
}
}
@Preview(showBackground = true)
@Composable
private fun NoConnectedDeviceViewPreview() {
NordicTheme {
NoConnectedDeviceView()
}
}

View File

@@ -1,60 +0,0 @@
/*
* Copyright (c) 2022, Nordic Semiconductor
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package no.nordicsemi.android.nrftoolbox.view
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.colorResource
import no.nordicsemi.android.common.analytics.view.AnalyticsPermissionButton
import no.nordicsemi.android.nrftoolbox.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TitleAppBar(text: String) {
TopAppBar(
title = { Text(text, maxLines = 2) },
colors = TopAppBarDefaults.topAppBarColors(
scrolledContainerColor = MaterialTheme.colorScheme.primary,
containerColor = colorResource(id = R.color.appBarColor),
titleContentColor = MaterialTheme.colorScheme.onPrimary,
actionIconContentColor = MaterialTheme.colorScheme.onPrimary,
navigationIconContentColor = MaterialTheme.colorScheme.onPrimary,
),
actions = {
AnalyticsPermissionButton()
}
)
}

View File

@@ -1,123 +1,74 @@
/*
* Copyright (c) 2022, Nordic Semiconductor
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package no.nordicsemi.android.nrftoolbox.viewmodel
import android.content.Context
import androidx.core.net.toUri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import no.nordicsemi.android.analytics.AppAnalytics
import no.nordicsemi.android.analytics.Link
import no.nordicsemi.android.analytics.ProfileOpenEvent
import no.nordicsemi.android.cgms.repository.CGMRepository
import no.nordicsemi.android.common.logger.LoggerLauncher
import no.nordicsemi.android.common.navigation.DestinationId
import no.nordicsemi.android.common.navigation.Navigator
import no.nordicsemi.android.csc.repository.CSCRepository
import no.nordicsemi.android.hrs.service.HRSRepository
import no.nordicsemi.android.hts.repository.HTSRepository
import no.nordicsemi.android.nrftoolbox.repository.ActivitySignals
import no.nordicsemi.android.nrftoolbox.view.HomeViewState
import no.nordicsemi.android.prx.repository.PRXRepository
import no.nordicsemi.android.rscs.repository.RSCSRepository
import no.nordicsemi.android.uart.repository.UARTRepository
import no.nordicsemi.android.nrftoolbox.ScannerDestinationId
import no.nordicsemi.android.toolbox.profile.manager.ServiceManager
import no.nordicsemi.android.toolbox.profile.ProfileDestinationId
import no.nordicsemi.android.toolbox.profile.repository.DeviceRepository
import no.nordicsemi.kotlin.ble.client.android.Peripheral
import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject constructor(
@ApplicationContext
private val context: Context,
private val navigationManager: Navigator,
private val activitySignals: ActivitySignals,
cgmRepository: CGMRepository,
cscRepository: CSCRepository,
hrsRepository: HRSRepository,
htsRepository: HTSRepository,
prxRepository: PRXRepository,
rscsRepository: RSCSRepository,
uartRepository: UARTRepository,
private val analytics: AppAnalytics
) : ViewModel() {
internal data class HomeViewState(
val connectedDevices: Map<String, Pair<Peripheral, List<ServiceManager>>> = emptyMap(),
)
private const val GITHUB_REPO_URL = "https://github.com/NordicSemiconductor/Android-nRF-Toolbox.git"
private const val NORDIC_DEV_ZONE_URL = "https://devzone.nordicsemi.com/"
@HiltViewModel
internal class HomeViewModel @Inject constructor(
private val navigator: Navigator,
deviceRepository: DeviceRepository,
private val analytics: AppAnalytics,
) : ViewModel() {
private val _state = MutableStateFlow(HomeViewState())
val state = _state.asStateFlow()
init {
cgmRepository.isRunning.onEach {
_state.value = _state.value.copy(isCGMModuleRunning = it)
}.launchIn(viewModelScope)
cscRepository.isRunning.onEach {
_state.value = _state.value.copy(isCSCModuleRunning = it)
}.launchIn(viewModelScope)
hrsRepository.isRunning.onEach {
_state.value = _state.value.copy(isHRSModuleRunning = it)
}.launchIn(viewModelScope)
htsRepository.isRunning.onEach {
_state.value = _state.value.copy(isHTSModuleRunning = it)
}.launchIn(viewModelScope)
prxRepository.isRunning.onEach {
_state.value = _state.value.copy(isPRXModuleRunning = it)
}.launchIn(viewModelScope)
rscsRepository.isRunning.onEach {
_state.value = _state.value.copy(isRSCSModuleRunning = it)
}.launchIn(viewModelScope)
uartRepository.isRunning.onEach {
_state.value = _state.value.copy(isUARTModuleRunning = it)
}.launchIn(viewModelScope)
activitySignals.state.onEach {
_state.value = _state.value.copyWithRefresh()
// Observe connected devices from the repository
deviceRepository.connectedDevices.onEach { devices ->
_state.update { currentState ->
currentState.copy(connectedDevices = devices)
}
}.launchIn(viewModelScope)
}
fun openProfile(destination: DestinationId<Unit, Unit>) {
navigationManager.navigateTo(destination)
fun onClickEvent(event: UiEvent) {
when (event) {
UiEvent.OnConnectDeviceClick -> navigator.navigateTo(ScannerDestinationId)
is UiEvent.OnDeviceClick -> {
// Log the event for analytics.
analytics.logEvent(ProfileOpenEvent(event.profile))
navigator.navigateTo(
ProfileDestinationId, event.deviceAddress
)
}
UiEvent.OnGitHubClick -> {
// Log the event for analytics.
analytics.logEvent(ProfileOpenEvent(Link.GITHUB))
navigator.open(GITHUB_REPO_URL.toUri())
}
UiEvent.OnNordicDevZoneClick -> {
// Log the event for analytics.
analytics.logEvent(ProfileOpenEvent(Link.DEV_ACADEMY))
navigator.open(NORDIC_DEV_ZONE_URL.toUri())
}
}
}
fun openLogger() {
LoggerLauncher.launch(context, null)
}
fun logEvent(event: ProfileOpenEvent) {
analytics.logEvent(event)
}
}
}

View File

@@ -0,0 +1,23 @@
package no.nordicsemi.android.nrftoolbox.viewmodel
import no.nordicsemi.android.toolbox.lib.utils.Profile
/**
* HomeViewEvent is a sealed interface that represents the events that can be emitted by the Home view.
*/
sealed interface UiEvent {
/** OnConnectDeviceClick event that is emitted when the user clicks on the Connect Device button. */
data object OnConnectDeviceClick : UiEvent
/** OnDeviceClick event is emitted when the user clicks on a connected device. */
data class OnDeviceClick(val deviceAddress: String, val profile: Profile) : UiEvent
/**
* OnGitHubClick event is emitted when the user clicks on the GitHub repository option.
*/
data object OnGitHubClick : UiEvent
/** OnNordicDevZoneClick event is emitted when the user clicks on the Nordic DevZone option. */
data object OnNordicDevZoneClick : UiEvent
}

View File

@@ -1,46 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M773.3,436.5c0,0 -0.1,-0.1 -0.1,-0.1L513,17.6c-5.2,-8.4 -14.4,-13.5 -24.2,-13.5s-19,5.1 -24.2,13.5L204.4,436.4c0,0 -0.1,0.1 -0.1,0.1c-20,32.6 -66.5,117.2 -66.5,198.7c0,46 9.3,90.6 27.7,132.6c17.7,40.5 43.1,76.8 75.4,108c66.3,63.9 154.3,99.1 247.8,99.1c93.6,0 181.6,-35.2 247.8,-99.1c32.3,-31.2 57.7,-67.5 75.4,-108c18.4,-42 27.7,-86.6 27.7,-132.6C839.8,553.7 793.3,469.1 773.3,436.5zM488.8,917.8c-162.1,0 -294,-126.8 -294,-282.6c0,-68.8 44.4,-146.5 58,-168.8l236,-379.8l236,379.8c13.7,22.3 58,100.1 58,168.8C782.8,791 650.9,917.8 488.8,917.8z" />
<path
android:fillColor="#00B3DC"
android:pathData="M405.2,423.6c-1.5,-2.2 -3.8,-2.2 -5.3,0.1l-53.4,81.7c-2.5,3.8 -0.8,10.5 2.7,10.5h35v246.4c0,10.5 8.5,19 19,19s19,-8.5 19,-19V515.9h35c3.5,0 5.2,-6.8 2.6,-10.6L405.2,423.6z" />
<path
android:fillColor="#00B3DC"
android:pathData="M628.3,696.8h-35V450.4c0,-10.5 -8.5,-19 -19,-19s-19,8.5 -19,19v246.4h-35c-3.5,0 -5.2,6.8 -2.6,10.6l54.7,81.7c1.5,2.2 3.8,2.2 5.3,-0.1l53.4,-81.7C633.5,703.5 631.8,696.8 628.3,696.8z" />
</vector>

View File

@@ -1,55 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M236.3,441.9c-77.1,0 -139.8,-61 -139.8,-135.9c0,-20.6 4.6,-40.4 13.8,-58.8c0,0 0,-0.1 0.1,-0.1c3.6,-7.2 7.8,-14.1 12.6,-20.6L212.1,83c5.8,-9.4 16.5,-14.6 27.5,-13.3c9.6,1.1 17.8,7 22.1,15.4c4.3,7.4 39.3,63.6 90,144.2c2.8,4 5.4,8.2 7.8,12.5c0.2,0.4 0.4,0.8 0.6,1.1c10.5,19.4 16,41.2 16,63.1C376.1,380.9 313.4,441.9 236.3,441.9zM161.3,272.6c-5.2,10.5 -7.8,21.7 -7.8,33.4c0,43.5 37.1,78.9 82.8,78.9s82.8,-35.4 82.8,-78.9c0,-12.8 -3.1,-25 -9.3,-36.3c0,0 0,0 0,0c0,0 0,0 0,-0.1c-1.5,-2.7 -3.2,-5.4 -5,-7.9c-0.3,-0.5 -0.6,-0.9 -0.9,-1.4c-11.6,-18.4 -34,-54.1 -53.9,-85.9c-5.3,-8.4 -9.8,-15.7 -13.8,-22.1l-65.4,105.3c-0.5,0.8 -1,1.5 -1.5,2.2c-3,4 -5.6,8.2 -7.8,12.5C161.4,272.4 161.4,272.5 161.3,272.6zM263.3,89C263.3,89 263.3,89 263.3,89C263.3,89 263.3,89 263.3,89zM263.3,88.9C263.3,88.9 263.3,89 263.3,88.9C263.3,89 263.3,88.9 263.3,88.9z" />
<path
android:fillColor="#00B3DC"
android:pathData="M403.9,1011.3c-22.3,0 -43.8,-7.6 -61.4,-21.9c0,0 0,0 0,0L167.7,847c-41.7,-33.9 -47.9,-95.5 -14,-137.1L679.2,64.7C695.7,44.5 719,32 744.9,29.3c25.9,-2.6 51.3,5 71.5,21.4l174.8,142.4c20.2,16.4 32.8,39.8 35.4,65.7s-5,51.3 -21.4,71.5L479.6,975.4c-16.4,20.2 -39.8,32.8 -65.7,35.4C410.6,1011.2 407.2,1011.3 403.9,1011.3zM378.5,945.2c8.4,6.8 18.9,10 29.7,8.9c10.7,-1.1 20.4,-6.3 27.3,-14.7L961,294.2c6.8,-8.4 10,-18.9 8.9,-29.7c-1.1,-10.7 -6.3,-20.4 -14.7,-27.3L780.3,94.9c-8.4,-6.8 -18.9,-10 -29.7,-8.9c-10.8,1.1 -20.4,6.3 -27.3,14.7L197.9,745.9c-14.1,17.3 -11.5,42.8 5.8,56.9L378.5,945.2L378.5,945.2z" />
<path
android:fillColor="#00B3DC"
android:pathData="M572,414.3m-41.9,0a41.9,41.9 0,1 1,83.8 0a41.9,41.9 0,1 1,-83.8 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M684.5,505.9m-41.9,0a41.9,41.9 0,1 1,83.8 0a41.9,41.9 0,1 1,-83.8 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M474.3,534.2m-41.9,0a41.9,41.9 0,1 1,83.8 0a41.9,41.9 0,1 1,-83.8 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M586.8,625.8m-41.9,0a41.9,41.9 0,1 1,83.8 0a41.9,41.9 0,1 1,-83.8 0" />
</vector>

View File

@@ -1,40 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M757,436l-65,-207.4c-3.3,-10.4 -12.9,-17.5 -23.8,-17.5H564.8c-13.8,0 -24.9,11.2 -24.9,24.9c0,13.8 11.2,24.9 24.9,24.9h85l28.4,90.6l-242.5,55.2L414.3,310h16.4c13.8,0 24.9,-11.2 24.9,-24.9s-11.2,-24.9 -24.9,-24.9H295.8c-13.8,0 -24.9,11.2 -24.9,24.9s11.2,24.9 24.9,24.9h67.4l24,107.9l-78.3,17.8c-2.4,0.6 -4.7,1.5 -6.8,2.6c-11.2,-2.1 -22.7,-3.3 -34.6,-3.3c-101.7,0 -184.4,82.7 -184.4,184.4s82.7,184.4 184.4,184.4s184.4,-82.7 184.4,-184.4c0,-60.6 -29.4,-114.5 -74.8,-148.2l316.1,-72l12.2,38.8c-86,15.6 -151.4,91 -151.4,181.4c0,101.7 82.7,184.4 184.4,184.4s184.4,-82.7 184.4,-184.4C922.8,524 850,445.4 757,436zM402.1,619.4c0,74.2 -60.3,134.5 -134.5,134.5s-134.5,-60.3 -134.5,-134.5s60.3,-134.5 134.5,-134.5S402.1,545.2 402.1,619.4zM738.4,753.9c-74.2,0 -134.5,-60.3 -134.5,-134.5c0,-74.1 60.3,-134.4 134.4,-134.5c0,0 0.1,0 0.1,0c0,0 0.1,0 0.1,0c74.1,0.1 134.4,60.4 134.4,134.5C872.9,693.6 812.6,753.9 738.4,753.9z" />
</vector>

View File

@@ -1,52 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M316.8,389.3c-2.2,0 -4,1.8 -4,4v238.3c0,2.2 1.8,4 4,4h49.5c40.1,0 61.9,-21.8 61.9,-62.3V451.5c0,-40.5 -21.8,-62.3 -61.9,-62.3H316.8zM390.9,454v116.8c0,20.8 -8.1,30.3 -26,30.3h-10.8c-2.2,0 -4,-1.8 -4,-4V427.8c0,-2.2 1.8,-4 4,-4h10.8C382.8,423.8 390.9,433.3 390.9,454z" />
<path
android:fillColor="#00B3DC"
android:pathData="M565.2,389.3h-95.1c-2.2,0 -4,1.8 -4,4v238.3c0,2.2 1.8,4 4,4h29.3c2.2,0 4,-1.8 4,-4v-99.6c0,-2.2 1.8,-4 4,-4h44.7c2.2,0 4,-1.8 4,-4v-26.4c0,-2.2 -1.8,-4 -4,-4h-44.7c-2.2,0 -4,-1.8 -4,-4v-61.6c0,-2.2 1.8,-4 4,-4h57.8c2.2,0 4,-1.8 4,-4v-26.4C569.2,391.1 567.4,389.3 565.2,389.3z" />
<path
android:fillColor="#00B3DC"
android:pathData="M714,580.3v-187c0,-2.2 -1.8,-4 -4,-4h-29.3c-2.2,0 -4,1.8 -4,4v186c0,17.9 -8.1,24.6 -21.1,24.6c-13,0 -21.1,-6.7 -21.1,-24.6v-186c0,-2.2 -1.8,-4 -4,-4h-27.8c-2.2,0 -4,1.8 -4,4v187c0,38.7 22.2,58.8 57.4,58.8C691.8,639.1 714,619 714,580.3z" />
<path
android:fillColor="#00B3DC"
android:pathData="M410.7,821.8c-3.4,-4.6 -12,-5.4 -13.5,-1.3l-13.9,38.5C191.3,787.7 92,574.1 161.8,381.2c34,-93.9 102.5,-169 192.9,-211.4c14.3,-6.7 20.4,-23.7 13.7,-37.9c-6.7,-14.3 -23.7,-20.4 -37.9,-13.7c-50.7,23.7 -95.6,56.5 -133.4,97.4c-39.2,42.3 -69.1,91.5 -88.9,146.2C88.4,416.5 79.9,473.5 83,531.1c3,55.6 16.5,109.5 40.2,160.2c23.7,50.7 56.5,95.6 97.4,133.4c41.6,38.5 89.8,68.1 143.3,87.8l-12.8,35.4c-1.5,4.1 5.8,9 11.3,7.6l119.7,-29.7c3.3,-0.8 4.2,-3.6 2.2,-6.3L410.7,821.8z" />
<path
android:fillColor="#00B3DC"
android:pathData="M943.8,485.8c-3,-55.6 -16.5,-109.5 -40.2,-160.2c-23.7,-50.7 -56.5,-95.6 -97.4,-133.4c-40.7,-37.7 -87.8,-66.8 -140,-86.6l10.7,-29.5c1.5,-4.1 -5.8,-9 -11.3,-7.6L545.8,98.1c-3.3,0.8 -4.2,3.6 -2.2,6.3l73.6,97.8c3.4,4.6 12,5.4 13.5,1.3l16,-44.4C836.6,231.6 934.3,443.8 865,635.6C831,729.5 762.5,804.6 672,847c-14.3,6.7 -20.4,23.7 -13.7,37.9c4.8,10.3 15.1,16.4 25.8,16.4c4.1,0 8.2,-0.9 12.1,-2.7c50.7,-23.7 95.6,-56.5 133.4,-97.4c39.2,-42.3 69.1,-91.5 88.9,-146.2S946.8,543.4 943.8,485.8z" />
</vector>

View File

@@ -1,43 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M386.1,310.1c0,-21.9 -5.5,-43.7 -15.9,-63c-0.2,-0.4 -0.5,-0.9 -0.7,-1.3c-2.4,-4.3 -5,-8.4 -7.8,-12.4C311,152.8 276,96.7 271.7,89.2c-4.3,-8.4 -12.5,-14.3 -22.1,-15.4c-11,-1.3 -21.7,3.9 -27.5,13.3L133,230.6c-4.8,6.4 -8.9,13.2 -12.5,20.3c-0.1,0.2 -0.2,0.4 -0.3,0.7c-9.1,18.4 -13.6,38.1 -13.6,58.6c0,74.9 62.7,135.9 139.8,135.9S386.1,385 386.1,310.1zM163.5,310.1c0,-11.8 2.7,-23.1 7.9,-33.6c0,0 0,0 0,-0.1c2.2,-4.3 4.8,-8.6 7.8,-12.5c0.5,-0.7 1,-1.4 1.5,-2.2l65.4,-105.3c4,6.3 8.5,13.6 13.8,22.1c19.9,31.8 42.3,67.5 53.9,85.9c0.3,0.5 0.6,1 0.9,1.4c1.8,2.5 3.5,5.2 5,7.9c0,0 0,0 0,0c0,0 0,0.1 0,0.1c6.2,11.3 9.3,23.5 9.3,36.3c0,43.5 -37.1,78.9 -82.8,78.9S163.5,353.6 163.5,310.1z" />
<path
android:fillColor="#00B3DC"
android:pathData="M975.7,103c-50.2,-48.2 -130.2,-46.5 -178.4,3.7L228.8,699.8c-10.9,11.4 -10.5,29.4 0.8,40.3l49.9,47.9c-1.7,1.2 -3.4,2.7 -4.8,4.3l-91.4,102.9c-10.5,11.8 -9.4,29.8 2.4,40.2c5.4,4.8 12.2,7.2 18.9,7.2c7.9,0 15.7,-3.2 21.3,-9.6l91.4,-102.9c1,-1.1 1.8,-2.2 2.6,-3.4l50.7,48.7c5.3,5.1 12.4,7.9 19.7,7.9c0.2,0 0.4,0 0.6,0c7.6,-0.2 14.8,-3.3 20,-8.8l568.4,-593c0,0 0.1,-0.1 0.1,-0.1C1027.6,231.2 1025.9,151.2 975.7,103zM938.3,241.9C938.3,241.9 938.3,241.9 938.3,241.9L389.5,814.5l-99.8,-95.8l548.8,-572.5c26.4,-27.5 70.3,-28.4 97.8,-2C963.8,170.5 964.7,214.3 938.3,241.9z" />
</vector>

View File

@@ -1,40 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M863.6,210.5c-42.2,-42.2 -98.4,-65.5 -158.2,-65.5c-57.2,0 -111.7,21.6 -153.3,60.8c-16.9,16 -31.1,34.2 -42.2,54c-11.1,-19.9 -25.2,-38.1 -42.2,-54c-41.6,-39.2 -96.1,-60.8 -153.3,-60.8c-59.7,0 -115.9,23.3 -158.2,65.5c-42.2,42.2 -65.5,98.4 -65.5,158.2c0,41.7 11.5,82.3 33.4,117.6c0.3,0.5 0.6,1.1 1,1.6C200,607.1 476.7,896 488.4,908.3c5.6,5.8 13.1,8.8 20.6,8.8c0.3,0 0.6,0 0.9,0c0.3,0 0.6,0 0.9,0c7.5,0 15,-2.9 20.6,-8.8c11.8,-12.3 288.5,-301.2 363.3,-420.5c0.3,-0.5 0.7,-1 1,-1.5c21.9,-35.3 33.4,-76 33.4,-117.6C929.1,308.9 905.9,252.7 863.6,210.5zM846.9,456.9C846.8,456.9 846.8,456.9 846.9,456.9c-0.1,0.1 -0.1,0.1 -0.1,0.1c-60.1,96.2 -271.2,321.8 -336.9,391.2c-65.7,-69.4 -276.8,-295 -336.8,-391.2c0,0 0,0 0,0c0,0 0,-0.1 -0.1,-0.1c-16.5,-26.4 -25.2,-56.9 -25.2,-88.2c0,-91.9 74.8,-166.7 166.7,-166.7c87.7,0 160.7,68.5 166.3,155.9c1,15.3 13.9,27.1 29.2,26.7c15.3,0.4 28.2,-11.3 29.2,-26.7c5.6,-87.4 78.6,-155.9 166.3,-155.9c91.9,0 166.7,74.8 166.7,166.7C872.1,399.9 863.4,430.4 846.9,456.9z" />
</vector>

View File

@@ -1,52 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M813.8,338h-92.9c-15.7,0 -28.5,12.8 -28.5,28.5s12.8,28.5 28.5,28.5h92.9c15.7,0 28.5,-12.8 28.5,-28.5S829.6,338 813.8,338z" />
<path
android:fillColor="#00B3DC"
android:pathData="M720.9,240.7h92.9c15.7,0 28.5,-12.8 28.5,-28.5s-12.8,-28.5 -28.5,-28.5h-92.9c-15.7,0 -28.5,12.8 -28.5,28.5S705.2,240.7 720.9,240.7z" />
<path
android:fillColor="#00B3DC"
android:pathData="M813.8,492.3h-92.9c-15.7,0 -28.5,12.8 -28.5,28.5c0,15.7 12.8,28.5 28.5,28.5h92.9c15.7,0 28.5,-12.8 28.5,-28.5C842.3,505.1 829.6,492.3 813.8,492.3z" />
<path
android:fillColor="#00B3DC"
android:pathData="M637.5,604.9V175.3c0,-66.8 -54.3,-121.1 -121.1,-121.1s-121.1,54.3 -121.1,121.1v429.6c-18.2,15.5 -33.5,34.6 -44.6,55.8c-13.9,26.5 -21.2,56.4 -21.2,86.5c0,103 83.8,186.8 186.8,186.8c103,0 186.8,-83.8 186.8,-186.8c0,-30.1 -7.3,-60 -21.2,-86.5C671,639.5 655.7,620.5 637.5,604.9zM516.4,877c-71.6,0 -129.8,-58.2 -129.8,-129.8c0,-41.6 20.2,-80.9 53.9,-105.3c7.4,-5.4 11.8,-14 11.8,-23.1V175.3c0,-35.3 28.7,-64.1 64.1,-64.1c35.3,0 64.1,28.7 64.1,64.1v443.4c0,9.2 4.4,17.8 11.8,23.1c33.8,24.4 53.9,63.8 53.9,105.3C646.2,818.8 588,877 516.4,877z" />
<path
android:fillColor="#00B3DC"
android:pathData="M601.3,747c0,-1.3 0,-2.7 -0.1,-4c0,-0.4 -0.1,-0.8 -0.1,-1.2c-0.1,-0.9 -0.1,-1.8 -0.2,-2.8c0,-0.5 -0.1,-0.9 -0.1,-1.4c-0.1,-0.9 -0.2,-1.8 -0.3,-2.7c-0.1,-0.4 -0.1,-0.8 -0.2,-1.2c-0.2,-1.3 -0.4,-2.6 -0.7,-3.8c0,0 0,-0.1 0,-0.1c-0.3,-1.2 -0.5,-2.4 -0.8,-3.6c-0.1,-0.4 -0.2,-0.8 -0.3,-1.2c-0.2,-0.9 -0.5,-1.7 -0.7,-2.5c-0.1,-0.4 -0.3,-0.9 -0.4,-1.3c-0.3,-0.8 -0.5,-1.7 -0.8,-2.5c-0.1,-0.4 -0.3,-0.8 -0.4,-1.1c-0.4,-1.2 -0.9,-2.3 -1.4,-3.5c0,-0.1 -0.1,-0.2 -0.1,-0.2c-0.5,-1.1 -0.9,-2.1 -1.4,-3.2c-0.2,-0.4 -0.4,-0.8 -0.6,-1.1c-0.4,-0.8 -0.8,-1.5 -1.2,-2.2c-0.2,-0.4 -0.4,-0.8 -0.7,-1.2c-0.4,-0.7 -0.8,-1.5 -1.3,-2.2c-0.2,-0.4 -0.4,-0.7 -0.6,-1.1c-0.6,-1 -1.3,-2 -1.9,-3c-0.1,-0.2 -0.2,-0.3 -0.3,-0.5c-0.6,-0.9 -1.2,-1.8 -1.9,-2.6c-0.3,-0.4 -0.5,-0.7 -0.8,-1.1c-0.5,-0.6 -1,-1.3 -1.5,-1.9c-0.3,-0.4 -0.6,-0.8 -0.9,-1.1c-0.5,-0.6 -1,-1.2 -1.6,-1.8c-0.3,-0.3 -0.6,-0.7 -0.9,-1c-0.8,-0.8 -1.5,-1.7 -2.3,-2.5c-0.2,-0.2 -0.4,-0.4 -0.6,-0.6c-0.7,-0.7 -1.4,-1.4 -2.2,-2.1c-0.4,-0.3 -0.7,-0.6 -1.1,-0.9c-0.6,-0.5 -1.2,-1 -1.7,-1.5c-0.4,-0.3 -0.8,-0.7 -1.2,-1c-0.6,-0.5 -1.2,-1 -1.8,-1.4c-0.4,-0.3 -0.7,-0.6 -1.1,-0.9c-0.9,-0.6 -1.8,-1.3 -2.7,-1.9c-0.3,-0.2 -0.6,-0.4 -1,-0.6c-0.8,-0.5 -1.6,-1 -2.4,-1.5c-0.4,-0.3 -0.9,-0.5 -1.3,-0.8c-0.6,-0.4 -1.3,-0.8 -2,-1.1c-0.5,-0.3 -0.9,-0.5 -1.4,-0.8c-0.7,-0.4 -1.4,-0.7 -2,-1c-0.4,-0.2 -0.9,-0.4 -1.3,-0.7c-1,-0.5 -2,-0.9 -3,-1.4c-0.4,-0.2 -0.8,-0.3 -1.1,-0.5c-0.9,-0.4 -1.7,-0.7 -2.6,-1c-0.5,-0.2 -1,-0.3 -1.4,-0.5c-0.4,-0.2 -0.9,-0.3 -1.3,-0.5V334.1l-53.8,0.8v331.6c-0.4,0.1 -0.9,0.3 -1.3,0.5c-0.5,0.2 -1,0.3 -1.4,0.5c-0.9,0.3 -1.8,0.7 -2.6,1c-0.4,0.2 -0.8,0.3 -1.1,0.5c-1,0.4 -2,0.9 -3,1.4c-0.4,0.2 -0.9,0.4 -1.3,0.7c-0.7,0.3 -1.4,0.7 -2,1c-0.5,0.2 -0.9,0.5 -1.4,0.8c-0.7,0.4 -1.3,0.7 -2,1.1c-0.4,0.3 -0.9,0.5 -1.3,0.8c-0.8,0.5 -1.6,1 -2.4,1.5c-0.3,0.2 -0.6,0.4 -1,0.6c-0.9,0.6 -1.8,1.3 -2.7,1.9c-0.4,0.3 -0.8,0.6 -1.1,0.9c-0.6,0.5 -1.2,0.9 -1.8,1.4c-0.4,0.3 -0.8,0.6 -1.2,1c-0.6,0.5 -1.2,1 -1.7,1.5c-0.4,0.3 -0.7,0.6 -1.1,0.9c-0.7,0.7 -1.5,1.4 -2.2,2.1c-0.2,0.2 -0.4,0.4 -0.6,0.6c-0.8,0.8 -1.6,1.6 -2.3,2.5c-0.3,0.3 -0.6,0.7 -0.9,1c-0.5,0.6 -1.1,1.2 -1.6,1.8c-0.3,0.4 -0.6,0.7 -0.9,1.1c-0.5,0.6 -1,1.3 -1.5,1.9c-0.3,0.4 -0.5,0.7 -0.8,1.1c-0.6,0.9 -1.3,1.7 -1.9,2.6c-0.1,0.2 -0.2,0.3 -0.3,0.5c-0.7,1 -1.3,2 -1.9,3c-0.2,0.4 -0.4,0.7 -0.6,1.1c-0.4,0.7 -0.8,1.4 -1.3,2.2c-0.2,0.4 -0.4,0.8 -0.7,1.2c-0.4,0.7 -0.8,1.5 -1.2,2.2c-0.2,0.4 -0.4,0.8 -0.6,1.1c-0.5,1.1 -1,2.1 -1.4,3.2c0,0.1 -0.1,0.2 -0.1,0.2c-0.5,1.2 -0.9,2.3 -1.4,3.5c-0.1,0.4 -0.3,0.8 -0.4,1.1c-0.3,0.8 -0.6,1.7 -0.8,2.5c-0.1,0.4 -0.3,0.9 -0.4,1.3c-0.3,0.8 -0.5,1.7 -0.7,2.5c-0.1,0.4 -0.2,0.8 -0.3,1.2c-0.3,1.2 -0.6,2.4 -0.8,3.6c0,0 0,0.1 0,0.1c-0.3,1.3 -0.5,2.5 -0.7,3.8c-0.1,0.4 -0.1,0.8 -0.2,1.2c-0.1,0.9 -0.2,1.8 -0.3,2.7c0,0.5 -0.1,0.9 -0.1,1.4c-0.1,0.9 -0.2,1.8 -0.2,2.8c0,0.4 -0.1,0.8 -0.1,1.2c-0.1,1.3 -0.1,2.7 -0.1,4c0,0 0,0 0,0v0c0,0 0,0 0,0c0,20.5 7.3,39.3 19.4,54c15.6,18.9 39.1,30.9 65.5,30.9c26.4,0 49.9,-12 65.5,-30.9C594,786.3 601.3,767.5 601.3,747C601.3,747 601.3,747 601.3,747L601.3,747C601.3,747 601.3,747 601.3,747z" />
</vector>

View File

@@ -1,55 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M176,180.1m-70.2,0a70.2,70.2 0,1 1,140.4 0a70.2,70.2 0,1 1,-140.4 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M152.7,433.7c-13.6,0 -25.7,-9.8 -28.1,-23.7c-2.7,-15.5 7.7,-30.3 23.3,-32.9c73.8,-12.7 123.5,-35.2 161.3,-72.9c44.4,-44.4 60.8,-101.4 71.1,-151.3c3.2,-15.4 18.2,-25.4 33.6,-22.2c15.4,3.2 25.4,18.2 22.2,33.6c-7.7,37.7 -16.8,67.8 -28.6,94.5c-14.8,33.4 -33.7,61.4 -58,85.7c-59.7,59.7 -133.9,78.8 -191.9,88.8C155.9,433.6 154.3,433.7 152.7,433.7z" />
<path
android:fillColor="#00B3DC"
android:pathData="M154.8,584.1c-0.8,0 -1.7,0 -2.5,0c-15.7,-0.1 -28.4,-12.9 -28.4,-28.7c0.1,-15.7 12.8,-28.4 28.5,-28.4c0.1,0 0.1,0 0.2,0c0.7,0 1.5,0 2.2,0c104,0 199.4,-38.2 268.9,-107.6c67.6,-67.6 105.8,-160.4 107.5,-261.4c0.3,-15.6 13,-28 28.5,-28c0.2,0 0.3,0 0.5,0c15.7,0.3 28.3,13.3 28,29c-1,56.7 -11.9,111 -32.3,161.6c-21.2,52.5 -52.2,99.3 -92,139.1C383.8,540 274.1,584.1 154.8,584.1z" />
<path
android:fillColor="#00B3DC"
android:pathData="M848,843.9m-70.2,0a70.2,70.2 0,1 1,140.4 0a70.2,70.2 0,1 1,-140.4 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M615.9,893.9c-1.9,0 -3.8,-0.2 -5.8,-0.6c-15.4,-3.2 -25.4,-18.2 -22.2,-33.6c7.7,-37.7 16.8,-67.8 28.6,-94.5c14.8,-33.4 33.7,-61.5 58,-85.7c59.7,-59.7 133.9,-78.8 191.9,-88.8c15.5,-2.7 30.3,7.7 32.9,23.3c2.7,15.5 -7.7,30.3 -23.3,32.9c-73.8,12.7 -123.5,35.2 -161.3,72.9c-44.4,44.4 -60.8,101.4 -71.1,151.3C641,884.6 629.2,893.9 615.9,893.9z" />
<path
android:fillColor="#00B3DC"
android:pathData="M464.3,893.9c-0.2,0 -0.3,0 -0.5,0c-15.7,-0.3 -28.3,-13.3 -28,-29c1,-56.7 11.9,-111 32.3,-161.6c21.2,-52.5 52.2,-99.3 92,-139.1c80.8,-80.8 191.5,-124.9 311.7,-124.3c15.7,0.1 28.4,12.9 28.4,28.7c-0.1,15.7 -12.8,28.4 -28.5,28.4c-0.1,0 -0.1,0 -0.2,0c-104.9,-0.5 -201.2,37.7 -271.1,107.6c-67.6,67.6 -105.8,160.4 -107.5,261.4C492.5,881.5 479.8,893.9 464.3,893.9z" />
</vector>

View File

@@ -1,49 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M982.9,706.2c-10.8,-37.3 -61.8,-59.1 -126.3,-86.7c-26.1,-11.2 -53.1,-22.7 -73.8,-34.3c-26.6,-14.9 -30.8,-23.3 -31.4,-24.8C730,504.6 641.7,260.1 634.7,237.4c-6.8,-22.1 -23.1,-38.5 -43.7,-43.8c-12.9,-3.3 -38.5,-5 -65.7,21.3c-16.6,16 -30.5,38.5 -40.2,57.1c-4.8,-3.8 -9.9,-7.9 -15,-12.3c-37.1,-31.1 -43.9,-44 -44.7,-46c-1.7,-8.8 -0.2,-25.9 1,-41c2.7,-31.8 5.2,-61.8 -11.7,-80.3c-15,-16.5 -41.3,-23.4 -72.2,-19.1c-31.8,4.4 -67.1,19.7 -105,45.4c-19.8,13.4 -36.3,27 -50,39.8c-0.6,0.5 -1.2,1.1 -1.8,1.7c-0.1,0.1 -0.3,0.3 -0.4,0.4c-14.2,13.4 -25.2,26 -33.6,36.8c-36.3,42.6 -64,85 -79.2,109.6c-14.6,23.8 -17.6,52.5 -8.3,78.8c9.5,26.7 30.1,66.5 74.6,103.9c91,76.7 198.5,176.9 227.5,227.9c19.9,35.1 48.2,80.3 90.2,118.7c52.8,48.3 114.7,74.2 184,77c38.5,1.6 77.8,2.8 115,2.8c33,0 64.3,-1 92,-3.7c50.6,-4.9 118.8,-17.4 127.9,-69c2.8,-15.7 4.7,-37.3 6.1,-57.8C984.7,758.2 987.6,722.4 982.9,706.2zM269.4,165.8c58,-39.4 91.9,-38.7 101.4,-35.5c1.1,8.3 -0.4,26.3 -1.4,37.6c-1.7,20.3 -3.5,41.4 0.1,58.3c2.8,13.1 12.3,33.5 61.1,74.9c24.4,20.7 47.7,37.4 48.7,38.1c7.2,5.1 16.3,6.6 24.7,4.1c8.4,-2.5 15.2,-8.8 18.4,-17c5.2,-13.3 22.9,-51.9 42.3,-70.6c6.8,-6.6 11.1,-7.3 11.9,-7.1c0.5,0.1 2.4,1.7 3.5,5.3c3.1,10.2 18.4,53.4 37.2,105.6l-73.1,12.9c-10.3,1.8 -17.2,11.7 -15.4,22c1.6,9.2 9.6,15.7 18.7,15.7c1.1,0 2.2,-0.1 3.3,-0.3l79.6,-14.1c5.3,14.8 10.8,29.9 16.2,44.7l-74.3,13.1c-10.3,1.8 -17.2,11.7 -15.4,22c1.6,9.2 9.6,15.7 18.7,15.7c1.1,0 2.2,-0.1 3.3,-0.3l80.9,-14.3c5.8,15.8 11.3,31 16.4,44.7L600.4,535c-10.3,1.8 -17.2,11.7 -15.4,22c1.6,9.2 9.6,15.7 18.7,15.7c1.1,0 2.2,-0.1 3.3,-0.3l82.6,-14.6c3.5,9.5 6.5,17.3 8.6,22.9c7.4,19.4 25.5,36.6 56.7,54.1c23.4,13.1 51.8,25.3 79.3,37c24.5,10.5 47.7,20.4 66.1,30.4c19.3,10.4 25.5,17 27.4,19.3c-0.1,0.5 -0.1,1.1 -0.2,1.6c-0.1,1.4 -0.2,3.5 -0.4,8.6c-0.3,6.3 -0.7,15.8 -1.3,26.9c-63.1,9.8 -182.8,18.5 -260.2,2.1c-98.2,-20.7 -146.9,-106.7 -179.2,-163.6l-1.5,-2.7C448.5,530.4 305.1,389 239.1,333.4c-40.1,-33.8 -51.7,-67.3 -55.1,-83.3c2.4,-3.9 6,-9.4 11.1,-16.1c9.5,-11.2 19.7,-22.4 30.4,-33.2C237.3,189.7 251.8,177.8 269.4,165.8zM841.8,855.7c-55.5,5.4 -128.5,3.5 -199.2,0.6c-119.9,-4.8 -184.2,-91.7 -226.9,-166.9c-40,-70.4 -181.4,-193.6 -240.3,-243.3c-34.7,-29.2 -50.5,-59.3 -57.6,-79.4c-3.5,-10 -2.4,-20.9 3.1,-29.9c5.6,-9.1 13,-20.7 22,-33.9c13.3,26.9 33.7,52.2 59.5,74c70.8,59.7 203.3,193.6 233,245.7l1.5,2.7c16.9,29.8 40.1,70.7 73.9,107.2c41,44.3 89.2,72.6 143.1,84c35.8,7.6 77.7,10.3 119.1,10.3c55.7,0 110.6,-5 148.4,-10.1c-0.7,6.2 -1.5,11.8 -2.3,16.7C919,833.7 912,848.9 841.8,855.7z" />
<path
android:fillColor="#00B3DC"
android:pathData="M54.9,666.5h87.5c10.5,0 19,-8.5 19,-19s-8.5,-19 -19,-19H54.9c-10.5,0 -19,8.5 -19,19S44.4,666.5 54.9,666.5z" />
<path
android:fillColor="#00B3DC"
android:pathData="M54.9,782.2H239c10.5,0 19,-8.5 19,-19s-8.5,-19 -19,-19H54.9c-10.5,0 -19,8.5 -19,19S44.4,782.2 54.9,782.2z" />
<path
android:fillColor="#00B3DC"
android:pathData="M364.3,859.9H54.9c-10.5,0 -19,8.5 -19,19s8.5,19 19,19h309.4c10.5,0 19,-8.5 19,-19S374.8,859.9 364.3,859.9z" />
</vector>

View File

@@ -1,40 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,12m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-10 0"
android:fillColor="#000000"/>
</vector>

View File

@@ -1,82 +0,0 @@
<!--
~ Copyright (c) 2022, Nordic Semiconductor
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without modification, are
~ permitted provided that the following conditions are met:
~
~ 1. Redistributions of source code must retain the above copyright notice, this list of
~ conditions and the following disclaimer.
~
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list
~ of conditions and the following disclaimer in the documentation and/or other materials
~ provided with the distribution.
~
~ 3. Neither the name of the copyright holder nor the names of its contributors may be
~ used to endorse or promote products derived from this software without specific prior
~ written permission.
~
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
~ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
~ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
~ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#00B3DC"
android:pathData="M267.4,472.8m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M349.3,472.8m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M431.1,472.8m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M513,472.8m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M594.9,472.8m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M676.7,472.8m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M758.6,472.8m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M306.5,545m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M388.4,545m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M470.2,545m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M552.1,545m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M634,545m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M715.9,545m-22.3,0a22.3,22.3 0,1 1,44.6 0a22.3,22.3 0,1 1,-44.6 0" />
<path
android:fillColor="#00B3DC"
android:pathData="M806.3,759.8H219.7c-30.7,0 -59.9,-9.8 -84.4,-28.2c-24.5,-18.5 -42,-43.8 -50.5,-73.3L6.6,387c-8.9,-30.8 -2.9,-63.1 16.4,-88.7S71.7,258 103.7,258h818.5c32,0 61.5,14.7 80.7,40.3c19.3,25.6 25.2,57.9 16.4,88.7l-78.1,271.3c-8.5,29.5 -26,54.9 -50.5,73.3C866.2,750 837,759.8 806.3,759.8zM103.7,315c-14,0 -26.8,6.4 -35.2,17.6c-8.4,11.2 -11,25.3 -7.1,38.7l78.1,271.3c10.2,35.5 43.2,60.3 80.1,60.3h586.7c37,0 69.9,-24.8 80.1,-60.3l78.1,-271.3c3.9,-13.4 1.3,-27.5 -7.1,-38.7c-8.4,-11.2 -21.2,-17.6 -35.2,-17.6H103.7z" />
<path
android:fillColor="#00B3DC"
android:pathData="M766.2,648.4H259.8c-18.5,0 -36.2,-5.3 -51.1,-15.5c-15.3,-10.4 -26.2,-24.8 -31.6,-41.6c-0.1,-0.4 -0.2,-0.7 -0.3,-1.1l-37.2,-146.5c-5.1,-16.7 -2.1,-34.5 8.4,-48.9c11.7,-16 31,-25.5 51.8,-25.5h626.5c20.8,0 40.1,9.5 51.8,25.5c10.5,14.4 13.6,32.2 8.4,48.9l-37.2,146.5c-0.1,0.4 -0.2,0.7 -0.3,1.1c-5.4,16.8 -16.3,31.2 -31.6,41.6C802.4,643.1 784.7,648.4 766.2,648.4zM213.5,580.3c5.9,17.8 24.9,30.2 46.4,30.2h506.4c21.4,0 40.4,-12.4 46.4,-30.2l37.2,-146.4c0.1,-0.4 0.2,-0.7 0.3,-1.1c2.2,-6.8 -0.3,-12.2 -2.7,-15.5c-4.5,-6.2 -12.4,-9.9 -21.1,-9.9H199.8c-8.7,0 -16.5,3.7 -21.1,9.9c-2.4,3.3 -4.9,8.7 -2.7,15.5c0.1,0.4 0.2,0.7 0.3,1.1L213.5,580.3z" />
</vector>

View File

@@ -32,33 +32,68 @@
<resources>
<string name="csc_module">CSC</string>
<string name="csc_module_full">Cyclic Speed and Cadence</string>
<string name="hrs_module">HRS</string>
<string name="hrs_module_full">Heart Rate</string>
<string name="gls_module">GLS</string>
<string name="gls_module_full">Glucose</string>
<string name="hts_module">HTS</string>
<string name="hts_module_full">Health Thermometer</string>
<string name="bps_module">BPS</string>
<string name="bps_module_full">Blood Pressure</string>
<string name="rscs_module">RSCS</string>
<string name="rscs_module_full">Running Speed and Cadence</string>
<string name="prx_module">PRX</string>
<string name="prx_module_full">Proximity</string>
<string name="cgm_module">CGMS</string>
<string name="cgm_module_full">Continuous Glucose</string>
<string name="uart_module">UART</string>
<string name="uart_module_full">Universal Asynchronous Receiver/Transmitter (UART)</string>
<string name="dfu_module">DFU</string>
<string name="dfu_module_full">Device Firmware Update</string>
<string name="dfu_module_info">Open DFU application.</string>
<string name="dfu_module_install">Download from Google Play.</string>
<string name="logger_module">nRF Logger</string>
<string name="logger_module_full">nRF Logger</string>
<string name="logger_module_info">Open nRF Logger application.</string>
<string name="direction_module">DF</string>
<string name="direction_module_full">Direction Finder</string>
<string name="viewmodel_profiles">ViewModel profiles</string>
<string name="service_profiles">Service profiles</string>
<string name="utils_services">Utils services</string>
<string name="running_profile_icon">Icon indicating if the profile is running</string>
<string name="battery_module">BATTERY</string>
<string name="battery_module_full">Battery</string>
<string name="channel_sounding_module"> CHANNEL SOUNDING</string>
<string name="throughput_module">Throughput</string>
<string name="unknown_device">Unknown Device</string>
<string name="lbs_blinky_module">LBS/Blinky</string>
<string name="device_not_connected_title">NO DEVICES CONNECTED</string>
<string name="device_not_connected_message">Tap Connect device button to begin.</string>
<string name="connect_device">Connect Device</string>
<string name="connected_devices">Connected devices</string>
<string name="github_repo">Source code (GitHub)</string>
<string name="nordic_dev_zone">Help (Nordic DevZone)</string>
<string name="links">Links</string>
</resources>