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:
parent
abfc172642
commit
eebb3a589d
17 changed files with 512 additions and 481 deletions
|
|
@ -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.dsl.JvmTarget
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val keystoreProperties = Properties ()
|
val keystoreProperties = Properties()
|
||||||
keystoreProperties . load ( FileInputStream ( rootProject . file ("keystore.properties") ) )
|
keystoreProperties.load(FileInputStream(rootProject.file("keystore.properties")))
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id ("com.android.application") . version ("9.0.0")
|
id("com.android.application").version("9.0.0")
|
||||||
id ("org.jetbrains.kotlin.plugin.compose") . version ("2.3.0")
|
id("org.jetbrains.kotlin.plugin.compose").version("2.3.0")
|
||||||
id ("org.jetbrains.kotlin.plugin.serialization") . version ("2.3.0")
|
id("org.jetbrains.kotlin.plugin.serialization").version("2.3.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.kernelmaft.zanbur"
|
namespace = "com.kernelmaft.zanbur"
|
||||||
compileSdk = 36
|
compileSdk = 36
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.kernelmaft.zanbur"
|
applicationId = "com.kernelmaft.zanbur"
|
||||||
minSdk = 36
|
minSdk = 36
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0"
|
versionName = "1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
create ("kernelmaft") {
|
create("kernelmaft") {
|
||||||
keyAlias = "kernelmaft"
|
keyAlias = "kernelmaft"
|
||||||
keyPassword = keystoreProperties ["keyPassword"] as String
|
keyPassword = keystoreProperties["keyPassword"] as String
|
||||||
storeFile = file ( keystoreProperties ["storeFile"] as String )
|
storeFile = file(keystoreProperties["storeFile"] as String)
|
||||||
storePassword = keystoreProperties ["storePassword"] as String
|
storePassword = keystoreProperties["storePassword"] as String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
debug {
|
debug {
|
||||||
signingConfig = signingConfigs . getByName ("kernelmaft")
|
signingConfig = signingConfigs.getByName("kernelmaft")
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
isMinifyEnabled = true
|
isMinifyEnabled = true
|
||||||
isShrinkResources = true
|
isShrinkResources = true
|
||||||
signingConfig = signingConfigs . getByName ("kernelmaft")
|
signingConfig = signingConfigs.getByName("kernelmaft")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
// Required even though we don't have any Java sources because it needs to match Kotlin's JVM version
|
// Required even though we don't have any Java sources because it needs to match Kotlin's JVM
|
||||||
targetCompatibility = JavaVersion . VERSION_25
|
// version.
|
||||||
}
|
targetCompatibility = JavaVersion.VERSION_25
|
||||||
buildFeatures {
|
}
|
||||||
compose = true
|
buildFeatures {
|
||||||
}
|
compose = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
jvmTarget = JvmTarget . JVM_25
|
jvmTarget = JvmTarget.JVM_25
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Android runtime libraries
|
// Android runtime libraries.
|
||||||
implementation ( "com.google.android.material:material:1.13.0" )
|
implementation("com.google.android.material:material:1.13.0")
|
||||||
implementation ( "androidx.activity:activity-compose:1.12.2" )
|
implementation("androidx.activity:activity-compose:1.12.2")
|
||||||
implementation ( "androidx.core:core-ktx:1.17.0" )
|
implementation("androidx.core:core-ktx:1.17.0")
|
||||||
implementation ( "androidx.compose.material3:material3:1.4.0" )
|
implementation("androidx.compose.material3:material3:1.4.0")
|
||||||
implementation ( "androidx.compose.ui:ui:1.10.1" )
|
implementation("androidx.compose.ui:ui:1.10.1")
|
||||||
implementation ( "androidx.compose.ui:ui-graphics:1.10.1" )
|
implementation("androidx.compose.ui:ui-graphics:1.10.1")
|
||||||
debugImplementation ( "androidx.compose.ui:ui-tooling:1.10.1" )
|
debugImplementation("androidx.compose.ui:ui-tooling:1.10.1")
|
||||||
implementation ( "androidx.lifecycle:lifecycle-runtime-ktx:2.10.0" )
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.10.0")
|
||||||
implementation ( "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2" )
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2")
|
||||||
implementation ( "org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0" )
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0")
|
||||||
// Other libraries
|
// Other libraries.
|
||||||
implementation ( "io.github.davidepianca98:kmqtt-common:1.0.0" )
|
implementation("io.github.davidepianca98:kmqtt-common:1.0.0")
|
||||||
implementation ( "io.github.davidepianca98:kmqtt-client:1.0.0" )
|
implementation("io.github.davidepianca98:kmqtt-client:1.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks . withType ( KotlinCompile :: class ) . all {
|
tasks.withType(KotlinCompile::class).all {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
freeCompilerArgs . addAll ("-opt-in=kotlin.ExperimentalUnsignedTypes")
|
freeCompilerArgs.addAll("-opt-in=kotlin.ExperimentalUnsignedTypes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
<?xml version = "1.0" encoding = "utf-8" ?>
|
<?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.INTERNET" />
|
||||||
<uses-permission android:name = "android.permission.NEARBY_WIFI_DEVICES" />
|
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label = "Zanbur"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:icon = "@mipmap/ic_launcher"
|
android:label="Zanbur"
|
||||||
android:roundIcon = "@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl = "true" >
|
android:supportsRtl="true">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name = "com.kernelmaft.zanbur.ui.MainActivity"
|
android:name="com.kernelmaft.zanbur.ui.MainActivity"
|
||||||
android:exported = "true" >
|
android:exported="true">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name = "android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name = "android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
||||||
|
|
@ -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 CurrentSceneSubscriber = (Group, Scene, ChangeSource) -> Unit
|
||||||
typealias GroupAddedSubscriber = ( Group , ChangeSource ) -> Unit
|
typealias GroupAddedSubscriber = (Group, ChangeSource) -> Unit
|
||||||
|
|
||||||
object AppState {
|
object AppState {
|
||||||
private val currentSceneSubscribers : MutableList <CurrentSceneSubscriber> = mutableListOf ()
|
private val currentSceneSubscribers: MutableList<CurrentSceneSubscriber> = mutableListOf()
|
||||||
private val groupAddedSubscribers : MutableList <GroupAddedSubscriber> = mutableListOf ()
|
private val groupAddedSubscribers: MutableList<GroupAddedSubscriber> = mutableListOf()
|
||||||
|
|
||||||
fun setCurrentScene ( group : Group , newScene : Scene , source : ChangeSource ) {
|
fun setCurrentScene(group: Group, newScene: Scene, source: ChangeSource) {
|
||||||
for ( subscriber in currentSceneSubscribers ) {
|
for (subscriber in currentSceneSubscribers) {
|
||||||
subscriber ( group , newScene , source )
|
subscriber(group, newScene, source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun subscribeToCurrentScene ( subscriber : CurrentSceneSubscriber ) {
|
|
||||||
currentSceneSubscribers . add (subscriber)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addGroup ( newGroup : Group , source : ChangeSource ) {
|
fun subscribeToCurrentScene(subscriber: CurrentSceneSubscriber) {
|
||||||
for ( subscriber in groupAddedSubscribers ) {
|
currentSceneSubscribers.add(subscriber)
|
||||||
subscriber ( newGroup , source )
|
}
|
||||||
}
|
|
||||||
}
|
fun addGroup(newGroup: Group, source: ChangeSource) {
|
||||||
fun subscribeToGroupAdded ( subscriber : GroupAddedSubscriber ) {
|
for (subscriber in groupAddedSubscribers) {
|
||||||
groupAddedSubscribers . add (subscriber)
|
subscriber(newGroup, source)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun subscribeToGroupAdded(subscriber: GroupAddedSubscriber) {
|
||||||
|
groupAddedSubscribers.add(subscriber)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,18 @@ package com.kernelmaft.zanbur.common
|
||||||
|
|
||||||
|
|
||||||
object Config {
|
object Config {
|
||||||
const val MQTT_SERVER_HOST = "merovech.kernelmaft.com"
|
const val MQTT_SERVER_HOST = "merovech.kernelmaft.com"
|
||||||
const val MQTT_SERVER_PORT = 1883
|
const val MQTT_SERVER_PORT = 1883
|
||||||
const val MQTT_TOPIC = "zigbee2mqtt"
|
const val MQTT_TOPIC = "zigbee2mqtt"
|
||||||
|
|
||||||
val groups = listOf (
|
val groups = listOf(
|
||||||
Group ( 0 , "All lights" , listOf (
|
Group(
|
||||||
Scene ( 0 , "Warm" ) ,
|
0, "All lights", listOf(
|
||||||
Scene ( 1 , "Warm dim" ) ,
|
Scene(0, "Warm"),
|
||||||
Scene ( 2 , "Warm dim with purple" ) ,
|
Scene(1, "Warm dim"),
|
||||||
Scene ( 100 , "All off" ) ,
|
Scene(2, "Warm dim with purple"),
|
||||||
) )
|
Scene(100, "All off"),
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@ package com.kernelmaft.zanbur.common
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data class Group (
|
data class Group(
|
||||||
val id : Int ,
|
val id: Int,
|
||||||
val name : String ,
|
val name: String,
|
||||||
val scenes : List <Scene> ,
|
val scenes: List<Scene>,
|
||||||
val currentScene : Scene ? = null ,
|
val currentScene: Scene? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Scene (
|
data class Scene(
|
||||||
val id : Int ,
|
val id: Int,
|
||||||
val name : String ,
|
val name: String,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val exceptionPrinter = CoroutineExceptionHandler { _ , throwable ->
|
val exceptionPrinter = CoroutineExceptionHandler { _, throwable ->
|
||||||
throwable . printStackTrace ()
|
throwable.printStackTrace()
|
||||||
throw throwable
|
throw throwable
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,45 @@
|
||||||
package com.kernelmaft.zanbur.network
|
package com.kernelmaft.zanbur.network
|
||||||
|
|
||||||
import com.kernelmaft.zanbur.common.Config.MQTT_SERVER_HOST
|
import com.kernelmaft.zanbur.common.Config
|
||||||
import com.kernelmaft.zanbur.common.Config.MQTT_SERVER_PORT
|
import io.github.davidepianca98.MQTTClient
|
||||||
import com.kernelmaft.zanbur.common.Config.MQTT_TOPIC
|
import io.github.davidepianca98.mqtt.MQTTVersion
|
||||||
import io.github.davidepianca98.*
|
import io.github.davidepianca98.mqtt.Subscription
|
||||||
import io.github.davidepianca98.mqtt.*
|
import io.github.davidepianca98.mqtt.packets.Qos
|
||||||
import io.github.davidepianca98.mqtt.MQTTVersion.*
|
import io.github.davidepianca98.mqtt.packets.mqtt.MQTTPublish
|
||||||
import io.github.davidepianca98.mqtt.packets.Qos.*
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import io.github.davidepianca98.mqtt.packets.mqtt.*
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.*
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typealias MqttPublishHandler = ( MQTTPublish , Json ) -> Unit
|
typealias MqttPublishHandler = (MQTTPublish, Json) -> Unit
|
||||||
|
|
||||||
object MqttClient {
|
object MqttClient {
|
||||||
private var client : MQTTClient ? = null
|
private var client: MQTTClient? = null
|
||||||
private var coroutineScope : CoroutineScope ? = null
|
private var coroutineScope: CoroutineScope? = null
|
||||||
private val publishHandlers : MutableList <MqttPublishHandler> = mutableListOf ()
|
private val publishHandlers: MutableList<MqttPublishHandler> = mutableListOf()
|
||||||
|
|
||||||
fun run ( coroutineScope : CoroutineScope ) {
|
fun run(coroutineScope: CoroutineScope) {
|
||||||
this . coroutineScope = coroutineScope
|
this.coroutineScope = coroutineScope
|
||||||
val json = Json { ignoreUnknownKeys = true }
|
val json = Json { ignoreUnknownKeys = true }
|
||||||
|
|
||||||
coroutineScope . launch ( IO + exceptionPrinter ) {
|
coroutineScope.launch(Dispatchers.IO + exceptionPrinter) {
|
||||||
client = MQTTClient ( MQTT5 , MQTT_SERVER_HOST , MQTT_SERVER_PORT , null ) {
|
client =
|
||||||
for ( handler in publishHandlers ) handler ( it , json )
|
MQTTClient(MQTTVersion.MQTT5, Config.MQTT_SERVER_HOST, Config.MQTT_SERVER_PORT, null) {
|
||||||
}
|
for (handler in publishHandlers) handler(it, json)
|
||||||
client !! . subscribe ( listOf ( Subscription ( MQTT_TOPIC + "/#" ) ) )
|
}
|
||||||
|
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 ) {
|
fun publish(topic: String, payload: UByteArray) {
|
||||||
coroutineScope !! . launch ( IO + exceptionPrinter ) {
|
coroutineScope!!.launch(Dispatchers.IO + exceptionPrinter) {
|
||||||
client !! . publish ( false , AT_MOST_ONCE , topic , payload )
|
client!!.publish(false, Qos.AT_MOST_ONCE, topic, payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,23 @@
|
||||||
package com.kernelmaft.zanbur.network
|
package com.kernelmaft.zanbur.network
|
||||||
|
|
||||||
import com.kernelmaft.zanbur.common.*
|
import com.kernelmaft.zanbur.common.Config
|
||||||
import com.kernelmaft.zanbur.common.Config.MQTT_TOPIC
|
import com.kernelmaft.zanbur.common.Group
|
||||||
import kotlinx.serialization.*
|
import com.kernelmaft.zanbur.common.Scene
|
||||||
import kotlinx.serialization.json.*
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun publishSceneChange ( group : Group , newScene : Scene ) {
|
fun publishSceneChange(group: Group, newScene: Scene) {
|
||||||
val topic = MQTT_TOPIC + "/" + group . name + "/set"
|
val topic = Config.MQTT_TOPIC + "/" + group.name + "/set"
|
||||||
val packet = Json . encodeToString ( SceneRecallPacket ( newScene . id ) )
|
val packet = Json.encodeToString(SceneRecallPacket(newScene.id))
|
||||||
. toByteArray ()
|
.toByteArray()
|
||||||
. asUByteArray ()
|
.asUByteArray()
|
||||||
MqttClient . publish ( topic , packet )
|
MqttClient.publish(topic, packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable private data class SceneRecallPacket (
|
@Serializable
|
||||||
@SerialName ("scene_recall") val sceneRecall : Int ,
|
private data class SceneRecallPacket(
|
||||||
|
@SerialName("scene_recall") val sceneRecall: Int,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,62 @@
|
||||||
package com.kernelmaft.zanbur.ui
|
package com.kernelmaft.zanbur.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Arrangement.Center
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.material3.*
|
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.buttonColors
|
||||||
import androidx.compose.material3.ButtonDefaults.filledTonalButtonColors
|
import androidx.compose.material3.ButtonDefaults.filledTonalButtonColors
|
||||||
import androidx.compose.material3.ButtonDefaults.shape
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.ui.*
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
|
import androidx.compose.ui.Alignment
|
||||||
import com.kernelmaft.zanbur.common.*
|
import androidx.compose.ui.Modifier
|
||||||
|
import com.kernelmaft.zanbur.common.Group
|
||||||
|
import com.kernelmaft.zanbur.common.Scene
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Composable fun AppFrame ( content : @Composable () -> Unit ) {
|
@Composable
|
||||||
ZanburTheme {
|
fun AppFrame(content: @Composable () -> Unit) {
|
||||||
Scaffold { scaffoldPadding ->
|
ZanburTheme {
|
||||||
CenteringColumn ( Modifier . padding (scaffoldPadding) . fillMaxSize () ) {
|
Scaffold { scaffoldPadding ->
|
||||||
content ()
|
CenteringColumn(
|
||||||
}
|
Modifier
|
||||||
}
|
.padding(scaffoldPadding)
|
||||||
}
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable fun SceneSwitcher ( group : Group , onSwitch : (Scene) -> Unit ) {
|
@Composable
|
||||||
CenteringColumn {
|
fun SceneSwitcher(group: Group, onSwitch: (Scene) -> Unit) {
|
||||||
Text ( group . name )
|
CenteringColumn {
|
||||||
Spacer ( Modifier . height ( compactSpacing ) )
|
Text(group.name)
|
||||||
|
Spacer(Modifier.height(compactSpacing))
|
||||||
|
|
||||||
for ( scene in group . scenes ) {
|
for (scene in group.scenes) {
|
||||||
val colors =
|
val colors =
|
||||||
if ( scene . id == group . currentScene ?. id ) buttonColors ()
|
if (scene.id == group.currentScene?.id) buttonColors()
|
||||||
else filledTonalButtonColors ()
|
else filledTonalButtonColors()
|
||||||
|
|
||||||
Button ( { onSwitch (scene) } , Modifier . fillMaxWidth () , true , shape , colors ) {
|
Button({ onSwitch(scene) }, Modifier.fillMaxWidth(), true, ButtonDefaults.shape, colors) {
|
||||||
Text ( scene . name )
|
Text(scene.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable fun CenteringColumn (
|
@Composable
|
||||||
modifier : Modifier = Modifier ,
|
fun CenteringColumn(
|
||||||
content : @Composable ColumnScope . () -> Unit ,
|
modifier: Modifier = Modifier,
|
||||||
) = Column ( modifier , Center , CenterHorizontally , content )
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
|
) = Column(modifier, Arrangement.Center, Alignment.CenterHorizontally, content)
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,26 @@
|
||||||
package com.kernelmaft.zanbur.ui
|
package com.kernelmaft.zanbur.ui
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.MutableState
|
||||||
import com.kernelmaft.zanbur.common.*
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import com.kernelmaft.zanbur.common.AppState
|
||||||
|
import com.kernelmaft.zanbur.common.Group
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun createGroupsComposeState () : MutableState < List <Group> > {
|
fun createGroupsComposeState(): MutableState<List<Group>> {
|
||||||
val groups : MutableState < List <Group> > = mutableStateOf ( emptyList () )
|
val groups: MutableState<List<Group>> = mutableStateOf(emptyList())
|
||||||
|
|
||||||
AppState . subscribeToGroupAdded { newGroup , _ ->
|
AppState.subscribeToGroupAdded { newGroup, _ ->
|
||||||
groups . value = groups . value . plus (newGroup)
|
groups.value = groups.value.plus(newGroup)
|
||||||
}
|
}
|
||||||
AppState . subscribeToCurrentScene { group , newScene , source ->
|
AppState.subscribeToCurrentScene { group, newScene, source ->
|
||||||
groups . value = groups . value . map { when ( it . id ) {
|
groups.value = groups.value.map {
|
||||||
group . id -> it . copy ( currentScene = newScene )
|
when (it.id) {
|
||||||
else -> it
|
group.id -> it.copy(currentScene = newScene)
|
||||||
} }
|
else -> it
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,46 @@
|
||||||
package com.kernelmaft.zanbur.ui
|
package com.kernelmaft.zanbur.ui
|
||||||
|
|
||||||
import android.os.*
|
import android.os.Bundle
|
||||||
import androidx.activity.compose.*
|
import androidx.activity.compose.setContent
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.ui.*
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.*
|
import androidx.compose.ui.unit.dp
|
||||||
import com.kernelmaft.zanbur.common.*
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.kernelmaft.zanbur.common.ChangeSource.*
|
import com.kernelmaft.zanbur.common.AppState
|
||||||
import com.kernelmaft.zanbur.network.*
|
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 () {
|
class MainActivity : EdgeToEdgeActivity() {
|
||||||
override fun onCreate ( savedInstanceState : Bundle ? ) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super . onCreate (savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
val groups = createGroupsComposeState ()
|
val groups = createGroupsComposeState()
|
||||||
|
|
||||||
AppState . subscribeToCurrentScene { group , newScene , source ->
|
AppState.subscribeToCurrentScene { group, newScene, source ->
|
||||||
if ( source == Local ) {
|
if (source == ChangeSource.Local) {
|
||||||
publishSceneChange ( group , newScene )
|
publishSceneChange(group, newScene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Config . groups . forEach { AppState . addGroup ( it , Remote ) }
|
Config.groups.forEach { AppState.addGroup(it, ChangeSource.Remote) }
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
AppFrame {
|
AppFrame {
|
||||||
Column ( Modifier . width ( 300 . dp ) ) {
|
Column(Modifier.width(300.dp)) {
|
||||||
groups . value . forEach { group ->
|
groups.value.forEach { group ->
|
||||||
SceneSwitcher (group) { newScene ->
|
SceneSwitcher(group) { newScene ->
|
||||||
AppState . setCurrentScene ( group , newScene , Local )
|
AppState.setCurrentScene(group, newScene, ChangeSource.Local)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttClient . run (lifecycleScope)
|
MqttClient.run(lifecycleScope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,35 @@
|
||||||
package com.kernelmaft.zanbur.ui
|
package com.kernelmaft.zanbur.ui
|
||||||
|
|
||||||
import android.os.*
|
import android.os.Bundle
|
||||||
import androidx.activity.*
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.MaterialTheme.shapes
|
import androidx.compose.material3.dynamicDarkColorScheme
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.dynamicLightColorScheme
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.platform.*
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val compactSpacing = 16 . dp
|
val compactSpacing = 16.dp
|
||||||
|
|
||||||
@Composable fun ZanburTheme ( content : @Composable () -> Unit ) {
|
@Composable
|
||||||
val colorScheme = run {
|
fun ZanburTheme(content: @Composable () -> Unit) {
|
||||||
if ( isSystemInDarkTheme () )
|
val colorScheme = run {
|
||||||
dynamicDarkColorScheme ( LocalContext . current )
|
if (isSystemInDarkTheme())
|
||||||
else
|
dynamicDarkColorScheme(LocalContext.current)
|
||||||
dynamicLightColorScheme ( LocalContext . current )
|
else
|
||||||
}
|
dynamicLightColorScheme(LocalContext.current)
|
||||||
|
}
|
||||||
|
|
||||||
MaterialTheme ( colorScheme, shapes , typography , content )
|
MaterialTheme(colorScheme, MaterialTheme.shapes, MaterialTheme.typography, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class EdgeToEdgeActivity : ComponentActivity () {
|
open class EdgeToEdgeActivity : ComponentActivity() {
|
||||||
override fun onCreate ( savedInstanceState : Bundle ? ) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super . onCreate (savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
actionBar ?. hide ()
|
actionBar?.hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,170 +1,170 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#3DDC84"
|
android:fillColor="#3DDC84"
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M9,0L9,108"
|
android:pathData="M9,0L9,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M19,0L19,108"
|
android:pathData="M19,0L19,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M29,0L29,108"
|
android:pathData="M29,0L29,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M39,0L39,108"
|
android:pathData="M39,0L39,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M49,0L49,108"
|
android:pathData="M49,0L49,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M59,0L59,108"
|
android:pathData="M59,0L59,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M69,0L69,108"
|
android:pathData="M69,0L69,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M79,0L79,108"
|
android:pathData="M79,0L79,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M89,0L89,108"
|
android:pathData="M89,0L89,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M99,0L99,108"
|
android:pathData="M99,0L99,108"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,9L108,9"
|
android:pathData="M0,9L108,9"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,19L108,19"
|
android:pathData="M0,19L108,19"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,29L108,29"
|
android:pathData="M0,29L108,29"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,39L108,39"
|
android:pathData="M0,39L108,39"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,49L108,49"
|
android:pathData="M0,49L108,49"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,59L108,59"
|
android:pathData="M0,59L108,59"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,69L108,69"
|
android:pathData="M0,69L108,69"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,79L108,79"
|
android:pathData="M0,79L108,79"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,89L108,89"
|
android:pathData="M0,89L108,89"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M0,99L108,99"
|
android:pathData="M0,99L108,99"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M19,29L89,29"
|
android:pathData="M19,29L89,29"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M19,39L89,39"
|
android:pathData="M19,39L89,39"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M19,49L89,49"
|
android:pathData="M19,49L89,49"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M19,59L89,59"
|
android:pathData="M19,59L89,59"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M19,69L89,69"
|
android:pathData="M19,69L89,69"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M19,79L89,79"
|
android:pathData="M19,79L89,79"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M29,19L29,89"
|
android:pathData="M29,19L29,89"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M39,19L39,89"
|
android:pathData="M39,19L39,89"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M49,19L49,89"
|
android:pathData="M49,19L49,89"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M59,19L59,89"
|
android:pathData="M59,19L59,89"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M69,19L69,89"
|
android:pathData="M69,19L69,89"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:pathData="M79,19L79,89"
|
android:pathData="M79,19L79,89"
|
||||||
android:strokeWidth="0.8"
|
android:strokeWidth="0.8"
|
||||||
android:strokeColor="#33FFFFFF" />
|
android:strokeColor="#33FFFFFF" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="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">
|
<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">
|
<aapt:attr name="android:fillColor">
|
||||||
<gradient
|
<gradient
|
||||||
android:endX="85.84757"
|
android:endX="85.84757"
|
||||||
android:endY="92.4963"
|
android:endY="92.4963"
|
||||||
android:startX="42.9492"
|
android:startX="42.9492"
|
||||||
android:startY="49.59793"
|
android:startY="49.59793"
|
||||||
android:type="linear">
|
android:type="linear">
|
||||||
<item
|
<item
|
||||||
android:color="#44000000"
|
android:color="#44000000"
|
||||||
android:offset="0.0" />
|
android:offset="0.0" />
|
||||||
<item
|
<item
|
||||||
android:color="#00000000"
|
android:color="#00000000"
|
||||||
android:offset="1.0" />
|
android:offset="1.0" />
|
||||||
</gradient>
|
</gradient>
|
||||||
</aapt:attr>
|
</aapt:attr>
|
||||||
</path>
|
</path>
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFF"
|
android:fillColor="#FFFFFF"
|
||||||
android:fillType="nonZero"
|
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: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:strokeWidth="1"
|
||||||
android:strokeColor="#00000000" />
|
android:strokeColor="#00000000" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
google ()
|
google()
|
||||||
mavenCentral ()
|
mavenCentral()
|
||||||
gradlePluginPortal ()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositories {
|
repositories {
|
||||||
google ()
|
google()
|
||||||
mavenCentral ()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject . name = "Zanbur"
|
rootProject.name = "Zanbur"
|
||||||
include (":app")
|
include(":app")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue