Skip to content

Commit 7319029

Browse files
committed
feat(sampleapp): add sample app skeleton
Signed-off-by: Nicklas Lundin <[email protected]>
1 parent 600b488 commit 7319029

28 files changed

+574
-1
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
plugins {
33
id("com.android.library").version("7.4.2").apply(false)
4+
id("com.android.application").version("7.4.2").apply(false)
45
id("org.jetbrains.kotlin.android").version("1.8.10").apply(false)
56
id("org.jlleitschuh.gradle.ktlint").version("11.6.1").apply(true)
67
id("io.github.gradle-nexus.publish-plugin").version("2.0.0").apply(true)

sampleapp/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

sampleapp/build.gradle.kts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
plugins {
2+
id("com.android.application")
3+
id("org.jetbrains.kotlin.android")
4+
}
5+
6+
android {
7+
namespace = "dev.openfeature.sdk.sampleapp"
8+
compileSdk = 33
9+
10+
defaultConfig {
11+
applicationId = "dev.openfeature.sdk.sampleapp"
12+
minSdk = 28
13+
targetSdk = 33
14+
versionCode = 1
15+
versionName = "1.0"
16+
17+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
18+
vectorDrawables {
19+
useSupportLibrary = true
20+
}
21+
}
22+
23+
buildTypes {
24+
release {
25+
isMinifyEnabled = false
26+
proguardFiles(
27+
getDefaultProguardFile("proguard-android-optimize.txt"),
28+
"proguard-rules.pro"
29+
)
30+
}
31+
}
32+
compileOptions {
33+
sourceCompatibility = JavaVersion.VERSION_11
34+
targetCompatibility = JavaVersion.VERSION_11
35+
}
36+
kotlinOptions {
37+
jvmTarget = "11"
38+
}
39+
buildFeatures {
40+
compose = true
41+
}
42+
composeOptions {
43+
kotlinCompilerExtensionVersion = "1.4.4"
44+
}
45+
packagingOptions {
46+
resources {
47+
excludes += "/META-INF/{AL2.0,LGPL2.1}"
48+
}
49+
}
50+
}
51+
52+
dependencies {
53+
implementation(project(":android"))
54+
implementation("androidx.core:core-ktx:1.7.0")
55+
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
56+
implementation("androidx.activity:activity-compose:1.3.0")
57+
implementation(platform("androidx.compose:compose-bom:2022.10.00"))
58+
implementation("androidx.compose.ui:ui")
59+
implementation("androidx.compose.ui:ui-graphics")
60+
implementation("androidx.compose.ui:ui-tooling-preview")
61+
implementation("androidx.compose.material3:material3")
62+
debugImplementation("androidx.compose.ui:ui-tooling")
63+
debugImplementation("androidx.compose.ui:ui-test-manifest")
64+
}

sampleapp/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<application
5+
android:allowBackup="true"
6+
android:icon="@mipmap/ic_launcher"
7+
android:label="@string/app_name"
8+
android:roundIcon="@mipmap/ic_launcher_round"
9+
android:supportsRtl="true"
10+
android:theme="@style/Theme.OpenFeature">
11+
<activity
12+
android:name=".MainActivity"
13+
android:exported="true"
14+
android:label="@string/app_name"
15+
android:theme="@style/Theme.OpenFeature">
16+
<intent-filter>
17+
<action android:name="android.intent.action.MAIN" />
18+
19+
<category android:name="android.intent.category.LAUNCHER" />
20+
</intent-filter>
21+
</activity>
22+
</application>
23+
24+
</manifest>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
@file:OptIn(ExperimentalMaterial3Api::class)
2+
3+
package dev.openfeature.sdk.sampleapp
4+
5+
import android.os.Bundle
6+
import androidx.activity.ComponentActivity
7+
import androidx.activity.compose.setContent
8+
import androidx.compose.foundation.layout.Column
9+
import androidx.compose.foundation.layout.Row
10+
import androidx.compose.foundation.layout.fillMaxSize
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.material3.ExperimentalMaterial3Api
13+
import androidx.compose.material3.Scaffold
14+
import androidx.compose.material3.Text
15+
import androidx.compose.runtime.Composable
16+
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.tooling.preview.Preview
18+
import androidx.lifecycle.lifecycleScope
19+
import dev.openfeature.sdk.OpenFeatureAPI
20+
import dev.openfeature.sdk.sampleapp.ui.theme.OpenFeatureTheme
21+
import kotlinx.coroutines.launch
22+
23+
class MainActivity : ComponentActivity() {
24+
override fun onCreate(savedInstanceState: Bundle?) {
25+
super.onCreate(savedInstanceState)
26+
lifecycleScope.launch {
27+
OpenFeatureAPI.setProviderAndWait(RemoteControlExampleProvider())
28+
}
29+
setContent {
30+
OpenFeatureTheme {
31+
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
32+
MainPage(
33+
modifier = Modifier.padding(innerPadding)
34+
)
35+
}
36+
}
37+
}
38+
}
39+
}
40+
@Composable
41+
fun MainPage(modifier: Modifier = Modifier) {
42+
Column(modifier = modifier) {
43+
Greeting()
44+
Row {
45+
Text(text = "Current status")
46+
}
47+
48+
}
49+
50+
}
51+
52+
53+
@Composable
54+
fun Greeting(modifier: Modifier = Modifier) {
55+
Text(
56+
text = "Welcome to OpenFeature!",
57+
modifier = modifier
58+
)
59+
}
60+
61+
@Preview(showBackground = true)
62+
@Composable
63+
fun MainPagePreview() {
64+
OpenFeatureTheme {
65+
MainPage()
66+
}
67+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package dev.openfeature.sdk.sampleapp
2+
3+
import dev.openfeature.sdk.*
4+
5+
class RemoteControlExampleProvider(override val hooks: List<Hook<*>>): FeatureProvider {
6+
7+
override val metadata: ProviderMetadata
8+
get() = TODO("Not yet implemented")
9+
10+
override suspend fun initialize(initialContext: EvaluationContext?) {
11+
TODO("Not yet implemented")
12+
}
13+
14+
override fun shutdown() {
15+
TODO("Not yet implemented")
16+
}
17+
18+
override suspend fun onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext) {
19+
TODO("Not yet implemented")
20+
}
21+
22+
override fun getBooleanEvaluation(
23+
key: String,
24+
defaultValue: Boolean,
25+
context: EvaluationContext?
26+
): ProviderEvaluation<Boolean> {
27+
TODO("Not yet implemented")
28+
}
29+
30+
override fun getStringEvaluation(
31+
key: String,
32+
defaultValue: String,
33+
context: EvaluationContext?
34+
): ProviderEvaluation<String> {
35+
TODO("Not yet implemented")
36+
}
37+
38+
override fun getIntegerEvaluation(
39+
key: String,
40+
defaultValue: Int,
41+
context: EvaluationContext?
42+
): ProviderEvaluation<Int> {
43+
TODO("Not yet implemented")
44+
}
45+
46+
override fun getDoubleEvaluation(
47+
key: String,
48+
defaultValue: Double,
49+
context: EvaluationContext?
50+
): ProviderEvaluation<Double> {
51+
TODO("Not yet implemented")
52+
}
53+
54+
override fun getObjectEvaluation(
55+
key: String,
56+
defaultValue: Value,
57+
context: EvaluationContext?
58+
): ProviderEvaluation<Value> {
59+
TODO("Not yet implemented")
60+
}
61+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package dev.openfeature.sdk.sampleapp.ui.theme
2+
3+
import androidx.compose.ui.graphics.Color
4+
5+
val Purple80 = Color(0xFFD0BCFF)
6+
val PurpleGrey80 = Color(0xFFCCC2DC)
7+
val Pink80 = Color(0xFFEFB8C8)
8+
9+
val Purple40 = Color(0xFF6650a4)
10+
val PurpleGrey40 = Color(0xFF625b71)
11+
val Pink40 = Color(0xFF7D5260)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package dev.openfeature.sdk.sampleapp.ui.theme
2+
3+
import android.app.Activity
4+
import android.os.Build
5+
import androidx.compose.foundation.isSystemInDarkTheme
6+
import androidx.compose.material3.MaterialTheme
7+
import androidx.compose.material3.darkColorScheme
8+
import androidx.compose.material3.dynamicDarkColorScheme
9+
import androidx.compose.material3.dynamicLightColorScheme
10+
import androidx.compose.material3.lightColorScheme
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.ui.platform.LocalContext
13+
14+
private val DarkColorScheme = darkColorScheme(
15+
primary = Purple80,
16+
secondary = PurpleGrey80,
17+
tertiary = Pink80
18+
)
19+
20+
private val LightColorScheme = lightColorScheme(
21+
primary = Purple40,
22+
secondary = PurpleGrey40,
23+
tertiary = Pink40
24+
25+
/* Other default colors to override
26+
background = Color(0xFFFFFBFE),
27+
surface = Color(0xFFFFFBFE),
28+
onPrimary = Color.White,
29+
onSecondary = Color.White,
30+
onTertiary = Color.White,
31+
onBackground = Color(0xFF1C1B1F),
32+
onSurface = Color(0xFF1C1B1F),
33+
*/
34+
)
35+
36+
@Composable
37+
fun OpenFeatureTheme(
38+
darkTheme: Boolean = isSystemInDarkTheme(),
39+
// Dynamic color is available on Android 12+
40+
dynamicColor: Boolean = true,
41+
content: @Composable () -> Unit
42+
) {
43+
val colorScheme = when {
44+
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
45+
val context = LocalContext.current
46+
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
47+
}
48+
49+
darkTheme -> DarkColorScheme
50+
else -> LightColorScheme
51+
}
52+
53+
MaterialTheme(
54+
colorScheme = colorScheme,
55+
typography = Typography,
56+
content = content
57+
)
58+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package dev.openfeature.sdk.sampleapp.ui.theme
2+
3+
import androidx.compose.material3.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+
bodyLarge = TextStyle(
12+
fontFamily = FontFamily.Default,
13+
fontWeight = FontWeight.Normal,
14+
fontSize = 16.sp,
15+
lineHeight = 24.sp,
16+
letterSpacing = 0.5.sp
17+
)
18+
/* Other default text styles to override
19+
titleLarge = TextStyle(
20+
fontFamily = FontFamily.Default,
21+
fontWeight = FontWeight.Normal,
22+
fontSize = 22.sp,
23+
lineHeight = 28.sp,
24+
letterSpacing = 0.sp
25+
),
26+
labelSmall = TextStyle(
27+
fontFamily = FontFamily.Default,
28+
fontWeight = FontWeight.Medium,
29+
fontSize = 11.sp,
30+
lineHeight = 16.sp,
31+
letterSpacing = 0.5.sp
32+
)
33+
*/
34+
)

0 commit comments

Comments
 (0)