Reformat to use more standard Android code style

Follows stock Android Studio styles for Kotlin and XML except that we
use an indent of two and allow up to three consecutive empty lines.
This commit is contained in:
Reinout Meliesie 2026-01-22 19:29:45 +01:00
commit eebb3a589d
Signed by: zedfrigg
GPG key ID: 3AFCC06481308BC6
17 changed files with 512 additions and 481 deletions

View file

@ -1,85 +1,85 @@
import java.io.FileInputStream
import java.util.Properties
import org.gradle.kotlin.dsl.android
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.FileInputStream
import java.util.Properties
val keystoreProperties = Properties ()
keystoreProperties . load ( FileInputStream ( rootProject . file ("keystore.properties") ) )
val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(rootProject.file("keystore.properties")))
plugins {
id ("com.android.application") . version ("9.0.0")
id ("org.jetbrains.kotlin.plugin.compose") . version ("2.3.0")
id ("org.jetbrains.kotlin.plugin.serialization") . version ("2.3.0")
id("com.android.application").version("9.0.0")
id("org.jetbrains.kotlin.plugin.compose").version("2.3.0")
id("org.jetbrains.kotlin.plugin.serialization").version("2.3.0")
}
android {
namespace = "com.kernelmaft.zanbur"
compileSdk = 36
namespace = "com.kernelmaft.zanbur"
compileSdk = 36
defaultConfig {
applicationId = "com.kernelmaft.zanbur"
minSdk = 36
targetSdk = 36
versionCode = 1
versionName = "1.0"
}
defaultConfig {
applicationId = "com.kernelmaft.zanbur"
minSdk = 36
targetSdk = 36
versionCode = 1
versionName = "1.0"
}
signingConfigs {
create ("kernelmaft") {
keyAlias = "kernelmaft"
keyPassword = keystoreProperties ["keyPassword"] as String
storeFile = file ( keystoreProperties ["storeFile"] as String )
storePassword = keystoreProperties ["storePassword"] as String
}
}
signingConfigs {
create("kernelmaft") {
keyAlias = "kernelmaft"
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
debug {
signingConfig = signingConfigs . getByName ("kernelmaft")
}
release {
isMinifyEnabled = true
isShrinkResources = true
signingConfig = signingConfigs . getByName ("kernelmaft")
}
}
compileOptions {
// Required even though we don't have any Java sources because it needs to match Kotlin's JVM version
targetCompatibility = JavaVersion . VERSION_25
}
buildFeatures {
compose = true
}
buildTypes {
debug {
signingConfig = signingConfigs.getByName("kernelmaft")
}
release {
isMinifyEnabled = true
isShrinkResources = true
signingConfig = signingConfigs.getByName("kernelmaft")
}
}
compileOptions {
// Required even though we don't have any Java sources because it needs to match Kotlin's JVM
// version.
targetCompatibility = JavaVersion.VERSION_25
}
buildFeatures {
compose = true
}
}
kotlin {
compilerOptions {
jvmTarget = JvmTarget . JVM_25
}
compilerOptions {
jvmTarget = JvmTarget.JVM_25
}
}
dependencies {
// Android runtime libraries
implementation ( "com.google.android.material:material:1.13.0" )
implementation ( "androidx.activity:activity-compose:1.12.2" )
implementation ( "androidx.core:core-ktx:1.17.0" )
implementation ( "androidx.compose.material3:material3:1.4.0" )
implementation ( "androidx.compose.ui:ui:1.10.1" )
implementation ( "androidx.compose.ui:ui-graphics:1.10.1" )
debugImplementation ( "androidx.compose.ui:ui-tooling:1.10.1" )
implementation ( "androidx.lifecycle:lifecycle-runtime-ktx:2.10.0" )
implementation ( "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2" )
implementation ( "org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0" )
// Other libraries
implementation ( "io.github.davidepianca98:kmqtt-common:1.0.0" )
implementation ( "io.github.davidepianca98:kmqtt-client:1.0.0" )
// Android runtime libraries.
implementation("com.google.android.material:material:1.13.0")
implementation("androidx.activity:activity-compose:1.12.2")
implementation("androidx.core:core-ktx:1.17.0")
implementation("androidx.compose.material3:material3:1.4.0")
implementation("androidx.compose.ui:ui:1.10.1")
implementation("androidx.compose.ui:ui-graphics:1.10.1")
debugImplementation("androidx.compose.ui:ui-tooling:1.10.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.10.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0")
// Other libraries.
implementation("io.github.davidepianca98:kmqtt-common:1.0.0")
implementation("io.github.davidepianca98:kmqtt-client:1.0.0")
}
tasks . withType ( KotlinCompile :: class ) . all {
compilerOptions {
freeCompilerArgs . addAll ("-opt-in=kotlin.ExperimentalUnsignedTypes")
}
tasks.withType(KotlinCompile::class).all {
compilerOptions {
freeCompilerArgs.addAll("-opt-in=kotlin.ExperimentalUnsignedTypes")
}
}

View file

@ -1,26 +1,26 @@
<?xml version = "1.0" encoding = "utf-8" ?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android" >
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.NEARBY_WIFI_DEVICES" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
<application
android:label = "Zanbur"
android:icon = "@mipmap/ic_launcher"
android:roundIcon = "@mipmap/ic_launcher_round"
android:supportsRtl = "true" >
<application
android:icon="@mipmap/ic_launcher"
android:label="Zanbur"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<activity
android:name = "com.kernelmaft.zanbur.ui.MainActivity"
android:exported = "true" >
<activity
android:name="com.kernelmaft.zanbur.ui.MainActivity"
android:exported="true">
<intent-filter>
<action android:name = "android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</activity>
</application>
</application>
</manifest>

View file

@ -2,30 +2,32 @@ package com.kernelmaft.zanbur.common
enum class ChangeSource { Local , Remote }
enum class ChangeSource { Local, Remote }
typealias CurrentSceneSubscriber = ( Group , Scene , ChangeSource ) -> Unit
typealias GroupAddedSubscriber = ( Group , ChangeSource ) -> Unit
typealias CurrentSceneSubscriber = (Group, Scene, ChangeSource) -> Unit
typealias GroupAddedSubscriber = (Group, ChangeSource) -> Unit
object AppState {
private val currentSceneSubscribers : MutableList <CurrentSceneSubscriber> = mutableListOf ()
private val groupAddedSubscribers : MutableList <GroupAddedSubscriber> = mutableListOf ()
private val currentSceneSubscribers: MutableList<CurrentSceneSubscriber> = mutableListOf()
private val groupAddedSubscribers: MutableList<GroupAddedSubscriber> = mutableListOf()
fun setCurrentScene ( group : Group , newScene : Scene , source : ChangeSource ) {
for ( subscriber in currentSceneSubscribers ) {
subscriber ( group , newScene , source )
}
}
fun subscribeToCurrentScene ( subscriber : CurrentSceneSubscriber ) {
currentSceneSubscribers . add (subscriber)
}
fun setCurrentScene(group: Group, newScene: Scene, source: ChangeSource) {
for (subscriber in currentSceneSubscribers) {
subscriber(group, newScene, source)
}
}
fun addGroup ( newGroup : Group , source : ChangeSource ) {
for ( subscriber in groupAddedSubscribers ) {
subscriber ( newGroup , source )
}
}
fun subscribeToGroupAdded ( subscriber : GroupAddedSubscriber ) {
groupAddedSubscribers . add (subscriber)
}
fun subscribeToCurrentScene(subscriber: CurrentSceneSubscriber) {
currentSceneSubscribers.add(subscriber)
}
fun addGroup(newGroup: Group, source: ChangeSource) {
for (subscriber in groupAddedSubscribers) {
subscriber(newGroup, source)
}
}
fun subscribeToGroupAdded(subscriber: GroupAddedSubscriber) {
groupAddedSubscribers.add(subscriber)
}
}

View file

@ -3,16 +3,18 @@ package com.kernelmaft.zanbur.common
object Config {
const val MQTT_SERVER_HOST = "merovech.kernelmaft.com"
const val MQTT_SERVER_PORT = 1883
const val MQTT_TOPIC = "zigbee2mqtt"
const val MQTT_SERVER_HOST = "merovech.kernelmaft.com"
const val MQTT_SERVER_PORT = 1883
const val MQTT_TOPIC = "zigbee2mqtt"
val groups = listOf (
Group ( 0 , "All lights" , listOf (
Scene ( 0 , "Warm" ) ,
Scene ( 1 , "Warm dim" ) ,
Scene ( 2 , "Warm dim with purple" ) ,
Scene ( 100 , "All off" ) ,
) )
)
val groups = listOf(
Group(
0, "All lights", listOf(
Scene(0, "Warm"),
Scene(1, "Warm dim"),
Scene(2, "Warm dim with purple"),
Scene(100, "All off"),
)
)
)
}

View file

@ -2,14 +2,14 @@ package com.kernelmaft.zanbur.common
data class Group (
val id : Int ,
val name : String ,
val scenes : List <Scene> ,
val currentScene : Scene ? = null ,
data class Group(
val id: Int,
val name: String,
val scenes: List<Scene>,
val currentScene: Scene? = null,
)
data class Scene (
val id : Int ,
val name : String ,
data class Scene(
val id: Int,
val name: String,
)

View file

@ -4,7 +4,7 @@ import kotlinx.coroutines.CoroutineExceptionHandler
val exceptionPrinter = CoroutineExceptionHandler { _ , throwable ->
throwable . printStackTrace ()
throw throwable
val exceptionPrinter = CoroutineExceptionHandler { _, throwable ->
throwable.printStackTrace()
throw throwable
}

View file

@ -1,45 +1,45 @@
package com.kernelmaft.zanbur.network
import com.kernelmaft.zanbur.common.Config.MQTT_SERVER_HOST
import com.kernelmaft.zanbur.common.Config.MQTT_SERVER_PORT
import com.kernelmaft.zanbur.common.Config.MQTT_TOPIC
import io.github.davidepianca98.*
import io.github.davidepianca98.mqtt.*
import io.github.davidepianca98.mqtt.MQTTVersion.*
import io.github.davidepianca98.mqtt.packets.Qos.*
import io.github.davidepianca98.mqtt.packets.mqtt.*
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.serialization.json.*
import com.kernelmaft.zanbur.common.Config
import io.github.davidepianca98.MQTTClient
import io.github.davidepianca98.mqtt.MQTTVersion
import io.github.davidepianca98.mqtt.Subscription
import io.github.davidepianca98.mqtt.packets.Qos
import io.github.davidepianca98.mqtt.packets.mqtt.MQTTPublish
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
typealias MqttPublishHandler = ( MQTTPublish , Json ) -> Unit
typealias MqttPublishHandler = (MQTTPublish, Json) -> Unit
object MqttClient {
private var client : MQTTClient ? = null
private var coroutineScope : CoroutineScope ? = null
private val publishHandlers : MutableList <MqttPublishHandler> = mutableListOf ()
private var client: MQTTClient? = null
private var coroutineScope: CoroutineScope? = null
private val publishHandlers: MutableList<MqttPublishHandler> = mutableListOf()
fun run ( coroutineScope : CoroutineScope ) {
this . coroutineScope = coroutineScope
val json = Json { ignoreUnknownKeys = true }
fun run(coroutineScope: CoroutineScope) {
this.coroutineScope = coroutineScope
val json = Json { ignoreUnknownKeys = true }
coroutineScope . launch ( IO + exceptionPrinter ) {
client = MQTTClient ( MQTT5 , MQTT_SERVER_HOST , MQTT_SERVER_PORT , null ) {
for ( handler in publishHandlers ) handler ( it , json )
}
client !! . subscribe ( listOf ( Subscription ( MQTT_TOPIC + "/#" ) ) )
coroutineScope.launch(Dispatchers.IO + exceptionPrinter) {
client =
MQTTClient(MQTTVersion.MQTT5, Config.MQTT_SERVER_HOST, Config.MQTT_SERVER_PORT, null) {
for (handler in publishHandlers) handler(it, json)
}
client!!.subscribe(listOf(Subscription(Config.MQTT_TOPIC + "/#")))
client !! . run ()
}
}
client!!.run()
}
}
fun addPublishHandler ( handler : MqttPublishHandler ) = publishHandlers . add (handler)
fun addPublishHandler(handler: MqttPublishHandler) = publishHandlers.add(handler)
fun publish ( topic : String , payload : UByteArray ) {
coroutineScope !! . launch ( IO + exceptionPrinter ) {
client !! . publish ( false , AT_MOST_ONCE , topic , payload )
}
}
fun publish(topic: String, payload: UByteArray) {
coroutineScope!!.launch(Dispatchers.IO + exceptionPrinter) {
client!!.publish(false, Qos.AT_MOST_ONCE, topic, payload)
}
}
}

View file

@ -1,20 +1,23 @@
package com.kernelmaft.zanbur.network
import com.kernelmaft.zanbur.common.*
import com.kernelmaft.zanbur.common.Config.MQTT_TOPIC
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import com.kernelmaft.zanbur.common.Config
import com.kernelmaft.zanbur.common.Group
import com.kernelmaft.zanbur.common.Scene
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
fun publishSceneChange ( group : Group , newScene : Scene ) {
val topic = MQTT_TOPIC + "/" + group . name + "/set"
val packet = Json . encodeToString ( SceneRecallPacket ( newScene . id ) )
. toByteArray ()
. asUByteArray ()
MqttClient . publish ( topic , packet )
fun publishSceneChange(group: Group, newScene: Scene) {
val topic = Config.MQTT_TOPIC + "/" + group.name + "/set"
val packet = Json.encodeToString(SceneRecallPacket(newScene.id))
.toByteArray()
.asUByteArray()
MqttClient.publish(topic, packet)
}
@Serializable private data class SceneRecallPacket (
@SerialName ("scene_recall") val sceneRecall : Int ,
@Serializable
private data class SceneRecallPacket(
@SerialName("scene_recall") val sceneRecall: Int,
)

View file

@ -1,46 +1,62 @@
package com.kernelmaft.zanbur.ui
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement.Center
import androidx.compose.material3.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ButtonDefaults.buttonColors
import androidx.compose.material3.ButtonDefaults.filledTonalButtonColors
import androidx.compose.material3.ButtonDefaults.shape
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import com.kernelmaft.zanbur.common.*
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.kernelmaft.zanbur.common.Group
import com.kernelmaft.zanbur.common.Scene
@Composable fun AppFrame ( content : @Composable () -> Unit ) {
ZanburTheme {
Scaffold { scaffoldPadding ->
CenteringColumn ( Modifier . padding (scaffoldPadding) . fillMaxSize () ) {
content ()
}
}
}
@Composable
fun AppFrame(content: @Composable () -> Unit) {
ZanburTheme {
Scaffold { scaffoldPadding ->
CenteringColumn(
Modifier
.padding(scaffoldPadding)
.fillMaxSize()
) {
content()
}
}
}
}
@Composable fun SceneSwitcher ( group : Group , onSwitch : (Scene) -> Unit ) {
CenteringColumn {
Text ( group . name )
Spacer ( Modifier . height ( compactSpacing ) )
@Composable
fun SceneSwitcher(group: Group, onSwitch: (Scene) -> Unit) {
CenteringColumn {
Text(group.name)
Spacer(Modifier.height(compactSpacing))
for ( scene in group . scenes ) {
val colors =
if ( scene . id == group . currentScene ?. id ) buttonColors ()
else filledTonalButtonColors ()
for (scene in group.scenes) {
val colors =
if (scene.id == group.currentScene?.id) buttonColors()
else filledTonalButtonColors()
Button ( { onSwitch (scene) } , Modifier . fillMaxWidth () , true , shape , colors ) {
Text ( scene . name )
}
}
}
Button({ onSwitch(scene) }, Modifier.fillMaxWidth(), true, ButtonDefaults.shape, colors) {
Text(scene.name)
}
}
}
}
@Composable fun CenteringColumn (
modifier : Modifier = Modifier ,
content : @Composable ColumnScope . () -> Unit ,
) = Column ( modifier , Center , CenterHorizontally , content )
@Composable
fun CenteringColumn(
modifier: Modifier = Modifier,
content: @Composable ColumnScope.() -> Unit,
) = Column(modifier, Arrangement.Center, Alignment.CenterHorizontally, content)

View file

@ -1,22 +1,26 @@
package com.kernelmaft.zanbur.ui
import androidx.compose.runtime.*
import com.kernelmaft.zanbur.common.*
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import com.kernelmaft.zanbur.common.AppState
import com.kernelmaft.zanbur.common.Group
fun createGroupsComposeState () : MutableState < List <Group> > {
val groups : MutableState < List <Group> > = mutableStateOf ( emptyList () )
fun createGroupsComposeState(): MutableState<List<Group>> {
val groups: MutableState<List<Group>> = mutableStateOf(emptyList())
AppState . subscribeToGroupAdded { newGroup , _ ->
groups . value = groups . value . plus (newGroup)
}
AppState . subscribeToCurrentScene { group , newScene , source ->
groups . value = groups . value . map { when ( it . id ) {
group . id -> it . copy ( currentScene = newScene )
else -> it
} }
}
AppState.subscribeToGroupAdded { newGroup, _ ->
groups.value = groups.value.plus(newGroup)
}
AppState.subscribeToCurrentScene { group, newScene, source ->
groups.value = groups.value.map {
when (it.id) {
group.id -> it.copy(currentScene = newScene)
else -> it
}
}
}
return groups
return groups
}

View file

@ -1,43 +1,46 @@
package com.kernelmaft.zanbur.ui
import android.os.*
import androidx.activity.compose.*
import androidx.compose.foundation.layout.*
import androidx.compose.ui.*
import androidx.compose.ui.unit.*
import androidx.lifecycle.*
import com.kernelmaft.zanbur.common.*
import com.kernelmaft.zanbur.common.ChangeSource.*
import com.kernelmaft.zanbur.network.*
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.width
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import com.kernelmaft.zanbur.common.AppState
import com.kernelmaft.zanbur.common.ChangeSource
import com.kernelmaft.zanbur.common.Config
import com.kernelmaft.zanbur.network.MqttClient
import com.kernelmaft.zanbur.network.publishSceneChange
class MainActivity : EdgeToEdgeActivity () {
override fun onCreate ( savedInstanceState : Bundle ? ) {
super . onCreate (savedInstanceState)
class MainActivity : EdgeToEdgeActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val groups = createGroupsComposeState ()
val groups = createGroupsComposeState()
AppState . subscribeToCurrentScene { group , newScene , source ->
if ( source == Local ) {
publishSceneChange ( group , newScene )
}
}
AppState.subscribeToCurrentScene { group, newScene, source ->
if (source == ChangeSource.Local) {
publishSceneChange(group, newScene)
}
}
Config . groups . forEach { AppState . addGroup ( it , Remote ) }
Config.groups.forEach { AppState.addGroup(it, ChangeSource.Remote) }
setContent {
AppFrame {
Column ( Modifier . width ( 300 . dp ) ) {
groups . value . forEach { group ->
SceneSwitcher (group) { newScene ->
AppState . setCurrentScene ( group , newScene , Local )
}
}
}
}
}
setContent {
AppFrame {
Column(Modifier.width(300.dp)) {
groups.value.forEach { group ->
SceneSwitcher(group) { newScene ->
AppState.setCurrentScene(group, newScene, ChangeSource.Local)
}
}
}
}
}
MqttClient . run (lifecycleScope)
}
MqttClient.run(lifecycleScope)
}
}

View file

@ -1,34 +1,35 @@
package com.kernelmaft.zanbur.ui
import android.os.*
import androidx.activity.*
import androidx.compose.foundation.*
import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme.shapes
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.runtime.*
import androidx.compose.ui.platform.*
import androidx.compose.ui.unit.*
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
val compactSpacing = 16 . dp
val compactSpacing = 16.dp
@Composable fun ZanburTheme ( content : @Composable () -> Unit ) {
val colorScheme = run {
if ( isSystemInDarkTheme () )
dynamicDarkColorScheme ( LocalContext . current )
else
dynamicLightColorScheme ( LocalContext . current )
}
@Composable
fun ZanburTheme(content: @Composable () -> Unit) {
val colorScheme = run {
if (isSystemInDarkTheme())
dynamicDarkColorScheme(LocalContext.current)
else
dynamicLightColorScheme(LocalContext.current)
}
MaterialTheme ( colorScheme, shapes , typography , content )
MaterialTheme(colorScheme, MaterialTheme.shapes, MaterialTheme.typography, content)
}
open class EdgeToEdgeActivity : ComponentActivity () {
override fun onCreate ( savedInstanceState : Bundle ? ) {
super . onCreate (savedInstanceState)
open class EdgeToEdgeActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
actionBar ?. hide ()
}
actionBar?.hide()
}
}

View file

@ -1,170 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View file

@ -1,30 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View file

@ -1,16 +1,16 @@
pluginManagement {
repositories {
google ()
mavenCentral ()
gradlePluginPortal ()
}
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositories {
google ()
mavenCentral ()
}
repositories {
google()
mavenCentral()
}
}
rootProject . name = "Zanbur"
include (":app")
rootProject.name = "Zanbur"
include(":app")