> For the complete documentation index, see [llms.txt](https://gramhal.gitbook.io/matar/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gramhal.gitbook.io/matar/developer-reference/frontend-code/code-directories/core-directory.md).

# Core Directory

{% hint style="info" %}
The core directory contains code and abstract classes that are extended by other activities in the Matar Android app.
{% endhint %}

***

## Core Directory

```
--core(directory)
       --base(directory)
         --ActBase.kt(file)(ActBase is an abstract class serving as blueprints for other classes)
         --BaseActivity.kt(file)()
         --FragBase.kt(file)
       --DataResult.kt(file)
       --ResultWrapper.kt(file)
```

### core/base/ActBase.kt

```kotlin
package com.matar.app.core.base

import android.os.Bundle
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import com.akexorcist.localizationactivity.ui.LocalizationActivity
import com.matar.app.ui.features.firebase.AnalyticsViewModel
import com.matar.app.ui.features.firebase.FirebaseViewModel
import com.matar.app.ui.util.PreferenceManager

abstract class ActBase<actBinding : ViewBinding> : LocalizationActivity() {

    lateinit var binding: actBinding

    protected val analyticsViewModel: AnalyticsViewModel by viewModels()
    protected val firebaseViewModel: FirebaseViewModel by viewModels()

    lateinit var preferenceManager: PreferenceManager

    override fun onCreate(savedInstanceState: Bundle?) {
        preferenceManager = PreferenceManager(this)
        super.onCreate(savedInstanceState)
        binding = setViewBinding()
        setContentView(binding.root)
        bindObjects()
        bindListeners()
        bindMethods()
    }

    abstract fun setViewBinding(): actBinding
    abstract fun bindObjects()
    abstract fun bindListeners()
    abstract fun bindMethods()

    fun openFragment(fragment: Fragment, fragmentName: String, fragmentContainerId: Int) {
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(fragmentContainerId, fragment, fragmentName)
        transaction.disallowAddToBackStack()
        transaction.commit()

    }

}
```

**Describing Code :**

This class is meant to be extended by other activities in your Android app. Here's a breakdown of what this class does:

1. **Imports**: It imports necessary packages and classes that are used in the class.
2. **Class Declaration**: It declares a generic class **ActBase** that extends **LocalizationActivity**. The generic type **actBinding** is expected to be a ViewBinding class specific to the child activity that extends this base class.
3. **Properties**:
   * **binding**: This property is used to hold the instance of the view binding for the child activity.
   * **analyticsViewModel**
   * **preferenceManager**
4. **onCreate() Method**: This method is an Android lifecycle method that gets called when the activity is created. In this method:
   * An instance of the activity's content view is set to the root view of the binding.
5. **Abstract Methods**:
   * **setViewBinding()**

     : This abstract method is meant to be implemented by child activities to provide the appropriate view binding for that activity.
   * **bindObjects()**
6. **openFragment() Method**: This method is used to replace a fragment within the activity's fragment container. It takes three parameters:
   * **fragment**: The fragment to be displayed.
   * \*\*fragmentName \*\*: A tag or name for the fragment.
   * \*\*fragmentContainerId \*\*: The ID of the container where the fragment should be displayed. It replaces the current fragment with the specified fragment using a transaction.

***

### **core/base/BaseActivity.kt**

```kotlin
package com.matar.app.core.base

import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.util.Patterns
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import com.akexorcist.localizationactivity.ui.LocalizationActivity
import com.matar.app.R
import com.matar.app.ui.dialog.AlertDialogs
import com.matar.app.ui.features.firebase.AnalyticsViewModel
import com.matar.app.ui.features.firebase.FirebaseViewModel
import com.matar.app.ui.util.PreferenceManager

abstract class BaseActivity : LocalizationActivity() {
    var dialog: AlertDialogs? = null
    var bind: ViewDataBinding? = null
    lateinit var preferencesManager: PreferenceManager

    protected val analyticsViewModel: AnalyticsViewModel by viewModels()
    protected val firebaseViewModel: FirebaseViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bind = DataBindingUtil.setContentView(this, getLayout())
        onViewReady(bind)
        preferencesManager = PreferenceManager(applicationContext)
        dialog = AlertDialogs(this)
    }


    fun showDialog() {
        dialog?.show()
    }

    fun hideDialog() {
        if (dialog != null) {
            dialog?.dismiss()
        }
    }

    protected abstract fun onViewReady(bind: ViewDataBinding?)
    abstract fun getLayout(): Int

    fun showToast(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }


    fun isValidEmail(target: CharSequence?): Boolean {
        return if (target == null) {
            false
        } else {
            Patterns.EMAIL_ADDRESS.matcher(target).matches()
        }
    }

    fun openFragment(fragment: Fragment, fragmentName: String) {
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.fragmentContainer, fragment, fragmentName)
        transaction.disallowAddToBackStack()
        transaction.commit()

    }

    fun Context.hideKeyboard(view: View) {
        val inputMethodManager =
            getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
    }
}
```

**Describing Code:**

An abstract base class named **BaseActivity** in an Android application serve as a foundation for other activities in your app. Let's break down what this class does:

1. **Inheritance**: **BaseActivity** inherits from another class named **LocalizationActivity**.
2. **Properties**:
   * **dialog**
   * **bind**
   * **preferencesManager**
   * **analyticsViewModel**
   * **firebaseViewModel**
3. **onCreate Method**: This is an override of the **onCreate** method from the Android **Activity** class. It sets up the activity by:
   * Setting the content view using data binding.
   * Calling
   * Initializing the
   * Creating an instance of
4. **showDialog and hideDialog Methods**: These methods allow you to show and hide dialog boxes, respectively. They use the **dialog** property.
5. **onViewReady and getLayout Methods**: These are abstract methods that you must implement in subclasses. **onViewReady** is called in **onCreate** after setting up the view, and **getLayout** should return the layout resource ID for the activity layout.
6. **showToast Method**: A utility method for displaying toast messages.
7. **isValidEmail Method**: A utility method for checking if a given string is a valid email address using a regular expression.
8. **openFragment Method**: This method allows you to replace the fragment in the activity's layout with a new one. It uses the **FragmentManager** to perform the transaction.
9. **hideKeyboard Extension Function**: An extension function for hiding the soft keyboard. It takes a **View** as an argument and uses the **InputMethodManager** to hide the keyboard.

Subclasses of **BaseActivity** can implement the **onViewReady** and **getLayout** methods to customize their behavior. Also, analytics and Firebase functionality can be integrated for tracking user interactions into the app.

***

### **core/base/Fragbase.kt**

```kotlin
package com.matar.app.core.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.viewbinding.ViewBinding
import com.matar.app.ui.features.firebase.AnalyticsViewModel
import com.matar.app.ui.features.firebase.FirebaseViewModel

abstract class FragBase<actBinding : ViewBinding> : Fragment() {

    protected val analyticsViewModel: AnalyticsViewModel by viewModels()
    protected val firebaseViewModel: FirebaseViewModel by viewModels()

    lateinit var binding: actBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = setViewBinding()
        bindObjects()
        bindListener()
        bindMethod()
        return binding.root
    }

    abstract fun setViewBinding(): actBinding
    abstract fun bindObjects()
    abstract fun bindListener()
    abstract fun bindMethod()
}
```

**Describing Code:**

1. **FragBase** is an abstract class that extends **Fragment**, making it a base class for other fragments in your Android app.
2. The class is parameterized with **actBinding**, which is expected to be a subtype of **ViewBinding**. This allows you to use view binding to interact with your fragment's layout.
3. Inside the class, two view models are declared and initialized using **viewModels()**. These view models are **analyticsViewModel** and **firebaseViewModel**, which are presumably used for handling analytics and Firebase-related functionality in your app.
4. A **lateinit** property **binding** of type **actBinding** is declared. This property will be used to store the view binding instance for the fragment's layout.
5. The **onCreateView** function is overridden. This function is called when the fragment is created and is responsible for inflating the fragment's layout, binding views, and returning the root view.
6. Inside **onCreateView**, **setViewBinding()** is called to initialize the **binding** property with the appropriate view binding instance for the fragment.
7. The **bindObjects()**, **bindListener()**, and **bindMethod()** functions are called within **onCreateView**. These are abstract functions that must be implemented by subclasses of **FragBase**. They are meant for initializing objects, setting up listeners, and binding methods related to the fragment's functionality.

**FragBase** can provide\*\* \*\* implementations for **setViewBinding()**, **bindObjects()**, **bindListener()**, and **bindMethod()**, which allows you to customize the behavior and layout of your fragment.

***

### **core/DataResult.kt**

```kotlin
package com.matar.app.core

sealed class DataResult<out T> {
    data class Success<out T>(val value: T): DataResult<T>()
    data class Error(val exception: Exception) : DataResult<Nothing>()
}

fun <T, V> DataResult<T>.toResultWrapper(mapper: (T) -> V) = when (this) {
    is DataResult.Error -> ResultWrapper.Error(exception)
    is DataResult.Success -> ResultWrapper.Success(mapper(value))
}
```

***

### core/ResultWrapper.kt

```kotlin
package com.matar.app.core

sealed class ResultWrapper<out T> {

    data class Success<out T>(val value: T) : ResultWrapper<T>()

    data class Error(val throwable: Throwable? = null) : ResultWrapper<Nothing>()

    object None : ResultWrapper<Nothing>()

    object Loading : ResultWrapper<Nothing>()

    @Throws(Exception::class)
    fun takeValueOrThrow(): T {
        return when (this) {
            is Success -> value
            is Error -> throw throwable ?: Throwable()
            else -> throw Throwable("Unknown the result type $this")
        }
    }
}
```
