├── .editorconfig
├── .gitignore
├── .vscode
└── extensions.json
├── App_Resources
├── Android
│ ├── app.gradle
│ ├── before-plugins.gradle
│ ├── gradle.properties
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── sinasamaki
│ │ │ └── dynamicisland
│ │ │ ├── App.kt
│ │ │ ├── IslandView.kt
│ │ │ ├── RadioButtonRow.kt
│ │ │ ├── island
│ │ │ ├── CallWaveform.kt
│ │ │ ├── DynamicIsland.kt
│ │ │ ├── FaceUnlock.kt
│ │ │ ├── IslandBubbleContent.kt
│ │ │ ├── IslandContent.kt
│ │ │ ├── IslandState.kt
│ │ │ ├── LeadingContent.kt
│ │ │ └── TrailingContent.kt
│ │ │ ├── metaball
│ │ │ ├── MetaContainter.kt
│ │ │ ├── MetaEntity.kt
│ │ │ └── Modifiers.kt
│ │ │ └── ui
│ │ │ └── theme
│ │ │ ├── Color.kt
│ │ │ ├── Shape.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ │ └── res
│ │ ├── drawable-hdpi
│ │ ├── background.png
│ │ └── logo.png
│ │ ├── drawable-ldpi
│ │ ├── background.png
│ │ └── logo.png
│ │ ├── drawable-mdpi
│ │ ├── background.png
│ │ └── logo.png
│ │ ├── drawable-nodpi
│ │ └── splash_screen.xml
│ │ ├── drawable-xhdpi
│ │ ├── background.png
│ │ └── logo.png
│ │ ├── drawable-xxhdpi
│ │ ├── background.png
│ │ └── logo.png
│ │ ├── drawable-xxxhdpi
│ │ ├── background.png
│ │ └── logo.png
│ │ ├── drawable
│ │ ├── ic_launcher_foreground.xml
│ │ └── timer.xml
│ │ ├── mipmap-anydpi-v26
│ │ └── ic_launcher.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-v21
│ │ ├── colors.xml
│ │ └── styles.xml
│ │ ├── values-v29
│ │ └── styles.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
└── iOS
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── icon-1024.png
│ │ ├── icon-20.png
│ │ ├── icon-20@2x.png
│ │ ├── icon-20@3x.png
│ │ ├── icon-29.png
│ │ ├── icon-29@2x.png
│ │ ├── icon-29@3x.png
│ │ ├── icon-40.png
│ │ ├── icon-40@2x.png
│ │ ├── icon-40@3x.png
│ │ ├── icon-60@2x.png
│ │ ├── icon-60@3x.png
│ │ ├── icon-76.png
│ │ ├── icon-76@2x.png
│ │ └── icon-83.5@2x.png
│ ├── Contents.json
│ ├── LaunchScreen.AspectFill.imageset
│ │ ├── Contents.json
│ │ ├── LaunchScreen-AspectFill.png
│ │ ├── LaunchScreen-AspectFill@2x.png
│ │ └── LaunchScreen-AspectFill@3x.png
│ └── LaunchScreen.Center.imageset
│ │ ├── Contents.json
│ │ ├── LaunchScreen-Center.png
│ │ ├── LaunchScreen-Center@2x.png
│ │ └── LaunchScreen-Center@3x.png
│ ├── Info.plist
│ ├── LaunchScreen.storyboard
│ └── build.xcconfig
├── README.md
├── nativescript.config.ts
├── package-lock.json
├── package.json
├── references.d.ts
├── src
├── app.css
├── app
│ ├── app-routing.module.ts
│ ├── app.component.html
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── home.component.html
│ └── home.component.ts
├── main.ts
└── polyfills.ts
├── tailwind.config.js
├── tsconfig.json
└── webpack.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | trim_trailing_whitespace = true
7 | charset = utf-8
8 |
9 | [*.json]
10 | indent_style = space
11 | indent_size = 2
12 |
13 | [*.js]
14 | indent_style = space
15 | indent_size = 2
16 |
17 | [*.ts]
18 | indent_style = space
19 | indent_size = 2
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # NativeScript
2 | hooks/
3 | node_modules/
4 | platforms/
5 |
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 |
13 | # General
14 | .DS_Store
15 | .AppleDouble
16 | .LSOverride
17 | .idea
18 | .cloud
19 | .project
20 | tmp/
21 | typings/
22 |
23 | # Visual Studio Code
24 | .vscode/*
25 | !.vscode/settings.json
26 | !.vscode/tasks.json
27 | !.vscode/launch.json
28 | !.vscode/extensions.json
29 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["nativescript.nativescript"]
3 | }
4 |
--------------------------------------------------------------------------------
/App_Resources/Android/app.gradle:
--------------------------------------------------------------------------------
1 | repositories {
2 | mavenCentral()
3 | }
4 |
5 | dependencies {
6 | implementation 'androidx.core:core-ktx:1.8.0'
7 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
8 | implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1'
9 | implementation 'androidx.activity:activity-compose:1.5.1'
10 | implementation 'androidx.compose.ui:ui:$compose_ui_version'
11 | implementation 'androidx.compose.material:material:1.2.1'
12 | }
13 |
14 | android {
15 | compileSdkVersion 33
16 | buildToolsVersion '33.0.0'
17 | // ndkVersion ''
18 |
19 | defaultConfig {
20 | minSdkVersion 33
21 | targetSdkVersion 33
22 |
23 | // Version Information
24 | versionCode 1
25 | versionName '1.0.0'
26 |
27 | generatedDensities = []
28 |
29 | // vectorDrawables {
30 | // useSupportLibrary true
31 | // }
32 | }
33 |
34 | aaptOptions {
35 | additionalParameters '--no-version-vectors'
36 | }
37 |
38 | compileOptions {
39 | sourceCompatibility JavaVersion.VERSION_1_8
40 | targetCompatibility JavaVersion.VERSION_1_8
41 | }
42 | kotlinOptions {
43 | jvmTarget = '1.8'
44 | }
45 | buildFeatures {
46 | compose true
47 | }
48 | composeOptions {
49 | kotlinCompilerExtensionVersion '1.3.2'
50 | }
51 | packagingOptions {
52 | resources {
53 | excludes += '/META-INF/{AL2.0,LGPL2.1}'
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/App_Resources/Android/before-plugins.gradle:
--------------------------------------------------------------------------------
1 | // this configurations is loaded before building plugins, as well as before building
2 | // the app - this is where you can apply global settings and overrides
3 |
4 | project.ext {
5 | // androidXAppCompat = "1.4.1"
6 | // androidXExifInterface = "1.3.3"
7 | // androidXFragment = "1.4.1"
8 | // androidXMaterial = "1.5.0"
9 | // androidXMultidex = "2.0.1"
10 | // androidXTransition = "1.4.1"
11 | // androidXViewPager = "1.0.0"
12 |
13 | // useKotlin = true
14 | // kotlinVersion = "1.6.0"
15 |
16 | compose_ui_version = '1.2.1'
17 | }
18 |
--------------------------------------------------------------------------------
/App_Resources/Android/gradle.properties:
--------------------------------------------------------------------------------
1 | useKotlin=true
2 | kotlinVersion=1.7.20
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/App.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland
2 |
3 | import androidx.compose.foundation.layout.Column
4 | import androidx.compose.foundation.layout.padding
5 | import androidx.compose.foundation.layout.size
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.runtime.getValue
8 | import androidx.compose.runtime.mutableStateOf
9 | import androidx.compose.runtime.remember
10 | import androidx.compose.runtime.setValue
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.graphics.Canvas
13 | import androidx.compose.ui.graphics.Color
14 | import androidx.compose.ui.unit.dp
15 | import com.sinasamaki.dynamicisland.island.DynamicIsland
16 | import com.sinasamaki.dynamicisland.island.IslandState
17 |
18 | @Composable
19 | fun App() {
20 | Column {
21 | var islandState: IslandState by remember { mutableStateOf(IslandState.DefaultState()) }
22 |
23 | DynamicIsland(islandState = islandState)
24 |
25 | RadioButtonRow(
26 | text = "Default",
27 | selected = islandState is IslandState.DefaultState
28 | ) {
29 | islandState = IslandState.DefaultState()
30 | }
31 |
32 | RadioButtonRow(
33 | text = "Call state",
34 | selected = islandState is IslandState.CallState
35 | ) {
36 | islandState = IslandState.CallState()
37 | }
38 |
39 | RadioButtonRow(
40 | text = "Call Timer state",
41 | selected = islandState is IslandState.CallTimerState
42 | ) {
43 | islandState = IslandState.CallTimerState()
44 | }
45 |
46 | RadioButtonRow(
47 | text = "Face unlock state",
48 | selected = islandState is IslandState.FaceUnlockState
49 | ) {
50 | islandState = IslandState.FaceUnlockState()
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/IslandView.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland
2 |
3 | import android.os.Bundle
4 | import android.content.Context
5 | import androidx.compose.material.MaterialTheme
6 | import androidx.compose.material.Text
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.runtime.getValue
9 | import androidx.compose.runtime.mutableStateOf
10 | import androidx.compose.runtime.setValue
11 | import androidx.compose.ui.platform.ComposeView
12 | import androidx.lifecycle.ViewModel
13 | import androidx.lifecycle.viewmodel.compose.viewModel
14 | import androidx.activity.ComponentActivity
15 | import androidx.activity.compose.setContent
16 | import androidx.compose.foundation.layout.fillMaxSize
17 | import androidx.compose.material.Surface
18 | import androidx.compose.ui.Modifier
19 | import com.sinasamaki.dynamicisland.ui.theme.DynamicIslandTheme
20 |
21 | class IslandView {
22 | fun generateComposeView(view: ComposeView): ComposeView {
23 | return view.apply {
24 | setContent {
25 | DynamicIslandTheme {
26 | Surface(
27 | modifier = Modifier.fillMaxSize(),
28 | color = MaterialTheme.colors.background
29 | ) {
30 | App()
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
37 | fun updateData(value: Map) {
38 | }
39 | var onEvent: ((String) -> Unit)? = null
40 |
41 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/RadioButtonRow.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland
2 |
3 | import androidx.compose.foundation.clickable
4 | import androidx.compose.foundation.layout.Row
5 | import androidx.compose.foundation.layout.fillMaxWidth
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.material.MaterialTheme
9 | import androidx.compose.material.RadioButton
10 | import androidx.compose.material.RadioButtonDefaults
11 | import androidx.compose.material.Text
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Alignment
14 | import androidx.compose.ui.Modifier
15 | import androidx.compose.ui.unit.dp
16 |
17 | @Composable
18 | fun RadioButtonRow(
19 | modifier: Modifier = Modifier,
20 | text: String,
21 | selected: Boolean,
22 | onSelected: () -> Unit
23 | ) {
24 |
25 | Row(
26 | modifier = modifier
27 | .height(48.dp)
28 | .fillMaxWidth()
29 | .clickable {
30 | onSelected()
31 | }
32 | .padding(horizontal = 16.dp),
33 | verticalAlignment = Alignment.CenterVertically
34 | ) {
35 |
36 | RadioButton(
37 | selected = selected,
38 | onClick = null,
39 | colors = RadioButtonDefaults.colors(
40 | selectedColor = MaterialTheme.colors.onSurface
41 | )
42 | )
43 |
44 | Text(text)
45 |
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/island/CallWaveform.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.island
2 |
3 | import androidx.compose.animation.core.Animatable
4 | import androidx.compose.animation.core.Spring
5 | import androidx.compose.animation.core.spring
6 | import androidx.compose.foundation.background
7 | import androidx.compose.foundation.layout.Box
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.fillMaxHeight
10 | import androidx.compose.foundation.layout.fillMaxSize
11 | import androidx.compose.foundation.layout.padding
12 | import androidx.compose.foundation.layout.width
13 | import androidx.compose.foundation.shape.RoundedCornerShape
14 | import androidx.compose.runtime.Composable
15 | import androidx.compose.runtime.LaunchedEffect
16 | import androidx.compose.runtime.remember
17 | import androidx.compose.ui.Alignment
18 | import androidx.compose.ui.Modifier
19 | import androidx.compose.ui.graphics.Color
20 | import androidx.compose.ui.unit.dp
21 | import com.sinasamaki.dynamicisland.ui.theme.Green
22 | import com.sinasamaki.dynamicisland.ui.theme.Orange
23 | import com.sinasamaki.dynamicisland.ui.theme.White
24 | import kotlin.random.Random
25 |
26 | @Composable
27 | fun CallWaveform() {
28 | Box(
29 | modifier = Modifier
30 | .padding(12.dp)
31 | .fillMaxSize()
32 | ) {
33 | Waveform(color = Green)
34 | Waveform(color = Orange)
35 | Waveform(color = White, limit = .7f)
36 | }
37 | }
38 |
39 | @Composable
40 | fun Waveform(
41 | color: Color,
42 | limit: Float = 1f,
43 | ) {
44 | Row(
45 | modifier = Modifier.fillMaxSize(),
46 | verticalAlignment = Alignment.CenterVertically,
47 | ) {
48 | for (i in 0..4) {
49 | val height = remember { Animatable(0f) }
50 |
51 | LaunchedEffect(Unit) {
52 | while (true) {
53 | height.animateTo(
54 | Random.nextFloat() * limit,
55 | animationSpec = spring(stiffness = Spring.StiffnessMediumLow)
56 | )
57 | }
58 | }
59 | Box(
60 | modifier = Modifier
61 | .background(
62 | color = color,
63 | shape = RoundedCornerShape(20.dp)
64 | )
65 | .fillMaxHeight(height.value)
66 | .weight(1f)
67 | )
68 | Box(modifier = Modifier.width(2.dp))
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/island/DynamicIsland.kt:
--------------------------------------------------------------------------------
1 | @file:OptIn(ExperimentalAnimationApi::class)
2 |
3 | package com.sinasamaki.dynamicisland.island
4 |
5 | import androidx.compose.animation.AnimatedVisibility
6 | import androidx.compose.animation.ExperimentalAnimationApi
7 | import androidx.compose.animation.animateContentSize
8 | import androidx.compose.animation.core.Animatable
9 | import androidx.compose.animation.core.Spring
10 | import androidx.compose.animation.core.animateDpAsState
11 | import androidx.compose.animation.core.spring
12 | import androidx.compose.animation.scaleIn
13 | import androidx.compose.animation.scaleOut
14 | import androidx.compose.animation.slideInHorizontally
15 | import androidx.compose.animation.slideOutHorizontally
16 | import androidx.compose.foundation.background
17 | import androidx.compose.foundation.layout.Box
18 | import androidx.compose.foundation.layout.Row
19 | import androidx.compose.foundation.layout.fillMaxSize
20 | import androidx.compose.foundation.layout.fillMaxWidth
21 | import androidx.compose.foundation.layout.height
22 | import androidx.compose.foundation.layout.offset
23 | import androidx.compose.foundation.layout.padding
24 | import androidx.compose.foundation.shape.RoundedCornerShape
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.runtime.LaunchedEffect
27 | import androidx.compose.runtime.getValue
28 | import androidx.compose.runtime.remember
29 | import androidx.compose.runtime.rememberCoroutineScope
30 | import androidx.compose.ui.Alignment
31 | import androidx.compose.ui.Modifier
32 | import androidx.compose.ui.graphics.Color
33 | import androidx.compose.ui.platform.LocalConfiguration
34 | import androidx.compose.ui.unit.IntOffset
35 | import androidx.compose.ui.unit.dp
36 | import androidx.compose.ui.zIndex
37 | import com.sinasamaki.dynamicisland.metaball.MetaContainer
38 | import com.sinasamaki.dynamicisland.metaball.MetaEntity
39 | import kotlinx.coroutines.launch
40 | import kotlin.math.roundToInt
41 |
42 | @Composable
43 | fun DynamicIsland(islandState: IslandState) {
44 | val config = LocalConfiguration.current
45 |
46 | val startPadding by animateDpAsState(
47 | targetValue = (config.screenWidthDp.dp / 2) - islandState.fullWidth / 2,
48 | animationSpec = spring(
49 | stiffness = Spring.StiffnessLow,
50 | dampingRatio = Spring.DampingRatioLowBouncy,
51 | )
52 | )
53 |
54 | val scope = rememberCoroutineScope()
55 |
56 | val shake = remember { Animatable(0f) }
57 | LaunchedEffect(islandState.hasBubbleContent) {
58 | scope.launch {
59 | shake.animateTo(15f)
60 | shake.animateTo(
61 | targetValue = 0f,
62 | animationSpec = spring(
63 | dampingRatio = Spring.DampingRatioMediumBouncy,
64 | stiffness = Spring.StiffnessLow,
65 | )
66 | )
67 | }
68 | }
69 |
70 | MetaContainer(
71 | modifier = Modifier.height(200.dp)
72 | ) {
73 | Row(
74 | modifier = Modifier
75 | .padding(top = 20.dp)
76 | .padding(start = startPadding)
77 | .fillMaxWidth(),
78 | verticalAlignment = Alignment.Top,
79 | ) {
80 |
81 |
82 | MetaEntity(
83 | modifier = Modifier
84 | .offset { IntOffset(shake.value.roundToInt(), 0) }
85 | .zIndex(10f),
86 | metaContent = {
87 | Box(
88 | modifier = Modifier
89 | .fillMaxSize()
90 | .background(
91 | color = Color.Black,
92 | shape = RoundedCornerShape(35.dp)
93 | )
94 | )
95 | }
96 | ) {
97 | IslandContent(state = islandState)
98 | }
99 |
100 | AnimatedVisibility(
101 | visible = islandState.hasBubbleContent,
102 | modifier = Modifier.padding(start = 8.dp),
103 | enter = bubbleEnterTransition,
104 | exit = bubbleExitTransition,
105 | ) {
106 | MetaEntity(
107 | metaContent = {
108 | Box(
109 | modifier = Modifier
110 | .fillMaxSize()
111 | .background(
112 | Color.Black,
113 | shape = RoundedCornerShape(50.dp)
114 | )
115 | )
116 | }
117 | ) {
118 | IslandBubbleContent(state = islandState)
119 | }
120 | }
121 | }
122 | }
123 | }
124 |
125 | private val bubbleEnterTransition = scaleIn(initialScale = .7f) + slideInHorizontally(
126 | animationSpec = spring(
127 | stiffness = Spring.StiffnessLow,
128 | dampingRatio = Spring.DampingRatioLowBouncy,
129 | )
130 | ) { -it }
131 |
132 | private val bubbleExitTransition = scaleOut(targetScale = .7f) + slideOutHorizontally(
133 | animationSpec = spring(
134 | stiffness = Spring.StiffnessLow
135 | )
136 | ) { (-it * 1.2f).roundToInt() }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/island/FaceUnlock.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.island
2 |
3 | import androidx.compose.foundation.layout.fillMaxSize
4 | import androidx.compose.foundation.layout.padding
5 | import androidx.compose.material.Icon
6 | import androidx.compose.material.icons.Icons
7 | import androidx.compose.material.icons.twotone.Face
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.unit.dp
11 | import com.sinasamaki.dynamicisland.ui.theme.Blue
12 |
13 | @Composable
14 | fun FaceUnlock() {
15 | Icon(
16 | imageVector = Icons.TwoTone.Face,
17 | contentDescription = null,
18 | modifier = Modifier
19 | .padding(16.dp)
20 | .fillMaxSize(),
21 | tint = Blue
22 | )
23 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/island/IslandBubbleContent.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.island
2 |
3 | import androidx.compose.animation.core.Animatable
4 | import androidx.compose.animation.core.Spring
5 | import androidx.compose.animation.core.spring
6 | import androidx.compose.foundation.layout.Box
7 | import androidx.compose.foundation.layout.height
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.material.Icon
10 | import androidx.compose.runtime.Composable
11 | import androidx.compose.runtime.LaunchedEffect
12 | import androidx.compose.runtime.getValue
13 | import androidx.compose.runtime.mutableStateOf
14 | import androidx.compose.runtime.remember
15 | import androidx.compose.runtime.setValue
16 | import androidx.compose.ui.Alignment
17 | import androidx.compose.ui.Modifier
18 | import androidx.compose.ui.res.painterResource
19 | import org.nativescript.nativescriptandroidcompose.R
20 | import com.sinasamaki.dynamicisland.ui.theme.Orange
21 |
22 | @Composable
23 | fun IslandBubbleContent(state: IslandState) {
24 | val width = state.bubbleContentSize.width
25 | val height = state.bubbleContentSize.height
26 |
27 | val scale = remember { Animatable(1.5f) }
28 | LaunchedEffect(Unit) {
29 | scale.animateTo(
30 | targetValue = 1f,
31 | animationSpec = spring(
32 | stiffness = Spring.StiffnessLow,
33 | dampingRatio = 0.35f,
34 | )
35 | )
36 | }
37 |
38 | Box(
39 | modifier = Modifier
40 | .width(width * scale.value)
41 | .height(height),
42 | contentAlignment = Alignment.Center,
43 | ) {
44 |
45 | var bubbleContent: @Composable () -> Unit by remember {
46 | mutableStateOf({})
47 | }
48 | LaunchedEffect(state, block = {
49 | when (state) {
50 | is IslandState.CallTimerState -> {
51 | bubbleContent = {
52 | Icon(
53 | painter = painterResource(id = R.drawable.timer),
54 | contentDescription = null,
55 | tint = Orange
56 | )
57 | }
58 | }
59 |
60 | else -> {}
61 | }
62 | })
63 | bubbleContent()
64 | }
65 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/island/IslandContent.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.island
2 |
3 | import androidx.compose.animation.AnimatedVisibility
4 | import androidx.compose.animation.core.Spring
5 | import androidx.compose.animation.core.animateDpAsState
6 | import androidx.compose.animation.core.spring
7 | import androidx.compose.animation.core.tween
8 | import androidx.compose.animation.fadeIn
9 | import androidx.compose.foundation.layout.Box
10 | import androidx.compose.foundation.layout.Row
11 | import androidx.compose.foundation.layout.fillMaxHeight
12 | import androidx.compose.foundation.layout.fillMaxSize
13 | import androidx.compose.foundation.layout.height
14 | import androidx.compose.foundation.layout.size
15 | import androidx.compose.foundation.layout.width
16 | import androidx.compose.material.Icon
17 | import androidx.compose.material.Text
18 | import androidx.compose.material.icons.Icons
19 | import androidx.compose.material.icons.rounded.Call
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.runtime.getValue
22 | import androidx.compose.ui.Alignment
23 | import androidx.compose.ui.Modifier
24 | import androidx.compose.ui.draw.clipToBounds
25 | import com.sinasamaki.dynamicisland.ui.theme.Green
26 |
27 | @Composable
28 | fun IslandContent(state: IslandState) {
29 | val width by animateDpAsState(
30 | targetValue = state.fullWidth,
31 | animationSpec = spring(
32 | stiffness = Spring.StiffnessLow,
33 | dampingRatio = .6f,
34 | )
35 | )
36 | val height by animateDpAsState(
37 | targetValue = state.contentSize.height,
38 | animationSpec = spring(
39 | stiffness = Spring.StiffnessLow,
40 | dampingRatio = .6f,
41 | )
42 | )
43 |
44 | Box(
45 | modifier = Modifier
46 | .width(width)
47 | .height(height)
48 | ) {
49 |
50 | AnimatedVisibility(
51 | visible = state.hasMainContent,
52 | enter = fadeIn(
53 | animationSpec = tween(300, 300)
54 | )
55 | ) {
56 | Box(
57 | modifier = Modifier.size(state.contentSize)
58 | ) {
59 | when (state) {
60 | is IslandState.FaceUnlockState -> {
61 | FaceUnlock()
62 | }
63 |
64 | else -> {}
65 | }
66 | }
67 | }
68 |
69 | Row(
70 | modifier = Modifier
71 | .fillMaxSize(),
72 | verticalAlignment = Alignment.CenterVertically,
73 | ) {
74 | LeadingContent(state)
75 | Box(Modifier.weight(1f))
76 | TrailingContent(state)
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/island/IslandState.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.island
2 |
3 | import androidx.compose.ui.unit.Dp
4 | import androidx.compose.ui.unit.DpSize
5 | import androidx.compose.ui.unit.dp
6 |
7 | sealed class IslandState(
8 | val contentSize: DpSize = DpSize(150.dp, 50.dp),
9 | val hasMainContent: Boolean = false,
10 |
11 | val leadingContentSize: Dp = Dp.Hairline,
12 | val hasLeadingContent: Boolean = false,
13 |
14 | val trailingContentSize: Dp = Dp.Hairline,
15 | val hasTrailingContent: Boolean = false,
16 |
17 | val bubbleContentSize: DpSize = DpSize(50.dp, 50.dp),
18 | val hasBubbleContent: Boolean = false
19 | ) {
20 |
21 | val fullWidth = contentSize.width + leadingContentSize + trailingContentSize
22 |
23 | class DefaultState : IslandState()
24 |
25 | class CallTimerState : IslandState(
26 | leadingContentSize = 50.dp,
27 | hasLeadingContent = true,
28 | hasBubbleContent = true
29 | )
30 |
31 | class CallState : IslandState(
32 | leadingContentSize = 65.dp,
33 | trailingContentSize = 55.dp,
34 | hasLeadingContent = true,
35 | hasTrailingContent = true,
36 | )
37 |
38 | class FaceUnlockState : IslandState(
39 | contentSize = DpSize(
40 | 150.dp, 150.dp
41 | ),
42 | hasMainContent = true,
43 | )
44 |
45 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/island/LeadingContent.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.island
2 |
3 | import androidx.compose.animation.AnimatedVisibility
4 | import androidx.compose.animation.core.tween
5 | import androidx.compose.animation.fadeIn
6 | import androidx.compose.foundation.layout.Box
7 | import androidx.compose.foundation.layout.fillMaxHeight
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.material.Icon
10 | import androidx.compose.material.Text
11 | import androidx.compose.material.icons.Icons
12 | import androidx.compose.material.icons.rounded.Call
13 | import androidx.compose.runtime.Composable
14 | import androidx.compose.ui.Alignment
15 | import androidx.compose.ui.Modifier
16 | import com.sinasamaki.dynamicisland.ui.theme.Green
17 |
18 | @Composable
19 | fun LeadingContent(state: IslandState) {
20 | AnimatedVisibility(
21 | modifier = Modifier.fillMaxHeight(),
22 | visible = state.hasLeadingContent,
23 | enter = fadeIn(animationSpec = tween(300, 300))
24 | ) {
25 | Box(
26 | Modifier
27 | .width(state.leadingContentSize),
28 | contentAlignment = Alignment.Center,
29 | ) {
30 | when (state) {
31 | is IslandState.CallState -> {
32 | Text(text = "9:41", color = Green)
33 | }
34 |
35 | is IslandState.CallTimerState -> {
36 | Icon(
37 | imageVector = Icons.Rounded.Call,
38 | contentDescription = null,
39 | tint = Green,
40 | )
41 | }
42 |
43 | else -> {}
44 | }
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/island/TrailingContent.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.island
2 |
3 | import androidx.compose.animation.AnimatedVisibility
4 | import androidx.compose.animation.core.tween
5 | import androidx.compose.animation.fadeIn
6 | import androidx.compose.foundation.layout.Box
7 | import androidx.compose.foundation.layout.fillMaxHeight
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Alignment
11 | import androidx.compose.ui.Modifier
12 |
13 | @Composable
14 | fun TrailingContent(state: IslandState) {
15 | AnimatedVisibility(
16 | modifier = Modifier.fillMaxHeight(),
17 | visible = state.hasTrailingContent,
18 | enter = fadeIn(animationSpec = tween(300,300))
19 | ) {
20 | Box(
21 | Modifier
22 | .width(state.trailingContentSize),
23 | contentAlignment = Alignment.Center,
24 | ) {
25 | when (state) {
26 | is IslandState.CallState -> {
27 | CallWaveform()
28 | }
29 |
30 | else -> {}
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/metaball/MetaContainter.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.metaball
2 |
3 | import android.graphics.RenderEffect
4 | import android.graphics.RuntimeShader
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.BoxScope
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.runtime.remember
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.graphics.asComposeRenderEffect
11 | import androidx.compose.ui.graphics.graphicsLayer
12 | import androidx.compose.ui.layout.onSizeChanged
13 | import org.intellij.lang.annotations.Language
14 |
15 | @Language("AGSL")
16 | const val ShaderSource = """
17 | uniform shader composable;
18 |
19 | uniform float cutoff;
20 |
21 | half4 main(float2 fragCoord) {
22 | half4 color = composable.eval(fragCoord);
23 | float alpha = color.a;
24 | if (alpha > cutoff) {
25 | alpha = 1.0;
26 | } else {
27 | alpha = 0.0;
28 | }
29 |
30 | color = half4(color.r, color.g, color.b, alpha);
31 | return color;
32 | }
33 | """
34 |
35 | @Composable
36 | fun MetaContainer(
37 | modifier: Modifier = Modifier,
38 | cutoff: Float = .5f,
39 | content: @Composable BoxScope.() -> Unit,
40 | ) {
41 | val metaShader = remember { RuntimeShader(ShaderSource) }
42 | Box(
43 | modifier
44 | .graphicsLayer {
45 | metaShader.setFloatUniform("cutoff", cutoff)
46 | renderEffect = RenderEffect.createRuntimeShaderEffect(
47 | metaShader, "composable"
48 | ).asComposeRenderEffect()
49 | },
50 | content = content,
51 | )
52 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/metaball/MetaEntity.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.metaball
2 |
3 | import androidx.compose.foundation.layout.Box
4 | import androidx.compose.foundation.layout.BoxScope
5 | import androidx.compose.foundation.layout.IntrinsicSize
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.width
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Alignment
10 | import androidx.compose.ui.Modifier
11 |
12 | @Composable
13 | fun MetaEntity(
14 | modifier: Modifier = Modifier,
15 | blur: Float = 30f,
16 | metaContent: @Composable BoxScope.() -> Unit,
17 | content: @Composable BoxScope.() -> Unit,
18 | ) {
19 | Box(
20 | modifier
21 | .width(IntrinsicSize.Min)
22 | .height(IntrinsicSize.Min),
23 | contentAlignment = Alignment.Center
24 | ) {
25 | Box(
26 | modifier = Modifier
27 | .customBlur(blur),
28 | content = metaContent,
29 | )
30 | content()
31 | }
32 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/metaball/Modifiers.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.metaball
2 |
3 | import android.graphics.RenderEffect
4 | import android.graphics.Shader
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.graphics.asComposeRenderEffect
7 | import androidx.compose.ui.graphics.graphicsLayer
8 |
9 | fun Modifier.customBlur(blur: Float) = this.then(
10 | graphicsLayer {
11 | renderEffect = RenderEffect
12 | .createBlurEffect(
13 | blur,
14 | blur,
15 | Shader.TileMode.DECAL,
16 | )
17 | .asComposeRenderEffect()
18 | }
19 | )
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.ui.theme
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val Purple200 = Color(0xFFBB86FC)
6 | val Purple500 = Color(0xFF6200EE)
7 | val Purple700 = Color(0xFF3700B3)
8 | val Teal200 = Color(0xFF03DAC5)
9 | val Green = Color(0xFF6EE228)
10 | val Orange = Color(0xFFFFAD57)
11 | val White = Color(0xffFFFFFF)
12 | val Blue = Color(0xFF2CADF1)
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/ui/theme/Shape.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.ui.theme
2 |
3 | import androidx.compose.foundation.shape.RoundedCornerShape
4 | import androidx.compose.material.Shapes
5 | import androidx.compose.ui.unit.dp
6 |
7 | val Shapes = Shapes(
8 | small = RoundedCornerShape(4.dp),
9 | medium = RoundedCornerShape(4.dp),
10 | large = RoundedCornerShape(0.dp)
11 | )
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.ui.theme
2 |
3 | import androidx.compose.foundation.isSystemInDarkTheme
4 | import androidx.compose.material.MaterialTheme
5 | import androidx.compose.material.darkColors
6 | import androidx.compose.material.lightColors
7 | import androidx.compose.runtime.Composable
8 |
9 | private val DarkColorPalette = darkColors(
10 | primary = Purple200,
11 | primaryVariant = Purple700,
12 | secondary = Teal200
13 | )
14 |
15 | private val LightColorPalette = lightColors(
16 | primary = Purple500,
17 | primaryVariant = Purple700,
18 | secondary = Teal200
19 |
20 | /* Other default colors to override
21 | background = Color.White,
22 | surface = Color.White,
23 | onPrimary = Color.White,
24 | onSecondary = Color.Black,
25 | onBackground = Color.Black,
26 | onSurface = Color.Black,
27 | */
28 | )
29 |
30 | @Composable
31 | fun DynamicIslandTheme(
32 | darkTheme: Boolean = isSystemInDarkTheme(),
33 | content: @Composable () -> Unit
34 | ) {
35 | val colors = if (darkTheme) {
36 | DarkColorPalette
37 | } else {
38 | LightColorPalette
39 | }
40 |
41 | MaterialTheme(
42 | colors = colors,
43 | typography = Typography,
44 | shapes = Shapes,
45 | content = content
46 | )
47 | }
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/java/com/sinasamaki/dynamicisland/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | package com.sinasamaki.dynamicisland.ui.theme
2 |
3 | import androidx.compose.material.Typography
4 | import androidx.compose.ui.text.TextStyle
5 | import androidx.compose.ui.text.font.FontFamily
6 | import androidx.compose.ui.text.font.FontWeight
7 | import androidx.compose.ui.unit.sp
8 |
9 | // Set of Material typography styles to start with
10 | val Typography = Typography(
11 | body1 = TextStyle(
12 | fontFamily = FontFamily.Default,
13 | fontWeight = FontWeight.Normal,
14 | fontSize = 16.sp
15 | )
16 | /* Other default text styles to override
17 | button = TextStyle(
18 | fontFamily = FontFamily.Default,
19 | fontWeight = FontWeight.W500,
20 | fontSize = 14.sp
21 | ),
22 | caption = TextStyle(
23 | fontFamily = FontFamily.Default,
24 | fontWeight = FontWeight.Normal,
25 | fontSize = 12.sp
26 | )
27 | */
28 | )
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-hdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-hdpi/background.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-hdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-hdpi/logo.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-ldpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-ldpi/background.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-ldpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-ldpi/logo.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-mdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-mdpi/background.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-mdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-mdpi/logo.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-nodpi/splash_screen.xml:
--------------------------------------------------------------------------------
1 |
2 | -
3 |
4 |
5 | -
6 |
7 |
8 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-xhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-xhdpi/background.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-xhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-xhdpi/logo.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-xxhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-xxhdpi/background.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-xxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-xxhdpi/logo.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-xxxhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-xxxhdpi/background.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable-xxxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/drawable-xxxhdpi/logo.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/drawable/timer.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/values-v21/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
15 |
16 |
17 |
21 |
22 |
23 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/values-v29/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
14 |
15 |
17 |
18 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #F5F5F5
5 |
6 |
7 | #757575
8 |
9 |
10 | #65ADF1
11 |
12 | #FFBB86FC
13 | #FF6200EE
14 | #FF3700B3
15 | #FF03DAC5
16 | #FF018786
17 | #FF000000
18 | #FFFFFFFF
19 |
20 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | NativeScript ❤️ Jetpack Compose
3 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
20 |
21 |
22 |
29 |
30 |
32 |
33 |
34 |
39 |
40 |
42 |
43 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/App_Resources/Android/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "icon-20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "icon-20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "icon-29.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "icon-29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "icon-29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "icon-40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "icon-40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "icon-60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "icon-60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "icon-20.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "icon-20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "icon-29.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "icon-29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "icon-40.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "icon-40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "icon-76.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "icon-76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "icon-83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "icon-1024.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchScreen-AspectFill.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchScreen-AspectFill@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchScreen-AspectFill@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@3x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchScreen-Center.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchScreen-Center@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchScreen-Center@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NativeScript/android-compose-example/995567191d67a910499d09bd152cd84a8bb56b6d/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@3x.png
--------------------------------------------------------------------------------
/App_Resources/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiresFullScreen
28 |
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/App_Resources/iOS/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/App_Resources/iOS/build.xcconfig:
--------------------------------------------------------------------------------
1 | // You can add custom settings here
2 | // for example you can uncomment the following line to force distribution code signing
3 | // CODE_SIGN_IDENTITY = iPhone Distribution
4 | // To build for device with XCode you need to specify your development team.
5 | // DEVELOPMENT_TEAM = YOUR_TEAM_ID;
6 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **@nativescript/jetpack-compose** Example 🚀📓♥️
2 |
3 |
4 |
5 | Android app using [Angular](https://angular.io/) to drive [Jetpack Compose](https://developer.android.com/jetpack/compose)
6 |
7 | - [Drive yourself](#drive-yourself)
8 | - [Credits](#credits)
9 |
10 | ## Drive yourself
11 |
12 | Prerequisites:
13 | - [NativeScript Environment Setup](https://docs.nativescript.org/environment-setup.html)
14 | - Android API Level 33 emulator or device
15 |
16 | *Note*: Uses APIs only available on API Level 33+
17 |
18 | ```
19 | ns debug android
20 | ```
21 |
22 | ## Credits
23 |
24 | Inspired by [@sinasamaki](https://twitter.com/sinasamaki)
25 |
26 | Usage from example shared [here](https://github.com/sinasamaki/DynamicIsland).
--------------------------------------------------------------------------------
/nativescript.config.ts:
--------------------------------------------------------------------------------
1 | import { NativeScriptConfig } from '@nativescript/core';
2 |
3 | export default {
4 | id: 'org.nativescript.nativescriptandroidcompose',
5 | appPath: 'src',
6 | appResourcesPath: 'App_Resources',
7 | android: {
8 | v8Flags: '--expose_gc',
9 | markingMode: 'none'
10 | }
11 | } as NativeScriptConfig;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nativescript-android-compose",
3 | "main": "./src/main.ts",
4 | "version": "1.0.0",
5 | "private": true,
6 | "dependencies": {
7 | "@angular/animations": "~15.1.0",
8 | "@angular/common": "~15.1.0",
9 | "@angular/compiler": "~15.1.0",
10 | "@angular/core": "~15.1.0",
11 | "@angular/forms": "~15.1.0",
12 | "@angular/platform-browser": "~15.1.0",
13 | "@angular/platform-browser-dynamic": "~15.1.0",
14 | "@angular/router": "~15.1.0",
15 | "@nativescript/angular": "^15.0.0",
16 | "@nativescript/core": "~8.4.0",
17 | "@nativescript/jetpack-compose": "^1.0.0-beta.0",
18 | "rxjs": "~7.6.0",
19 | "zone.js": "~0.12.0"
20 | },
21 | "devDependencies": {
22 | "@angular-devkit/build-angular": "~15.1.0",
23 | "@angular/compiler-cli": "~15.1.0",
24 | "@nativescript/android": "8.4.0",
25 | "@nativescript/tailwind": "^2.0.1",
26 | "@nativescript/types": "~8.4.0",
27 | "@nativescript/webpack": "~5.0.12",
28 | "@ngtools/webpack": "~15.1.0",
29 | "tailwindcss": "^3.2.0",
30 | "typescript": "~4.8.4"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/references.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/app.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 | import { Routes } from '@angular/router'
3 | import { NativeScriptRouterModule } from '@nativescript/angular'
4 |
5 | import { HomeComponent } from './home.component'
6 |
7 | const routes: Routes = [
8 | { path: '', redirectTo: '/home', pathMatch: 'full' },
9 | { path: 'home', component: HomeComponent },
10 | ]
11 |
12 | @NgModule({
13 | imports: [NativeScriptRouterModule.forRoot(routes)],
14 | exports: [NativeScriptRouterModule],
15 | })
16 | export class AppRoutingModule {}
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'ns-app',
5 | templateUrl: './app.component.html',
6 | })
7 | export class AppComponent {}
8 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'
2 | import { NativeScriptModule } from '@nativescript/angular'
3 |
4 | import { AppRoutingModule } from './app-routing.module'
5 | import { AppComponent } from './app.component'
6 | import { HomeComponent } from './home.component'
7 |
8 | @NgModule({
9 | bootstrap: [AppComponent],
10 | imports: [NativeScriptModule, AppRoutingModule],
11 | declarations: [AppComponent, HomeComponent],
12 | providers: [],
13 | schemas: [NO_ERRORS_SCHEMA],
14 | })
15 | export class AppModule {}
16 |
--------------------------------------------------------------------------------
/src/app/home.component.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
16 |
17 |
18 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/app/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from "@angular/core";
2 |
3 |
4 | @Component({
5 | selector: "ns-home",
6 | templateUrl: "./home.component.html",
7 | })
8 | export class HomeComponent {
9 |
10 | }
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { platformNativeScript, registerElement, runNativeScriptAngularApp } from '@nativescript/angular';
2 |
3 | import { AppModule } from './app/app.module';
4 | import { registerJetpackCompose, ComposeDataDriver, JetpackCompose } from '@nativescript/jetpack-compose';
5 |
6 | registerElement('JetpackCompose', () => JetpackCompose);
7 | // A. You can generate types for your own Compose Provider with 'ns typings android --aar {path/to/{name}.aar}'
8 | // B. Otherwise you can ignore by declaring the package resolution path you know you provided
9 | declare var com;
10 | registerJetpackCompose('dynamicIsland', (view) => new ComposeDataDriver(new com.sinasamaki.dynamicisland.IslandView(), view));
11 |
12 | runNativeScriptAngularApp({
13 | appModuleBootstrap: () => platformNativeScript().bootstrapModule(AppModule),
14 | });
15 |
16 |
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * NativeScript Polyfills
3 | */
4 |
5 | // Install @nativescript/core polyfills (XHR, setTimeout, requestAnimationFrame)
6 | import '@nativescript/core/globals';
7 | // Install @nativescript/angular specific polyfills
8 | import '@nativescript/angular/polyfills';
9 |
10 | /**
11 | * Zone.js and patches
12 | */
13 | // Add pre-zone.js patches needed for the NativeScript platform
14 | import '@nativescript/zone-js/dist/pre-zone-polyfills';
15 |
16 | // Zone JS is required by default for Angular itself
17 | import 'zone.js';
18 |
19 | // Add NativeScript specific Zone JS patches
20 | import '@nativescript/zone-js';
21 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | './src/**/*.{css,xml,html,vue,svelte,ts,tsx}'
5 | ],
6 | // use the .ns-dark class to control dark mode (applied by NativeScript) - since 'media' (default) is not supported.
7 | darkMode: ['class', '.ns-dark'],
8 | theme: {
9 | extend: {},
10 | },
11 | plugins: [],
12 | corePlugins: {
13 | preflight: false // disables browser-specific resets
14 | }
15 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "esnext",
4 | "target": "es2017",
5 | "moduleResolution": "node",
6 | "experimentalDecorators": true,
7 | "emitDecoratorMetadata": true,
8 | "noEmitHelpers": true,
9 | "noEmitOnError": true,
10 | "skipLibCheck": true,
11 | "lib": ["es2017", "dom"],
12 | "baseUrl": ".",
13 | "paths": {
14 | "~/*": ["src/*"],
15 | "@/*": ["src/*"]
16 | }
17 | },
18 | "include": ["src/tests/**/*.ts", "src/**/*.ios.ts", "src/**/*.android.ts"],
19 | "files": ["./src/main.ts", "./references.d.ts", "./src/polyfills.ts"],
20 | "exclude": ["node_modules", "platforms", "e2e"]
21 | }
22 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require("@nativescript/webpack");
2 |
3 | module.exports = (env) => {
4 | webpack.init(env);
5 |
6 | // Learn how to customize:
7 | // https://docs.nativescript.org/webpack
8 |
9 | return webpack.resolveConfig();
10 | };
11 |
--------------------------------------------------------------------------------