diff --git a/.gitignore b/.gitignore
index 2b75303..503d55c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,5 @@
/build
/captures
.externalNativeBuild
+lib/build/generated
+lib/build
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 34dc27c..0000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
index 79ee123..a55e7a1 100644
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..ef688f2
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dictionaries/.xml b/.idea/dictionaries/.xml
deleted file mode 100644
index 68cf6a6..0000000
--- a/.idea/dictionaries/.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- bindable
- snackbar
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 97626ba..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 5d6f65c..d7d05b2 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,18 +1,25 @@
+
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..dc07417
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 10467e7..561e5d5 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,16 @@
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 2588e5f..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/Crash/.gitignore b/Crash/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Crash/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Crash/build.gradle b/Crash/build.gradle
new file mode 100644
index 0000000..362cc5f
--- /dev/null
+++ b/Crash/build.gradle
@@ -0,0 +1,40 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+
+
+android {
+ compileSdkVersion 31
+
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 31
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles "consumer-rules.pro"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.6.0'
+ implementation 'androidx.appcompat:appcompat:1.3.1'
+ implementation 'com.google.android.material:material:1.4.0'
+ implementation 'com.github.Omega-R.OmegaIntentBuilder:core:1.3.4'
+ implementation "com.squareup.retrofit2:retrofit:2.9.0"
+
+ testImplementation 'junit:junit:4.+'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+}
\ No newline at end of file
diff --git a/Crash/consumer-rules.pro b/Crash/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/Crash/proguard-rules.pro b/Crash/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Crash/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/Crash/src/androidTest/java/com/omega_r/base/crash/ExampleInstrumentedTest.kt b/Crash/src/androidTest/java/com/omega_r/base/crash/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..1b150ea
--- /dev/null
+++ b/Crash/src/androidTest/java/com/omega_r/base/crash/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.omega_r.base.crash
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.omega_r.base.crash.test", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Crash/src/main/AndroidManifest.xml b/Crash/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..71b59ec
--- /dev/null
+++ b/Crash/src/main/AndroidManifest.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Crash/src/main/java/com/omega_r/base/crash/CrashInitProvider.kt b/Crash/src/main/java/com/omega_r/base/crash/CrashInitProvider.kt
new file mode 100644
index 0000000..4fe06b3
--- /dev/null
+++ b/Crash/src/main/java/com/omega_r/base/crash/CrashInitProvider.kt
@@ -0,0 +1,32 @@
+package com.omega_r.base.crash
+
+import android.app.Application
+import android.content.ContentProvider
+import android.content.ContentValues
+import android.database.Cursor
+import android.net.Uri
+import com.omega_r.base.crash.CrashSender.Companion
+
+class CrashInitProvider: ContentProvider() {
+
+ override fun onCreate(): Boolean {
+ (context?.applicationContext as? Application)?.also(Companion::setup)
+ return false
+ }
+
+ override fun query(
+ uri: Uri,
+ projection: Array?,
+ selection: String?,
+ selectionArgs: Array?,
+ sortOrder: String?
+ ): Cursor? = null
+
+ override fun getType(uri: Uri): String? = null
+
+ override fun insert(uri: Uri, values: ContentValues?): Uri? = null
+
+ override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int = 0
+
+ override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array?): Int = 0
+}
\ No newline at end of file
diff --git a/Crash/src/main/java/com/omega_r/base/crash/CrashReport.kt b/Crash/src/main/java/com/omega_r/base/crash/CrashReport.kt
new file mode 100644
index 0000000..df272f8
--- /dev/null
+++ b/Crash/src/main/java/com/omega_r/base/crash/CrashReport.kt
@@ -0,0 +1,10 @@
+package com.omega_r.base.crash
+
+import android.graphics.Bitmap
+
+
+class CrashReport(
+ val info: Map>,
+ val stacktrace: String,
+ val screenshot: Bitmap?
+)
\ No newline at end of file
diff --git a/Crash/src/main/java/com/omega_r/base/crash/CrashSender.kt b/Crash/src/main/java/com/omega_r/base/crash/CrashSender.kt
new file mode 100644
index 0000000..a2759d2
--- /dev/null
+++ b/Crash/src/main/java/com/omega_r/base/crash/CrashSender.kt
@@ -0,0 +1,188 @@
+package com.omega_r.base.crash
+
+import android.annotation.SuppressLint
+import android.app.Activity
+import android.app.Application
+import android.content.Context
+import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.os.Build
+import android.os.Bundle
+import android.view.View
+import androidx.core.content.pm.PackageInfoCompat
+import java.io.PrintWriter
+import java.io.StringWriter
+import java.lang.Exception
+import java.lang.ref.WeakReference
+import java.util.concurrent.CopyOnWriteArrayList
+import java.util.concurrent.CopyOnWriteArraySet
+
+
+class CrashSender(context: Context) : Thread.UncaughtExceptionHandler,
+ Application.ActivityLifecycleCallbacks {
+
+ companion object {
+
+ val senderWays = CopyOnWriteArraySet().apply {
+ add(EmailSenderCrashWay())
+ }
+
+ val reporters = CopyOnWriteArraySet()
+
+ @SuppressLint("StaticFieldLeak")
+ private var singleCrashSender: CrashSender? = null
+
+ fun setup(application: Application) {
+ singleCrashSender?.let {
+ application.unregisterActivityLifecycleCallbacks(it)
+ OmegaUncaughtExceptionHandler.remove(it)
+ }
+ val handler = CrashSender(application)
+ OmegaUncaughtExceptionHandler.add(handler)
+ application.registerActivityLifecycleCallbacks(handler)
+ singleCrashSender = handler
+ }
+
+
+ }
+
+ private val context = context.applicationContext
+ private var activityWeakRef: WeakReference? = null
+
+ override fun uncaughtException(thread: Thread, error: Throwable) {
+ try {
+ val currentActivity = activityWeakRef?.get()
+ val screenshotBitmap = currentActivity?.createScreenshotBitmap()
+ val crashReport = createCrashReport(currentActivity, error, screenshotBitmap)
+
+ senderWays.forEach {
+ try {
+ it.send(context, currentActivity, error, crashReport)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ screenshotBitmap?.recycle()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ private fun createCrashReport(currentActivity: Activity?, error: Throwable, screenshotBitmap: Bitmap?): CrashReport {
+ val info = mutableMapOf>().apply {
+ putGroupMap("OS", getOsInfo())
+ putGroupMap("Application", getApplicationInfo())
+ putGroupMap("Activity", getActivityInfo(currentActivity))
+ }
+
+ reporters.forEach {
+ it.report(info)
+ }
+
+ return CrashReport(info, getStackTrace(error) ?: "", screenshotBitmap)
+ }
+
+ private fun MutableMap>.putGroupMap(groupName: String, map: Map?) {
+ if (map?.isNotEmpty() == true) {
+ put(groupName, map)
+ }
+ }
+
+ private fun getActivityInfo(currentActivity: Activity?): Map? {
+ if (currentActivity != null) {
+ val title = currentActivity.title
+
+ return mutableMapOf().also { map ->
+ currentActivity::class.simpleName?.let { map["ClassName"] = it }
+ title?.let { map["title"] = title.toString() }
+ }
+ }
+ return null
+ }
+
+ private fun getOsInfo(): Map? {
+ return mapOf("Version" to "Android ${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})")
+ }
+
+
+ private fun getApplicationInfo(): Map? {
+ try {
+ with(context.packageManager.getPackageInfo(context.packageName, 0)) {
+ return mapOf(
+ "Package" to packageName,
+ "Version Name" to versionName,
+ "Version Code" to PackageInfoCompat.getLongVersionCode(this).toString()
+ )
+ }
+ } catch (e: PackageManager.NameNotFoundException) {
+ return null // Ignored, this shouldn't happen
+ }
+ }
+
+ private fun getStackTrace(error: Throwable): String? {
+ val stack: Array = error.stackTrace
+ if (stack.isNotEmpty()) {
+ val stringWriter = StringWriter()
+ val printWriter = PrintWriter(stringWriter)
+ error.printStackTrace(printWriter)
+ return stringWriter.toString()
+ }
+ return null
+ }
+
+ private fun Activity.createScreenshotBitmap(): Bitmap? {
+ val window = window ?: return null
+ val view = window.decorView
+ return getBitmapFromView(view)
+ }
+
+ private fun getBitmapFromView(view: View): Bitmap? {
+ val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(bitmap)
+ view.draw(canvas)
+ return bitmap
+ }
+
+ override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
+ // nothing
+ }
+
+ override fun onActivityStarted(activity: Activity) {
+ // nothing
+ }
+
+ override fun onActivityResumed(activity: Activity) {
+ activityWeakRef = WeakReference(activity)
+ }
+
+ override fun onActivityPaused(activity: Activity) {
+ activityWeakRef = null
+ }
+
+ override fun onActivityStopped(activity: Activity) {
+ // nothing
+ }
+
+ override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
+ // nothing
+ }
+
+ override fun onActivityDestroyed(activity: Activity) {
+ // nothing
+ }
+
+ interface SenderCrashWay {
+
+ fun send(context: Context, currentActivity: Activity?, error: Throwable, crashReport: CrashReport)
+
+ }
+
+ interface CrashReporter {
+
+ fun report(map: MutableMap>)
+
+ }
+
+}
\ No newline at end of file
diff --git a/Crash/src/main/java/com/omega_r/base/crash/EmailSenderCrashWay.kt b/Crash/src/main/java/com/omega_r/base/crash/EmailSenderCrashWay.kt
new file mode 100644
index 0000000..b59b96e
--- /dev/null
+++ b/Crash/src/main/java/com/omega_r/base/crash/EmailSenderCrashWay.kt
@@ -0,0 +1,54 @@
+package com.omega_r.base.crash
+
+import android.app.Activity
+import android.content.Context
+import com.omega_r.libs.omegaintentbuilder.OmegaIntentBuilder
+import java.io.PrintWriter
+import java.io.StringWriter
+
+class EmailSenderCrashWay(private val emailTo: String? = null) : CrashSender.SenderCrashWay {
+
+ override fun send(context: Context, currentActivity: Activity?, error: Throwable, crashReport: CrashReport) {
+ OmegaIntentBuilder.share()
+ .subject("~ CRASH REPORT ~")
+ .text(createBodyText(crashReport))
+ .apply {
+ crashReport.screenshot?.let { bitmap(crashReport.screenshot) }
+ emailTo?.let { emailTo(emailTo) }
+ }
+ .startActivity(context)
+ }
+
+ private fun createBodyText(crashReport: CrashReport): String {
+ val stringWriter = StringWriter()
+ with(PrintWriter(stringWriter)) {
+ printGroupMap(crashReport.info)
+ printGroupSingleValue("Stack Trace", crashReport.stacktrace)
+ }
+ return stringWriter.toString()
+ }
+
+
+ private fun PrintWriter.printGroupMap(map: Map>) {
+ map.forEach {
+ println("[${it.key}]: ")
+ printMap(it.value)
+ println()
+ }
+ }
+
+ private fun PrintWriter.printGroupSingleValue(groupName: String, value: String) {
+ if (value.isNotEmpty()) {
+ println("[$groupName]: ")
+ println(value)
+ println()
+ }
+ }
+
+ private fun PrintWriter.printMap(map: Map) {
+ map.forEach {
+ println(" - ${it.key}: ${it.value}")
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Crash/src/main/java/com/omega_r/base/crash/OmegaUncaughtExceptionHandler.kt b/Crash/src/main/java/com/omega_r/base/crash/OmegaUncaughtExceptionHandler.kt
new file mode 100644
index 0000000..42e9a39
--- /dev/null
+++ b/Crash/src/main/java/com/omega_r/base/crash/OmegaUncaughtExceptionHandler.kt
@@ -0,0 +1,35 @@
+package com.omega_r.base.crash
+
+import java.lang.Thread.UncaughtExceptionHandler
+import java.util.concurrent.CopyOnWriteArraySet
+
+object OmegaUncaughtExceptionHandler : UncaughtExceptionHandler {
+
+ private var defaultHandler: UncaughtExceptionHandler? = null
+
+ private val uncaughtExceptionHandlers = CopyOnWriteArraySet()
+
+ init {
+ defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
+ Thread.setDefaultUncaughtExceptionHandler(this)
+ }
+
+ override fun uncaughtException(thread: Thread, error: Throwable) {
+ try {
+ uncaughtExceptionHandlers.forEach {
+ it.uncaughtException(thread, error)
+ }
+ } finally {
+ defaultHandler?.uncaughtException(thread, error)
+ }
+ }
+
+ fun add(handler: UncaughtExceptionHandler) {
+ uncaughtExceptionHandlers.add(handler)
+ }
+
+ fun remove(handler: UncaughtExceptionHandler) {
+ uncaughtExceptionHandlers.remove(handler)
+ }
+
+}
\ No newline at end of file
diff --git a/Crash/src/main/java/com/omega_r/base/crash/RocketChatSenderCrashWay.kt b/Crash/src/main/java/com/omega_r/base/crash/RocketChatSenderCrashWay.kt
new file mode 100644
index 0000000..86d4979
--- /dev/null
+++ b/Crash/src/main/java/com/omega_r/base/crash/RocketChatSenderCrashWay.kt
@@ -0,0 +1,92 @@
+package com.omega_r.base.crash
+
+import android.app.Activity
+import android.content.Context
+import android.util.Log
+import okhttp3.*
+import org.json.JSONObject
+import java.io.IOException
+
+
+class RocketChatSenderCrashWay(private val webHookUrl: String) : CrashSender.SenderCrashWay {
+
+ companion object {
+ private val MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8")
+ }
+
+ private val client = OkHttpClient()
+
+ override fun send(context: Context, currentActivity: Activity?, error: Throwable, crashReport: CrashReport) {
+ val content = """
+ {
+ "text": ${JSONObject.quote("```\n" + crashReport.stacktrace + "\n```")},
+ ${getJsonAttachments(crashReport.info)}
+
+ }
+ """.trimIndent()
+ val body = RequestBody.create(
+ MEDIA_TYPE_JSON,
+ content
+ )
+
+ val request: Request = Request.Builder()
+ .post(body)
+ .url(webHookUrl)
+ .build()
+
+
+ client.newCall(request).enqueue(object : Callback {
+
+ override fun onFailure(call: Call, e: IOException) {
+ e.printStackTrace()
+ }
+
+ override fun onResponse(call: Call, response: Response) {
+ // nothing
+ }
+
+ })
+
+ Thread.sleep(1)
+
+ }
+
+ private fun getJsonFields(map: Map): String {
+ val entries = map.entries
+ return StringBuilder().apply {
+ append("\"fields\":[")
+ entries.forEachIndexed { index, entry ->
+ if (index > 0) {
+ append(",")
+ }
+ append("{")
+ append("\"title\": ${JSONObject.quote(entry.key)}, ")
+ append("\"value\": ${JSONObject.quote(entry.value)}")
+ append("}")
+
+
+ }
+ append("]")
+ }.toString()
+ }
+
+ private fun getJsonAttachments(map: Map>): String {
+ val entries = map.entries
+ return StringBuilder().apply {
+ append("\"attachments\":[")
+ entries.forEachIndexed { index, entry ->
+ if (index > 0) {
+ append(",")
+ }
+ append("{")
+ append("\"title\": ${JSONObject.quote(entry.key)}, ")
+ append(getJsonFields(entry.value))
+ append("}")
+
+ }
+ append("]")
+ }.toString()
+
+ }
+
+}
\ No newline at end of file
diff --git a/Crash/src/test/java/com/omega_r/base/crash/ExampleUnitTest.kt b/Crash/src/test/java/com/omega_r/base/crash/ExampleUnitTest.kt
new file mode 100644
index 0000000..ad8dd7a
--- /dev/null
+++ b/Crash/src/test/java/com/omega_r/base/crash/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.omega_r.base.crash
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index abc2b92..6dac785 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,18 @@
-# OmegaBase
\ No newline at end of file
+[](https://jitpack.io/#Omega-R/OmegaBase)
+[](https://opensource.org/licenses/MIT)
+# OmegaBase
+
+
+Add it in your root build.gradle at the end of repositories:
+
+ allprojects {
+ repositories {
+ ...
+ maven { url 'https://jitpack.io' }
+ }
+ }
+Step 2. Add the dependency
+
+ dependencies {
+ implementation 'com.github.Omega-R:OmegaBase:1.3.1'
+ }
diff --git a/lib/.gitignore b/annotations/.gitignore
similarity index 100%
rename from lib/.gitignore
rename to annotations/.gitignore
diff --git a/annotations/build.gradle b/annotations/build.gradle
new file mode 100644
index 0000000..178a53a
--- /dev/null
+++ b/annotations/build.gradle
@@ -0,0 +1,38 @@
+apply plugin: 'kotlin'
+apply plugin: 'maven-publish'
+
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+}
+
+publishing {
+ publications {
+ release(MavenPublication) {
+ groupId = 'com.github.Omega-R.OmegaBase'
+ artifactId = 'annotations'
+ version project.hasProperty('version') ? project.version : gradle.gitHash()
+
+ afterEvaluate {
+ from components.java
+ }
+ }
+ }
+ repositories {
+ maven {
+ url gradle.nexusUrl
+ credentials {
+ username gradle.nexusUsername
+ password gradle.nexusPassword
+ }
+ }
+ }
+
+ dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation "org.jetbrains.kotlin:kotlin-reflect"
+ //noinspection DifferentStdlibGradleVersion
+ }
+
+}
diff --git a/annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt b/annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt
new file mode 100644
index 0000000..7b992f8
--- /dev/null
+++ b/annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt
@@ -0,0 +1,5 @@
+package com.omega_r.base.annotations
+
+@Retention(AnnotationRetention.SOURCE)
+@Target(allowedTargets = [AnnotationTarget.CLASS])
+annotation class AppOmegaRepository
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 39c8e6e..1d34a20 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,14 +1,16 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
-apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
+apply plugin: 'com.google.devtools.ksp'
+apply plugin: 'kotlin-parcelize'
android {
- compileSdkVersion 28
+ compileSdk 33
defaultConfig {
applicationId "com.omega_r.omegabase.simple"
- minSdkVersion 14
- targetSdkVersion 28
+ multiDexEnabled true
+ minSdkVersion 21
+ targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -19,22 +21,52 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+
+ packagingOptions {
+ pickFirst 'META-INF/kotlinx-io.kotlin_module'
+ pickFirst 'META-INF/atomicfu.kotlin_module'
+ pickFirst 'META-INF/kotlinx-coroutines-io.kotlin_module'
+ pickFirst 'META-INF/library_release.kotlin_module'
+ pickFirst 'META-INF/core_release.kotlin_module'
+ }
+
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+
+
+}
+
+kotlin {
+ sourceSets {
+ main.kotlin.srcDirs += 'build/generated/ksp/debug/kotlin'
+ }
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
- implementation 'androidx.core:core-ktx:1.1.0-alpha05'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'
- implementation project(':lib')
- implementation 'com.github.Omega-R:OmegaRecyclerView:1.9.4'
- implementation 'com.github.Omega-R.OmegaMoxy:moxy:1.5.7'
- implementation 'com.github.Omega-R.OmegaMoxy:moxy-androidx:1.5.7'
- kapt 'com.github.Omega-R.OmegaMoxy:moxy-compiler:1.5.7'
- implementation 'com.github.Omega-R.OmegaTypes:omegatypes:0.0.7'
+ implementation 'androidx.appcompat:appcompat:1.4.0'
+ implementation 'androidx.core:core-ktx:1.7.0'
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlinCorutines_version}"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${kotlinCorutines_version}"
+ implementation 'androidx.constraintlayout:constraintlayout:2.2.0-alpha04'
+ implementation 'androidx.recyclerview:recyclerview:1.2.1'
+ implementation "com.github.Omega-R.OmegaRecyclerView:omegarecyclerview:${omegaRecyclerView}"
+
+ implementation project(':core')
+
+ ksp "com.github.Omega-R.OmegaMoxy:moxy-compiler:${omegaMoxy_version}"
+ kapt project(':processor')
+
+ implementation 'com.github.bumptech.glide:glide:4.9.0'
+
+ testImplementation 'junit:junit:4.13-beta-3'
+ androidTestImplementation 'androidx.test:runner:1.3.0-alpha02'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha02'
+ implementation 'com.google.android.material:material:1.5.0-beta01'
+
+ ksp project(":mvp-processor")
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e29d537..fa3639f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,14 +2,22 @@
+
+
+
-
+
+
+
+
diff --git a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt
new file mode 100644
index 0000000..cc161a4
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt
@@ -0,0 +1,35 @@
+package com.omega_r.base.simple
+
+import com.omega_r.base.annotations.AppOmegaRepository
+import com.omega_r.base.data.OmegaRepository.Strategy
+import kotlinx.coroutines.channels.ReceiveChannel
+
+@AppOmegaRepository
+interface InspectionRepository : ParentRepository {
+
+ val isAuth: Boolean?
+ get() = true
+ var age: Int
+
+ val inspectionUpdateChannel: ReceiveChannel>
+
+ suspend fun getInspectionsChannel(strategy: Strategy, index: Int): ReceiveChannel
+
+ suspend fun getInspections(strategy: Strategy, index: Int): String
+
+ suspend fun getInspections(pair: Pair, second: Boolean)
+
+ suspend fun pair(): Pair?
+
+ suspend fun returnInt(): Int?
+
+ suspend fun returnBoolean(): Boolean {
+ return true
+ }
+
+ fun clearCache()
+
+ // TODO future code generation
+// suspend fun lambda(func: (String) -> Boolean): Int
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/MainActivity.kt b/app/src/main/java/com/omega_r/base/simple/MainActivity.kt
index 5b0df98..e4787f7 100644
--- a/app/src/main/java/com/omega_r/base/simple/MainActivity.kt
+++ b/app/src/main/java/com/omega_r/base/simple/MainActivity.kt
@@ -1,29 +1,121 @@
package com.omega_r.base.simple
-import com.omega_r.base.adapters.OmegaAutoAdapter
-import com.omega_r.base.annotations.OmegaContentView
+import android.content.pm.PackageManager
+import android.os.Bundle
+import android.util.Log
+import android.view.MenuItem
+import android.view.View
+import androidx.recyclerview.widget.RecyclerView
+import com.omega_r.adapters.OmegaListAdapter
import com.omega_r.base.components.OmegaActivity
-import com.omega_r.libs.omegarecyclerview.OmegaRecyclerView
+import com.omega_r.bind.adapters.OmegaAutoAdapter
+import com.omega_r.bind.delegates.IdHolder
+import com.omega_r.bind.model.binders.bindImage
import com.omega_r.libs.omegatypes.Text
+import com.omega_r.libs.omegatypes.image.Image
+import com.omega_r.libs.omegatypes.image.from
-@OmegaContentView(R.layout.activity_main)
-class MainActivity : OmegaActivity(), OmegaAutoAdapter.Callback {
+class MainActivity : OmegaActivity(R.layout.activity_main), MainView {
- private val adapter = OmegaAutoAdapter.create- (R.layout.item_test) {
- bind(R.id.textview_test, Item::text)
+ override val presenter: MainPresenter by providePresenter()
+
+ private val adapter = OmegaAutoAdapter.create(R.layout.item_test_3, ::onClickItem) {
+ bindImage(R.id.imageview)
}.apply {
- callback = this@MainActivity
+ watcher = OmegaListAdapter.ImagePreloadWatcher(this)
+ list = listOf(
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?156"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?256"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?35"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?45"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?56"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?64"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?79"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?85"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?91"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?102"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?113"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?124"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?135"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?146"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?1578"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?169"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?174"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?185"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?1956"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?201"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?212"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?2212"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?231"),
+ Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?242")
+ )
+ }
+
+ private val recyclerView: RecyclerView by bind(R.id.recyclerview, adapter) {
+ recyclerView.setHasFixedSize(true)
}
- private val recyclerView: OmegaRecyclerView by bind(R.id.recyclerview) {
- this@MainActivity.adapter.list = listOf(Item(), Item())
- adapter = this@MainActivity.adapter
+ private val maps: Map by bind(Field.values()) {
+ //showToast(Text.from(it.id.toString()))
}
- override fun onClickItem(item: Item, position: Int) {
- showToast(Text.from("Click $position"))
+ override var list: String = ""
+
+ override var enabled: Boolean
+ get() = false
+ set(value) {
+ println("YES")
+ }
+
+ private val menuItem: MenuItem? by bindMenuItem(R.id.action_test)
+
+ private var imageMenuItem: Image by bindIconMenuItem(R.id.action_test)
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+// title = this[EXTRA_TITLE]
+ setClickListener(R.id.button) {
+ showToast(Text.from("Test"))
+ }
+ setMenu(R.menu.menu_main, R.id.action_test to { showToast(Text.from("Test")) })
+ imageMenuItem = Image.from(R.drawable.ic_error_omega)
+ val applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
+ val metaData = applicationInfo.metaData
+ val email = metaData?.getString("CRASH_SENDER_EMAIL")
+ Log.v("Test123", email.toString())
+ }
+
+ private fun onClickItem(item: Image) {
+ showToast(Text.from("Click $item"))
+ throw NullPointerException()
+// ActivityLauncher.launch(this, null, createLauncher("1"), createLauncher("2"))
+
+// createLauncher("1").launch(this, createLauncher("2"))
+ }
+
+ data class Item(
+ val text: String = "123",
+ val list: List = listOf(
+ SubItem(),
+ SubItem(),
+ SubItem(),
+ SubItem(),
+ SubItem(),
+ SubItem(),
+ SubItem(),
+ SubItem(),
+ SubItem(),
+ SubItem()
+ )
+ )
+
+ data class SubItem(val text: String = "123")
+
+ enum class Field(override val id: Int) : IdHolder {
+ ITEM1(R.id.recyclerview),
+ ITEM2(R.id.recyclerview),
}
- data class Item (val text: String = "123")
}
diff --git a/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt b/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt
new file mode 100644
index 0000000..83e130d
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt
@@ -0,0 +1,65 @@
+package com.omega_r.base.simple
+
+import android.os.SystemClock
+import com.omega_r.base.mvp.presenters.OmegaPresenter
+import com.omega_r.base.simple.dialog_fragment.DialogScreenFactory
+import com.omega_r.libs.omegatypes.Text
+import java.io.Serializable
+
+/**
+ * Created by Anton Knyazev on 06.05.19.
+ */
+typealias TestEntity2 = TestEntity
+class MainPresenter(testEntity: TestEntity?, t2: TestEntity2?): OmegaPresenter() {
+
+ companion object {
+ var lastTime = SystemClock.elapsedRealtime()
+ }
+
+ init {
+
+ val time = (SystemClock.elapsedRealtime() - lastTime)
+ lastTime = SystemClock.elapsedRealtime()
+
+ if (testEntity == null) {
+ MainScreenFactory.createLauncher(TestEntity(), TestEntity()).launch()
+ } else {
+ println("TestAnt: $time")
+ viewState.showToast(Text.from(time.toString()))
+
+ }
+ viewState.enabled = false
+// launch {
+// try {
+// Retrofit.Builder()
+// .baseUrl("https://git.omega-r.club")
+// .build()
+// .create(Api::class.java)
+// .test("aga", RequestBody.create(MediaType.get("text/html"), "Run"))
+// } catch (e: Exception) {
+// throw ErrorHandler().handleThrowable(e)
+// }
+// }
+
+ DialogScreenFactory.createLauncher().launch()
+// viewState.showMe
+// log {
+// "Message"
+// }ssage(Text.from("test"), Action(Text.from("Test")) {
+// viewState.showToast(Text.from("test"))
+// })
+//
+// viewState.showQuery(
+// Text.from("message"),
+// Text.from("title"),
+// positiveAction = Action("Yes"),
+// negativeAction = Action("No")
+// )
+ }
+
+ override fun onLaunchResult(requestCode: Int, success: Boolean, data: Serializable?): Boolean {
+ viewState.showToast(Text.from("onLaunchResult = $requestCode"))
+ return super.onLaunchResult(requestCode, success, data)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/MainView.kt b/app/src/main/java/com/omega_r/base/simple/MainView.kt
new file mode 100644
index 0000000..84a18f8
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/MainView.kt
@@ -0,0 +1,11 @@
+package com.omega_r.base.simple
+
+import com.omega_r.base.mvp.views.OmegaView
+
+interface MainView: OmegaView {
+
+ var list: String
+
+ var enabled: Boolean
+}
+
diff --git a/app/src/main/java/com/omega_r/base/simple/ParentRepository.kt b/app/src/main/java/com/omega_r/base/simple/ParentRepository.kt
new file mode 100644
index 0000000..e59fb55
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/ParentRepository.kt
@@ -0,0 +1,7 @@
+package com.omega_r.base.simple
+
+interface ParentRepository {
+
+ suspend fun parentMethod(): String
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/SampleApp.kt b/app/src/main/java/com/omega_r/base/simple/SampleApp.kt
new file mode 100644
index 0000000..86c318e
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/SampleApp.kt
@@ -0,0 +1,11 @@
+package com.omega_r.base.simple
+
+import android.app.Application
+
+class SampleApp : Application() {
+
+ override fun onCreate() {
+ super.onCreate()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/Settings.kt b/app/src/main/java/com/omega_r/base/simple/Settings.kt
new file mode 100644
index 0000000..7e81885
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/Settings.kt
@@ -0,0 +1,17 @@
+package com.omega_r.base.simple
+
+import com.omega_r.base.settings.BaseSettings
+import com.omega_r.base.settings.SettingStorage
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.adapter
+
+class Settings(setting: SettingStorage, moshi: Moshi): BaseSettings(setting) {
+
+ var firstLaunch by provideBoolean(key = "jklh", defaultValue = false, label = "possim")
+
+ @OptIn(ExperimentalStdlibApi::class)
+ var session: Session? by provideAnyJson(key = "", defaultValue = null, label = "sdf", moshi.adapter())
+
+ class Session(val token: String, val refreshToken: String)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/TestEntity.kt b/app/src/main/java/com/omega_r/base/simple/TestEntity.kt
new file mode 100644
index 0000000..7de29bd
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/TestEntity.kt
@@ -0,0 +1,11 @@
+package com.omega_r.base.simple
+
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+import java.io.Serializable
+
+@Parcelize
+class TestEntity : Parcelable, Serializable {
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/TestFragment.kt b/app/src/main/java/com/omega_r/base/simple/TestFragment.kt
new file mode 100644
index 0000000..3b76967
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/TestFragment.kt
@@ -0,0 +1,6 @@
+package com.omega_r.base.simple
+
+import com.omegar.mvp.MvpAppCompatFragment
+
+class TestFragment(contentLayoutId: Int) : MvpAppCompatFragment(contentLayoutId) {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogDialogFragment.kt b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogDialogFragment.kt
new file mode 100644
index 0000000..784a0b2
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogDialogFragment.kt
@@ -0,0 +1,26 @@
+package com.omega_r.base.simple.dialog_fragment
+
+import android.os.Bundle
+import com.omega_r.base.annotations.OmegaContentView
+import com.omega_r.base.components.OmegaDialogFragment
+import com.omega_r.base.simple.R
+import com.omega_r.libs.omegatypes.Text
+import com.omegar.libs.omegalaunchers.createDialogFragmentLauncher
+
+/**
+ * Created by Anton Knyazev on 10.03.2020.
+ */
+@OmegaContentView(R.layout.activity_main)
+class DialogDialogFragment : OmegaDialogFragment(), DialogView {
+
+
+ override val presenter: DialogPresenter by providePresenter()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setClickListener(R.id.button) {
+ showToast(Text.from("Test from dialog"))
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogPresenter.kt b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogPresenter.kt
new file mode 100644
index 0000000..0b3cd00
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogPresenter.kt
@@ -0,0 +1,10 @@
+package com.omega_r.base.simple.dialog_fragment
+
+import com.omega_r.base.mvp.presenters.OmegaPresenter
+
+/**
+ * Created by Anton Knyazev on 10.03.2020.
+ */
+class DialogPresenter : OmegaPresenter() {
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogView.kt b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogView.kt
new file mode 100644
index 0000000..da2a40b
--- /dev/null
+++ b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogView.kt
@@ -0,0 +1,8 @@
+package com.omega_r.base.simple.dialog_fragment
+
+import com.omega_r.base.mvp.views.OmegaView
+
+/**
+ * Created by Anton Knyazev on 10.03.2020.
+ */
+interface DialogView: OmegaView
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 93fcf82..0e5e488 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,14 +1,26 @@
-
+
+
+
+
+ android:layout_height="match_parent"
+ app:layoutManager="LinearLayoutManager" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_test.xml b/app/src/main/res/layout/item_test.xml
index ac0d79c..483007c 100644
--- a/app/src/main/res/layout/item_test.xml
+++ b/app/src/main/res/layout/item_test.xml
@@ -1,5 +1,6 @@
+ android:layout_height="wrap_content"
+ />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_test2.xml b/app/src/main/res/layout/item_test2.xml
new file mode 100644
index 0000000..8ba1016
--- /dev/null
+++ b/app/src/main/res/layout/item_test2.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_test_3.xml b/app/src/main/res/layout/item_test_3.xml
new file mode 100644
index 0000000..429a9d4
--- /dev/null
+++ b/app/src/main/res/layout/item_test_3.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..915f2e4
--- /dev/null
+++ b/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 5885930..460f967 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,7 +1,7 @@
-