diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2f6be48b..be712480 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,7 +5,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
deleted file mode 100644
index 6a7128f4..00000000
--- a/app/src/main/res/drawable/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_launcher_monochrome.xml b/app/src/main/res/drawable/ic_launcher_monochrome.xml
deleted file mode 100644
index 9b58398e..00000000
--- a/app/src/main/res/drawable/ic_launcher_monochrome.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
deleted file mode 100644
index 7b32835e..00000000
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 2bde775e..00000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index e808cbff..00000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 6d592b62..00000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 667a2fce..00000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index d55a909d..00000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/core/base/src/main/ic_launcher_3_green-playstore.png b/core/base/src/main/ic_launcher_3_green-playstore.png
new file mode 100644
index 00000000..da2313ed
Binary files /dev/null and b/core/base/src/main/ic_launcher_3_green-playstore.png differ
diff --git a/core/base/src/main/res/drawable/ic_launcher_1_foreground.xml b/core/base/src/main/res/drawable/ic_launcher_1_foreground.xml
new file mode 100644
index 00000000..49768b8d
--- /dev/null
+++ b/core/base/src/main/res/drawable/ic_launcher_1_foreground.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/core/base/src/main/res/drawable/ic_launcher_2_foreground.xml b/core/base/src/main/res/drawable/ic_launcher_2_foreground.xml
new file mode 100644
index 00000000..8e7f2b97
--- /dev/null
+++ b/core/base/src/main/res/drawable/ic_launcher_2_foreground.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
diff --git a/core/base/src/main/res/drawable/ic_launcher_3_foreground.xml b/core/base/src/main/res/drawable/ic_launcher_3_foreground.xml
new file mode 100644
index 00000000..a85ec69f
--- /dev/null
+++ b/core/base/src/main/res/drawable/ic_launcher_3_foreground.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_green.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_green.xml
new file mode 100644
index 00000000..7ab49ade
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_green.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_orange.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_orange.xml
new file mode 100644
index 00000000..9dbdd14d
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_orange.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_red.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_red.xml
new file mode 100644
index 00000000..f368821a
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_1_red.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_green.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_green.xml
new file mode 100644
index 00000000..65cea040
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_green.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_orange.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_orange.xml
new file mode 100644
index 00000000..96547697
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_orange.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_red.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_red.xml
new file mode 100644
index 00000000..6ed087c9
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_2_red.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_green.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_green.xml
new file mode 100644
index 00000000..d56b3738
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_green.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_orange.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_orange.xml
new file mode 100644
index 00000000..b42d62bc
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_orange.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_red.xml b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_red.xml
new file mode 100644
index 00000000..866e20de
--- /dev/null
+++ b/core/base/src/main/res/mipmap-anydpi-v26/ic_launcher_3_red.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_green.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_green.png
new file mode 100644
index 00000000..2a2737fd
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_green.png differ
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_orange.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_orange.png
new file mode 100644
index 00000000..0bf2874c
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_orange.png differ
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_red.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_red.png
new file mode 100644
index 00000000..4b9697a2
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_1_red.png differ
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_green.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_green.png
new file mode 100644
index 00000000..342ebf24
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_green.png differ
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_orange.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_orange.png
new file mode 100644
index 00000000..75160b4f
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_orange.png differ
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_red.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_red.png
new file mode 100644
index 00000000..1f502550
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_2_red.png differ
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_green.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_green.png
new file mode 100644
index 00000000..e54454f7
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_green.png differ
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_orange.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_orange.png
new file mode 100644
index 00000000..8c3f5f55
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_orange.png differ
diff --git a/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_red.png b/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_red.png
new file mode 100644
index 00000000..e07823f3
Binary files /dev/null and b/core/base/src/main/res/mipmap-hdpi/ic_launcher_3_red.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_green.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_green.png
new file mode 100644
index 00000000..6d28a7d5
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_green.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_orange.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_orange.png
new file mode 100644
index 00000000..7c6ecae6
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_orange.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_red.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_red.png
new file mode 100644
index 00000000..88bde280
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_1_red.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_green.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_green.png
new file mode 100644
index 00000000..07cfdad1
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_green.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_orange.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_orange.png
new file mode 100644
index 00000000..43de32e0
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_orange.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_red.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_red.png
new file mode 100644
index 00000000..aa27c24a
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_2_red.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_green.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_green.png
new file mode 100644
index 00000000..c564b0ff
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_green.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_orange.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_orange.png
new file mode 100644
index 00000000..46b86e9b
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_orange.png differ
diff --git a/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_red.png b/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_red.png
new file mode 100644
index 00000000..f5ccaeef
Binary files /dev/null and b/core/base/src/main/res/mipmap-mdpi/ic_launcher_3_red.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_green.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_green.png
new file mode 100644
index 00000000..837bd9f2
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_green.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_orange.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_orange.png
new file mode 100644
index 00000000..477861cf
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_red.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_red.png
new file mode 100644
index 00000000..550a7031
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_1_red.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_green.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_green.png
new file mode 100644
index 00000000..c898a7a2
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_green.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_orange.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_orange.png
new file mode 100644
index 00000000..8e5f90e4
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_red.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_red.png
new file mode 100644
index 00000000..292071f4
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_2_red.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_green.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_green.png
new file mode 100644
index 00000000..6965ba9e
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_green.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_orange.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_orange.png
new file mode 100644
index 00000000..b1ebafad
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_red.png b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_red.png
new file mode 100644
index 00000000..b52c03bb
Binary files /dev/null and b/core/base/src/main/res/mipmap-xhdpi/ic_launcher_3_red.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_green.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_green.png
new file mode 100644
index 00000000..1ff614e7
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_green.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_orange.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_orange.png
new file mode 100644
index 00000000..41c4b560
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_red.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_red.png
new file mode 100644
index 00000000..0d7066c6
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_1_red.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_green.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_green.png
new file mode 100644
index 00000000..4ca55d7d
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_green.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_orange.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_orange.png
new file mode 100644
index 00000000..126b3e38
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_red.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_red.png
new file mode 100644
index 00000000..772ee987
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_2_red.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_green.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_green.png
new file mode 100644
index 00000000..8a6381e4
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_green.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_orange.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_orange.png
new file mode 100644
index 00000000..2025c39c
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_red.png b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_red.png
new file mode 100644
index 00000000..c04b30d9
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxhdpi/ic_launcher_3_red.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_green.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_green.png
new file mode 100644
index 00000000..53c54fa7
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_green.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_orange.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_orange.png
new file mode 100644
index 00000000..c4dece23
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_red.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_red.png
new file mode 100644
index 00000000..f79e98a6
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_1_red.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_green.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_green.png
new file mode 100644
index 00000000..cff15555
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_green.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_orange.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_orange.png
new file mode 100644
index 00000000..33001066
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_red.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_red.png
new file mode 100644
index 00000000..75b5149c
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_2_red.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_green.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_green.png
new file mode 100644
index 00000000..0e30e949
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_green.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_orange.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_orange.png
new file mode 100644
index 00000000..f074609a
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_orange.png differ
diff --git a/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_red.png b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_red.png
new file mode 100644
index 00000000..4adf8b57
Binary files /dev/null and b/core/base/src/main/res/mipmap-xxxhdpi/ic_launcher_3_red.png differ
diff --git a/core/base/src/main/res/values/colors.xml b/core/base/src/main/res/values/colors.xml
new file mode 100644
index 00000000..e00bc481
--- /dev/null
+++ b/core/base/src/main/res/values/colors.xml
@@ -0,0 +1,23 @@
+
+
+
+ #186C31
+ #FF9800
+ #E91E63
+
\ No newline at end of file
diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml
index 1665a142..4b9d976a 100644
--- a/core/base/src/main/res/values/strings.xml
+++ b/core/base/src/main/res/values/strings.xml
@@ -1324,6 +1324,7 @@
Use colors from your wallpaper
Color scheme
Selected color
+ Selected icon
Loading…
@@ -1331,6 +1332,9 @@
Copied %1$s!
Cancel
OK
+ Apply
+ Warning!
+ This feature is unstable. App will be closed to apply changes. Restart your launcher if nothing changes. Reinstall app from phone settings if things go horribly. You have been warned!
Search units
No results found
Open settings
diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/AppIcon.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/AppIcon.kt
new file mode 100644
index 00000000..5d3b108c
--- /dev/null
+++ b/data/model/src/main/java/com/sadellie/unitto/data/model/AppIcon.kt
@@ -0,0 +1,47 @@
+/*
+ * Unitto is a unit converter for Android
+ * Copyright (c) 2023 Elshan Agaev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sadellie.unitto.data.model
+
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+
+private const val unitto = 0xFF186c31
+private const val white = 0xFFFFFFFF
+private const val red = 0xFFE91E63
+private const val orange = 0xFFFF9800
+
+enum class LauncherIcon(
+ val component: String,
+ @StringRes val labelString: Int = R.string.app_name,
+ @DrawableRes val foregroundDrawable: Int,
+ val foregroundColor: Long,
+ val backgroundColor: Long,
+) {
+ MAIN_DEFAULT( "com.sadellie.unitto.MainActivity", R.string.app_name, R.drawable.ic_launcher_1_foreground, white, unitto),
+ MAIN_RED( "com.sadellie.unitto.custom.MainActivity2", R.string.app_name, R.drawable.ic_launcher_1_foreground, white, red),
+ MAIN_ORANGE( "com.sadellie.unitto.custom.MainActivity3", R.string.app_name, R.drawable.ic_launcher_1_foreground, white, orange),
+
+ CALC1_DEFAULT( "com.sadellie.unitto.custom.MainActivity4", R.string.calculator, R.drawable.ic_launcher_2_foreground, white, unitto),
+ CALC1_RED( "com.sadellie.unitto.custom.MainActivity5", R.string.calculator, R.drawable.ic_launcher_2_foreground, white, red),
+ CALC1_ORANGE( "com.sadellie.unitto.custom.MainActivity6", R.string.calculator, R.drawable.ic_launcher_2_foreground, white, orange),
+
+ CALC2_DEFAULT( "com.sadellie.unitto.custom.MainActivity7", R.string.calculator, R.drawable.ic_launcher_3_foreground, white, unitto),
+ CALC2_RED( "com.sadellie.unitto.custom.MainActivity8", R.string.calculator, R.drawable.ic_launcher_3_foreground, white, red),
+ CALC2_ORANGE( "com.sadellie.unitto.custom.MainActivity9", R.string.calculator, R.drawable.ic_launcher_3_foreground, white, orange),
+}
diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt
index 9511a071..9b15672b 100644
--- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt
+++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt
@@ -32,6 +32,7 @@ import com.sadellie.unitto.core.base.Separator
import com.sadellie.unitto.core.base.TopLevelDestinations
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.model.AbstractUnit
+import com.sadellie.unitto.data.model.LauncherIcon
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.units.MyUnitIDS
@@ -62,6 +63,7 @@ import javax.inject.Inject
* @property unitConverterFavoritesOnly If true will show only units that are marked as favorite.
* @property unitConverterFormatTime If true will format time to be more human readable.
* @property unitConverterSorting Units list sorting mode.
+ * @property launcherIcon Current [LauncherIcon]/
*/
data class UserPreferences(
val themingMode: ThemingMode? = null,
@@ -81,6 +83,7 @@ data class UserPreferences(
val unitConverterFavoritesOnly: Boolean = false,
val unitConverterFormatTime: Boolean = false,
val unitConverterSorting: UnitsListSorting = UnitsListSorting.USAGE,
+ val launcherIcon: LauncherIcon = LauncherIcon.MAIN_DEFAULT
)
/**
@@ -108,6 +111,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
val UNIT_CONVERTER_FAVORITES_ONLY = booleanPreferencesKey("UNIT_CONVERTER_FAVORITES_ONLY_PREF_KEY")
val UNIT_CONVERTER_FORMAT_TIME = booleanPreferencesKey("UNIT_CONVERTER_FORMAT_TIME_PREF_KEY")
val UNIT_CONVERTER_SORTING = stringPreferencesKey("UNIT_CONVERTER_SORTING_PREF_KEY")
+ val LAUNCHER_ICON = stringPreferencesKey("LAUNCHER_ICON_PREF_KEY")
}
val userPreferencesFlow: Flow = dataStore.data
@@ -149,8 +153,8 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
val radianMode: Boolean = preferences[PrefsKeys.RADIAN_MODE] ?: true
val unitConverterFavoritesOnly: Boolean = preferences[PrefsKeys.UNIT_CONVERTER_FAVORITES_ONLY] ?: false
val unitConverterFormatTime: Boolean = preferences[PrefsKeys.UNIT_CONVERTER_FORMAT_TIME] ?: false
- val unitConverterSorting: UnitsListSorting = preferences[PrefsKeys.UNIT_CONVERTER_SORTING]?.let { UnitsListSorting.valueOf(it) }
- ?: UnitsListSorting.USAGE
+ val unitConverterSorting: UnitsListSorting = preferences[PrefsKeys.UNIT_CONVERTER_SORTING]?.let { UnitsListSorting.valueOf(it) } ?: UnitsListSorting.USAGE
+ val launcherIcon: LauncherIcon = preferences[PrefsKeys.LAUNCHER_ICON]?.let { LauncherIcon.valueOf(it) } ?: LauncherIcon.MAIN_DEFAULT
UserPreferences(
themingMode = themingMode,
@@ -169,7 +173,8 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
radianMode = radianMode,
unitConverterFavoritesOnly = unitConverterFavoritesOnly,
unitConverterFormatTime = unitConverterFormatTime,
- unitConverterSorting = unitConverterSorting
+ unitConverterSorting = unitConverterSorting,
+ launcherIcon = launcherIcon
)
}
@@ -346,4 +351,15 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
preferences[PrefsKeys.UNIT_CONVERTER_SORTING] = sorting.name
}
}
+
+ /**
+ * Update [UserPreferences.launcherIcon].
+ *
+ * @see UserPreferences.launcherIcon
+ */
+ suspend fun updateLauncherIcon(icon: LauncherIcon) {
+ dataStore.edit { preferences ->
+ preferences[PrefsKeys.LAUNCHER_ICON] = icon.name
+ }
+ }
}
diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt
index 92cb1f5c..c38fc7fa 100644
--- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt
+++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt
@@ -22,9 +22,11 @@ import androidx.compose.ui.graphics.Color
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.core.ui.Formatter
+import com.sadellie.unitto.data.model.LauncherIcon
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.unitgroups.UnitGroupsRepository
+import com.sadellie.unitto.data.userprefs.UserPreferences
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import io.github.sadellie.themmo.ThemingMode
@@ -41,10 +43,10 @@ class SettingsViewModel @Inject constructor(
private val userPrefsRepository: UserPreferencesRepository,
private val unitGroupsRepository: UnitGroupsRepository,
) : ViewModel() {
- var userPrefs = userPrefsRepository.userPreferencesFlow
+ val userPrefs = userPrefsRepository.userPreferencesFlow
.onEach { Formatter.setSeparator(it.separator) }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000),
- com.sadellie.unitto.data.userprefs.UserPreferences()
+ UserPreferences()
)
val shownUnitGroups = unitGroupsRepository.shownUnitGroups
val hiddenUnitGroups = unitGroupsRepository.hiddenUnitGroups
@@ -197,6 +199,16 @@ class SettingsViewModel @Inject constructor(
}
}
+ /**
+ * @see UserPreferencesRepository.updateLauncherIcon
+ */
+ fun updateLauncherIcon(icon: LauncherIcon, finished: () -> Unit?) {
+ viewModelScope.launch {
+ userPrefsRepository.updateLauncherIcon(icon)
+ finished()
+ }
+ }
+
/**
* Prevent from dragging over non-draggable items (headers and hidden)
*
diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/ThemesScreen.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/ThemesScreen.kt
index 8f40a7a0..6e693873 100644
--- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/ThemesScreen.kt
+++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/ThemesScreen.kt
@@ -18,8 +18,13 @@
package com.sadellie.unitto.feature.settings
+import android.app.Activity
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageManager
import android.os.Build
import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
@@ -29,36 +34,63 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Colorize
import androidx.compose.material.icons.filled.DarkMode
+import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Palette
+import androidx.compose.material.icons.filled.Warning
+import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.ui.R
import com.sadellie.unitto.core.ui.common.Header
import com.sadellie.unitto.core.ui.common.NavigateUpButton
-import com.sadellie.unitto.core.ui.common.UnittoListItem
-import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
-import com.sadellie.unitto.feature.settings.components.ColorSelector
import com.sadellie.unitto.core.ui.common.SegmentedButton
import com.sadellie.unitto.core.ui.common.SegmentedButtonRow
+import com.sadellie.unitto.core.ui.common.UnittoListItem
+import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
+import com.sadellie.unitto.data.model.LauncherIcon
+import com.sadellie.unitto.feature.settings.components.ColorSelector
+import com.sadellie.unitto.feature.settings.components.IconsSelector
import io.github.sadellie.themmo.ThemingMode
import io.github.sadellie.themmo.ThemmoController
+private val colorSchemes: List by lazy {
+ listOf(
+ Color(0xFFE91E63),
+ Color(0xFFFF9800),
+ Color(0xFF4CAF50),
+ Color(0xFF2196F3),
+ Color(0xFF9C27B0),
+ Color(0xFF5C76AA),
+ Color(0xFF756FAA),
+ Color(0xFF9E6C2A),
+ )
+}
+
@Composable
internal fun ThemesRoute(
navigateUpAction: () -> Unit = {},
themmoController: ThemmoController,
viewModel: SettingsViewModel
) {
+ val userPrefs = viewModel.userPrefs.collectAsStateWithLifecycle()
+
ThemesScreen(
navigateUpAction = navigateUpAction,
currentThemingMode = themmoController.currentThemingMode,
@@ -80,7 +112,11 @@ internal fun ThemesRoute(
onColorChange = {
themmoController.setCustomColor(it)
viewModel.updateCustomColor(it)
- }
+ },
+ currentIcon = userPrefs.value.launcherIcon,
+ onIconChange = { newValue, callback ->
+ viewModel.updateLauncherIcon(newValue, callback)
+ },
)
}
@@ -95,7 +131,10 @@ private fun ThemesScreen(
onAmoledThemeChange: (Boolean) -> Unit,
selectedColor: Color,
onColorChange: (Color) -> Unit,
+ currentIcon: LauncherIcon,
+ onIconChange: (LauncherIcon, () -> Unit) -> Unit
) {
+ val mContext = LocalContext.current
val themingModes by remember {
mutableStateOf(
mapOf(
@@ -105,12 +144,72 @@ private fun ThemesScreen(
)
)
}
+ var showIconChangeWarning: Boolean by rememberSaveable { mutableStateOf(false) }
+
+ var selectedLauncherIcon: LauncherIcon by remember { mutableStateOf(currentIcon) }
+ var selectedLauncherIconColor: Color by remember { mutableStateOf(Color(currentIcon.backgroundColor)) }
+ val selectedLauncherIconColorAnim = animateColorAsState(targetValue = selectedLauncherIconColor)
+ val launcherIcons: List by remember(selectedLauncherIcon) {
+ derivedStateOf {
+ LauncherIcon
+ .values()
+ .toList()
+ .filter { Color(it.backgroundColor) == selectedLauncherIconColor }
+ }
+ }
UnittoScreenWithLargeTopBar(
title = stringResource(R.string.theme_setting),
navigationIcon = { NavigateUpButton(navigateUpAction) }
) { paddingValues ->
LazyColumn(contentPadding = paddingValues) {
+
+ item {
+ ListItem(
+ headlineContent = { Text(stringResource(R.string.selected_color)) },
+ supportingContent = {
+ ColorSelector(
+ modifier = Modifier.padding(top = 12.dp),
+ selected = selectedLauncherIconColor,
+ onItemClick = {
+ selectedLauncherIconColor = it
+ },
+ colorSchemes = remember {
+ LauncherIcon.values().map { Color(it.backgroundColor) }
+ .distinct()
+ },
+ )
+ },
+ modifier = Modifier.padding(start = 40.dp)
+ )
+ }
+
+ item {
+ ListItem(
+ headlineContent = { Text(stringResource(R.string.selected_launcher_icon)) },
+ supportingContent = {
+ IconsSelector(
+ modifier = Modifier.padding(top = 12.dp),
+ selectedColor = selectedLauncherIconColorAnim.value,
+ icons = launcherIcons,
+ selectedIcon = selectedLauncherIcon,
+ onIconChange = { selectedLauncherIcon = it }
+ )
+ },
+ modifier = Modifier.padding(start = 40.dp)
+ )
+ }
+
+ item {
+ FilledTonalButton(
+ modifier = Modifier.padding(start = 56.dp),
+ enabled = currentIcon != selectedLauncherIcon,
+ onClick = { showIconChangeWarning = true },
+ ) {
+ Text(stringResource(R.string.apply_label))
+ }
+ }
+
item {
ListItem(
leadingContent = {
@@ -190,7 +289,9 @@ private fun ThemesScreen(
ColorSelector(
modifier = Modifier.padding(top = 12.dp),
selected = selectedColor,
- onItemClick = onColorChange
+ onItemClick = onColorChange,
+ colorSchemes = colorSchemes,
+ defaultColor = Color(0xFF186c31)
)
},
modifier = Modifier.padding(start = 40.dp)
@@ -199,6 +300,63 @@ private fun ThemesScreen(
}
}
}
+
+ if (showIconChangeWarning) {
+ AlertDialog(
+ icon = {
+ Icon(Icons.Default.Warning, stringResource(R.string.warning_label))
+ },
+ title = {
+ Text(stringResource(R.string.warning_label))
+ },
+ text = {
+ Text(
+ stringResource(R.string.icon_change_warning)
+ )
+ },
+ confirmButton = {
+ TextButton(
+ onClick = {
+ onIconChange(selectedLauncherIcon) {
+ mContext.changeIcon(selectedLauncherIcon)
+ (mContext as Activity).finish()
+ }
+ showIconChangeWarning = false
+ }
+ ) {
+ Text(stringResource(R.string.apply_label))
+ }
+ },
+ dismissButton = {
+ TextButton(
+ onClick = { showIconChangeWarning = false }
+ ) {
+ Text(stringResource(R.string.cancel_label))
+ }
+ },
+ onDismissRequest = { showIconChangeWarning = false }
+ )
+ }
+}
+
+private fun Context.changeIcon(newIcon: LauncherIcon) {
+ // Enable new icon
+ packageManager.setComponentEnabledSetting(
+ ComponentName(this, newIcon.component),
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP
+ )
+
+ val packages = LauncherIcon.values().toList() - newIcon
+
+ // We make sure that other icons are disabled to avoid bugs.
+ packages.forEach {
+ packageManager.setComponentEnabledSetting(
+ ComponentName(this, it.component),
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP
+ )
+ }
}
@Preview
@@ -213,6 +371,8 @@ private fun Preview() {
isAmoledThemeEnabled = false,
onAmoledThemeChange = {},
selectedColor = Color.Unspecified,
- onColorChange = {}
+ onColorChange = {},
+ currentIcon = LauncherIcon.MAIN_DEFAULT,
+ onIconChange = {_,_->}
)
}
diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/ColorCheckbox.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/ColorCheckbox.kt
index d3585466..4a38d6d3 100644
--- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/ColorCheckbox.kt
+++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/ColorCheckbox.kt
@@ -30,7 +30,8 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
-import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.CircleShape
@@ -41,11 +42,9 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.unit.dp
@@ -55,34 +54,24 @@ internal fun ColorSelector(
modifier: Modifier = Modifier,
selected: Color,
onItemClick: (Color) -> Unit,
+ colorSchemes: List,
+ defaultColor: Color? = null
) {
- val colorSchemes: List by remember {
- mutableStateOf(
- listOf(
- Color(0xFFE91E63),
- Color(0xFFFF9800),
- Color(0xFF4CAF50),
- Color(0xFF2196F3),
- Color(0xFF9C27B0),
- Color(0xFF5C76AA),
- Color(0xFF756FAA),
- Color(0xFF9E6C2A),
- )
- )
- }
-
LazyRow(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
- // Default, Unitto colors
- item {
- ColorCheckbox(
- color = Color(0xFF186c31),
- selected = Color.Unspecified == selected,
- onClick = { onItemClick(Color.Unspecified) }
- )
+ if (defaultColor != null) {
+ // Default, Unitto colors
+ item {
+ ColorCheckbox(
+ color = defaultColor,
+ selected = Color.Unspecified == selected,
+ onClick = { onItemClick(Color.Unspecified) }
+ )
+ }
}
+
colorSchemes.forEach {
item {
ColorCheckbox(
@@ -103,20 +92,20 @@ private fun ColorCheckbox(
) {
Box(
modifier = Modifier
- .clickable(onClick = onClick)
- .background(
- MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp),
- RoundedCornerShape(25)
- )
.width(72.dp)
- .aspectRatio(1f),
+ .clip(RoundedCornerShape(25))
+ .clickable(onClick = onClick)
+ .background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)),
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier
- .background(color, CircleShape)
- .size(54.dp)
- .border(1.dp, Color.Black.copy(0.5f), CircleShape)
+ .fillMaxSize()
+ .aspectRatio(1f)
+ .padding(8.dp)
+ .clip(CircleShape)
+ .background(color)
+ .border(1.dp, Color.Black.copy(0.5f), CircleShape),
)
AnimatedVisibility(
visible = selected,
diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/IconSelector.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/IconSelector.kt
new file mode 100644
index 00000000..24744a47
--- /dev/null
+++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/IconSelector.kt
@@ -0,0 +1,144 @@
+/*
+ * Unitto is a unit converter for Android
+ * Copyright (c) 2023 Elshan Agaev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sadellie.unitto.feature.settings.components
+
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.scaleIn
+import androidx.compose.animation.scaleOut
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Check
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.surfaceColorAtElevation
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.scale
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.luminance
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.sadellie.unitto.data.model.LauncherIcon
+
+
+@Composable
+internal fun IconsSelector(
+ modifier: Modifier,
+ selectedColor: Color,
+ icons: List,
+ selectedIcon: LauncherIcon,
+ onIconChange: (LauncherIcon) -> Unit
+) {
+ LazyRow(
+ modifier = modifier,
+ horizontalArrangement = Arrangement.spacedBy(8.dp)) {
+ items(icons) {
+ IconCheckbox(
+ iconRes = it.foregroundDrawable,
+ foregroundColor = Color(it.foregroundColor),
+ backGroundColor = selectedColor,
+ selected = it == selectedIcon,
+ onClick = { onIconChange(it) },
+ label = it.labelString
+ )
+ }
+ }
+}
+
+@Composable
+private fun IconCheckbox(
+ @DrawableRes iconRes: Int,
+ foregroundColor: Color,
+ backGroundColor: Color,
+ @StringRes label: Int,
+ selected: Boolean,
+ onClick: () -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .width(72.dp)
+ .clip(RoundedCornerShape(25))
+ .clickable(onClick = onClick)
+ .background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp))
+ .padding(bottom = 8.dp)
+ ,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .aspectRatio(1f)
+ .padding(8.dp)
+ .clip(CircleShape)
+ .background(backGroundColor)
+ .border(1.dp, Color.Black.copy(0.5f), CircleShape),
+ contentAlignment = Alignment.Center
+ ) {
+ Icon(
+ painter = painterResource(iconRes),
+ contentDescription = null,
+ tint = foregroundColor,
+ modifier = Modifier.scale(1.5f)
+ )
+
+ // bug in language, need to call it like this
+ androidx.compose.animation.AnimatedVisibility(
+ visible = selected,
+ enter = fadeIn(tween(250)) + scaleIn(tween(150)),
+ exit = fadeOut(tween(250)) + scaleOut(tween(150)),
+ ) {
+ Box(
+ modifier = Modifier
+ .background(MaterialTheme.colorScheme.scrim.copy(0.5f))
+ .fillMaxSize(),
+ contentAlignment = Alignment.Center
+ ) {
+ Icon(
+ imageVector = Icons.Default.Check,
+ contentDescription = null,
+ tint = if (backGroundColor.luminance() > 0.5) Color.Black else Color.White,
+ )
+ }
+ }
+ }
+
+ Text(stringResource(label), style = MaterialTheme.typography.labelSmall)
+ }
+}